Obsolete Device API Functions Model to Simulator Interfaces
API Reference Manual  / 

Model to Model Interfaces

a20

Name

a20 — access the A20 line

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(a20) {
        void (*set_a20_line)(conf_object_t *NOTNULL obj, int value);
        int (*get_a20_line)(conf_object_t *NOTNULL obj);
};

#define A20_INTERFACE "a20"

Python

import simics

class simics.a20_interface_t(set_a20_line=None, get_a20_line=None)

Description

This interface is used between the A20 line handling device (typically the keyboard controller) and the x86 processor. The processor implements this interface and the keyboard controller calls it.

Execution Context

Cell Context for all methods.

aarch64_sysreg

Name

aarch64_sysreg — interface for accessing system registers of AArch64 systems

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

SIM_INTERFACE(aarch64_sysreg) {
        uint64 (*read_register)(conf_object_t *obj,
                                int op0, int op1, int crn, int crm,
                                int op2, bool inquiry);
        void (*write_register)(conf_object_t *obj,
                               int op0, int op1, int crn, int crm,
                               int op2, uint64 value);
};

#define AARCH64_SYSREG_INTERFACE "aarch64_sysreg"

Python

import simics

class simics.aarch64_sysreg_interface_t(read_register=None, write_register=None)

Description

This is an interface that provides access to AArch64 system registers on an external device using the encoding tuple (op0, op1, CRn, CRm, op2)

The read_register function reads a system register identified by its encoding. If inquiry is true, the read must not have side effects.

The write_register function writes value to the system register identified by its encoding.

Execution Context

Cell Context for all methods.

apic_destination_mode_t, apic_delivery_mode_t, apic_trigger_mode_t, apic_bus_status_t, apic_bus

Name

apic_destination_mode_t, apic_delivery_mode_t, apic_trigger_mode_t, apic_bus_status_t, apic_bus — interface for apic buses

Synopsis

C and DML

#include <simics/devs/apic.h> // in C
import "simics/devs/apic.dml"; // in DML

typedef enum {
        Apic_Destination_Mode_Physical = 0,
        Apic_Destination_Mode_Logical = 1
} apic_destination_mode_t;

typedef enum {
        Apic_Delivery_Mode_Fixed = 0,
        Apic_Delivery_Mode_Lowest_Priority = 1,
        Apic_Delivery_Mode_SMI = 2,
        Apic_Delivery_Mode_Remote_Read = 3,
        Apic_Delivery_Mode_NMI = 4,
        Apic_Delivery_Mode_INIT = 5,
        Apic_Delivery_Mode_Start_Up = 6,
        Apic_Delivery_Mode_Ext_INT = 7
} apic_delivery_mode_t;

typedef enum {
        Apic_Trigger_Mode_Edge = 0,
        Apic_Trigger_Mode_Level = 1
} apic_trigger_mode_t;

typedef enum {
        Apic_Bus_Accepted = 0,
        Apic_Bus_Retry = 1,
        Apic_Bus_No_Target = 2,
        Apic_Bus_Invalid = 3
} apic_bus_status_t;

SIM_INTERFACE(apic_bus) {
        apic_bus_status_t (*interrupt)(conf_object_t *obj,
                                       apic_destination_mode_t dest_mode,
                                       apic_delivery_mode_t delivery_mode,
                                       int level_assert,
                                       apic_trigger_mode_t trigger_mode,
                                       uint8 vector,
                                       uint8 destination);
};

#define APIC_BUS_INTERFACE "apic_bus"

Python

import simics

simics.Apic_Destination_Mode_Logical
simics.Apic_Destination_Mode_Physical
simics.Apic_Delivery_Mode_Start_Up
simics.Apic_Delivery_Mode_NMI
simics.Apic_Delivery_Mode_Fixed
simics.Apic_Delivery_Mode_Lowest_Priority
simics.Apic_Delivery_Mode_INIT
simics.Apic_Delivery_Mode_Ext_INT
simics.Apic_Delivery_Mode_SMI
simics.Apic_Delivery_Mode_Remote_Read
simics.Apic_Trigger_Mode_Edge
simics.Apic_Trigger_Mode_Level
simics.Apic_Bus_Invalid
simics.Apic_Bus_Retry
simics.Apic_Bus_Accepted
simics.Apic_Bus_No_Target
class simics.apic_bus_interface_t(interrupt=None)

Description

This interface is implemented by all apic buses, and used by the IO-APICs to send a message over the bus.

Messages with delivery mode Apic_Delivery_Mode_Ext_INT needs to be acknowledged. They are acknowledged at the object pointed to by the apic’s “pic” attribute via the interrupt_cpu interface.

See the architecture software developer’s manual for more information about the parameters. For IPIs, the sender is responsible for filtering out reserved vectors (vectors 0 through 15) and flagging the appropriate error on the sending side. For I/O-APIC initiated interrupts, reserved vectors can be sent and will flag errors in the receiving APICs.

Execution Context

Cell Context for all methods.

apic_bus_to_apic

Name

apic_bus_to_apic — This interface is provided by APIC to APIC bus

Synopsis

C and DML


SIM_INTERFACE(apic_bus_to_apic) {
        uint32      (*get_arbitration_id)(conf_object_t *obj);
        void        (*set_arbitration_id)(conf_object_t *obj, uint32 val);

        uint32      (*get_arbitration_priority)(conf_object_t *obj);
        uint32      (*get_processor_priority)(conf_object_t *obj);

        uint32      (*get_apr)(conf_object_t *obj);
        uint32      (*get_lvt_lint0)(conf_object_t *obj);

        apic_type_t (*get_apic_type)(conf_object_t *obj);
        uint32      (*get_apic_id)(conf_object_t *obj);

        bool        (*get_ack_in_progress)(conf_object_t *obj);

        void        (*set_pin_status)(conf_object_t *obj, x86_pin_t pin, int status);

        bool        (*has_physical_destination)(conf_object_t *obj,
                                                uint32 destination,
                                                bool exclude,
                                                uint32 exclude_id);
        bool        (*has_logical_destination)(conf_object_t *obj, uint32 destination);

        bool        (*is_focus)(conf_object_t *obj, uint8 vector);
        bool        (*is_interrupt_slot_available)(conf_object_t *obj, uint8 vector);
        void        (*remote_read)(conf_object_t *obj, uint8 vector);
        void        (*do_lower_ext_int)(conf_object_t *obj);
        void        (*start_up)(conf_object_t *obj, uint32 start_address);

#ifndef PYWRAP
        void        (*interrupt)(conf_object_t *obj,
                                 apic_delivery_mode_t delivery_mode,
                                 bool level_assert,
                                 apic_trigger_mode_t trigger_mode,
                                 uint8 vector,
                                 interrupt_ack_fn_t ack_func,
                                 conf_object_t *ack_func_arg);

#endif
};

#define APIC_BUS_TO_APIC_INTERFACE "apic_bus_to_apic"

Description

get_arbitration_id and set_arbitration_id methods are used to get/set value of the 4-bit software-transparent arbitration id register of the LAPIC.

get_apic_type method is used to get type of the certain APIC. Also APIC has an attribute apic_type which indicate APIC’s type. The type of APIC is one of the constants defined in apic_type_t.

There are 3 types of the APIC:

  1. “P6” - this type of the APIC is used in system based on P6 family and Pentium® processors, obsolete.

  2. “P4” - this type of the APIC is used in system based Pentium® 4 and Intel® Xeon® processors. Also “P4” APICs is an extension of the APIC architecture found in the P6 family processors. Architecture of the APIC with type “P4” called the xAPIC architecture. See more information in IA SDM Vol3 ch. 10.3.

  3. “X2” - this type of the APIC provides an extension of the xAPIC architecture (“P4” APIC type) - x2APIC. The x2APIC architecture provides backward compatibility to the xAPIC architecture and forward extendability for future Intel platform innovations. These extensions and modifications are supported by a new mode of execution (x2APIC mode) are detailed in IA SDM Vol. 3 Section 10.12.

remote_read method is used to do remote memory transaction. Remote transactions are supported only in the 82489DX and local APIC for Pentium® processors. This method is obsolete for modern processors.

get_apic_id method is used to get local APIC ID.

get_arbitration_priority method is used to get arbitration priority of the local APIC. Each local APIC is given an arbitration priority of from 0 to 15. The arbitration priority is available only for system based on P6 family processors. This method is obsolete for modern processors.

get_apr method is used to get value of the read only Arbitration Priority Register (APR) of the APIC. The APR is available only for system based on P6 family processors, so it is obsolete method for modern processors.

has_physical_destination and has_logical_destination methods are used to find out which destination mode has IPI: physical or logical.

is_focus method is used to find out is to be checked processor is focus processor. A processor is said to be the focus of an interrupt if it is currently servicing that interrupt or if it has a pending request for that interrupt. This arbitration scheme was used only in P6 family and Pentium® processors, so it is obsolete method for modern processors.

The start_up function is used by the local APIC to bring the processor obj out of the waiting for start-up IPI state, with a start address of start_address.

is_interrupt_slot_available method is used to do check for the free interrupt slots in the local APIC. Only the local APICs having free interrupt slots participate in the lowest priority arbitration. The interrupt slot based arbitration scheme was used only in system based on the P6 family and Pentium® processors and it is not used in modern processors (obsolete method).

set_pin_status method is used to specify interrupt input pin polarity of the processor’s LINT0 and LINT1 pins: (0) active high or (1) active low.

get_ack_in_progress method indicates that acknowledging of the external interrupt is currently processing.

do_lower_ext_int method is used to clear posted and requested interrupts in the processor.

get_processor_priority method is used to get value of the Processor Priority Register (PPR) of the APIC.

get_lvt_lint0 method is used to get value of the LVT entry called LINT0 of the APIC.

interrupt method is used to send interrupt from APIC bus to certain APIC. Also interrupt method is not available from Python.

Execution Context

Cell Context for all methods.

apic_bus_v2

Name

apic_bus_v2 — interface for handling 32-bit address mode interrupts

Synopsis

C and DML


SIM_INTERFACE(apic_bus_v2) {
        apic_bus_status_t (*interrupt)(conf_object_t *obj,
                apic_destination_mode_t dest_mode,
                apic_delivery_mode_t delivery_mode,
                int level_assert,
                apic_trigger_mode_t trigger_mode,
                uint8 vector,
                uint32 destination);
};
#define APIC_BUS_V2_INTERFACE "apic_bus_v2"

Description

The interface is used to handle extended 32-bit addressing mode supported by x2APIC. See apic_bus documentation.

Execution Context

Cell Context.

local_apic_interrupt_t, apic_cpu

Name

local_apic_interrupt_t, apic_cpu — interface for the local APIC

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef enum {
        Apic_Lvt_2e = 0x2e0,
        Apic_CMCI = 0x2f0,
        Apic_Performance_Counter = 0x340,
        Apic_Thermal_Sensor = 0x330
} local_apic_interrupt_t;

SIM_INTERFACE(apic_cpu) {
        uint64 (*tpr_r)(conf_object_t *NOTNULL obj);
        void (*tpr_w)(conf_object_t *NOTNULL obj, uint64 tpr);
        void (*local_int)(conf_object_t *NOTNULL obj,
                          local_apic_interrupt_t int_type);
        void (*power_on)(conf_object_t *NOTNULL obj, bool bsp, int apic_id);
        void (*init)(conf_object_t *NOTNULL obj);
        bool (*enabled_r)(conf_object_t *NOTNULL obj);
};

#define APIC_CPU_INTERFACE "apic_cpu"

Python

import simics

simics.Apic_Lvt_2e
simics.Apic_Performance_Counter
simics.Apic_Thermal_Sensor
simics.Apic_CMCI
class simics.apic_cpu_interface_t(tpr_r=None, tpr_w=None, local_int=None,
        power_on=None, init=None, enabled_r=None)

Description

This interface is implemented by the local APIC device and is used by the processor and machine initialization code to interact with the local APIC.

The tpr_r and tpr_w methods read and write the task priority register. The format of the tpr argument and the returned value from tpr_r is the same as for CR8, meaning TPR[bits 7:4], zero extended to 64 bits.

Interrupts coming from the CPU itself are passed via the local_int function. The type of interrupt is one of the constants defined in local_apic_interrupt_t.

The init function is called by the CPU when it receives the INIT signal. The APIC should only update its internal state and not propagate this signal further. Both the CPU and the APIC should reset their pending interrupt flags when this function is called. The init function is not called at instantiation time.

The power_on function is called at machine creation time, and the call initializes the APIC to the power on state. The bsp argument is true if the APIC is connected to the boot processor, and false otherwise. The initial APIC ID is set through the apic_id argument. The power_on function would typically be called from component code for the processor that includes the APIC.

The enabled_r method returns bit 11 from the APIC BASE MSR, and is used by the processor to return the correct status for CPUID.

Execution Context

Cell Context for all methods.

apic_delivery_status_t

Name

apic_delivery_status_t — APIC delivery status

Synopsis

C and DML

#include <simics/devs/apic.h> // in C
import "simics/devs/apic.dml"; // in DML

typedef enum {
        Apic_Delivery_Status_Idle = 0,
        Apic_Delivery_Status_Send_Pending = 1
} apic_delivery_status_t;

Python

import simics

simics.Apic_Delivery_Status_Idle
simics.Apic_Delivery_Status_Send_Pending

apic_rr_status_t

Name

apic_rr_status_t — APIC RR status

Synopsis

C and DML

#include <simics/devs/apic.h> // in C
import "simics/devs/apic.dml"; // in DML

typedef enum {
        Apic_RR_Invalid = 0,
        Apic_RR_Pending = 1,
        Apic_RR_Valid = 2
} apic_rr_status_t;

Python

import simics

simics.Apic_RR_Pending
simics.Apic_RR_Invalid
simics.Apic_RR_Valid

apic_timer_mode_t

Name

apic_timer_mode_t — type for expressing APIC timer mode

Synopsis

C and DML


typedef enum {
    Apic_Timer_Mode_One_Shot        = 0,
    Apic_Timer_Mode_Periodic        = 1,
    Apic_Timer_Mode_Tsc_Deadline    = 2
} apic_timer_mode_t;

apic_type_t

Name

apic_type_t — APIC types

Synopsis

C and DML


typedef enum {
        Apic_P6,
        Apic_P4,
        Apic_X2
} apic_type_t;

arinc429_bus

Name

arinc429_bus — interface to Arinc-429 serial buses

Synopsis

C and DML

#include <simics/devs/arinc-429.h> // in C
import "simics/devs/arinc-429.dml"; // in DML

SIM_INTERFACE(arinc429_bus) {
    void (*send_word)(conf_object_t *bus, uint32 word, int parity_ok);
};
#define ARINC429_BUS_INTERFACE "arinc429_bus"

Python

import simics

class simics.arinc429_bus_interface_t(send_word=None)

Description

Interface to Arinc-429 serial buses.

The send_word function is used by a device to send an Arinc-429 formatted word. The most significant bit (bit 31) is the parity bit, but if the device have checksumming built in, it can set parity_ok to tell the bus to ignore bit 31 of the data.

If the parity bit is already calculated, pass -1 as parity_ok.

Execution Context

Cell Context for all methods.

arinc429_receiver

Name

arinc429_receiver — interface to Arinc-429 compatible receivers

Synopsis

C and DML

#include <simics/devs/arinc-429.h> // in C
import "simics/devs/arinc-429.dml"; // in DML

SIM_INTERFACE(arinc429_receiver) {
    void (*receive_word)(conf_object_t *dev, uint32 word, int parity_ok);
};
#define ARINC429_RECEIVER_INTERFACE "arinc429_receiver"

Python

import simics

class simics.arinc429_receiver_interface_t(receive_word=None)

Description

Interface to Arinc-429 compatible receivers.

The receive_word is called when there is traffic on the bus. word contains the data received (with valid parity bit), and the parity_ok tells whether the parity of the word is correct or not.

Execution Context

Cell Context for all methods.

arm_avic_t, arm_avic

Name

arm_avic_t, arm_avic — ARM AVIC interface

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

typedef struct arm_avic {
        int valid;
        uint32 address;
} arm_avic_t;

SIM_INTERFACE(arm_avic) {
        arm_avic_t (*get_interrupt_address)(conf_object_t *obj);
};

#define ARM_AVIC_INTERFACE "arm_avic"

Python

import simics

class simics.arm_avic_t(valid=0, address=0)
class simics.arm_avic_interface_t(get_interrupt_address=None)

Description

The arm_avic interface makes it possible for an ARM processor to get the interrupt vector address from an AVIC device connected to the processor core. Both processor and AVIC must enable the AVIC interface to support this feature.

The processor calls get_interrupt_address function to get the interrupt vector address. The AVIC returns an arm_avic_t struct with a valid field and an address field, the address field is only valid when the valid is not 0.

Execution Context

Cell Context for all methods.

arm_coprocessor

Name

arm_coprocessor — ARM coprocessor interface

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

SIM_INTERFACE(arm_coprocessor) {
        void (*process_data)(conf_object_t *NOTNULL obj,
                             uint32 CRd,
                             uint32 opcode_1,
                             uint32 CRn,
                             uint32 CRm,
                             uint32 opcode_2,
                             int type);
        void (*load_coprocessor)(conf_object_t *NOTNULL obj,
                                 uint32 CRd,
                                 uint32 N,
                                 uint32 Options,
                                 uint32 value,
                                 int type);

        uint32 (*read_register)(conf_object_t *NOTNULL obj,
                                uint32 opcode_1,
                                uint32 CRn,
                                uint32 CRm,
                                uint32 opcode_2,
                                int type);
        void (*write_register)(conf_object_t *NOTNULL obj,
                               uint32 value,
                               uint32 opcode_1,
                               uint32 CRn,
                               uint32 CRm,
                               uint32 opcode_2,
                               int type);
        uint64 (*read_register_64_bit)(conf_object_t *NOTNULL obj,
                                       uint32 opcode_1,
                                       uint32 CRm,
                                       int type);
        void (*write_register_64_bit)(conf_object_t *NOTNULL obj,
                                      uint64 value,
                                      uint32 opcode_1,
                                      uint32 CRm,
                                      int type);
        uint32 (*store_coprocessor)(conf_object_t *NOTNULL obj,
                               uint32 CRd,
                               uint32 N,
                               uint32 Options,
                               int type);
        void (*reset)(conf_object_t *NOTNULL obj, int hard_reset);
};

#define ARM_COPROCESSOR_INTERFACE "arm_coprocessor"

Python

import simics

class simics.arm_coprocessor_interface_t(process_data=None, load_coprocessor=None,
        read_register=None, write_register=None, read_register_64_bit=None,
        write_register_64_bit=None, store_coprocessor=None, reset=None)

Description

A coprocessor for the ARM has to provide the arm_coprocessor_interface. This interface defines the functions that will be called when the coprocessor instructions (cdp, ldc, mcr, mrc, mrrc, mcrr, stc) are executed.

The read_register_64_bit and write_register_64_bit are used for mrrc and mccr instructions which read and write 64 bit values in to two registers.

The interface also defines a flag, finished, which indicates whether a memory transfer operation is finished or not.

The function reset is called when the cpu is reset, and allows the coprocessor to also do a reset, the argument hard_reset indicates whether the reset was soft (0) or hard (1).

Execution Context

Cell Context for all methods.

arm_cpu_group_event

Name

arm_cpu_group_event — ARM cpu group event interface

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

SIM_INTERFACE(arm_cpu_group_event) {
        void (*signal_event)(conf_object_t *obj);
};

#define ARM_CPU_GROUP_EVENT_INTERFACE "arm_cpu_group_event"

Python

import simics

class simics.arm_cpu_group_event_interface_t(signal_event=None)

Description

This interface is only intended to be used between Arm CPU objects. It contains the functions needed for cross-CPU communication related to event signalling.

signal_event notifies the CPU to set the event register.

Execution Context

Threaded Context for all methods.

arm_cpu_group_exclusive

Name

arm_cpu_group_exclusive — ARM cpu group exclusive interface

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

SIM_INTERFACE(arm_cpu_group_exclusive) {
        void (*mark_exclusive)(
                conf_object_t *obj,
                physical_address_t address,
                physical_address_t size);
        bool (*clear_and_probe_exclusive)(
                conf_object_t *obj,
                physical_address_t clear_address,
                physical_address_t clear_size,
                physical_address_t probe_address,
                physical_address_t probe_size);
};

#define ARM_CPU_GROUP_EXCLUSIVE_INTERFACE "arm_cpu_group_exclusive"

Python

import simics

class simics.arm_cpu_group_exclusive_interface_t(mark_exclusive=None,
        clear_and_probe_exclusive=None)

Description

This interface is only intended to be used between Arm CPU objects. It contains the functions needed for cross-CPU communication related to exclusive memory accesses.

mark_exclusive notifies the CPU that another CPU has marked the address range as exclusive. The CPU must then probe all CPUs in the CPU group for exclusive address ranges using probe_exclusive and possibly invalidate them using clear_exclusive before accessing the address range.

clear_and_probe_exclusive notifies the CPU to invalidate any exclusive address ranges that it has overlapping the specified clear address range. Also returns true if the CPU still has any exclusive address ranges overlapping the specified probe address range.

Execution Context

Threaded Context for all methods.

arm_cpu_group_tlb

Name

arm_cpu_group_tlb — ARM cpu group tlb interface

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

SIM_INTERFACE(arm_cpu_group_tlb) {
        void (*invalidate_tlb)(
                conf_object_t *obj,
                arm_translation_regime_t translation_regime,
                bool by_virtual_address,
                logical_address_t virtual_address);
};

#define ARM_CPU_GROUP_TLB_INTERFACE "arm_cpu_group_tlb"

Python

import simics

class simics.arm_cpu_group_tlb_interface_t(invalidate_tlb=None)

Description

This interface is only intended to be used between Arm CPU objects. It contains the functions needed for cross-CPU communication related to TLB invalidation.

invalidate_tlb notifies the CPU to invalidate TLB entries related to the translation regime. If by_virtual_address is true only entries containing the specified virtual address should be invalidated, otherwise all entries should be invalidated.

Execution Context

Threaded Context for all methods.

arm_gic_cpu_state

Name

arm_gic_cpu_state — interface for ARM processors to provide state to gic-models

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

SIM_INTERFACE(arm_gic_cpu_state) {
        arm_cpu_state_t (*get_cpu_state)(conf_object_t *obj);
};

#define ARM_GIC_CPU_STATE_INTERFACE "arm_gic_cpu_state"

Python

import simics

class simics.arm_gic_cpu_state_interface_t(get_cpu_state=None)

Description

This arm_gic_cpu_state interface is used providing cpu states for a device implementing the Generic Interrupt Controller architecture.

The get_cpu_state_info function is called to get current state of the a CPU, e.g. exception level, secure mode.

See Also

arm_cpu_state_t

Execution Context

Cell Context for all methods.

gic_reg_info_t, arm_gic

Name

gic_reg_info_t, arm_gic — interface for ARM cores to access generic interrupt controller

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

typedef struct gic_reg_info {
        int op1;
        int crn;
        int crm;
        int op2;
        arm_cpu_state_t cpu_state;
} gic_reg_info_t;

SIM_INTERFACE(arm_gic) {
        uint64 (*read_register)(conf_object_t *obj, gic_reg_info_t reg_info,
                                bool inquiry);
        void (*write_register)(conf_object_t *obj, gic_reg_info_t reg_info,
                               uint64 value);
        void (*cpu_state_changed)(conf_object_t *obj, arm_cpu_state_t cpu_state);
};

#define ARM_GIC_INTERFACE "arm_gic"

Python

import simics

class simics.gic_reg_info_t(op1=0, crn=0, crm=0, op2=0,
        cpu_state=arm_cpu_state_t())
class simics.arm_gic_interface_t(read_register=None, write_register=None,
        cpu_state_changed=None)

Description

This arm_gic interface is used accessing registers in a device implementing the Generic Interrupt Controller architecture..

The read_register function is called reading the registers in GIC device.

The write_register function is called writing the registers in GIC device.

The cpu_state_changed function is called to notify the GIC device that the cpu has changed state. This function is only called when the cpu changes state with an interrupt pending.

See Also

arm_cpu_state_t

Execution Context

Cell Context for all methods.

arm

Name

arm — interface that provides various functionality specific for Arm processors

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

SIM_INTERFACE(arm) {
        uint64 (*read_register_mode)(conf_object_t *processor_obj,
                                     int reg_num, int mode);
        void (*write_register_mode)(conf_object_t *processor_obj,
                                    int reg_num, int mode, uint64 value);
};

#define ARM_INTERFACE "arm"

Python

import simics

class simics.arm_interface_t(read_register_mode=None, write_register_mode=None)

Description

This interface is implemented by ARM processors to provide various functionality that is specific for this class of processors.

The read_register_mode and write_register_mode functions are used to access banked copies of the registers. They are used just like the int_register interface read and write functions, except that they take an extra parameter mode that specifies which register bank should be used. mode should be the mode bits in the cpsr corresponding to the mode shifted right to bits 0-4.

Execution Context

Cell Context for all methods.

See Also

int_register

arm_trustzone_mode_t, arm_trustzone

Name

arm_trustzone_mode_t, arm_trustzone — ARM Trustzone interface

Synopsis

C and DML

#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML

typedef enum {
        Arm_Trustzone_Secure = 0,
        Arm_Trustzone_Non_Secure = 1
} arm_trustzone_mode_t;

SIM_INTERFACE(arm_trustzone) {
        arm_trustzone_mode_t (*get_security_mode)(conf_object_t *NOTNULL obj);
        arm_trustzone_mode_t (*mem_op_security_mode)(
                conf_object_t *NOTNULL obj,
                generic_transaction_t *NOTNULL memop);
};

#define ARM_TRUSTZONE_INTERFACE "arm_trustzone"

Python

import simics

simics.Arm_Trustzone_Secure
simics.Arm_Trustzone_Non_Secure
class simics.arm_trustzone_interface_t(get_security_mode=None,
        mem_op_security_mode=None)

Description

This interface is implemented by ARM processors that supports the arm ARM TrustZone feature. The get_security_mode function returns the current state of the processor, whereas mem_op_security_mode extracts the mode of a memory operation in progress.

The get_security_mode functions corresponds to the expression (cpsr.mode != Monitor && scr.ns) ? Arm_Trustzone_Non_Secure : Arm_Trustzone_Secure.

The mem_op_security_mode function always returns Arm_Trustzone_Non_Secure when the processor is in non-secure mode, in secure mode it returns the ns bit in the first-level page table entry for the actual area being accessed.

Execution Context

Cell Context for all methods.

bridge

Name

bridge — implemented by objects that bridge between memory spaces

Synopsis

C and DML

#include <simics/devs/memory-space.h> // in C
import "simics/devs/memory-space.dml"; // in DML

SIM_INTERFACE(bridge) {
        exception_type_t (*not_taken)(conf_object_t *NOTNULL obj,
                                      conf_object_t *NOTNULL src_space,
                                      conf_object_t *NOTNULL dst_space,
                                      exception_type_t ex,
                                      generic_transaction_t *NOTNULL mem_op,
                                      map_info_t mapinfo);
};

#define BRIDGE_INTERFACE "bridge"

Python

import simics

class simics.bridge_interface_t(not_taken=None)

Description

The bridge interface is implemented by objects that bridge between memory spaces. The not_taken function is called if the access is not claimed by any device in the destination memory-space. If a memory transaction reaches a mapping that has the same bridge object as the previous mapping, the access is considered as not taken, and the not_taken function for the first bridge mapping is called.

Execution Context

Cell Context for all methods.

can_device

Name

can_device — Interface for receiving from CAN controller

Synopsis

C and DML


SIM_INTERFACE(can_device) {
        void (*receive)(conf_object_t *obj, can_frame_t *frame);
};
#define CAN_DEVICE_INTERFACE "can_device"

Description

The can_device interface is implemented by CAN controllers. The receive function is called by can-endpoint to pass CAN frame from other can-endpoint to the connected CAN controller.

The CAN frame is expressed by the frame parameter, which is a pointer of can_frame_t.

Execution Context

Cell Context for all methods.

can_frame_t

Name

can_frame_t — CAN frame

Synopsis

C and DML


typedef struct {
        /* arbitration field */
        uint32 identifier;
        bool extended;
        bool rtr;
        /* control field */
        uint8 data_length;
        /* data field */
        uint8 data[CAN_DATA_MAX_NUM];
        /* crc field */
        uint16 crc;
} can_frame_t;

Description

Standard Format
Arbitration Field(11bit_ID+RTR)+Control Field(IDE+r0+DLC)
Extended Format
Arbitration Field(11bit_sID+SRR+IDE+18bit_eID+RTR)+Control Field(r1+r0+DLC)

Above are the Arbitration Field and Control Field of the physical Standard frame and Extended frame. But the can_frame_t only focus on the logical meanings of such fields and tries to adapt different CAN controllers:

identifier
For Standard frame, 11bit_ID should be put in identifier[10:0];for Extended frame, 11bit_sID should be put in identifier[28:18] and 18bit_eID should be put in identifier[17:0].
extended
There isn’t IDE in can_frame_t, instead, extended is used to indicate if the frame is Extended frame or Standard frame.
rtr
There isn’t SRR in can_frame_t for Extended frame, instead, rtr is used to indicate if the frame is a remote frame or not. Here we don’t care whether the frame is Extended frame or Standard frame.
data_length
The data_length contains the arithmetic value of the DLC.
data[CAN_DATA_MAX_NUM]\
This is the data field of Date frame.
crc
This is the crc field of a CAN frame.

Name

can_link — Interface for sending to CAN endpoint

Synopsis

C and DML


SIM_INTERFACE(can_link) {
        can_status_t (*send)(conf_object_t *obj, can_frame_t *frame);
};
#define CAN_LINK_INTERFACE "can_link"

Description

The can_link interface is implemented by can-endpoint. The send function is called by CAN controller to pass CAN frame to the connected can-endpoint. Then can-link delivers the CAN frame to other can-endpoints.

Execution Context

Cell Context for all methods.

coreint_reply_t, coreint

Name

coreint_reply_t, coreint — interface between CoreInt capable processor and interrupt controller

Synopsis

C and DML

#include <simics/devs/coreint.h> // in C
// not available in DML

typedef struct {
        bool enabled;
        uint64 vector;
} coreint_reply_t;

SIM_INTERFACE(coreint) {
        coreint_reply_t (*acknowledge)(conf_object_t *obj, conf_object_t *core);
};
#define COREINT_INTERFACE "coreint"

Description

This interface is implemented by CoreInt capable interrupt controllers and allows the processor to automatically acknowledge external interrupts without software intervention.

The acknowledge function is called by the processor when an external interrupt is taken. If coreint is enabled in the interrupt controller, the interrupt controller should lower the interrupt signal towards the processor and return the interrupt source vector. This way the software doesn’t have to go and query the interrupt controller for the source. If coreint is not enabled, the interrupt should not do anything and the vector value in the reply is undefined.

Execution Context

Cell Context for all methods.

cxl_type_t, cxl_map

Name

cxl_type_t, cxl_map — interface used to claim ranges in CXL address spaces

Synopsis

C and DML

#include <simics/devs/cxl.h> // in C
import "simics/devs/cxl.dml"; // in DML

typedef enum {
        CXL_Type_Not_Set,
        CXL_Type_Io,
        CXL_Type_Mem,
        CXL_Type_Cache,
        CXL_Type_Other,
} cxl_type_t;

SIM_INTERFACE(cxl_map)
{
        void (*add_map)(conf_object_t *obj, conf_object_t *map_obj,
                        map_info_t info, cxl_type_t type);
        void (*del_map)(conf_object_t *obj, conf_object_t *map_obj,
                        physical_address_t base, cxl_type_t type);
};

#define CXL_MAP_INTERFACE "cxl_map"

Python

import simics

simics.CXL_Type_Cache
simics.CXL_Type_Mem
simics.CXL_Type_Other
simics.CXL_Type_Not_Set
simics.CXL_Type_Io
class simics.cxl_map_interface_t(add_map=None, del_map=None)

Description

This interface is used to claim ranges in CXL address spaces.

Functions add_map and del_map are used to add and remove maps, map_obj will be mapped in the address space indicated by type according to the information in info.

This interface is considered tech-preview and may change without notice.

Execution Context

Cell Context for all methods.

cxl_mem_downstream_port_managing

Name

cxl_mem_downstream_port_managing — interface for cxl downstream port memory management

Synopsis

C and DML

#include <simics/devs/cxl.h> // in C
import "simics/devs/cxl.dml"; // in DML

SIM_INTERFACE(cxl_mem_downstream_port_managing)
{
        bool (*register_port_mem_obj)(conf_object_t *obj, uint8 port_number,
                                      conf_object_t *port_mem_obj);
        void (*unregister_port_mem_obj)(conf_object_t *obj, uint8 port_number);
};

#define CXL_MEM_DOWNSTREAM_PORT_MANAGING_INTERFACE "cxl_mem_downstream_port_managing"

Python

import simics

class simics.cxl_mem_downstream_port_managing_interface_t(register_port_mem_obj=None,
        unregister_port_mem_obj=None)

Description

Functions register_port_mem_obj and unregister_port_mem_obj are used to register and unregister port memory objects.

Execution Context

Cell Context for all methods.

cxl_non_device_decoder_handling

Name

cxl_non_device_decoder_handling — interface for cxl_hdm_port

Synopsis

C and DML

#include <simics/devs/cxl.h> // in C
import "simics/devs/cxl.dml"; // in DML

SIM_INTERFACE(cxl_non_device_decoder_handling)
{
        int (*enable_decoder)(conf_object_t *obj, uint8 index, uint8 ig,
                              uint8 iw, uint64 base, uint64 size,
                              uint64 target_list);
        int (*disable_decoder)(conf_object_t *obj, uint8 decoder_index);
};

#define CXL_NON_DEVICE_DECODER_HANDLING_INTERFACE "cxl_non_device_decoder_handling"

Python

import simics

class simics.cxl_non_device_decoder_handling_interface_t(enable_decoder=None,
        disable_decoder=None)

Description

Functions enable_decoder and disable_decoder are used to enable and disable HDM decoders on a cxl-hdm-port device.

Execution Context

Cell Context for all methods.

Name

datagram_link — implemented by objects that receive messages from a datagram-link

Synopsis

C and DML

#include <simics/devs/datagram-link.h> // in C
import "simics/devs/datagram-link.dml"; // in DML

SIM_INTERFACE(datagram_link) {
        /* Transmit a message to the object. */
        void (*receive)(conf_object_t *NOTNULL obj, bytes_t msg);
};

#define DATAGRAM_LINK_INTERFACE "datagram_link"

Python

import simics

class simics.datagram_link_interface_t(receive=None)

Description

This interface is implemented by objects that receive messages from a datagram-link, and by the datagram-link connection endpoints themselves.

There is a single function receive(), which is used to pass the message msg to the object obj.

The message msg is treated as a series of bytes with no special format or meaning expected. If obj is a datagram-link endpoint, it will forward the message to all other endpoints registered on the link except the sender, effectively broadcasting the message on the link. If obj is a device, it will simply receive the message as sent by the original sender.

Note that the symmetry of the interface allows two devices to be connected directly to each other and talk as if connected via a datagram-link. This is however not supported by the default datagram-link component, so a special connector must be created for this purpose. Additionally, the standard link features, such as multicell configurations and latency, will not be available in that setup.

Execution Context

Cell Context

eri_reg_num_t

Name

eri_reg_num_t — Registers number used by ERI or DCRA

Synopsis

C and DML


typedef enum {
    DCRA_ERI_PMA_RESOLUTION_CONTROL = 0,
    ERI_PMA_CORE_TTT_L32,   // low 32-bit of arat_ttt small core
    ERI_PMA_CORE_TTT_H32,   // high 32-bit of arat_ttt small core
    DCRA_ERI_PMA_CORE_STATUS,
    DCRA_PMA_ACODE_TO_UCODE_CFG,
    DCRA_PMA_ARAT_TTT,      // arat_ttt of big core
    DCRA_ERI_PMA_CSTT_THRESHOLD,
    ERI_PMA_CR_UCODE_ASSIST_INFO,
} eri_reg_num_t;

eri_transaction_t

Name

eri_transaction_t — Transaction info used in x86_eri_v1

Synopsis

C and DML


typedef struct {
        uint64 val;   // Read or Write value
        bool   valid; // Valid or not data in val field
} eri_transaction_t;

eri_v2_transaction_t

Name

eri_v2_transaction_t — Transaction info used in x86_eri_v2

Synopsis

C and DML


typedef struct {
        uint32 value; // read or write value
        uint16 addr;
        uint8  scope;
        uint8  type;
        uint8  wrbe;  // write bytes enable mask
        bool   valid; // valid or not data in val field
} eri_v2_transaction_t;

ethernet_cable

Name

ethernet_cable — ethernet interface used for notification of link status

Synopsis

C and DML

#include <simics/devs/ethernet.h> // in C
import "simics/devs/ethernet.dml"; // in DML

SIM_INTERFACE(ethernet_cable) {
        void (*link_status)(conf_object_t *NOTNULL ep, bool link_up);
};
#define ETHERNET_CABLE_INTERFACE "ethernet_cable"

Python

import simics

class simics.ethernet_cable_interface_t(link_status=None)

Description

This interface is implemented by Ethernet devices and link endpoints that are interested in the link status of the peer.

The link_status function is used to notify the peer that the link status at the local end is up or down. The ethernet_cable class propagates this information to the device connected at the other end.

Execution Context

Cell Context

ethernet_common

Name

ethernet_common — common ethernet interface used by all ethernet links and devices

Synopsis

C and DML

#include <simics/devs/ethernet.h> // in C
import "simics/devs/ethernet.dml"; // in DML

SIM_INTERFACE(ethernet_common) {
        void (*frame)(conf_object_t *NOTNULL obj, const frags_t *frame,
                      eth_frame_crc_status_t crc_status);
};
#define ETHERNET_COMMON_INTERFACE "ethernet_common"

Python

import simics

class simics.ethernet_common_interface_t(frame=None)

Description

This interface is implemented by objects that receive Ethernet frames, both Ethernet devices and Ethernet link endpoints.

There is a single function frame which sends an Ethernet frame, without preamble nor SFD (Start Frame Delimiter), but with a CRC field.

The crc_status parameter provides out-of-band information on the contents of the frame with regards to the CRC field using one of the values in the eth_frame_crc_status_t enum.

When a device calls a link’s frame function, it can set crc_status to any of the three values. If the link receives a Eth_Frame_CRC_Unknown, it will compute the CRC itself to set the status to Eth_Frame_CRC_Match or Eth_Frame_CRC_Mismatch.

When a link calls a device’s frame function, crc_status will be set to either Eth_Frame_CRC_Match or Eth_Frame_CRC_Mismatch, and never Eth_Frame_CRC_Unknown.

When two devices are directly connected to each others without using a link, the interpretation of Eth_Frame_CRC_Unknown is up to the devices’ implementation.

Execution Context

Cell Context

eth_probe_side_t, ethernet_probe_snoop_t, ethernet_probe

Name

eth_probe_side_t, ethernet_probe_snoop_t, ethernet_probe — used to attach to ethernet connections and look at and/or modify frames

Synopsis

C and DML

#include <simics/devs/eth-probe.h> // in C
import "simics/devs/eth-probe.dml"; // in DML

typedef enum {
        Eth_Probe_Port_A = 0,
        Eth_Probe_Port_B = 1
} eth_probe_side_t;

typedef void (*ethernet_probe_snoop_t)(lang_void *user_data,
                                       conf_object_t *probe,
                                       eth_probe_side_t to_side,
                                       const frags_t *frame,
                                       eth_frame_crc_status_t crc_status);

SIM_INTERFACE(ethernet_probe) {
        void (*attach_snooper)(conf_object_t *NOTNULL probe,
                               ethernet_probe_snoop_t snoop_fun,
                               lang_void *user_data);
        void (*attach_probe)(conf_object_t *NOTNULL probe,
                             ethernet_probe_snoop_t snoop_fun,
                             lang_void *user_data);
        void (*detach)(conf_object_t *NOTNULL probe);
        void (*send_frame)(conf_object_t *NOTNULL probe,
                           eth_probe_side_t to_side,
                           const frags_t *frame,
                           eth_frame_crc_status_t crc_status);
};

#define ETHERNET_PROBE_INTERFACE "ethernet_probe"

Python

import simics

simics.Eth_Probe_Port_A
simics.Eth_Probe_Port_B
class simics.ethernet_probe_interface_t(attach_snooper=None, attach_probe=None,
        detach=None, send_frame=None)

Description

This interface should only be used for inspection, and never as part of the actual simulation. The snoop functions must not affect the simulation in any way.

This interface is implemented by eth-probe objects. Once a probe has been inserted between a device and an Ethernet link, the functions of this interface can be used to setup callbacks:

attach_snooper
Attach a snooper function: the probe will pass each frame to the snooper function, then forward it unchanged where it should be going
attach_probe
Attach a probe function: the probe will pass each frame to the probe function, and give it the responsibility of forwarding the frame or any number of modified or additional frames using the send_frame function.
detach
Detach the currently registered callback from the probe.
send_frame
Send a frame via the probe, either to the side A or B of the probe. Which side is which can be obtained with the <eth-probe>.info function.

Snooped frames with a matching CRC will contain the correct frame check sequence.

The user_data parameter is passed to the snoop function every time it is called.

Execution Context

Cell Context for all methods.

ethernet_link_snoop_t, ethernet_snoop

Name

ethernet_link_snoop_t, ethernet_snoop — used to attach snooping functions to ethernet links

Synopsis

C and DML

#include <simics/devs/ethernet.h> // in C
import "simics/devs/ethernet.dml"; // in DML

typedef void (*ethernet_link_snoop_t)(lang_void *user_data,
                                      conf_object_t *clock,
                                      const frags_t *packet,
                                      eth_frame_crc_status_t crc_status);

SIM_INTERFACE(ethernet_snoop) {
        conf_object_t *(*attach)(conf_object_t *NOTNULL link,
                                 conf_object_t *clock,
                                 ethernet_link_snoop_t snoop_fun,
                                 lang_void *user_data);
};
#define ETHERNET_SNOOP_INTERFACE "ethernet_snoop"

Python

import simics

class simics.ethernet_snoop_interface_t(attach=None)

Description

This interface is implemented by Ethernet link objects. It is used to attach snoop functions to the link. The snoop function will receive all traffic going over the link.

This interface should only be used for inspection, and never as part of the actual simulation. The snoop functions must not affect the simulation in any way.

The clock parameter tells the link on which clock to post the events that call the snoop function. The snoop function will be called at the delivery time of the network packet, which means that it will be called at the same time as any Ethernet devices attached to the same clock that receives packets from the same link.

Snooped frames with a matching CRC will contain the correct frame check sequence.

The user_data parameter is passed to the snoop function every time it is called.

Execution Context

Global Context

ethernet_vlan_snoop

Name

ethernet_vlan_snoop — used to attach snoop functions to VLAN network

Synopsis

C and DML

#include <simics/devs/ethernet.h> // in C
import "simics/devs/ethernet.dml"; // in DML

SIM_INTERFACE(ethernet_vlan_snoop) {
        conf_object_t *(*attach)(
                conf_object_t *NOTNULL link, conf_object_t *clock,
                ethernet_link_snoop_t snoop_fun, lang_void *user_data,
                uint16 vlan_id, bool is_vlan_trunk);
};
#define ETHERNET_VLAN_SNOOP_INTERFACE "ethernet_vlan_snoop"

Python

import simics

class simics.ethernet_vlan_snoop_interface_t(attach=None)

Description

This interface is implemented by Ethernet VLAN switch link objects. It is used to attach snoop functions to the link. The snoop function will receive all traffic going over the link, either on a single VLAN, or on all of them.

This interface should only be used for inspection, and never as part of the actual simulation. The snoop functions must not affect the simulation in any way.

The clock parameter tells the link on which clock to post the events that call the snoop function. The snoop function will be called at the delivery time of the network packet, which means that it will be called at the same time as any Ethernet devices attached to the same clock that receives packets from the same link.

Snooped frames with a matching CRC will contain the correct frame check sequence.

The user_data parameter is passed to the snoop function every time it is called.

The vlan_id indicates on which VLAN the snoop function should be attached (as its native VLAN).

The is_vlan_trunk flag indicates whether the snoop function should also receive the traffic on all other VLANs, tagged with an 802.1Q tag.

Execution Context

Global Context

exec_trace

Name

exec_trace — interface for handling registration of trace listeners

Synopsis

C and DML

#include <simics/model-iface/exec-trace.h> // in C
import "simics/model-iface/exec-trace.dml"; // in DML

SIM_INTERFACE(exec_trace) {
        void (*register_tracer)(conf_object_t *NOTNULL cpu_obj,
                                instruction_trace_callback_t tracer,
                                lang_void *tracer_data);
        void (*unregister_tracer)(conf_object_t *NOTNULL cpu_obj,
                                  instruction_trace_callback_t tracer,
                                  lang_void *tracer_data);
};

#define EXEC_TRACE_INTERFACE "exec_trace"

Python

import simics

class simics.exec_trace_interface_t(register_tracer=None, unregister_tracer=None)

Description

The exec_trace interface is implemented by processor models that support tracing. A trace listener registers itself with the register_tracer call. The tracer callback (of type instruction_trace_callback_t) will be called by the processor model when each instruction is just about to be executed, passing the tracer_data as passed to the register_tracer function in addition to information about the instruction that is executed. Invoke unregister_tracer with the same two pointers to deregister the listener.

The pa parameter to the callback will always be valid, but some CPU architectures may not support la or va. The la argument is typically only valid for x86 CPUs. Lastly, the opcode of the instruction is passed in opcode. The opcode is passed without endian conversion, meaning that byte X in opcode corresponds to the byte at pa + X.

Execution Context

Global Context for both methods. Cell Context for the callback.

extended_serial

Name

extended_serial — extension to serial_device interface

Synopsis

C and DML

#include <simics/devs/serial-device.h> // in C
import "simics/devs/serial-device.dml"; // in DML

SIM_INTERFACE(extended_serial) {
        void (*write_at)(conf_object_t *obj,
                         int value, int x, int y, int fg, int bg);
        void (*graphics_mode)(conf_object_t *obj, int in_graphics_mode);
};

#define EXTENDED_SERIAL_INTERFACE "extended_serial"

Python

import simics

class simics.extended_serial_interface_t(write_at=None, graphics_mode=None)

Description

This interface extends the serial_device with a write_at function. It is similar to the write function of the mentioned interface, but accepts an on-screen character position. This interface is implemented by text consoles allowing them to be connected to text oriented frame buffers, such as VGA in text mode.

Execution Context

Cell Context for all methods.

firewire_ack_code_t, firewire_bus

Name

firewire_ack_code_t, firewire_bus — interface implemented by firewire buses

Synopsis

C and DML

#include <simics/devs/firewire.h> // in C
import "simics/devs/firewire.dml"; // in DML

typedef enum {
        /* Values defined in the FireWire specification */
        Firewire_Ack_Complete = 1,
        Firewire_Ack_Pending = 2,
        Firewire_Ack_Busy_X = 4,
        Firewire_Ack_Busy_A = 5,
        Firewire_Ack_Busy_B = 6,
        Firewire_Ack_Tardy = 0xb,
        Firewire_Ack_Conflict_Error = 0xc,
        Firewire_Ack_Data_Error = 0xd,
        Firewire_Ack_Type_Error = 0xe,
        Firewire_Ack_Address_Error = 0xf,

        /* Values not defined in FireWire but used in Simics */
        Firewire_Ack_No_Destination = 0x10, /* no destination found */
        Firewire_Ack_No_Ack = 0x11 /* no ack signal sent for packet */
} firewire_ack_code_t;

SIM_INTERFACE(firewire_bus) {
        int (*connect_device)(conf_object_t *NOTNULL bus,
                              conf_object_t *NOTNULL dev);
        int (*disconnect_device)(conf_object_t *NOTNULL bus,
                                 conf_object_t *NOTNULL dev);
        void (*set_device_bus_id)(conf_object_t *NOTNULL bus,
                                  conf_object_t *NOTNULL dev,
                                  uint16 bus_id);

        void (*set_id_mask)(conf_object_t *NOTNULL bus,
                            conf_object_t *NOTNULL dev,
                            uint16 id_mask);

        firewire_ack_code_t (*transfer)(conf_object_t *NOTNULL bus,
                                        conf_object_t *NOTNULL source,
                                        dbuffer_t *packet, int crc_calculated);

        int (*register_channel)(conf_object_t *NOTNULL bus,
                                conf_object_t *NOTNULL dev,
                                uint32 channel);
        int (*unregister_channel)(conf_object_t *NOTNULL bus,
                                  conf_object_t *NOTNULL dev,
                                  uint32 channel);

        void (*reset)(conf_object_t *NOTNULL bus);
};
#define FIREWIRE_BUS_INTERFACE "firewire_bus"

Python

import simics

simics.Firewire_Ack_Address_Error
simics.Firewire_Ack_Busy_X
simics.Firewire_Ack_Tardy
simics.Firewire_Ack_No_Ack
simics.Firewire_Ack_Busy_A
simics.Firewire_Ack_No_Destination
simics.Firewire_Ack_Busy_B
simics.Firewire_Ack_Type_Error
simics.Firewire_Ack_Complete
simics.Firewire_Ack_Pending
simics.Firewire_Ack_Data_Error
simics.Firewire_Ack_Conflict_Error
class simics.firewire_bus_interface_t(connect_device=None, disconnect_device=None,
        set_device_bus_id=None, set_id_mask=None, transfer=None,
        register_channel=None, unregister_channel=None, reset=None)

Description

This interface must be implemented by all firewire buses.

connect_device is called when a device wants to connect to the bus. The bus should return 0 upon success.

disconnect_device is called when a device wants to disconnect from the bus. The bus should return 0 upon success.

set_device_bus_id sets the bus id for the device. This needs to be called by a device when its Node_IDS[bus_id] field is updated. The new bus id should be placed in bits 15-6 in the bus_id argument.

set_id_mask can be called by a device to specify a mask that should be applied to the device ID when routing transfers. This can be used to e.g. accept transfers to multiple bus-numbers.

transfer sends a packet. The bus will route the transfer to the correct device(s). The source parameter should be set to the device which sent the transfer. The bus uses this parameter to avoid sending packets to their sender. If the crc_calculated argument is non-zero the packet’s crc fields are filled in.The return code is one of:

register_channel can be called to tell the bus that the device want to receive isochronous transfers to channel channel. channel must be in the range [0, 63). A device can register several channels. It is an error to subscribe a device to a channel it is already subscribed to. Returns 0 on success.

unregister_channel tells the bus the device is no longer interested in transfers to channel channel. channel must be in the range [0, 63). It is an error to unsubscribe a device from a channel if it isn’t subscribing to it. Returns 0 on success.

reset can be called to cause a bus reset. After the bus reset, all the devices may have received new IDs.

Execution Context

Cell Context for all methods.

uint32_array_t, firewire_device

Name

uint32_array_t, firewire_device — implemented by firewire devices

Synopsis

C and DML

#include <simics/devs/firewire.h> // in C
import "simics/devs/firewire.dml"; // in DML

typedef struct {
        size_t len;
        uint32 *data;
} uint32_array_t;

SIM_INTERFACE(firewire_device) {
        firewire_ack_code_t (*transfer)(conf_object_t *NOTNULL dev,
                                        dbuffer_t *packet, int crc_calculated);

        void (*reset)(conf_object_t *NOTNULL dev, uint16 id,
                      uint8 root_id,
                      uint32_array_t self_ids);
        uint32 (*get_self_id_template)(
                conf_object_t *NOTNULL dev);

        int (*get_rhb)(conf_object_t *NOTNULL dev);
        uint8 (*get_port_count)(conf_object_t *NOTNULL dev);
        uint16 (*get_port_mask)(conf_object_t *NOTNULL dev);
};
#define FIREWIRE_DEVICE_INTERFACE "firewire_device"

Python

import simics

class simics.firewire_device_interface_t(transfer=None, reset=None,
        get_self_id_template=None, get_rhb=None, get_port_count=None,
        get_port_mask=None)

Description

This interface must be implemented by all firewire devices.

transfer is called when the device receives a packet. If the crc_calculated argument is non-zero the packet’s crc fields are filled in.The return code is one of:

reset is called when the bus is reset. id is the new ID of the device (top 10 bits represent the bus number, and the low 6 bits the node ID). root_id is the node ID for the root node. self_ids is the list of Self-ID packets during the Self-ID phase of the reset.

get_self_id_template is an accessor function called by the bus or other self-ID provider to provide the static parts of the Self-ID for this device. The ID and port parts will be overwritten by the Self-ID provider.

get_rhb gets the current status of the root hold off bit in the device.

get_port_count returns the number of ports the device has. The largest allowed value is 16 and the lowest 1. This should remain constant during the lifetime of the device and always return a valid value.

get_port_mask returns a bitmask. Each bit is one if that port is enabled and zero if it is disabled. The least significant bit describes port 0 and the most significant bit port 15. The bits for ports which do not exist on the device should be set to zero.

Execution Context

Cell Context for all methods.

fmn_station_control

Name

fmn_station_control — interface for Fast Messaging Network stations

Synopsis

C and DML

#include <simics/arch/mips.h> // in C
import "simics/arch/mips.dml"; // in DML

SIM_INTERFACE(fmn_station_control) {
        uint64 (*send_message)(conf_object_t *NOTNULL obj,
                               uint32 thread_id,
                               uint64 rt_value);
        void (*load_message)(conf_object_t *NOTNULL obj,
                             uint32 thread_id,
                             uint8 bucket);
        int (*wait)(conf_object_t *NOTNULL obj,
                    uint32 thread_id,
                    uint8 vector);
        void (*sync)(conf_object_t *NOTNULL obj,
                     uint32 thread_id);

};
#define FMN_STATION_CONTROL_INTERFACE "fmn_station_control"

Python

import simics

class simics.fmn_station_control_interface_t(send_message=None, load_message=None,
        wait=None, sync=None)

Description

The fmn_station_control interface is implemented by Fast Messaging Network stations for processors prior to the XLP II.

For all functions, the thread_id parameter denotes the thread id for the core that invokes the call.

The send_message function notifies the station to initiate a message send on the FMN. The rt_value parameter carries control bits and the message to send; its content and bit layout is determined by the system architecture. The return value indicates whether the FMN station is able to send the message. The station must check for available resources and immediately return 1 if the message will be queued for delivery, otherwise, if the station is not ready or if no buffers are available, the station immediately returns 0.

The load_message function notifies the station to initiate a message load on the FMN. The bucket indicates the FMN station bucket to read from.

The wait function is used by the core to probe the station if it should put itself to sleep waiting for a message or not. Each bit in the vector corresponds to a bucket to check for messages, i.e. bit 0 corresponds to bucket 0. The station must return 0 if there are any messages in any of the buckets requested. The station must return 1 if there are no messages in any of the buckets. Returning 1 means that the core can go to sleep until the station wakes the core. The station must later send a wake signal to the core when a new message arrive to any of the buckets checked in the last call to wait. The station wakes the core by raising the signal on the wakeup port interface for the core.

The sync function enforces a hazard barrier across the send_message function executions, thereby enforcing a strict ordering of the message sequence delivered to the FMN.

Execution Context

Cell Context for all methods.

fmn_station_control_v2

Name

fmn_station_control_v2 — interface for Fast Messaging Network stations

Synopsis

C and DML

#include <simics/arch/mips.h> // in C
import "simics/arch/mips.dml"; // in DML

SIM_INTERFACE(fmn_station_control_v2) {
        uint64 (*send_message)(conf_object_t *NOTNULL obj,
                               uint32 thread_id,
                               uint64 rt_value);
        uint64 (*load_message)(conf_object_t *NOTNULL obj,
                               uint32 thread_id,
                               uint64 rt_value);
        int (*wait)(conf_object_t *NOTNULL obj,
                    uint32 thread_id,
                    uint64 rt_value);
        void (*sync)(conf_object_t *NOTNULL obj,
                     uint32 thread_id);
};
#define FMN_STATION_CONTROL_V2_INTERFACE "fmn_station_control_v2"

Python

import simics

class simics.fmn_station_control_v2_interface_t(send_message=None,
        load_message=None, wait=None, sync=None)

Description

The fmn_station_control_v2 interface is implemented by Fast Messaging Network stations for the XLP II processor.

For all functions, the thread_id parameter denotes the thread id for the core that invokes the call.

The send_message function is called when the processor executes the msgsnd instruction. The rt_value parameter contains the value of the rt register. The function must return the value to be written into the rd register.

The load_message function is called when the processor executes the msgld instruction. The rt_value parameter contains the value of the rt register. The function must return the value to be written into the rd register.

The wait function is called when the processor executes the msgwait instruction. The rt_value parameter contains the value of the rt register. The function should return 1 if the receive queues are empty, 0 if not. If the receive queues are empty the station must wake the thread by raising the signal on the wakeup port of the thread when the next message arrives to one of the receive queues.

The sync function is called when the processor executes the msgsync instruction.

Execution Context

Cell Context for all methods.

frequency

Name

frequency — interface used to publish frequency

Synopsis

C and DML

#include <simics/devs/frequency.h> // in C
import "simics/devs/frequency.dml"; // in DML

SIM_INTERFACE(frequency) {
        double (*get)(conf_object_t *NOTNULL obj);
};
#define FREQUENCY_INTERFACE "frequency"

Python

import simics

class simics.frequency_interface_t(get=None)

Description

The frequency interface is used to publish a frequency to other objects.

The get method returns the current frequency.

The object implementing this interface is expected to implement the Sim_Notify_Frequency_Change notifier, which should be raised when the object changes its frequency. Objects subscribing to this notifier can acquire the new frequency by doing a new call to the get method.

Execution Context

Cell Context for all methods.

frequency_listener

Name

frequency_listener — interface used to model frequency changes

Synopsis

C and DML

#include <simics/devs/frequency.h> // in C
import "simics/devs/frequency.dml"; // in DML

SIM_INTERFACE(frequency_listener) {
        void (*set)(conf_object_t *NOTNULL obj, uint64 numerator,
                    uint64 denominator);
};

#define FREQUENCY_LISTENER_INTERFACE "frequency_listener"

Python

import simics

class simics.frequency_listener_interface_t(set=None)

Description

The frequency_listener interface is used for modeling frequency changes.

The frequency change initiator should call set to set the new frequency. The set function may be called multiple times with the same frequency value. The frequency is specified by the numerator and denominator arguments in units of Hz.

The set function should also be used to set the initial value for a target.

An object that implements the frequency_listener interface typically has an attribute that refers to an object and port that implements the simple_dispatcher interface, from where the frequency originates.

The initiator of a frequency change should implement the simple_dispatcher interface, and it should only call the set function on objects that have registered with this interface.

Execution Context

Cell Context for all methods.

generic_message_device

Name

generic_message_device — Interface for receiving from generic message devices

Synopsis

C and DML


SIM_INTERFACE(generic_message_device) {
        void (*receive_frame)(conf_object_t *dev, conf_object_t *link,
                              dbuffer_t *frame);
};

#define GENERIC_MESSAGE_DEVICE_INTERFACE "generic_message_device"

Description

This interface is implemented by generic message device objects that connect to generic-message-link objects. It is used by the link object to send messages to the device object. The link should implement the generic_message_link interface.

The receive_frame function is called by the link to send a frame to the device. The frame is passed as a dbuffer_t pointer that may not be modified without cloning it first.

Execution Context

FunctionContext
receive_frameCell Context

Name

generic_message_link — Interface for gml-link

Synopsis

C and DML


SIM_INTERFACE(generic_message_link) {
#ifndef PYWRAP
        int  (*connect_device)(conf_object_t *_obj, conf_object_t *dev,
                               int *new_connection, uint32 address);
        void (*disconnect_device)(conf_object_t *_obj, conf_object_t *dev);
#endif
        void (*send_frame)(conf_object_t *_obj, int id, uint32 address,
                           dbuffer_t *frame, nano_secs_t delay);
};

#define GENERIC_MESSAGE_LINK_INTERFACE "generic_message_link"

Description

This interface is used for gml-link which is based on the link library. Refer to the Link Library Programming Guide for more information.

This interface is implemented by generic message link objects that provide a data link layer interface for frame delivery. It is used by the device object to talk to the link object. The device must implement the generic_message_device interface.

The connect_device function attaches a generic link device to the link. The return value is an identification number that should be used in subsequent calls to the link to identify the device. The address parameter sets the address of the device on the link. Currently the new_connection parameter is not in use, a NULL pointer can be passed as the parameter.

The disconnect_device function detaches a generic link device from the link. It will not receive any more frames from the link and may not call any functions in the interface, except connect_device.

The send_frame function is used by a device to send a generic device frame onto the link to be delivered to another device connected to the same link. The frame should be a dbuffer_t containing a data frame. The address parameter is the address to sent the frame to. The delay makes it possible to add a small delay to the frame. This can be used when a device wants to send multiple frames at once, but want them to be delivered in a specific sequence. Instead of using an event handler to send each frame, they can be sent at once, with an increasing delay for each frame. The delay is given in nanoseconds.

Execution Context

FunctionContext
connect_deviceGlobal Context
disconnect_deviceGlobal Context
send_frameCell Context

hpi

Name

hpi — interface for Host Port Interface

Synopsis

C and DML

#include <simics/devs/hpi-interface.h> // in C
// not available in DML

SIM_INTERFACE(hpi) {
        /* HCNTL = 0 */
        uint32 (*read_hpic)(conf_object_t *obj);
        void  (*write_hpic)(conf_object_t *obj, uint32 value);

        /* HCNTL = 1 */
        uint32 (*read_hpia)(conf_object_t *obj);
        void  (*write_hpia)(conf_object_t *obj, uint32 value);

        /* HCNTL = 1 (autoincrement == 0) */
        /* HCNTL = 2 (autoincrement == 1) */
        uint32 (*read_hpid)(conf_object_t *obj, int autoincrement);
        void  (*write_hpid)(conf_object_t *obj, uint32 value,
                            int autoincrement);
};

#define HPI_INTERFACE "hpi"

Description

This interface defines HPI, Host Port Interface, which can be used by a host to access the DSP memory space. The access functions have been designed to resemble the HPI hardware interface.

The interface consists of three read/write access functions; read/write_hpic accesses the HPI controller register. Typically the host uses write_hpic to clear the HINT bit (writing a one to the bit) when the interrupt has been serviced.

The read/write_hpia functions are used to read or set the address to the memory location which should be later read or written. Reading HPIA either returns HPIAR or HPIAW depending on if last access to HPID was a read or write. Setting HPIA sets both HPIAR and HPIAW.

Finally, to access the memory the read/write_hpid functions are used. These functions have a autoincrement flag allowing the HPIAR or HPIAW to automatically increment the value with 4 after the access is finished.

All access functions assumes that the registers and data are represented in host endianness.

Execution Context

Cell Context for all methods.

i2c_ack_t, i2c_master_v2

Name

i2c_ack_t, i2c_master_v2 — interface implemented by I2C masters

Synopsis

C and DML

#include <simics/devs/i2c.h> // in C
import "simics/devs/i2c.dml"; // in DML

typedef enum {
        I2C_ack = 0,
        I2C_noack = 1
} i2c_ack_t;

SIM_INTERFACE(i2c_master_v2) {
        void (*acknowledge)(conf_object_t *device, i2c_ack_t ack);
        void (*read_response)(conf_object_t *device, uint8 value);
};

#define I2C_MASTER_V2_INTERFACE "i2c_master_v2"

Python

import simics

simics.I2C_noack
simics.I2C_ack
class simics.i2c_master_v2_interface_t(acknowledge=None, read_response=None)

Description

The i2c_master_v2 interface should be implemented by devices that intend to act as a master on an I2C link.

The function acknowledge is called in response to a start or write call in the i2c_slave_v2 interface of the slave device. read_response is called as response to a read call. More details can be found in the documentation of the i2c_slave_v2 interface.

Execution Context

Cell Context for all methods.

i2c_slave_v2

Name

i2c_slave_v2 — interface used by I2C devices

Synopsis

C and DML

#include <simics/devs/i2c.h> // in C
import "simics/devs/i2c.dml"; // in DML

SIM_INTERFACE(i2c_slave_v2) {
        void (*start)(conf_object_t *device, uint8 address);
        void (*read)(conf_object_t *device);
        void (*write)(conf_object_t *device, uint8 value);
        void (*stop)(conf_object_t *device);
        attr_value_t (*addresses)(conf_object_t *device);
};
#define I2C_SLAVE_V2_INTERFACE "i2c_slave_v2"

Python

import simics

class simics.i2c_slave_v2_interface_t(start=None, read=None, write=None,
        stop=None, addresses=None)

Description

The i2c_slave_v2 interface is used together with the i2c_master_v2 interface to model communication over an I2C bus. Most calls to a method in the i2c_slave_v2 interface expect a response call to a method in the i2c_master_v2 interface. It is up to each device to find the caller’s interface; usually it is configured with an attribute in both the master and slave device.

The i2c_slave_v2 and i2c_master_v2 interfaces replace the obsolete interfaces i2c_master, i2c_slave, i2c_link, and i2c_bridge.

An I2C bus consists of a number of master devices and a number of slave devices. Each slave device listens to one or more 7-bit addresses or 10-bit addresses. It is an error to connect two slave devices to the same bus if they listen to the same address. Communication over the bus is initiated by a master, which can communicate with one slave device at a time. Only one master on a bus can communicate at a time.

Two I2C devices can communicate directly if one implements the i2c_master_v2 interface and the other one implements the i2c_slave_v2 interface. An I2C bus with multiple masters or slaves is typically modeled using an i2c_link_v2 object, where each device is connected to an endpoint object.

The start method starts a transfer. The address parameter is the address of the slave device, encoded as an 8-bit number. To communicate with 7-bit address slave device, using little-endian bit numbering, bit 0 is a read/write bit (0 → master writes, 1 → master reads) and bits 1 to 7 is the 7-bit address of the slave device. The address parameter should normally be in the (inclusive) range 0x10 - 0xef; the ranges 0x00 - 0x0f and 0xf0 - 0xff are reserved for special addressing modes. To communicate with 10-bit address slave device, using little-endian bit numbering, bit 0 is a read/write bit (same as 7-bit address), bits 1 to 2 is part of 10-bit address, and bits 3 to 7 is 10-bit address mode 0b11110.

The slave responds to start using the acknowledge method. The ack parameter may be I2C_ack or I2C_noack if the start is acked or noacked, respectively. In a multi-master configuration, the slave may instead respond by calling the start method in the i2c_slave_v2 interface of the master device; this signals that the master lost the bus arbitration. This is discussed further below.

If a start was acked by a slave device, read/write bit in the start method was 1, the master proceeds with a sequence of read calls. Each call is followed by a read_response call from the slave. If the read/write bit in the start was 0, the master instead proceeds with a sequence of write calls, each one followed by an acknowledge call. The ack parameter of the acknowledge method may be either I2C_ack or I2C_noack, representing ack and noack, respectively.

After sending a number of reads or writes, the master may choose to either call the stop method to issue a stop condition which terminates the transfer, or to call the start method again to issue a repeated start condition. The repeated start condition works like a normal start condition.

When 0 is passed as the address parameter of the start method, a General Call transfer is initiated. A General Call transfer works like a normal write transfer, except that multiple slave devices may acknowledge the start and write requests. The master will conceive a request as acknowledged if it was acknowledged by at least one of the slaves.

When 10-bit address pattern is passed as the address parameter of the start method, a 10-bit address transaction is initiated. A 10-bit address transaction begins with write status (read/write bit should be 0). As mentioned before, bits 1 to 2 are the most significant bits of 10-bit address. Then following is a call to the write method with the last 8 bits of 10-bit address. If the transaction is slave-receiver, the next transfer works like a normal write transfer. If the transaction is slave-transmitter, then the start method is called again with the same address pattern as before, but with bit 0 (the read/write bit) set to 1. This is followed by calls to read like in a normal read transaction.

The addresses method is used to retrieve the set of addresses a device currently listens to. The method is called by the i2c_link_v2 to provide an overview of the bus topology, and to detect address collisions early. The method may not have any side-effects on the simulation. The return value is a list containing all the different values of the address parameter in a start call that the slave would respond to with I2C_ack. The list may also contain an element Nil to mark that the device might respond to other addresses as well. If a device is configured to listen to a specific address but is currently disabled, then that address may still be included in the list.

For example, if a slave device listens to the single 7-bit address 0x55, the return value of addresses would be [0xaa, 0xab], using Python list syntax.

The specification of the return value may be extended in the future, to allow other values than Nil and 8-bit integers. Therefore, callers should not make any assumptions on how the elements are formatted in the return value.

For most I2C devices it is sufficient to implement only one of the i2c_slave_v2 and i2c_master_v2 interfaces. In some cases it may be useful for a device to implement both interfaces, either because the device can act both as a master and as a slave on the bus, or because it needs to use the start and stop methods to monitor start and stop conditions on the bus. I2C link endpoints also implement both interfaces.

If multiple master devices are connected to the same i2c link, then all master devices need to implement the i2c_slave_v2 interface in addition to i2c_master_v2, in order to handle bus arbitration correctly:

Note that there is no need for a master device to implement the i2c_slave_v2 interface if the device only will be used in single-master configurations.

The start, write and read methods in the i2c_slave_v2 interface are allowed to respond synchronously; i.e., the acknowledge or read_response method may be called before the corresponding method in the slave interface has returned. A master that needs to connect directly to a slave device needs to take this into consideration; however, when communicating via an i2c_link_v2 object, the link guarantees that all responses are asynchronous.

Execution Context

The addresses method needs Global Context. All other methods can be used in Cell Context.

i3c_daa_snoop

Name

i3c_daa_snoop — interface used with I3C monitoring

Synopsis

C and DML

#include <simics/devs/i3c.h> // in C
import "simics/devs/i3c.dml"; // in DML

SIM_INTERFACE(i3c_daa_snoop) {
        void (*assigned_address)(conf_object_t *obj, uint64 id,
                                 uint8 bcr, uint8 dcr, uint8 address);
};

#define I3C_DAA_SNOOP_INTERFACE "i3c_daa_snoop"

Python

import simics

class simics.i3c_daa_snoop_interface_t(assigned_address=None)

Description

During DAA process, the assigned address information will be monitored to devices who implement the interface i3c_daa_snoop]. Whenever an address is assigned to a slave, the method assigned_address is called in all devices that implement the interface. The parameter id, bcr and dcr in method assigned_address is slave specific daa data which indicates who gets the assigned address. Parameter address stores the assigned address. The 7-bit address is represented as 8-bit number with the highest bit set to 0.

Interface i3c_daa_snoop is mainly implemented by slave who may become secondary master later and needs to know the information about slave addresses.

Execution Context

Cell Context for all methods.

i3c_hdr_slave, i3c_hdr_master

Name

i3c_hdr_slave, i3c_hdr_master — interfaces for I3C HDR communication

Synopsis

C and DML

#include <simics/devs/i3c.h> // in C
import "simics/devs/i3c.dml"; // in DML

SIM_INTERFACE(i3c_hdr_slave) {
        void (*hdr_write)(conf_object_t *obj, bytes_t data);
        void (*hdr_read)(conf_object_t *obj, uint32 max_len);
        void (*hdr_restart)(conf_object_t *obj);
        void (*hdr_exit)(conf_object_t *obj);
};

#define I3C_HDR_SLAVE_INTERFACE "i3c_hdr_slave"

SIM_INTERFACE(i3c_hdr_master) {
        void (*hdr_read_response)(conf_object_t *obj, bytes_t bytes, bool more);
        void (*hdr_acknowledge)(conf_object_t *obj, i3c_ack_t ack);
};

#define I3C_HDR_MASTER_INTERFACE "i3c_hdr_master"

Python

import simics

class simics.i3c_hdr_slave_interface_t(hdr_write=None, hdr_read=None,
        hdr_restart=None, hdr_exit=None)
class simics.i3c_hdr_master_interface_t(hdr_read_response=None,
        hdr_acknowledge=None)

Description

The interfaces i3c_hdr_slave and i3c_hdr_master are used together to model I3C HDR communication over the bus. HDR modes are entered by sending one of the ENTHDRx broadcast CCCs on the bus through normal SDR communication. Slaves that support HDR shall now internally switch to HDR mode. The master can exit HDR mode by calling hdr_exit on the i3c_hdr_slave interface and then follow it with a stop call. All slaves that support HDR shall now internally switch back to SDR mode.

All write transfers in HDR mode are done using the hdr_write method. Slaves must always respond through method hdr_acknowledge to either ACK or NACK the write. Devices not supporting active acknowledgement for specific write transfer blocks, must in such cases respond with an ACK as it represents a passive acknowledgement according to MIPI I3C V1.1.1 spec.

All read transfers in HDR mode are done using the hdr_read method. Parameter max_len in method hdr_read is the maximum number of bytes that the slave is allowed to send in response. The slave shall respond with an hdr_read_response call after each hdr_read call. The parameter more indicates if the slave has more data to send. The slave is allowed to send back less than max_len and at the same time set more to true. This feature is an optimization in order to:

  1. Minimize the number of hdr_read calls needed to read a large amount of data.
  2. Avoid underflow on the slave side by allowing the slave respond with less data.

If more is set to false, the master has to end its current transfer by either calling hdr_restart or exit HDR through the procedure described above.

Examples of HDR write transactions:

HDR Private Write 256 bytes followed by a 64 byte write:

MasterSlaveArguments
hdr_write2 bytes: RnW @ 15
hdr_acknowledgeACK
hdr_write100-bytes
hdr_acknowledgeACK
hdr_write100-bytes
hdr_acknowledgeACK
hdr_write56-bytes
hdr_acknowledgeACK
hdr_restart
hdr_write2 bytes: RnW @ 15
hdr_acknowledgeACK
hdr_write64-bytes
hdr_acknowledgeACK
hdr_exit
stop

The sequence of hdr_write calls could be made differently. Master can send smaller or larger chunks of data in each hdr_write call. The main concerns are to minimize the number of interface calls and to avoid overflow on the slave side. A balance between the two should be considered in the implementation of the master.

HDR Private Read 256 bytes:

MasterSlaveArguments
hdr_write2 bytes: RnW @ 15
hdr_acknowledgeACK
hdr_readmax_len = 128
hdr_read_responsebytes.len = 64, more = true
hdr_readmax_len = 128
hdr_read_responsebytes.len = 64, more = true
hdr_readmax_len = 128
hdr_read_responsebytes.len = 64, more = true
hdr_readmax_len = 64
hdr_read_responsebytes.len = 64, more = false
hdr_exit
stop

The sequence of hdr_read calls could be made differently. Master can read smaller chunks of data in each hdr_read call. The main concerns are to minimize the number of interface calls and to avoid underflow on the slave side. A balance between the two should be considered in the implementation of the master.

This interface is in tech-preview and may change without notice.

Execution Context

Cell Context for all methods.

i3c_ack_t, i3c_master, i3c_slave

Name

i3c_ack_t, i3c_master, i3c_slave — interfaces for I3C bus communication

Synopsis

C and DML

#include <simics/devs/i3c.h> // in C
import "simics/devs/i3c.dml"; // in DML

typedef enum {
        I3C_ack = 0,
        I3C_noack
} i3c_ack_t;

SIM_INTERFACE(i3c_master) {
        void (*acknowledge)(conf_object_t *obj, i3c_ack_t ack);
        void (*read_response)(conf_object_t *obj, uint8 value, bool more);
        void (*daa_response)(conf_object_t *obj,
                             uint64 id, uint8 bcr, uint8 dcr);
        void (*ibi_request)(conf_object_t *obj);
        void (*ibi_address)(conf_object_t *obj, uint8 address);
};

#define I3C_MASTER_INTERFACE "i3c_master"

SIM_INTERFACE(i3c_slave) {
        void (*start)(conf_object_t *obj, uint8 address);
        void (*write)(conf_object_t *obj, uint8 value);
        void (*sdr_write)(conf_object_t *obj, bytes_t data);
        void (*read)(conf_object_t *obj);
        void (*daa_read)(conf_object_t *obj);
        void (*stop)(conf_object_t *obj);
        void (*ibi_start)(conf_object_t *obj);
        void (*ibi_acknowledge)(conf_object_t *obj, i3c_ack_t ack);
};

#define I3C_SLAVE_INTERFACE "i3c_slave"

Python

import simics

simics.I3C_noack
simics.I3C_ack
class simics.i3c_master_interface_t(acknowledge=None, read_response=None,
        daa_response=None, ibi_request=None, ibi_address=None)
class simics.i3c_slave_interface_t(start=None, write=None, sdr_write=None,
        read=None, daa_read=None, stop=None, ibi_start=None,
        ibi_acknowledge=None)

Description

The interfaces i3c_master, i3c_slave and i3c_daa_snoop are used together to model communication over an I3C bus. There are four kinds of devices roles on the I3C bus: Main Master, Secondary Master, Slave and Legacy I2C Slave. Exactly one device must be the Main Master; this is typically configured statically. Main Master should implement the i3c_master interface, while slave should implement the i3c_slave interface. Secondary Master should implement both. Most calls to a method in the slave device interfaces expect a response call to a method in the master device interfaces. One exception is the method sdr_write in the i3c_slave interface, master expects no response when calling it. It is up to each device to find the caller’s interfaces; usually it is configured with attributes in both the master and slave device.

Two I3C devices can communicate directly if one implements the i3c_master interface and the other one implements the i3c_slave interface. An I3C bus with multiple masters or slaves is typically modelled using an i3c_link object, where each device is connected to an endpoint object.

An I3C bus consists of a number of master devices and a number of slave devices. Each I3C slave device listens to one or more 7-bit addresses. The slave devices can be I3C slave devices or Legacy I2C slave devices. This is because I3C protocol is compatible with I2C protocol, so that I3C master device can communicate with I2C slave devices. For legacy I2C slave device, the address it listens to is pre-configured by the device, i.e. static address. For I3C slave device, the address it listens to can be either static address or dynamic address. The dynamic address is assigned by master during Dynamic Address Assignment process. It is an error to connect two slave devices to the same bus if they listen to the same address. In a communication, the Current Master refers to the device who now drives the bus. It can be Main Master, or Secondary Master. Usually, communication over the bus is initiated by the Current Master, which can communicate with one or more slave devices at a time. A slave device can request to initiate an communication, i.e., issue an ibi_request, in three cases: Hot-Join, In-Band Interrupt and as a Secondary Master other than the Current Master requesting to become Current Master. Only one device on a bus can communicate at a time.

The start method starts a transfer. The address parameter is the address header combined with read/write bit encoded as an 8-bit number. The least significant bit is the read/write bit and the other bits is the 7-bit address header. If the start method is called from master, the address header can be address pattern 0x7E for broadcast, or specific slave address (either I2C slave static address or I3C slave dynamic address).

In I3C bus or link implementation, every start request will broadcast to all other devices. So does the stop request. This will monitor bus/link status to all devices.

Normally, master starts a transfer, then the slave responds to start using the acknowledge method (implemented by master side interface). The ack parameter may be I3C_ack or I3C_noack if the start is acked or noacked, respectively.

There are five types of different start requests: I3C master read transaction
If a master’s start with specific slave address was acked by other device, and read/write bit in the address parameter of the start method was 1, then master proceeds with a sequence of read calls. Each call is followed by a read_response call from the slave. Parameter data in the method read_response is the data transferred. The procedure is no difference with regard to read from I3C slave or read from I2C slave. In hardware, the ACK/T bit is handled differently for i2c and i3c, and the master is supposed to know whether the slave is an i2c or i3c device. In the i3c case, the slave is supposed to pass the T bit in the more argument of read_response, while an i2c device always passes more as true. Further more, in the i2c case, a master sends an ACK bit, which is not represented explicitly in the interface. The value of this bit can be deduced from whether the following operation is START/STOP or READ. For i3c case, parameter more in method read_response indicates if there are still data waiting to be transferred from slave to master. more is true when there are still data left, false otherwise.
I3C master write transaction (write to I3C slave)
If a master’s start with specific slave address was acked by other device, and the read/write bit in the address parameter of start method was 0, the master proceeds with a sdr_write call, no response is expected. Parameter data in method write is the data transferred. The parity bit is not passed explicitly in sdr_write, and that the slave can assume the parity bit is correctly set.
I3C master write transaction (write to I2C slave)
When the master’s start request is to write to I2C slave, i.e., master issues a start request to I2C slave address with read/write bit is 0, then master proceeds with a sequence of write calls, each call expects a response call to a method acknowledge. This is quite similar to I2C write transaction.
I3C broadcast transaction
When master starts a transfer with I3C Broadcast Address 0x7E which is passed as address header, i.e., address 0xFC passed in the address argument of method start, a typical I3C message transfer is initiated.

Multiple I3C slave devices may acknowledge the start request. The master will conceive a request as being acknowledged if it was acknowledged by at least one of the slaves. Note that there will be a single acknowledge call in the master; the link or bus handles aggregation of acks.

Master sends the I3C Commands (Common Command Code, CCC) using sdr_write method after receiving ACK, showing to communicate with either all Slaves (Broadcast CCCs) or specific individual Slaves (Direct CCCs). This operation expects no response, and master will proceed.

If Broadcast CCC sent previously, master calls sdr_write method to transfer data to all slaves who acked the initial access.

I3C direct transaction
After sending a Direct CCC, master continues with a repeated start request along with one specific I3C slave address. The transaction goes on just like master is communicating with only one slave. After the communication with one slave, master may be issue a repeated start request to another slave. Further communication is routed only to the targeted slave device.

After sending a number of reads or a number of writes, the master may choose to either call the stop method to issue a stop condition which terminates the transfer, or to call the start method again to issue a repeated start condition. The repeated start condition works like a normal start condition.

The start method and read method in the slave interfaces are allowed to respond synchronously; i.e., the acknowledge or read method may be called before the corresponding method in the slave interfaces has returned. A master that needs to connect directly to a slave device needs to take this into consideration; however, when communicating via an i3c_link object, the link guarantees that all responses are asynchronous.

The method daa_read and method daa_response are used in Dynamic Address Assignment process. Method daa_read is called from master to signal a daa read request. Method daa_response is called from slave to send slave specific 8-bytes data (48-bit Unique ID, BCR, DCR) to master. The parameter id, bcr and dcr in method daa_response represent the slave specific daa data. If multiple slaves response daa data, the slave with the lowest data wins and it will get the assigned address this time. Master calls method write in slave interfaces to send assigned dynamic address to the slave who wins. This operation expects a response call to method acknowledge in master side. Parameter data in method write stores the assigned address.

Master should implement the method stop in the interface i3c_slave in case there is secondary master in the configuration which may issue start request.

Slave can request to start a communication through ibi_request. The request is sent to Current Master which drives the bus now. If the master chooses to continue the slave request, ibi_start is called, this ibi start will broadcast to all devices in the configuration. Then slave can send its address header with ibi_address argument address. The address header can be 0x02 for Hot-Join, or the address of the slave itself for IBI and secondary master with read/write bit 1 and 0 respectively. If more than one slave issues ibi_address, arbitration occurs, the slave with lowest address header wins and the winning address will be delivered to master by link or bus. At that time, master issues ibi_acknowledge to the slave who wins. Other slaves which do not receive ibi_acknowledge will consume it lost arbitration already.

Execution Context

Cell Context for all methods.

i8051_interrupt

Name

i8051_interrupt — interface for interrupts in i8051 cores

Synopsis

C and DML

#include <simics/arch/i8051.h> // in C
import "simics/arch/i8051.dml"; // in DML

SIM_INTERFACE(i8051_interrupt) {
        int (*active_interrupt)(conf_object_t *NOTNULL obj);
        void (*reti)(conf_object_t *NOTNULL obj);
        bool (*suppress_irq)(conf_object_t *NOTNULL obj, uint32 addr);
};
#define I8051_INTERRUPT_INTERFACE "i8051_interrupt"

Python

import simics

class simics.i8051_interrupt_interface_t(active_interrupt=None, reti=None,
        suppress_irq=None)

Description

The active_interrupt function returns the interrupt vector address of the highest pending interrupt. This function should only be called when the processor should take an interrupt. This function may also set internal interrupt controller state, which can be cleared by the reti function call when returning from the interrupt.

The reti function is used to notify the interrupt controller that the currently active interrupt has completed.

The suppress_irq function is used to determine whether interrupt should be blocked after a writing access to a memory location.

Execution Context

Cell Context for all methods.

i8051_timer

Name

i8051_timer — interface to control timer in i8051 cores

Synopsis

C and DML

#include <simics/arch/i8051.h> // in C
import "simics/arch/i8051.dml"; // in DML

SIM_INTERFACE(i8051_timer) {
        void (*change_mode)(conf_object_t *NOTNULL obj, uint8 mode);
        void (*switch_timer)(conf_object_t *obj, uint8 caller, bool onoff);
};
#define I8051_TIMER_INTERFACE "i8051_timer"

Python

import simics

class simics.i8051_timer_interface_t(change_mode=None, switch_timer=None)

Description

The change_mode function is used to change the working mode (e.g. 16bit timer, 8 bit timer or event counting etc.) of the timer.

The switch_timer function is used to enable or disable the timer. Timers can be switched on or off by either software or hardware. The parameter caller is either 0 or 1, indicating the control is from software or hardware. Only when the timer is switched on or off by hardware, the third parameter onoff is used, which indicates whether the timer is to be enabled or disabled.

Execution Context

Cell Context for all methods.

ieee_802_15_4_control

Name

ieee_802_15_4_control — 802.15.4 control interface

Synopsis

C and DML


SIM_INTERFACE(ieee_802_15_4_control) {
        void (*set_rssi)(conf_object_t *NOTNULL obj,
                         uint64 tgt_ep_id,
                         uint32 rssi);
        void (*remove_rssi)(conf_object_t *NOTNULL obj,
                            uint64 tgt_ep_id);
        void (*clear_all_rssi)(conf_object_t *NOTNULL obj);
};
#define IEEE_802_15_4_CONTROL_INTERFACE "ieee_802_15_4_control"

Description

The ieee_802_15_4_control interface is implemented by the IEEE 802.15.4 link endpoint objects that provide a interface for endpoint configuration. Simics command (Python program) calls set_rssi, remove_rssi and clear_all_rssi to update the RSSI table.

Execution Context

Cell Context for all methods.

ieee_802_15_4_frame_crc_status_t

Name

ieee_802_15_4_frame_crc_status_t — 802.15.4 frame CRC status

Synopsis

C and DML


typedef enum {
        IEEE_802_15_4_Frame_CRC_Match = 0,
        IEEE_802_15_4_Frame_CRC_Mismatch,
        IEEE_802_15_4_Frame_CRC16_Unknown,
        IEEE_802_15_4_Frame_CRC32_Unknown,
} ieee_802_15_4_frame_crc_status_t;

Description

IEEE_802_15_4_Frame_CRC_Match
means that to the link that, regardless of the actual contents of the CRC field in frame, the CRC is considered matching the frame contents.
IEEE_802_15_4_Frame_CRC_Mismatch
means that the CRC field and the frame contents do not agree. Just like the Ethernet links, the endpoint does not really send out the packet in this case.
IEEE_802_15_4_Frame_CRC16_Unknown/IEEE_802_15_4_Frame_CRC32_Unknown
means that the link to compute the CRC and compare it with FCS (Frame Check Sequence) of the MAC frame. If the CRC field and frame contents do not agree, the endpoint does not send out the packet. IEEE_802_15_4_Frame_CRC32_Unknown is for 802.15.4g only.

Name

ieee_802_15_4_link — An interface for 802.15.4 transmissions

Synopsis

C and DML


SIM_INTERFACE(ieee_802_15_4_link) {
        ieee_802_15_4_transmit_status_t (*transmit)(
                                conf_object_t *NOTNULL obj,
                                const frags_t *frame,
                                uint16 channel_page,
                                uint16 channel_number,
                                ieee_802_15_4_frame_crc_status_t crc_status);
};
#define IEEE_802_15_4_LINK_INTERFACE "ieee_802_15_4_link"

Description

The ieee_802_15_4_link interface is implemented by the IEEE 802.15.4 link endpoint objects that provide an interface for frame traffic.

Transceiver calls transmit to send out frames. The return value is using one of the values in the ieee_802_15_4_transmit_status_t enum.

The crc_status parameter provides out-of-band information on the contents of the frame with regards to the CRC field using one of the values in the ieee_802_15_4_frame_crc_status_t enum.

The frequency channels are defined through a combination of channel numbers and channel pages. Channel page is a concept added to IEEE 802.15.4 in 2006 to distinguish between supported PHYs. Both channel page and channel number must match on source and target sides for successful transmission.

Execution Context

Cell Context for all methods.

ieee_802_15_4_probe

Name

ieee_802_15_4_probe — Probe interface for 802.15.4 devices

Synopsis

C and DML


SIM_INTERFACE(ieee_802_15_4_probe) {
        void (*attach_snooper)(conf_object_t *NOTNULL probe,
                               ieee_802_15_4_probe_snoop_t snoop_fun,
                               lang_void *user_data);
        void (*detach)(conf_object_t *NOTNULL probe);
};
#define IEEE_802_15_4_PROBE_INTERFACE "ieee_802_15_4_probe"

Description

The ieee_802_15_4_probe interface is implemented by the IEEE 802.15.4 probe devices that provide an interface for Simics users to register their own callback to listen to the traffic going-on in the probe. The attach_snooper attaches a snooper function. The probe will pass each frame to the snooper function, then forward it unchanged where it should be going. The detach detaches the currently registered callback from the probe.

This interface should only be used for inspection, and never as part of the actual simulation. The snoop functions must not affect the simulation in any way. The user_data parameter is passed to the snoop function every time it is called.

See Also

ieee_802_15_4_probe_snoop_t, ieee_802_15_4_probe_side_t,

Execution Context

Cell Context for all methods.

ieee_802_15_4_probe_side_t

Name

ieee_802_15_4_probe_side_t — 802.15.4 probe

Synopsis

C and DML


typedef enum {
        IEEE_802_15_4_Probe_Port_A = 0,
        IEEE_802_15_4_Probe_Port_B = 1
} ieee_802_15_4_probe_side_t;

Description

IEEE_802_15_4_Probe_Port_A
means that the frame is from device to link.
IEEE_802_15_4_Probe_Port_B
means that the frame is from link to device.

ieee_802_15_4_probe_snoop_t

Name

ieee_802_15_4_probe_snoop_t — Function prototype for 802.15.4 probe snope functions.

Synopsis

C and DML


typedef void (*ieee_802_15_4_probe_snoop_t)(
                                lang_void *user_data,
                                conf_object_t *probe,
                                ieee_802_15_4_probe_side_t to_side,
                                const frags_t *frame,
                                uint32 rssi,
                                uint16 channel_page,
                                uint16 channel_number,
                                ieee_802_15_4_frame_crc_status_t crc_status);

See Also

ieee_802_15_4_probe_side_t, ieee_802_15_4_frame_crc_status_t

ieee_802_15_4_receiver

Name

ieee_802_15_4_receiver — 802.15.4 receiver interface

Synopsis

C and DML


SIM_INTERFACE(ieee_802_15_4_receiver) {
        void (*receive)(conf_object_t *NOTNULL obj,
                        const frags_t *frame,
                        uint32 rssi,
                        uint16 channel_page,
                        uint16 channel_number,
                        ieee_802_15_4_frame_crc_status_t crc_status);
        void (*frame_lost)(conf_object_t *NOTNULL obj,
                           uint32 rssi,
                           uint16 channel_page,
                           uint16 channel_number);
};
#define IEEE_802_15_4_RECEIVER_INTERFACE "ieee_802_15_4_receiver"

Description

The ieee_802_15_4_receiver interface is implemented by the IEEE 802.15.4 transceivers that provide an interface for traffic. Endpoints call receive to deliver a frame to transceiver. Transceiver should check if the received frame from endpoint is in the channel that it is using. The channel being used is defined by channel_page and channel_number. Endpoints call frame_lost to notify transceivers on that a frame was lost because of low RSSI value.

Execution Context

Cell Context for all methods.

ieee_802_15_4_transmit_status_t

Name

ieee_802_15_4_transmit_status_t — 802.15.4 transmit status

Synopsis

C and DML


typedef enum {
        IEEE_802_15_4_Transmit_No_Error = 0,
        IEEE_802_15_4_Transmit_Channel_Contention,
        IEEE_802_15_4_Transmit_Data_Corruption
} ieee_802_15_4_transmit_status_t;

Description

IEEE_802_15_4_Transmit_No_Error
means that the frame was sent out without error.
IEEE_802_15_4_Transmit_Channel_Contention
means that there was collision and the frame was not sent out.
IEEE_802_15_4_Transmit_Data_Corruption
means that the endpoint detected CRC mismatch and didn’t send out the frame.

ieee_802_3_mac

Name

ieee_802_3_mac — interface used for media access control layer

Synopsis

C and DML

#include <simics/devs/ieee_802_3.h> // in C
import "simics/devs/ieee_802_3.dml"; // in DML

SIM_INTERFACE(ieee_802_3_mac) {
        int (*receive_frame)(conf_object_t *obj, int phy,
                             dbuffer_t *buf, int crc_ok);
        void (*tx_bandwidth_available)(conf_object_t *obj, int phy);
        void (*link_status_changed)(conf_object_t *obj, int phy,
                                    ieee_802_3_link_status_t status);
};
#define IEEE_802_3_MAC_INTERFACE "ieee_802_3_mac"

Python

import simics

class simics.ieee_802_3_mac_interface_t(receive_frame=None,
        tx_bandwidth_available=None, link_status_changed=None)

Deprecated!

use ieee_802_3_mac_v3 instead.

Interface that should be implemented by 802.3 media access control layers.

The receive_frame function is called when a frame has been received by the phy. The frame is passed as a dbuffer_t that may not be modified without cloning it first. The return value have no meaning, callers should ignore it, and new implementations should return 0.

The tx_bandwidth_available is called by the PHY when a previous call to send_frame or check_tx_bandwidth in the ieee_802_3_phy interface have returned no bandwidth available.

link_status_changed is called when the phy detects a change of the link status.

The phy parameter is a number that identifies this particular PHY, in configurations with several PHYs connected to the same MAC.

Execution Context

Cell Context for all methods.

ieee_802_3_link_status_t, ieee_802_3_mac_v3

Name

ieee_802_3_link_status_t, ieee_802_3_mac_v3 — interface used for media access control layer

Synopsis

C and DML

#include <simics/devs/ieee_802_3.h> // in C
import "simics/devs/ieee_802_3.dml"; // in DML

typedef enum {
        IEEE_link_unconnected,
        IEEE_link_down,
        IEEE_link_up
} ieee_802_3_link_status_t;

SIM_INTERFACE(ieee_802_3_mac_v3) {
        void (*receive_frame)(
                conf_object_t *obj, int phy, const frags_t *frame, int crc_ok);
        void (*tx_bandwidth_available)(conf_object_t *obj, int phy);
        void (*link_status_changed)(
                conf_object_t *obj, int phy, ieee_802_3_link_status_t status);
};
#define IEEE_802_3_MAC_V3_INTERFACE "ieee_802_3_mac_v3"

Python

import simics

simics.IEEE_link_unconnected
simics.IEEE_link_up
simics.IEEE_link_down
class simics.ieee_802_3_mac_v3_interface_t(receive_frame=None,
        tx_bandwidth_available=None, link_status_changed=None)

Description

Interface that should be implemented by 802.3 media access control layers.

The receive_frame function is called when a frame has been received by the phy. The frame is passed as a frags_t that must not be modified.

The crc_ok flag is set to indicate that the frame is valid with regards to CRC calculations. If the crc_ok flag is not set, the frame is considered invalid. Note that in general, crc_ok does not indicate whether or not the CRC field in the frame can be relied upon, or whether its computation has been skipped to improve simulation performance. When using new-style links, crc_ok set to false indicates that the CRC field contains valid information that is not matching with the frame contents.

The tx_bandwidth_available is called by the PHY when a previous call to send_frame or check_tx_bandwidth in the ieee_802_3_phy_v3 interface have returned no bandwidth available.

link_status_changed is called when the phy detects a change of the link status.

The phy parameter is deprecated and should be ignored.

Execution Context

Cell Context for all methods.

ieee_802_3_phy

Name

ieee_802_3_phy — interface used with 802.3 physical layers

Synopsis

C and DML

#include <simics/devs/ieee_802_3.h> // in C
import "simics/devs/ieee_802_3.dml"; // in DML

SIM_INTERFACE(ieee_802_3_phy) {

        int (*send_frame)(conf_object_t *obj, dbuffer_t *buf, int replace_crc);
        int (*check_tx_bandwidth)(conf_object_t *obj);
#if !defined(PYWRAP)
        void (*add_mac)(conf_object_t *obj, const uint8 *mac);
        void (*del_mac)(conf_object_t *obj, const uint8 *mac);
        void (*add_mac_mask)(conf_object_t *obj, const uint8 *mac,
                             const uint8 *mask);
        void (*del_mac_mask)(conf_object_t *obj, const uint8 *mac,
                             const uint8 *mask);
#endif
        void (*set_promiscous_mode)(conf_object_t *obj, int enable);
};
#define IEEE_802_3_PHY_INTERFACE "ieee_802_3_phy"

Python

import simics

class simics.ieee_802_3_phy_interface_t(send_frame=None, check_tx_bandwidth=None,
        set_promiscous_mode=None)

Description

Interface that should be implemented by 802.3 physical layers.

Deprecated!

use ieee_802_3_phy_v2 instead.

ieee_802_3_phy_v2

Name

ieee_802_3_phy_v2 — interface used with 802.3 physical layers

Synopsis

C and DML

#include <simics/devs/ieee_802_3.h> // in C
import "simics/devs/ieee_802_3.dml"; // in DML

SIM_INTERFACE(ieee_802_3_phy_v2) {
        int (*send_frame)(conf_object_t *obj, dbuffer_t *buf, int replace_crc);
        int (*check_tx_bandwidth)(conf_object_t *obj);
        void (*add_mac)(conf_object_t *obj, byte_string_t mac);
        void (*del_mac)(conf_object_t *obj, byte_string_t mac);
        void (*add_mac_mask)(conf_object_t *obj, byte_string_t mac,
                             byte_string_t mask);
        void (*del_mac_mask)(conf_object_t *obj, byte_string_t mac,
                             byte_string_t mask);
        void (*set_promiscous_mode)(conf_object_t *obj, int enable);
};
#define IEEE_802_3_PHY_V2_INTERFACE "ieee_802_3_phy_v2"

Python

import simics

class simics.ieee_802_3_phy_v2_interface_t(send_frame=None,
        check_tx_bandwidth=None, add_mac=None, del_mac=None,
        add_mac_mask=None, del_mac_mask=None, set_promiscous_mode=None)

Deprecated!

use ieee_802_3_phy_v3 instead.

Interface that should be implemented by 802.3 physical layers.

The send_frame function is used by a device to send an Ethernet frame. The frame should be a dbuffer_t containing a complete Ethernet frame. excluding the preamble and SFD, but including the CRC. The replace_crc flag indicates whether the CRC is not actually calculated yet. The passed buf should not be modified by the called function. If the function return 0, the frame was sent to the link; In case -1 is returned, there was not enough bandwidth available right now, and the frame could not be sent. The PHY should call the tx_bandwidth_available in the ieee_802_3_mac interface at the MAC, when the frame can be sent.

The check_tx_bandwidth can also be used to check that there is bandwidth available, without sending a frame. It returns 0 if there is no bandwidth available, and a positive value if the frame can be sent right away.

add_mac, del_mac and set_promiscous_mode do nothing if the PHY is connected to the new-style links using the ethernet_common interface.

The word “promiscuous” is misspelled in the interface.

Execution Context

Cell Context for all methods.

ieee_802_3_phy_v3

Name

ieee_802_3_phy_v3 — interface used with 802.3 physical layers

Synopsis

C and DML

#include <simics/devs/ieee_802_3.h> // in C
import "simics/devs/ieee_802_3.dml"; // in DML

SIM_INTERFACE(ieee_802_3_phy_v3) {
        int (*send_frame)(
                conf_object_t *obj, const frags_t *frame, int replace_crc);
        int (*check_tx_bandwidth)(conf_object_t *obj);
};
#define IEEE_802_3_PHY_V3_INTERFACE "ieee_802_3_phy_v3"

Python

import simics

class simics.ieee_802_3_phy_v3_interface_t(send_frame=None,
        check_tx_bandwidth=None)

Description

Interface that should be implemented by 802.3 physical layers.

The send_frame function is used by a device to send an Ethernet frame. The frame should be a frags_t containing a complete Ethernet frame, excluding the preamble and SFD, but including space for the CRC field. The passed frame must not be modified by the called function.

The replace_crc flag indicates whether the CRC field contents can be modified by the implementing object: if replace_crc is not set, the implementing object will leave the CRC field untouched; if replace_crc is set, the implementing object is free to rewrite the CRC field according to the link constraints. Note that in many cases, setting replace_crc to true will allow the link to assume the CRC field to be matching the frame contents, thus skipping CRC calculation and improving simulation performance. replace_crc should only be set to false when the device wants to send a frame with a CRC field not matching the frame contents.

If the function return 0, the frame was sent to the link; In case -1 is returned, there was not enough bandwidth available right now, and the frame could not be sent. The PHY should call the tx_bandwidth_available in the ieee_802_3_mac_v3 interface at the MAC, when the frame can be sent.

The check_tx_bandwidth can also be used to check that there is bandwidth available, without sending a frame. It returns 0 if there is no bandwidth available, and a positive value if the frame can be sent right away.

Execution Context

Cell Context for all methods.

instruction_trace_callback_t

Name

instruction_trace_callback_t — Function type for callbacks in exec_trace_interface_t

Synopsis

C and DML

#include <simics/model-iface/exec-trace.h> // in C
import "simics/model-iface/exec-trace.dml"; // in DML

typedef void (*instruction_trace_callback_t)(lang_void *tracer_data,
                                             conf_object_t *cpu,
                                             linear_address_t la,
                                             logical_address_t va,
                                             physical_address_t pa,
                                             byte_string_t opcode);

Description

It takes the following arguments:

tracer_data
The exact pointer passed as tracer_data when registering the listener function with register_tracer() in the exec_trace interface.
cpu
The cpu executing the instruction.
la
The linear address of the instruction for x86 processors, and nothing for all others.
va
The virtual address of the instruction as contained in the program counter, or instruction pointer register.
pa
The physical address of the instruction after doing a MMU lookup.
opcode
The bytes composing the instruction.

int_register

Name

int_register — access registers in a processor

Synopsis

C and DML

#include <simics/model-iface/int-register.h> // in C
import "simics/model-iface/int-register.dml"; // in DML

typedef enum {
        Sim_RegInfo_Catchable
} ireg_info_t;

SIM_INTERFACE(int_register) {
        int (*get_number)(conf_object_t *NOTNULL obj,
                          const char *NOTNULL name);
        const char *(*get_name)(conf_object_t *NOTNULL obj, int reg);
        uint64 (*read)(conf_object_t *NOTNULL obj, int reg);
        void (*write)(conf_object_t *NOTNULL obj, int reg, uint64 val);
        attr_value_t (*all_registers)(conf_object_t *NOTNULL obj);
        int (*register_info)(conf_object_t *NOTNULL obj, int reg,
                             ireg_info_t info);
};

#define INT_REGISTER_INTERFACE "int_register"

Python

import simics

simics.Sim_RegInfo_Catchable
class simics.int_register_interface_t(get_number=None, get_name=None, read=None,
        write=None, all_registers=None, register_info=None)

Description

The int_register interface is used for access to registers in a processor. It can be used to access any kind of integer register, not only the “normal” registers. This includes all kinds of control registers, hidden registers and anything else that might be useful to access as a register. The only limitation is that the register value should be representable as a 64-bit unsigned integer.

This interface can be implemented by other classes than processors, but it is likely to be found mostly in processors.

Registers are identified by a number, and there are two functions to translate from register names to register numbers and back. The translation need not be one-to-one, which means that one register can have several names. A register name can, however, only translate to a single register number.

Often, registers are grouped in register banks, where registers in the bank are numbered from 0 up. Registers in a bank should have consecutive numbers (unless their numbering is very sparse). This allows a user to deduce register numbers by calling get_number for the first register only. The first register numbers should be used for the general-purpose integer registers, if possible (so that integer register rN has number N).

Using this interface to read or write registers does not cause any side effects, such as triggering interrupts or signalling haps.

get_number translates a register name to its number. Returns -1 if the register does not exist.

get_name translates a register number to its canonical name.

read reads a register value.

write writes a new register value.

all_registers returns a list of all register numbers that can be used for this object.

register_info returns information about a single register. The information return depends on the info parameter:

Sim_RegInfo_Catchable
Return 1 if Core_Control_Register_Write and Core_Control_Register_Read are triggered when this register is written or read. Return 0 otherwise.

Execution Context

Cell Context for all methods, except for write where the register is a program counter; Global Context in that case.

interrupt_ack

Name

interrupt_ack — interface used with acked interrupts

Synopsis

C and DML

#include <simics/devs/interrupt-ack.h> // in C
import "simics/devs/interrupt-ack.dml"; // in DML

SIM_INTERFACE(interrupt_ack) {
        void (*raise_interrupt)(conf_object_t *NOTNULL obj,
                                interrupt_ack_fn_t cb,
                                conf_object_t *ack_obj);
        void (*lower_interrupt)(conf_object_t *NOTNULL obj,
                                interrupt_ack_fn_t cb);
};

#define INTERRUPT_ACK_INTERFACE "interrupt_ack"

Python

import simics

class simics.interrupt_ack_interface_t(raise_interrupt=None, lower_interrupt=None)

Description

Interface for acked interrupts. The target is typically a cpu that later calls the supplied ack function when the interrupt is actually taken.

The ack argument in the lower_interrupt function serves no purpose and should not be used.

To recover the ack function after a checkpoint restoration, read it from the interrupt_cpu interface.

Execution Context

Cell Context for all methods.

interrupt_cpu

Name

interrupt_cpu — interface used with interrupts

Synopsis

C and DML

#include <simics/devs/interrupt-ack.h> // in C
import "simics/devs/interrupt-ack.dml"; // in DML

SIM_INTERFACE(interrupt_cpu) {
        interrupt_ack_fn_t ack;
};

#define INTERRUPT_CPU_INTERFACE "interrupt_cpu"

Python

import simics

class simics.interrupt_cpu_interface_t(ack=None)

Description

Interface that must be implemented by an interrupt source that sends interrupts through the x86 interface. Used to reestablish the ack function when loading a checkpoint.

Execution Context

Cell Context for all methods.

interrupt_subscriber

Name

interrupt_subscriber — interface used with interrupts

Synopsis

C and DML

#include <simics/devs/interrupt-subscriber.h> // in C
import "simics/devs/interrupt-subscriber.dml"; // in DML

SIM_INTERFACE(interrupt_subscriber) {
        void (*notify)(
                conf_object_t *NOTNULL obj,
                apic_delivery_mode_t delivery_mode,
                bool level_assert,
                apic_trigger_mode_t trigger_mode,
                uint8 vector,
                interrupt_source_t source);
        void (*reset)(conf_object_t *NOTNULL obj);
};
#define INTERRUPT_SUBSCRIBER_INTERFACE "interrupt_subscriber"

Python

import simics

class simics.interrupt_subscriber_interface_t(notify=None, reset=None)

Description

The target is typically a CPU that reacts to the interrupt.

The function notify notifies when an interrupt has occurred.

The function reset is run when the interrupt notifier source is reset.

Execution Context

Threaded Context for all methods.

addr_space_t, io_memory

Name

addr_space_t, io_memory — legacy interface for devices that can be mapped into address spaces

Synopsis

C and DML

#include <simics/device-api.h> // in C
// always available in DML

typedef enum {
        Sim_Addr_Space_Conf,
        Sim_Addr_Space_IO,
        Sim_Addr_Space_Memory
} addr_space_t;

#include <simics/devs/io-memory.h> // in C
import "simics/devs/io-memory.dml"; // in DML

SIM_INTERFACE(io_memory) {
        int (*DEPRECATED_FUNC(map))(conf_object_t *NOTNULL obj,
                                    addr_space_t memory_or_io,
                                    map_info_t map_info);
        exception_type_t (*operation)(conf_object_t *NOTNULL obj,
                generic_transaction_t *NOTNULL mem_op,
                map_info_t map_info);
};

#define IO_MEMORY_INTERFACE "io_memory"

Python

import simics

simics.Sim_Addr_Space_IO
simics.Sim_Addr_Space_Memory
simics.Sim_Addr_Space_Conf
class simics.io_memory_interface_t(_deprecated_map=None, operation=None)

Description

This interface is legacy. New code should use the transaction interface.

This interface is implemented by devices that can be mapped into address spaces (including port spaces). The operation() is called when the object is accessed through an address space.

The obj argument is a pointer to the mapped object and map_info contains information about how and where the device is mapped into memory. The mem_op argument to operation() contains information about the access.

The offset into the device mapping for the access is typically calculated in the following way:

offset = SIM_get_mem_op_physical_address(mem_op)
         - map_info.base + map_info.start

The map() function is deprecated and should not be used. The function may be called when the object is mapped into an address space, but it is not guaranteed that this happens. The function can be left unimplemented (NULL).

The exception_type_t type, returned by the operation() function may be used to signal errors to Simics, but should in most cases be Sim_PE_No_Exception. If the device does not support inquiry accesses, it should return Sim_PE_Inquiry_Unhandled if mem_op->inquiry is 1.

Execution Context

Cell Context for all methods.

map_demap

Name

map_demap — interface used to configure memory spaces

Synopsis

C and DML

#include <simics/devs/map-demap.h> // in C
import "simics/devs/map-demap.dml"; // in DML

SIM_INTERFACE(map_demap) {
        /* old-style */
        int (*add_map)(conf_object_t *NOTNULL space,
                       conf_object_t *NOTNULL dev,
                       conf_object_t *target,
                       map_info_t map_info);
        int (*remove_map)(conf_object_t *NOTNULL space,
                          conf_object_t *NOTNULL dev,
                          int function);
        int (*add_default)(conf_object_t *NOTNULL space,
                           conf_object_t *NOTNULL dev,
                           conf_object_t *target,
                           map_info_t map_info);
        void (*remove_default)(conf_object_t *NOTNULL space);

        /* new-style */
        int (*map_simple)(conf_object_t *NOTNULL space,
                          conf_object_t *NOTNULL dev,
                          const char *dev_port,
                          map_info_t map_info);
        int (*map_bridge)(conf_object_t *NOTNULL space,
                          conf_object_t *NOTNULL dev,
                          const char *dev_port,
                          conf_object_t *target,
                          const char *target_port,
                          map_info_t map_info);
        int (*unmap)(conf_object_t *NOTNULL space,
                     conf_object_t *NOTNULL dev,
                     const char *dev_port);
        int (*unmap_address)(conf_object_t *NOTNULL space,
                             conf_object_t *NOTNULL dev,
                             physical_address_t base,
                             const char *dev_port);
};

#define MAP_DEMAP_INTERFACE "map_demap"

Python

import simics

class simics.map_demap_interface_t(add_map=None, remove_map=None,
        add_default=None, remove_default=None, map_simple=None,
        map_bridge=None, unmap=None, unmap_address=None)

Description

Interface used to dynamically add and remove mappings in a memory space. The first argument to all functions, space is the memory space to map an object in.

The map_simple function adds a device/port pair to the memory map. The added device (port) must implement either the ram, rom, io_memory, port_space, translator, transaction_translator, transaction or memory_space interfaces.

The map_bridge function adds a device/port pair to the memory map to act as a bridge that translates memory accesses before passing them on to another object. The added device (port) must implement either the translate interface or the bridge interface, and the target and target_port parameter specifies the object behind the bridge. The target is typically another memory space.

The unmap removes an object from the memory map. The dev and port parameters are the same as those given to the map_simple and map_bridge functions.

The unmap_address removes all mappings that map object and start at the base address.

The add_map, remove_map, add_default and remove_default functions are deprecated and should not be used. Both base and length of the map_info_t structure should be 0 to map a default_target.

All functions in the map_demap return 1 on success and 0 on failure.

More information about the different kinds of memory space mappings is available in Simics Model Builder User’s Guide.

Execution Context

Cell Context for all methods.

mdio45_bus

Name

mdio45_bus — interface for PHY with MDIO management interface

Synopsis

C and DML

#include <simics/devs/mii.h> // in C
import "simics/devs/mii.dml"; // in DML

SIM_INTERFACE(mdio45_bus) {
        uint16 (*read_register)(conf_object_t *obj, int phy, int mmd, int reg);
        void   (*write_register)(conf_object_t *obj, int phy, int mdd, int reg,
                                 uint16 value);

};
#define MDIO45_BUS_INTERFACE "mdio45_bus"

Python

import simics

class simics.mdio45_bus_interface_t(read_register=None, write_register=None)

Description

Interface that should be implemented by classes that either represent an MDIO bus, or multi PHY devices implementing the IEEE 802.3 clause 45 MDIO management interface.

The read_register function should return the 16-bit value of the specified register. phy specifies the PHY address (0-31), mmd specifies the MMD (MDIO manageable device) within the PHY (0-31) and reg specifies the register number within the MMD (0-65535).

Devices modeling a single PHY should implement the mdio45_phy interface instead.

Execution Context

Cell Context for all methods.

mdio45_phy

Name

mdio45_phy — interface for PHY with MDIO management interface

Synopsis

C and DML

#include <simics/devs/mii.h> // in C
import "simics/devs/mii.dml"; // in DML

SIM_INTERFACE(mdio45_phy) {
        uint16 (*read_register)(conf_object_t *obj, int mmd, int reg);
        void   (*write_register)(conf_object_t *obj, int mmd, int reg,
                                 uint16 value);

};
#define MDIO45_PHY_INTERFACE "mdio45_phy"

Python

import simics

class simics.mdio45_phy_interface_t(read_register=None, write_register=None)

Description

Interface that should be implemented by classes representing a single PHY implementing the IEEE 802.3 clause 45 MDIO management interface.

The read_register function should return the 16-bit value of the specified register. mmd specifies the MMD (MDIO manageable device) within the PHY (0-31) and reg specifies the register number within the MMD (0-65535).

Devices modeling either an MDIO bus, or multiple PHYs should implement the mdio45_bus interface instead.

Execution Context

Cell Context for all methods.

memory_space

Name

memory_space — implemented by classes that provide linear address spaces

Synopsis

C and DML

#include <simics/devs/memory-space.h> // in C
import "simics/devs/memory-space.dml"; // in DML

// some parts deprecated with SIMICS_API = 7
SIM_INTERFACE(memory_space) {
        map_list_t *(*space_lookup)(conf_object_t *NOTNULL obj,
                                    generic_transaction_t *NOTNULL mop,
                                    map_info_t mapinfo);
        exception_type_t (*access)(conf_object_t *NOTNULL obj,
                                   generic_transaction_t *NOTNULL mop);
#if !defined(PYWRAP)
        exception_type_t (*access_simple)(conf_object_t *obj,
                                          conf_object_t *initiator,
                                          physical_address_t addr,
                                          uint8 *buf,
                                          physical_address_t len,
                                          read_or_write_t type,
                                          endianness_t endian);
        exception_type_t (*access_simple_inq)(conf_object_t *obj,
                                              conf_object_t *initiator,
                                              physical_address_t addr,
                                              uint8 *buf,
                                              physical_address_t len,
                                              read_or_write_t type,
                                              endianness_t endian);
#endif /* !PYWRAP */
        attr_value_t (*read)(conf_object_t *NOTNULL obj,
                             conf_object_t *initiator,
                             physical_address_t addr,
                             int length,
                             int inquiry);
        exception_type_t (*write)(conf_object_t *NOTNULL obj,
                                  conf_object_t *initiator,
                                  physical_address_t addr,
                                  attr_value_t data,
                                  int inquiry);
        cycles_t (*DEPRECATED_FUNC(timing_model_operate))(
                conf_object_t *NOTNULL space,
                generic_transaction_t *NOTNULL mop);
        uint64 (*fill)(conf_object_t *NOTNULL obj,
                       physical_address_t start, uint64 size, uint8 value,
                       bool inquiry);
};

#define MEMORY_SPACE_INTERFACE "memory_space"

Python

import simics

class simics.memory_space_interface_t(space_lookup=None, access=None, read=None,
        write=None, timing_model_operate=None, fill=None)

Description

This interface is implemented by classes that provide linear address spaces.

Other objects may perform accesses in the address space using the access function or one of the simplified access functions, or may ask for mapped objects using space_lookup. Typical usage of this interface would be memory accesses from devices or processors.

The space_lookup function would be used to find end-points for a memory request. The mop needs to be crafted similarly as for a regular read or write operation and would typically be created with SIM_make_mem_op_read or SIM_make_mem_op_write. The return value for space_lookup is a list of all mappings that match the input mop.

The access function operates on a generic transaction that would typically be created with SIM_make_mem_op_read or SIM_make_mem_op_write. The access_simple function is similar to access but takes some additional arguments instead of a complete generic_transaction_t structure. An inquiry version of this function is available as access_simple_inq. Both these functions can perform endian conversion if the buffer pointed to by buf contains a value in host endian byte-order. To avoid endian conversion, Sim_Endian_Target should be specified as endian. These two functions are not available from Python.

The read and write methods are primarily intended for use in Python. They operate on data encapsulated in attribute values which should be of data type; in Python, this corresponds to tuples of integers (bytes). These two methods signal errors by raising a frontend exception. They can be used to read or write up to 1024 bytes in a single call. The return value from write should be ignored.

The fill method fills size bytes starting at start with value. It only works on memory, and returns the number of bytes actually written before encountering something that isn’t RAM.

Exceptions

The read and write methods signal errors by raising frontend exceptions.

Execution Context

Cell Context for all methods.

microwire

Name

microwire — interface used to communicate with a 3-wire devices

Synopsis

C and DML

#include <simics/devs/microwire.h> // in C
import "simics/devs/microwire.dml"; // in DML

SIM_INTERFACE(microwire) {
        void (*set_cs)(conf_object_t *obj, int cs);
        void (*set_sk)(conf_object_t *obj, int sk);
        void (*set_di)(conf_object_t *obj, int di);
        int  (*get_do)(conf_object_t *obj);
        uint16 (*read_word)(conf_object_t *obj, int offset);
        void (*write_word)(conf_object_t *obj, int offset, uint16 value);
};
#define MICROWIRE_INTERFACE "microwire"

Python

import simics

class simics.microwire_interface_t(set_cs=None, set_sk=None, set_di=None,
        get_do=None, read_word=None, write_word=None)

Description

This interface is used to communicate with a 3-wire (microwire) serial EEPROM device, for example, the 93Cxx series, via its pins. To set the values of the CS, SK, and DI pins, use the set_cs, set_sk, and set_di functions, respectively. To read the value output on the DO pin, use the get_do function. Zero represents low signal and non-zero high signal. The read_word and write_word functions are provided to shortcut high-level operations. They operate on 8-bit or 16-bit entities depending on the width of the eeprom.

Execution Context

Cell Context for all methods.

mii

Name

mii — interface for PHY with MII management interface

Synopsis

C and DML

#include <simics/devs/mii.h> // in C
import "simics/devs/mii.dml"; // in DML

SIM_INTERFACE(mii) {
        int    (*serial_access)(conf_object_t *obj, int data_in, int clock);
        uint16 (*read_register)(conf_object_t *obj, int index);
        void   (*write_register)(conf_object_t *obj, int index, uint16 value);
};
#define MII_INTERFACE "mii"

Python

import simics

class simics.mii_interface_t(serial_access=None, read_register=None,
        write_register=None)

Description

Obsolete interface that is implemented by some PHY’s that support the MII management interface.

It has the same methods as the mii_management interface, but does not pass along the PHY number.

To support low-level bitwise accesses via MDIO and MDC pins, the function serial_access can be used. It is recommended to leave this function unimplemented and let an instance of mii-management-bus convert the low-level bit operations to higher level read/write register calls.

Execution Context

Cell Context for all methods.

mii_management

Name

mii_management — interface for PHY with MII management interface

Synopsis

C and DML

#include <simics/devs/mii.h> // in C
import "simics/devs/mii.dml"; // in DML

SIM_INTERFACE(mii_management) {
        int    (*serial_access)(conf_object_t *obj, int data_in, int clock);
        uint16 (*read_register)(conf_object_t *obj, int phy, int reg);
        void   (*write_register)(conf_object_t *obj, int phy, int reg,
                                 uint16 value);
};
#define MII_MANAGEMENT_INTERFACE "mii_management"

Python

import simics

class simics.mii_management_interface_t(serial_access=None, read_register=None,
        write_register=None)

Description

Interface that should be implemented by classes that represents one or multiple PHY’s that have MII management interfaces.

The read_register function should return the 16-bit value of the specified register. There are 32 registers numbered 0-31. The phy argument indicates the PHY number (0-31). Classes that represents one PHY can ignore this argument. The write_register function is called when a register is written.

To support low-level bitwise accesses via MDIO and MDC pins, the function serial_access can be used. It is recommended to leave this function unimplemented and let an instance of mii-management-bus convert the low-level bit operations to higher level read/write register calls. The serial_access function takes as argument the MDIO and MDC pin levels on the master, and return the MDIO pin from the slave. Note that mii-management-bus also have signal interfaces for these pins.

Execution Context

Cell Context for all methods.

mips_cache_instruction

Name

mips_cache_instruction — interface for side effects of cache instructions

Synopsis

C and DML

#include <simics/arch/mips.h> // in C
import "simics/arch/mips.dml"; // in DML

SIM_INTERFACE(mips_cache_instruction) {
        int (*cache_instruction)(conf_object_t *NOTNULL self,
                                 conf_object_t *NOTNULL cpu,
                                 uint32 op, logical_address_t vaddr);
};
#define MIPS_CACHE_INSTRUCTION_INTERFACE "mips_cache_instruction"

Python

import simics

class simics.mips_cache_instruction_interface_t(cache_instruction=None)

Description

This mips_cache_instruction interface is used when side-effects are wanted when cache instructions are run.

The cache_instruction function is called whenever the cache instruction is run, and the parameters operation and vaddr are taken directly from the instruction.

The exact meaning of operation is processor-dependent.

A non-zero return value indicates that an exception should be raised on the MIPS core, whereas a zero value means no exception.

Execution Context

Cell Context.

mips_coprocessor

Name

mips_coprocessor — interface used by MIPS cores to access coprocessors

Synopsis

C and DML

#include <simics/arch/mips.h> // in C
import "simics/arch/mips.dml"; // in DML

SIM_INTERFACE(mips_coprocessor) {
        uint64 (*read_register)(conf_object_t *NOTNULL obj,
                                uint32 thread_id,
                                uint32 reg,
                                uint32 sel);
        void (*write_register)(conf_object_t *NOTNULL obj,
                               uint32 thread_id,
                               uint64 value,
                               uint32 reg,
                               uint32 sel);
};
#define MIPS_COPROCESSOR_INTERFACE "mips_coprocessor"

Python

import simics

class simics.mips_coprocessor_interface_t(read_register=None, write_register=None)

Description

This mips_coprocessor interface is implemented by MIPS coprocessors. The MIPS processor cores use this interface to access coprocessor registers.

The read_register function returns a 64-bit value from a coprocessor register. The return value should be zero extended if the coprocessor register is less than 64-bits.

The write_register function writes a 64-bit value to a coprocessor register. The target register can be smaller than 64-bits.

The thread_id is the thread id for the calling processor core. The reg and sel selects the coprocessor register to read or write. For instructions that make use of the whole implementation-defined bits 15:0, that field is passed as reg and sel is zero.

Execution Context

Cell Context for all methods.

mips_eic

Name

mips_eic — interface used between MIPS cores and external interrupt controllers

Synopsis

C and DML

#include <simics/arch/mips.h> // in C
import "simics/arch/mips.dml"; // in DML

SIM_INTERFACE(mips_eic) {
        void (*cpu_pending_irqs)(conf_object_t *NOTNULL obj, uint32 cause);
        uint32 (*requested_ipl)(conf_object_t *NOTNULL obj);
        uint32 (*requested_offset)(conf_object_t *NOTNULL obj);
        uint32 (*requested_vect_num)(conf_object_t *NOTNULL obj);
        uint32 (*reg_set)(conf_object_t *NOTNULL obj);
        void (*handled)(conf_object_t *NOTNULL obj);
};

#define MIPS_EIC_INTERFACE "mips_eic"

Python

import simics

class simics.mips_eic_interface_t(cpu_pending_irqs=None, requested_ipl=None,
        requested_offset=None, requested_vect_num=None, reg_set=None,
        handled=None)

Description

The mips_eic must be implemented by devices that acts as MIPS External Interrupt Controllers. After the external IRQ signal in the CPU has been raised, the CPU will query the registered External Interrupt Controller for information about the current interrupt request. When the CPU starts the interrupt servicing it calls the handled function.

The cpu_pending_irqs function sends current cause register which stores the pending irqs for software irq, timer irq, fdci irq and pci irq. The external irq controller should take this information to do irq arbitration.

requested_ipl should used to return the requested interrupt priority level.

There are two options for vector offset calculation. Option 1, EIC device returns a vector number. This vector number will be used together with intctl.vs to calculate the offset. Option 2, EIC returns the offset directly. When using option 1, the requested_vect_num function should be used to return the vector number. When using option 2, the requested_offset should be used to return the offset of the requested interrupt.

The reg_set should return the shadow register set number.

Execution Context

Cell Context for all methods.

mips_exception_query

Name

mips_exception_query — interface used with instrumentation of MIPS cores

Synopsis

C and DML

#include <simics/arch/mips-instrumentation.h> // in C
import "simics/arch/mips-instrumentation.dml"; // in DML

SIM_INTERFACE(mips_exception_query) {
        logical_address_t (*return_pc)(conf_object_t *cpu,
                                       exception_handle_t *handle);
};

#define MIPS_EXCEPTION_QUERY_INTERFACE "mips_exception_query"

Python

import simics

class simics.mips_exception_query_interface_t(return_pc=None)

Description

Used to query information of an exception from a cpu_exception_cb_t callback.

return_pc is used to get the return address for the exception.

Execution Context

Cell Context for all methods.

mips

Name

mips — MIPS dummy interface

Synopsis

C and DML

#include <simics/arch/mips.h> // in C
import "simics/arch/mips.dml"; // in DML

SIM_INTERFACE(mips) {
        int dummy;
};

#define MIPS_INTERFACE "mips"

Python

import simics

class simics.mips_interface_t()

Description

This interface is implemented by MIPS processors to provide various functionality that is specific for this class of processors.

There are currently no MIPS-specific functions.

Execution Context

Not applicable.

mips_ite

Name

mips_ite — interface for MIPS Inter-Thread Communication Unit

Synopsis

C and DML

#include <simics/arch/mips.h> // in C
import "simics/arch/mips.dml"; // in DML

SIM_INTERFACE(mips_ite) {
        void (*set_dtag_lo)(conf_object_t *NOTNULL obj, uint32 value);
        uint32 (*get_dtag_lo)(conf_object_t *NOTNULL obj);
        uint32 (*get_errctl)(conf_object_t *NOTNULL obj);
        void (*block_tc)(conf_object_t *NOTNULL obj);
        void (*gated_exception)(conf_object_t *NOTNULL obj);
        int (*current_tc_num)(conf_object_t *NOTNULL obj);
        void (*unblock_tc)(conf_object_t *NOTNULL obj, int tc_num);
        bool (*is_big_endian)(conf_object_t *NOTNULL obj);
};
#define MIPS_ITE_INTERFACE "mips_ite"

Python

import simics

class simics.mips_ite_interface_t(set_dtag_lo=None, get_dtag_lo=None,
        get_errctl=None, block_tc=None, gated_exception=None,
        current_tc_num=None, unblock_tc=None, is_big_endian=None)

Description

This mips_ite interface is implemented by the CPU, for communicating with the MIPS Inter-Thread Communication Unit.

The set_dtag_lo function sets the DTagLo SPR.

The get_dtag_lo function returns the value of the DTagLo SPR.

The get_errctl function returns the value of the ErrCtl SPR.

The block_tc function marks the current TC as blocked on gating storage and swaps in another TC.

The gated_exception function throws an immediate exception.

The current_tc_num function returns the currently running TC number on the VPE.

The unblock_tc function unblocks the specified TC if it is currently blocked on gating storage.

The is_big_endian function indicates if the CPU expects big endian memory storage.

Execution Context

Cell Context for all methods.

multi_level_signal

Name

multi_level_signal — model a signal with multiple levels, such as an analog signal

Synopsis

C and DML

#include <simics/devs/signal.h> // in C
import "simics/devs/signal.dml"; // in DML

SIM_INTERFACE(multi_level_signal) {
        void (*signal_level_change)(conf_object_t *NOTNULL obj, uint64 level);
        void (*signal_current_level)(conf_object_t *NOTNULL obj, uint64 level);
};
#define MULTI_LEVEL_SIGNAL_INTERFACE "multi_level_signal"

Python

import simics

class simics.multi_level_signal_interface_t(signal_level_change=None,
        signal_current_level=None)

Description

Obsoleted by the uint64_state interface.

The signal initiator (i.e. the object producing the signal) should call signal_level_change when the level changes. Multiple calls with the same level should be accepted by the signal receiver.

The optional function signal_current_level can be called when a new target is connected.

Execution Context

Cell Context for all methods.

nand_flash

Name

nand_flash — interface implemented by NAND Flash devices

Synopsis

C and DML

#include <simics/devs/nand-flash.h> // in C
import "simics/devs/nand-flash.dml"; // in DML

SIM_INTERFACE(nand_flash) {
        uint16 (*read_access)(conf_object_t *obj);
        void (*write_access)(conf_object_t *obj, uint16 value);

        void (*set_command_latch_enable)(conf_object_t *obj, int value);
        void (*set_address_latch_enable)(conf_object_t *obj, int value);
        void (*set_write_protect)(conf_object_t *obj, int value);
        void (*set_spare_area_enable)(conf_object_t *obj, int value);
};
#define NAND_FLASH_INTERFACE "nand_flash"

Python

import simics

class simics.nand_flash_interface_t(read_access=None, write_access=None,
        set_command_latch_enable=None, set_address_latch_enable=None,
        set_write_protect=None, set_spare_area_enable=None)

Description

The nand_flash interface is used to perform read and write accesses and control some pins on NAND Flash devices.

The read_access and write_access functions perform read and write accesses.

The set_command_latch_enable, set_address_latch_enable, set_write_protect and set_spare_area_enable functions set the input level of the pins with the same names. 0 represents low input and 1 represents high input.

The chip enable and ready/busy pins are not modelled. The NAND Flash device assumes that chip enable is always asserted, and the device is never busy.

Execution Context

Cell Context for all methods.

network_breakpoint

Name

network_breakpoint — used to attach snoop functions to VLAN network

Synopsis

C and DML

#include <simics/devs/ethernet.h> // in C
import "simics/devs/ethernet.dml"; // in DML

SIM_INTERFACE(network_breakpoint) {
        int64 (*add)(conf_object_t *NOTNULL obj, bytes_t src_mac_addr,
                     bytes_t dst_mac_addr, int ether_type,
                     break_net_cb_t cb, bool once, int64 bp_id);
        void (*remove)(conf_object_t *NOTNULL obj, int64 bp_id);
};
#define NETWORK_BREAKPOINT_INTERFACE "network_breakpoint"

Python

import simics

class simics.network_breakpoint_interface_t(add=None, remove=None)

Description

The network_breakpoint interface is implemented by objects that handles ethernet links to have breakpoints. The add is used to set a breakpoint on a given src mac address or gived dst mac address or by ether type. If they are combined then the criteria is that all given has to match. The remove is used to remove an existing breakpoint.

Execution Context

Global Context for all methods

See Also

break_net_cb_t

nios_cache

Name

nios_cache — NIOS cache interface

Synopsis

C and DML

#include <simics/arch/nios.h> // in C
import "simics/arch/nios.dml"; // in DML

SIM_INTERFACE(nios_cache) {
        void (*flushd)(conf_object_t *NOTNULL self, logical_address_t addr);
        void (*flushda)(conf_object_t *NOTNULL self, logical_address_t addr);
        void (*flushi)(conf_object_t *NOTNULL self, logical_address_t addr);
        void (*flushp)(conf_object_t *NOTNULL self);
        void (*initd)(conf_object_t *NOTNULL self, logical_address_t addr);
        void (*initda)(conf_object_t *NOTNULL self, logical_address_t addr);
        void (*initi)(conf_object_t *NOTNULL self, logical_address_t addr);
        void (*sync)(conf_object_t *NOTNULL self);
};
#define NIOS_CACHE_INTERFACE "nios_cache"

Python

import simics

class simics.nios_cache_interface_t(flushd=None, flushda=None, flushi=None,
        flushp=None, initd=None, initda=None, initi=None, sync=None)

Description

This nios_cache interface is used when the side-effects are required for cache instructions.

Each function is called when the corresponding instruction is executed. See Nios® II processor reference guide, section 8, for further information.

Execution Context

Cell Context for all methods.

nios_custom

Name

nios_custom — interface used with the NIOS custom instruction

Synopsis

C and DML

#include <simics/arch/nios.h> // in C
import "simics/arch/nios.dml"; // in DML

SIM_INTERFACE(nios_custom) {
        uint32 (*custom)(conf_object_t *NOTNULL self, uint32 n,
                         uint32 a, uint32 b, uint32 c, uint32 rA, uint32 rB,
                         bool readra, bool readrb, bool writerc);
};
#define NIOS_CUSTOM_INTERFACE "nios_custom"

Python

import simics

class simics.nios_custom_interface_t(custom=None)

Description

This nios_custom interface is used when the custom instruction needs to be used.

The custom function is called whenever the custom instruction is executed.

See Nios® II processor reference guide page 8-35 for further information about the parameters.

Execution Context

Cell Context

nios_eic

Name

nios_eic — interface for NIOS external interrupt controllers

Synopsis

C and DML

#include <simics/arch/nios.h> // in C
import "simics/arch/nios.dml"; // in DML

SIM_INTERFACE(nios_eic) {
        logical_address_t (*handler)(conf_object_t *NOTNULL obj);
        uint32 (*level)(conf_object_t *NOTNULL obj);
        uint32 (*reg_set)(conf_object_t *NOTNULL obj);
        bool (*nmi)(conf_object_t *NOTNULL obj);

        void (*handled)(conf_object_t *NOTNULL obj);
};

#define NIOS_EIC_INTERFACE "nios_eic"

Python

import simics

class simics.nios_eic_interface_t(handler=None, level=None, reg_set=None,
        nmi=None, handled=None)

Description

The nios_eic must be implemented by devices that acts as Nios® External Interrupt Controllers. After the external IRQ signal in the CPU has been raised, the CPU will query the registered External Interrupt Controller for information about the current interrupt request. When the CPU calls the handled function, it has finished processing the request.

The handler function should return the logical address of the interrupt handler.

The level should return the interrupt level.

The reg_set should return the shadow register set number.

The nmi should indicate if this is a non-maskable interrupt.

See Nios® II processor reference guide page 3-41 for further information.

Execution Context

Cell Context for all methods.

nios

Name

nios — NIOS dummy interface

Synopsis

C and DML

#include <simics/arch/nios.h> // in C
import "simics/arch/nios.dml"; // in DML

SIM_INTERFACE(nios) {
        int dummy;
};

#define NIOS_INTERFACE "nios"

Python

import simics

class simics.nios_interface_t()

Description

This interface is implemented by Intel® Nios® processors to provide various functionality that is specific for this class of processors.

There are currently no Nios-specific functions.

Execution Context

Not applicable.

nvm_subsystem_controller_management

Name

nvm_subsystem_controller_management — Interface for NVME Subsystem Controller management

Synopsis

C and DML


SIM_INTERFACE(nvm_subsystem_controller_management)
{
        int (*register_controller)(conf_object_t *obj, uint16 cntid,
                                   conf_object_t *controller);
        attr_value_t (*get_all_controllers)(conf_object_t *obj);
};

#define NVM_SUBSYSTEM_CONTROLLER_MANAGEMENT_INTERFACE \
        "nvm_subsystem_controller_management"

Description

This interface is intended for implementing NVM Subsystem Controller management.

register_controller
registers a new controller with the NVM subsystem using the specified controller ID. Returns 0 on success, or a negative error code on failure. Parameters:
  • cntid: The controller identifier to register
  • controller: The controller object to register
get_all_controllers
retrieves a list of all controllers currently registered with the NVM subsystem. Returns an attribute value containing the list of controller identifiers. The caller must free the returned attribute.

Execution Context

Cell Context for all methods.

nvme_namespace_management

Name

nvme_namespace_management — Interface for NVMe namespace management

Synopsis

C and DML


SIM_INTERFACE(nvme_namespace_management)
{
        int (*create_namespace)(conf_object_t *obj, uint64 size, char *file);
        int (*delete_namespace)(conf_object_t *obj, uint32 nsid);
        void (*delete_all_namespaces)(conf_object_t *obj);
        int (*attach_namespace)(conf_object_t *obj, uint32 nsid,
                                attr_value_t *cntids);
        int (*detach_namespace)(conf_object_t *obj, uint32 nsid,
                                attr_value_t *cntids);
        uint32 (*get_max_namespaces)(conf_object_t *obj);
        attr_value_t (*get_namespaces)(conf_object_t *obj);
        bytes_t (*get_namespace_uuid)(conf_object_t *obj, uint32 nsid);
        uint64 (*get_namespace_size)(conf_object_t *obj, uint32 nsid);
        uint64 (*get_total_disk_capacity)(conf_object_t *obj);
        uint64 (*get_free_disk_capacity)(conf_object_t *obj);
        int (*sanitize)(conf_object_t *obj, uint8 sanitize_action);
        int (*format_nvm)(conf_object_t *obj, uint32 nsid);
};

#define NVME_NAMESPACE_MANAGEMENT_INTERFACE "nvme_namespace_management"

Description

This interface is intended for implementing NVMe namespace management.

create_namespace

creates a new NVMe namespace with the specified size and backing file. Returns 0 on success, or a negative error code on failure. Parameters:

  • size: The size of the namespace in bytes. If 0, and file is not NULL, the size of the backing file is used.
  • file: Path to the backing file for the namespace. If NULL, a sparse backing store is used.
delete_namespace

deletes an existing namespace identified by the given namespace ID. Returns 0 on success, or a negative error code on failure. Parameters:

  • nsid: The namespace identifier to delete
delete_all_namespaces

deletes all existing namespaces.

attach_namespace

attaches a namespace to one or more controllers. Returns 0 on success, or a negative error code on failure. Parameters:

  • nsid: The namespace identifier to attach
  • cntids: List of controller IDs to attach the namespace to
detach_namespace

detaches a namespace from one or more controllers. Returns 0 on success, or a negative error code on failure. Parameters:

  • nsid: The namespace identifier to detach
  • cntids: List of controller IDs to detach the namespace from
get_max_namespaces

returns the maximum number of namespaces supported by the NVM subsystem.

get_namespaces

returns a list of all currently active namespace identifiers in the subsystem. The returned attribute is a list that is structured as follows:

[image object, namespace id, uuid string, attached controllers list]

The caller must free the returned attribute.

get_namespace_uuid

retrieves the UUID of the specified namespace. Returns the UUID as a string, or NULL if the namespace doesn’t exist. Parameters:

  • nsid: The namespace identifier
get_namespace_size

retrieves the size in bytes of the specifiednamespace. Returns the size, or 0 if the namespace doesn’t exist. Parameters:

  • nsid: The namespace identifier
get_total_disk_capacity

returns the total disk capacity in bytes available to the NVM subsystem.

get_free_disk_capacity

returns the free (unallocated) disk capacity in bytes available for new namespaces.

sanitize

performs a sanitize operation on the NVM subsystem using the specified action. Returns 0 on success, or a negative error code on failure.

format_nvm

performs a format NVM operation using the specified nsid. If the nsid is 0xFFFFFFFF, the format applies to all namespaces. Returns 0 on success, or -1 in case of failure. Parameters:

  • sanitize_action: The sanitize action to perform

Execution Context

Cell Context for all methods.

packet

Name

packet — interface used to transfer data between devices

Synopsis

C and DML

#include <simics/model-iface/packet.h> // in C
import "simics/model-iface/packet.dml"; // in DML

SIM_INTERFACE(packet) {
        void (*transfer)(conf_object_t *obj, bytes_t data);
};

#define PACKET_INTERFACE "packet"

Python

import simics

class simics.packet_interface_t(transfer=None)

Description

The packet interface is implemented by objects that transfer chunks of data without exposing the underlying structure of the data.

The transfer function is called to transfer data from one device to another.

pci_bridge

Name

pci_bridge — interface used with downstream PCI(e)

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pci_bridge) {
        void (*system_error)(conf_object_t *obj);
        void (*raise_interrupt)(conf_object_t *obj, conf_object_t *pci_bus,
                                int device, int pin);
        void (*lower_interrupt)(conf_object_t *obj, conf_object_t *pci_bus,
                                int device, int pin);
};

#define PCI_BRIDGE_INTERFACE "pci_bridge"

Python

import simics

class simics.pci_bridge_interface_t(system_error=None, raise_interrupt=None,
        lower_interrupt=None)

Description

This interface is implemented by all PCI bridges. For interrupts, the initiating device is specified with a pci-bus object and PCI device number pair, and the pin represents PCI interrupt lines (A, B, C, or D) as numbers in the range of 0 to 3.

Execution Context

Cell Context for all methods.

pci_bus

Name

pci_bus — interface implemented by all PCI buses

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pci_bus) {
        /* Deprecated; memory_access */
        exception_type_t (*memory_access)(
                conf_object_t *obj, generic_transaction_t *NOTNULL mem_op);
        void (*raise_interrupt)(conf_object_t *obj, conf_object_t *NOTNULL dev,
                                int pin);
        void (*lower_interrupt)(conf_object_t *obj, conf_object_t *NOTNULL dev,
                                int pin);
        /* Deprecated; interrupt_acknowledge */
        int (*interrupt_acknowledge)(conf_object_t *obj);
        int (*add_map)(conf_object_t *obj, conf_object_t *dev,
                       addr_space_t space, conf_object_t *target,
                       map_info_t info);
        int (*remove_map)(conf_object_t *obj, conf_object_t *dev,
                          addr_space_t space, int function);
        void (*set_bus_number)(conf_object_t *obj, int bus_id);
        void (*set_sub_bus_number)(conf_object_t *obj, int bus_id);
        /* Deprecated; add_default, remove_default */
        void (*add_default)(conf_object_t *obj, conf_object_t *dev,
                            addr_space_t space, conf_object_t *target,
                            map_info_t info);
        void (*remove_default)(conf_object_t *obj, addr_space_t space);
        void (*bus_reset)(conf_object_t *obj);
        /* Deprecated; special_cycle */
        void (*special_cycle)(conf_object_t *obj, uint32 value);
        void (*system_error)(conf_object_t *obj);

        int (*get_bus_address)(conf_object_t *obj, conf_object_t *NOTNULL dev);

        void (*set_device_status)(conf_object_t *obj, int device, int function,
                                  int enabled);

        /* Memory spaces */
        conf_object_t *(*configuration_space)(conf_object_t *obj);
        conf_object_t *(*io_space)(conf_object_t *obj);
        conf_object_t *(*memory_space)(conf_object_t *obj);
};
#define PCI_BUS_INTERFACE       "pci_bus"

Python

import simics

class simics.pci_bus_interface_t(memory_access=None, raise_interrupt=None,
        lower_interrupt=None, interrupt_acknowledge=None, add_map=None,
        remove_map=None, set_bus_number=None, set_sub_bus_number=None,
        add_default=None, remove_default=None, bus_reset=None,
        special_cycle=None, system_error=None, get_bus_address=None,
        set_device_status=None, configuration_space=None, io_space=None,
        memory_space=None)

Description

This interface is implemented by all PCI buses and its functions are accessed by PCI devices. For further details, see Model Builder User’s Guide, chapter “Modeling PCI Devices”.

The memory_access function is deprecated and must not be called (as it is not implemented by Simics pci-bus object). The interrupt_acknowledge, special_cycle, add_default and remove_default functions are also deprecated, but they are still implemented by Simics pci-bus and thus callable.

Execution Context

Cell Context for all methods.

pci_device

Name

pci_device — interface implemented by PCI devices

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pci_device) {
        void (*bus_reset)(conf_object_t *obj);

        /* Deprecated; interrupt_acknowledge, special_cycle */
        int (*DEPRECATED_FUNC(interrupt_acknowledge))(conf_object_t *obj);
        void (*DEPRECATED_FUNC(special_cycle))(conf_object_t *obj,
                                               uint32 value);

        /* System Error */
        void (*system_error)(conf_object_t *obj);

        /* peer-to-peer interrupt mechanism */
        void (*interrupt_raised)(conf_object_t *obj, int pin);
        void (*interrupt_lowered)(conf_object_t *obj, int pin);
};

#define PCI_DEVICE_INTERFACE "pci_device"

Python

import simics

class simics.pci_device_interface_t(bus_reset=None,
        _deprecated_interrupt_acknowledge=None,
        _deprecated_special_cycle=None, system_error=None,
        interrupt_raised=None, interrupt_lowered=None)

Description

This interface is implemented by all PCI devices (including bridges).

The interrupt_acknowledge and special_cycle functions are deprecated. The functions can be left unimplemented (NULL).

Execution Context

Cell Context for all methods.

pci_downstream

Name

pci_downstream — interface used with downstream PCI(e)

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pci_downstream) {
        exception_type_t (*operation)(conf_object_t *obj,
                                      generic_transaction_t *mem_op,
                                      addr_space_t space);
};
#define PCI_DOWNSTREAM_INTERFACE   "pci_downstream"

Python

import simics

class simics.pci_downstream_interface_t(operation=None)

Description

The pci_downstream interface is implemented by PCI(e) buses to handle downstream transactions.

Execution Context

Cell Context for all methods.

pci_express_hotplug

Name

pci_express_hotplug — deprecated interface part of the old PCIe library

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

// only supported with SIMICS_API = 6
SIM_INTERFACE(pci_express_hotplug) {
        /* This is sent when a device is added or removed from the bus. */
        void (*presence_change)(conf_object_t *dst, conf_object_t *NOTNULL src,
                                int is_present);
        void (*inject_power_fault)(conf_object_t *obj);
        void (*press_attention_button)(conf_object_t *obj);
        void (*set_mrl_state)(conf_object_t *obj, int locked);
        int  (*get_mrl_state)(conf_object_t *obj);
};
#define PCI_EXPRESS_HOTPLUG_INTERFACE "pci_express_hotplug"

Python

import simics

class simics.pci_express_hotplug_interface_t(presence_change=None,
        inject_power_fault=None, press_attention_button=None,
        set_mrl_state=None, get_mrl_state=None)

Description

Deprecated as part of the old PCIe library. Replaced by the new PCIe library.

This interface is intended for PCI Express switches that need to monitor the status of their downports. The interface should be implemented by the bridge object.

presence_change is called from the pci-bus when an device is added or removed from the bus. is_present is set to 1 when the device is added, and 0 when it is removed.

inject_power_fault can be used to simulate a power fault on the downport. It is never called automatically.

press_attention_button can be called to simulate the attention button being pressed. The switch can respond to this by e.g. raising an interrupt and setting appropriate status bits. It is never called automatically.

set_mrl_state is similar to attention_button_press but controls the Manually operated Retention Latch. Set locked to 1 to simulate it being locked/closed, and 0 to simulate it being unlocked/opened.

Finally, get_mrl_state returns the state of the Manually operated Retention Latch.

Execution Context

Cell Context for all methods.

pcie_message_type_t, pci_express

Name

pcie_message_type_t, pci_express — deprecated interface part of the old PCIe library

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

typedef enum {
        /* Address Translation */
        PCIE_ATS_Invalidate = 0x01,
        PCIE_ATS_Invalidate_Completion = 0x02,
        PCIE_PRS_Request    = 0x04,
        PCIE_PRS_Response   = 0x05,

        PCIE_Latency_Tolerance_Reporting = 0x10,
        PCIE_Optimized_Buffer_Flush_Fill = 0x12,

        /* INTx emulation */
        PCIE_Msg_Assert_INTA       = 0x20,
        PCIE_Msg_Assert_INTB       = 0x21,
        PCIE_Msg_Assert_INTC       = 0x22,
        PCIE_Msg_Assert_INTD       = 0x23,
        PCIE_Msg_Deassert_INTA     = 0x24,
        PCIE_Msg_Deassert_INTB     = 0x25,
        PCIE_Msg_Deassert_INTC     = 0x26,
        PCIE_Msg_Deassert_INTD     = 0x27,

        /* Power Management */
        PCIE_PM_Active_State_Nak   = 0x14,
        PCIE_PM_PME                = 0x18,
        PCIE_PM_Turn_Off           = 0x19,
        PCIE_PM_PME_TO_Ack         = 0x1B,

        /* Error Messages */
        PCIE_ERR_COR               = 0x30,
        PCIE_ERR_NONFATAL          = 0x31,
        PCIE_ERR_FATAL             = 0x33,

        /* Locked Transaction */
        PCIE_Unlock                = 0x00,

        /* Slot Power Limit */
        PCIE_Set_Slot_Power_Limit  = 0x50,

        PCIE_Precision_Time_Measurement = 0x52,

        /* Hot Plug Messages */
        PCIE_HP_Power_Indicator_On        = 0x45,
        PCIE_HP_Power_Indicator_Blink     = 0x47,
        PCIE_HP_Power_Indicator_Off       = 0x44,
        PCIE_HP_Attention_Button_Pressed  = 0x48,
        PCIE_HP_Attention_Indicator_On    = 0x41,
        PCIE_HP_Attention_Indicator_Blink = 0x43,
        PCIE_HP_Attention_Indicator_Off   = 0x40,

        PCIE_Vendor_Defined_Type_0 = 0x7e,
        PCIE_Vendor_Defined_Type_1 = 0x7f,

        PCIE_Locked_Transaction    = 0x00,  // legacy name for PCIE_Unlock

        /* Data Link Layer (virtual) Messages

           NOTE: these messages only exist on Simics simulator, as they are
           normally part of the Data Link Layer which is below the level of
           abstraction for Simics PCIe models

           According to PCIe rev 2.0, when a target receives a message that it
           does not recognize or support, except for the "Vendor Defined Type
           1" message, it should treat the request as an "Unsupported Request"
           and report it accordingly (see sec 2.3.1 for reference).

           Hence models that comply with rev 2.0 must be updated to either
           1) handle these messages or 2) ignore these messages.

           Ideally we would like to use a new pcie_link interface to transmit
           this information - see bug 17849 for more info. */
        PCIE_DLL_Link_Down = -1,
        PCIE_DLL_Link_Up = -2,
} pcie_message_type_t;

// only supported with SIMICS_API = 6
SIM_INTERFACE(pci_express) {
        int (*send_message)(conf_object_t *dst, conf_object_t *src,
                            pcie_message_type_t type, byte_string_t payload);
};
#define PCI_EXPRESS_INTERFACE "pci_express"

Python

import simics

simics.PCIE_PRS_Request
simics.PCIE_ATS_Invalidate_Completion
simics.PCIE_Msg_Deassert_INTC
simics.PCIE_PM_Turn_Off
simics.PCIE_Msg_Deassert_INTA
simics.PCIE_HP_Attention_Indicator_Blink
simics.PCIE_PM_Active_State_Nak
simics.PCIE_PM_PME
simics.PCIE_PM_PME_TO_Ack
simics.PCIE_HP_Attention_Indicator_Off
simics.PCIE_ERR_FATAL
simics.PCIE_Msg_Assert_INTC
simics.PCIE_ATS_Invalidate
simics.PCIE_Optimized_Buffer_Flush_Fill
simics.PCIE_HP_Power_Indicator_Blink
simics.PCIE_Msg_Assert_INTB
simics.PCIE_DLL_Link_Up
simics.PCIE_PRS_Response
simics.PCIE_HP_Attention_Button_Pressed
simics.PCIE_Latency_Tolerance_Reporting
simics.PCIE_Vendor_Defined_Type_1
simics.PCIE_DLL_Link_Down
simics.PCIE_HP_Power_Indicator_On
simics.PCIE_Msg_Assert_INTD
simics.PCIE_Precision_Time_Measurement
simics.PCIE_HP_Power_Indicator_Off
simics.PCIE_HP_Attention_Indicator_On
simics.PCIE_Msg_Deassert_INTD
simics.PCIE_ERR_COR
simics.PCIE_Unlock
simics.PCIE_ERR_NONFATAL
simics.PCIE_Msg_Assert_INTA
simics.PCIE_Vendor_Defined_Type_0
simics.PCIE_Msg_Deassert_INTB
simics.PCIE_Set_Slot_Power_Limit
class simics.pci_express_interface_t(send_message=None)

Description

Deprecated as part of the old PCIe library. Replaced by the new PCIe library.

This interface is deprecated. The transaction interface implemented by the pcie-bus (upstream and downstream ports) can be used to send any type of message with any type of routing by adding related pcie_type and pcie_msg_route ATOMs to the transaction.

This interface can be implemented by any PCI Express device, switch or endpoint. It is also implemented by the pci-bus, which will pass it on to the other end; e.g. if the endpoint sends a message, the pci-bus will pass it on to the bridge (downport), and if the downport sends it, it will be broadcasted to all devices on the bus.

Please note that message routing is not supported. The implications of this limitation is that a switch does not know if the message is intended for the switch itself or for some device connected to it. In addition, since the bus does not replace the src parameter when forwarding the message, and the bus does not support port mappings, it is impossible for a bus-to-bus bridge (up-port/down-port) to know from which bus the message originates making it impossible to forward the message to the other side.

Another way of looking at this limitation is to say that the only message routing currently supported is the implicit routing that terminates at the receiver (Type2:0 = 0b100), so bus-to-bus bridges should not try to forward the message to the other side.

src is the object sending the message. type is one of pcie_message_type_t.

The contents of payload depends on type.

Execution Context

Cell Context for all methods.

pci_interrupt

Name

pci_interrupt — interface used with PCI(e) interrupts

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pci_interrupt) {
        void (*raise_interrupt)(conf_object_t *obj, conf_object_t *pci_bus,
                                int device, int pin);
        void (*lower_interrupt)(conf_object_t *obj, conf_object_t *pci_bus,
                                int device, int pin);
};

#define PCI_INTERRUPT_INTERFACE "pci_interrupt"

Python

import simics

class simics.pci_interrupt_interface_t(raise_interrupt=None, lower_interrupt=None)

Description

This interface should only be used when a device other than the bridge handles PCI interrupts on the PCI bus. The initiating device is specified with a PCI device number, and the pin represents PCI interrupt lines (A, B, C, or D) as numbers in the range of 0 to 3.

Execution Context

Cell Context for all methods.

pci_multi_function_device

Name

pci_multi_function_device — interface used by PCI devices with multiple functions

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pci_multi_function_device) {
        attr_value_t (*supported_functions)(conf_object_t *obj);
};
#define PCI_MULTI_FUNCTION_DEVICE_INTERFACE "pci_multi_function_device"

Python

import simics

class simics.pci_multi_function_device_interface_t(supported_functions=None)

Description

This interface is intended for PCI devices that want to have multiple functions implemented within the same device instance, as compared to the scheme of having each PCI function defined in a separate instance.

supported_functions is called from the pci-bus to find out how many functions are supported by this device. The expected return value is a list of tuples, where each tuple contains the PCI function number followed by one or two elements controlling what to map into the bus’ config-space. The list can consist of any number of tuples using any and all of the supported formats:

The list can contain a mix of formats, each entry corresponds to a unique mapping of a function.

For ARI enabled PCIe devices, the device number is assumed to be zero thus it is an error to try to claim a function number greater than seven while connecting with a device number greater than zero.

Execution Context

Global Context for all methods.

pci_upstream

Name

pci_upstream — interface used with upstream PCI(e)

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pci_upstream) {
        exception_type_t (*operation)(conf_object_t *obj,
                                      generic_transaction_t *mem_op,
                                      addr_space_t space);
};
#define PCI_UPSTREAM_INTERFACE   "pci_upstream"

Python

import simics

class simics.pci_upstream_interface_t(operation=None)

Description

This interface is implemented by PCI(e) buses and bridges to handle upstream transactions (primarily memory or IO).

A PCI(e) bus typically forwards all transactions to an upstream bridge.

PCI(e) bridges either forward a transaction to its primary side bus or initiate a downstream operation on the secondary bus using the pci_downstream interface.

It should be noted that a PCI bridge using this interface will see peer-to-peer traffic from its secondary interface; this is a difference compared to real hardware where such transactions never involve the bridge. To behave like real hardware, PCI bridges should send all peer-to-peer traffic downstream.

Execution Context

Cell Context for all methods.

pci_upstream_operation

Name

pci_upstream_operation — interface used with upstream PCI(e)

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pci_upstream_operation) {
        exception_type_t (*read)(conf_object_t *obj,
                                 conf_object_t *initiator,
                                 uint16 rid,
                                 addr_space_t space,
                                 physical_address_t address,
                                 buffer_t buffer);
        exception_type_t (*write)(conf_object_t *obj,
                                  conf_object_t *initiator,
                                  uint16 rid,
                                  addr_space_t space,
                                  physical_address_t address,
                                  bytes_t buffer);
};
#define PCI_UPSTREAM_OPERATION_INTERFACE   "pci_upstream_operation"

Python

import simics

class simics.pci_upstream_operation_interface_t(read=None, write=None)

Description

This interface is implemented by PCI(e) buses to handle upstream transactions (primarily memory or IO) from PCI(e) devices.

The initiator should be the PCI device object itself. There are currently no requirements on this object in terms of interfaces. It is intended for future use and could be left NULL.

The 16-bit Requester ID is provided by the rid parameter. This is the ID that uniquely identifies the initiator in a PCIe hierarchy, also more commonly known as the BDF (Bus/Device/Function). This ID can be left blank (0) by non-PCIe devices if the BDF is not known.

Return value is of type exception_type_t and maps, just like all other PCI interfaces, onto PCI concepts accordingly:

Sim_PE_No_Exception
OK Sim_PE_IO_Not_Taken
Master Abort Sim_PE_IO_Error
Target Abort

Other return values are currently unexpected.

Execution Context

Cell Context for all methods.

pcie_adapter_compat

Name

pcie_adapter_compat — interface used with PCIe

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

// only supported with SIMICS_API = 6
SIM_INTERFACE(pcie_adapter_compat) {
        void (*set_secondary_bus_number)(conf_object_t *obj,
                                         int secondary_bus_number);
};
#define PCIE_ADAPTER_COMPAT_INTERFACE "pcie_adapter_compat"

Python

import simics

class simics.pcie_adapter_compat_interface_t(set_secondary_bus_number=None)

Description

Deprecated as part of the old PCIe library. Replaced by the new PCIe library.

This interface is used by PCI buses that want to be compatible with PCIe devices created with the new PCIe library. This interface is implemented by the legacy-pcie-upstream-adapter.

Execution Context

Cell Context for all methods.

pcie_device

Name

pcie_device — interface implemented by PCI devices

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pcie_device) {
        void (*connected)(conf_object_t *obj, conf_object_t *port_obj,
                          uint16 device_id);
        void (*disconnected)(conf_object_t *obj, conf_object_t *port_obj,
                             uint16 device_id);
        void (*hot_reset)(conf_object_t *obj);
};

#define PCIE_DEVICE_INTERFACE "pcie_device"

Python

import simics

class simics.pcie_device_interface_t(connected=None, disconnected=None,
        hot_reset=None)

Description

This interface must be implemented by all PCIe devices that can receive downstream transactions.

connected and disconnected are used to indicate that the device is (dis)connected to port_obj with device id device_id and may use the pcie_map interface to add/remove functions and claim/release other resources. These functions should only be called once for each (dis)connected physical device no matter how many physical or virtual functions it has. The device_id contains the device number (D part of B:D:F) and should use 0 as the function number (F part of B:D:F).

hot_reset is used to indicate that a Hot Reset has been signaled on the PCIe link to which the device is connected. It is up to the device to reset functions and other resources mapped using the pcie_map interface.

This interface is considered tech-preview and may change without notice.

Execution Context

Global Context for all methods.

pcie_function_info

Name

pcie_function_info — interface used with PCIe

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pcie_function_info)
{
        uint16 (*get_device_id)(conf_object_t *obj);
        conf_object_t *(*get_upstream_target)(conf_object_t *obj);
        bool (*is_virtual_function)(conf_object_t *obj);
        conf_object_t *(*get_bar_map_obj)(conf_object_t *obj, uint8 bar_offset);
        map_info_t (*get_bar_map_info)(conf_object_t *obj, uint8 bar_offset);
};

#define PCIE_FUNCTION_INFO_INTERFACE "pcie_function_info"

Python

import simics

class simics.pcie_function_info_interface_t(get_device_id=None,
        get_upstream_target=None, is_virtual_function=None,
        get_bar_map_obj=None, get_bar_map_info=None)

Description

This interface should be implemented by all PCIe functions that wants to provide useful information for inspecting the function.

get_device_id returns the device id of the function.

get_upstream_target returns the upstream target of the PCIe device the PCIe function belongs to.

is_virtual_function returns true if the function is a virtual function.

get_bar_map_obj returns the object that is mapped by the BAR at bar_offset. If there is no BAR register at bar_offset, NULL is returned. For a physical function, the bar_offset is the offset in the Type 0/1 Configuration Space Header. For a virtual function, the bar_offset is the offset in the SR-IOV Extended Capability structure of the associated physical function (starting at 0x24).

Execution Context

Cell Context for all methods.

pcie_hotplug_pd_t, pcie_hotplug_mrl_t, pcie_hotplug_events

Name

pcie_hotplug_pd_t, pcie_hotplug_mrl_t, pcie_hotplug_events — interface implemented by Hot-Plug capable Downstream Ports

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

typedef enum {
        PCIE_HP_PD_Adapter_Not_Present = 0,
        PCIE_HP_PD_Adapter_Present = 1
} pcie_hotplug_pd_t;

typedef enum {
        PCIE_HP_MRL_Closed = 0,
        PCIE_HP_MRL_Open = 1
} pcie_hotplug_mrl_t;

SIM_INTERFACE(pcie_hotplug_events) {
        void (*presence_change)(conf_object_t *obj, pcie_hotplug_pd_t state);
        void (*power_fault)(conf_object_t *obj);
        void (*attention_button_pressed)(conf_object_t *obj);
        void (*mrl_sensor)(conf_object_t *obj, pcie_hotplug_mrl_t state);
        void (*data_link_layer)(conf_object_t *obj, bool is_active);
};

#define PCIE_HOTPLUG_EVENTS_INTERFACE "pcie_hotplug_events"

Python

import simics

simics.PCIE_HP_PD_Adapter_Present
simics.PCIE_HP_PD_Adapter_Not_Present
simics.PCIE_HP_MRL_Open
simics.PCIE_HP_MRL_Closed
class simics.pcie_hotplug_events_interface_t(presence_change=None,
        power_fault=None, attention_button_pressed=None, mrl_sensor=None,
        data_link_layer=None)

Description

This interface should be implemented by Hot-Plug capable Downstream Ports. Such devices should be either a Downstream Port of a PCI Express Switch or a Root Port of PCI Express Root Complex.

The device that implements this interface should on the invocation of any of the methods in this interface should do the following:

  1. If the applicable Hot-Plug capability has been enabled, set the new value of the corresponding Hot-Plug event in the applicable register.
  2. If the value changed from its previous value, set the changed register value for the applicable Hot-Plug event.
  3. If the value changed from its previous value, notify software using an interrupt if notifications are enabled for the applicable Hot-Plug event and an interrupt mechanism has been configured by the software (MSI/MSI-X or PCI-compatible INTx Emulation).

The presence_change method is called by the pcie-downstream-port (if its upstream target implements this interface) when it goes from having no adapter present to having an adapter present and vice versa.

Execution Context

Cell Context for all methods.

Name

pcie_link_control — Interface allowing receiving upstream and downstream

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pcie_link_control) {
        void (*downstream_component_blocking)(conf_object_t *obj, bool is_blocking);
        void (*upstream_component_blocking)(conf_object_t *obj, bool is_blocking);
        void (*request_link_retraining)(conf_object_t *obj);
};

#define PCIE_LINK_CONTROL_INTERFACE "pcie_link_control"

Python

import simics

class simics.pcie_link_control_interface_t(downstream_component_blocking=None,
        upstream_component_blocking=None, request_link_retraining=None)

Description

This interface should be implemented by pcie-downstream-ports to receive directions from upstream and downstream components on the link to tear down the link or retrain the link.

Execution Context

Cell Context for all methods.

Name

pcie_link_readiness — Interface for receiving link blocking state changes.

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pcie_link_readiness) {
        void (*link_down)(conf_object_t *obj);
        void (*link_not_blocking)(conf_object_t *obj);
};

#define PCIE_LINK_READINESS_INTERFACE "pcie_link_readiness"

Python

import simics

class simics.pcie_link_readiness_interface_t(link_down=None,
        link_not_blocking=None)

Description

This interface is implemented by PCIe devices so that they can be notified if a link has been torn down by the link blocking mechanism. The implementer of this interface will be notified when the link peer component is blocking or unblocking the link.

Execution Context

Cell Context for all methods.

Name

pcie_link_training — interface used with PCIe training

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pcie_link_training) {
        // Deprecated
        bool (*trigger)(conf_object_t *obj, uint16 device_id);

        bool (*invoke)(conf_object_t *obj);
};

#define PCIE_LINK_TRAINING_INTERFACE "pcie_link_training"

Python

import simics

class simics.pcie_link_training_interface_t(trigger=None, invoke=None)

Description

Trigger link training on obj. The trigger function is deprecated and should not be used. The implementation of trigger ignores the device_id.

Execution Context

Cell Context for all methods.

pcie_map

Name

pcie_map — interface used with PCIe address space

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pcie_map) {
        void (*add_map)(conf_object_t *obj, conf_object_t *map_obj,
                        map_info_t info, pcie_type_t type);
        void (*del_map)(conf_object_t *obj, conf_object_t *map_obj,
                        physical_address_t base, pcie_type_t type);
        void (*add_function)(conf_object_t *obj, conf_object_t *map_obj,
                             uint16 device_and_function);
        void (*del_function)(conf_object_t *obj, conf_object_t *map_obj,
                             uint16 device_and_function);
        void (*enable_function)(conf_object_t *obj, uint16 device_and_function);
        void (*disable_function)(conf_object_t *obj,
                                 uint16 device_and_function);
        uint16 (*get_device_id)(conf_object_t *obj, conf_object_t *dev_obj);
};

#define PCIE_MAP_INTERFACE "pcie_map"

Python

import simics

class simics.pcie_map_interface_t(add_map=None, del_map=None, add_function=None,
        del_function=None, enable_function=None, disable_function=None,
        get_device_id=None)

Description

This interface is used to claim ranges in PCIe address spaces and to manage virtual functions.

Functions add_map and del_map are used to add and remove maps, map_obj will be mapped in the address space indicated by type according to the information in info.

Functions add_function, del_function, enable_function and disable_function are used to add, delete, enable and disable functions, both virtual and physical. The supplied map_obj must be a valid map-target, it will receive both Config and Message transactions. For Message transactions, the device id (not including bus number) will be in bits 55:48 of the 64-bit address. For Config transactions, the device id is not part of the address. The supplied device_and_function passed to these methods should contain the device and function number (D:F part of B:D:F).

The function get_device_id returns the current device id of dev_obj, as a 16 bit number. Note that the bus number part is saved immediately after the RC/Switch sets it, even if no successful Config-Write has been made.

This interface is considered tech-preview and may change without notice.

Execution Context

Cell Context for all methods.

pcie_port_control

Name

pcie_port_control — interface used to configure PCIe downstream ports

Synopsis

C and DML

#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML

SIM_INTERFACE(pcie_port_control) {
        void (*set_secondary_bus_number)(conf_object_t *obj, uint64 value);
        void (*hot_reset)(conf_object_t *obj);
};

#define PCIE_PORT_CONTROL_INTERFACE "pcie_port_control"

Python

import simics

class simics.pcie_port_control_interface_t(set_secondary_bus_number=None,
        hot_reset=None)

Description

This interface is used to configure instances of the pcie-downstream-port.

The set_secondary_bus_number method should be called whenever the Secondary Bus Number register in the Type 1 Configuration Header of this downstream port changes.

The hot_reset method sends a hot reset to all downstream devices

This interface is considered tech-preview and may change without notice.

Execution Context

Cell Context for all methods.

pmr

Name

pmr — PPC performance monitor interface

Synopsis

C and DML

#include <simics/arch/ppc.h> // in C
import "simics/arch/ppc.dml"; // in DML

SIM_INTERFACE(pmr) {
        uint64 (*get)(
                conf_object_t *obj,
                int pmr_number,
                bool instruction_read);
        void (*set)(
                conf_object_t *obj,
                int pmr_number,
                uint64 value,
                bool instruction_write);
};
#define PMR_INTERFACE "pmr"

Python

import simics

class simics.pmr_interface_t(get=None, set=None)

Description

This interface provides a way for a user to write their own handler for the performance monitor register bank. The processor’s pmr_handler attribute should be set point at the to the module, which implements the pmr interface. When set, all reads and writes toward the defined PMR registers will be forwarded to the user module instead. Simics CPU module will perform all the privilege checks and only forward the read/write if it is permitted.

The supervisor registers are checkpointed by the CPU module and the register content for the PMR registers is distributed to the user module in the finalize phase, after the pmr_handler has been set.

The function get is used for attribute reads, int_register reads or for mfpmr instructions. The value for the PMR register should be returned. The instruction_read will be true only for mfpmr instructions, allowing distinction between register reads by the user and instructions which could have side-effects.

Similar, the set function is used for attribute writes, int_register writes or for mtpmr instructions. The instruction_write will be true only for mtpmr instructions. The value indicates the value written to the PMR register.

Execution Context

Cell Context for all methods.

port_space

Name

port_space — I/O port interface

Synopsis

C and DML

#include <simics/devs/memory-space.h> // in C
import "simics/devs/memory-space.dml"; // in DML

SIM_INTERFACE(port_space) {
        exception_type_t (*port_operation)(conf_object_t *NOTNULL pspace_obj,
                                           generic_transaction_t *NOTNULL mop,
                                           map_info_t map_info);
        attr_value_t (*read)(conf_object_t *NOTNULL obj,
                             conf_object_t *initiator,
                             physical_address_t addr,
                             int length,
                             int inquiry);
        exception_type_t (*write)(conf_object_t *NOTNULL obj,
                                  conf_object_t *initiator,
                                  physical_address_t addr,
                                  attr_value_t data,
                                  int inquiry);
};

#define PORT_SPACE_INTERFACE "port_space"

Python

import simics

class simics.port_space_interface_t(port_operation=None, read=None, write=None)

Execution Context

Cell Context for all methods.

ppc_mc_exc_t, ppc

Name

ppc_mc_exc_t, ppc — PPC specific interface

Synopsis

C and DML

#include <simics/arch/ppc.h> // in C
import "simics/arch/ppc.dml"; // in DML

typedef enum {
        Sim_PPC_Generic_MC,

        Sim_PPC_MC_TEA,
        Sim_PPC_MC_MCP,
        Sim_PPC_Bus_Address_Parity,
        Sim_PPC_Bus_Data_Parity,
        Sim_PPC_Instruction_Cache_Parity,
        Sim_PPC_Data_Cache_Parity,
        Sim_PPC_L2_Data_Parity,
        Sim_PPC_L3_Data_Parity,
        Sim_PPC_L3_Address_Parity,

        Sim_PPC970_Data_Cache_Parity,
        Sim_PPC970_Data_Cache_Tag_Parity,
        Sim_PPC970_D_ERAT_Parity,
        Sim_PPC970_TLB_Parity,
        Sim_PPC970_SLB_Parity,
        Sim_PPC970_L2_Load_ECC_Parity,
        Sim_PPC970_L2_Page_Table_ECC_Parity,
        Sim_PPC970_Uncacheable_Load_Parity,
        Sim_PPC970_MC_External
} ppc_mc_exc_t;

SIM_INTERFACE(ppc) {
        void (*PYTHON_METHOD clear_atomic_reservation_bit)(conf_object_t *cpu);
        void (*PYTHON_METHOD raise_machine_check_exception)(conf_object_t *cpu,
                                                            ppc_mc_exc_t exc);

        /* Timebase */
        unsigned (*PYTHON_METHOD get_timebase_enabled)(conf_object_t *cpu);
        void     (*PYTHON_METHOD set_timebase_enabled)(conf_object_t *cpu,
                                                       unsigned enabled);
        /* Power mode */
        ppc_sleep_state_t (*PYTHON_METHOD get_sleep_state)(conf_object_t *cpu);
        void (*PYTHON_METHOD set_sleep_state)(conf_object_t *cpu,
                                              ppc_sleep_state_t state);
};
#define PPC_INTERFACE "ppc"

Python

import simics

simics.Sim_PPC_L2_Data_Parity
simics.Sim_PPC_Data_Cache_Parity
simics.Sim_PPC970_SLB_Parity
simics.Sim_PPC_Bus_Data_Parity
simics.Sim_PPC970_Data_Cache_Parity
simics.Sim_PPC_Bus_Address_Parity
simics.Sim_PPC_L3_Address_Parity
simics.Sim_PPC970_MC_External
simics.Sim_PPC970_L2_Load_ECC_Parity
simics.Sim_PPC970_L2_Page_Table_ECC_Parity
simics.Sim_PPC970_TLB_Parity
simics.Sim_PPC970_Uncacheable_Load_Parity
simics.Sim_PPC970_D_ERAT_Parity
simics.Sim_PPC_MC_TEA
simics.Sim_PPC_Generic_MC
simics.Sim_PPC_MC_MCP
simics.Sim_PPC970_Data_Cache_Tag_Parity
simics.Sim_PPC_L3_Data_Parity
simics.Sim_PPC_Instruction_Cache_Parity
class simics.ppc_interface_t(clear_atomic_reservation_bit=None,
        raise_machine_check_exception=None, get_timebase_enabled=None,
        set_timebase_enabled=None, get_sleep_state=None,
        set_sleep_state=None)

Description

The clear_atomic_reservation_bit function clears the reservation bit which is set by an lwarx instruction. Clearing the reservation will cause a following stwcx. instruction to fail. This function is typically used by a cache hierarchy supporting SMP.

The raise_machine_check_exception function raises a machine check exception.

The get_timebase_enabled and set_timebase_enabled functions can be used to query and set the enabled state of the timebase.

Execution Context

Cell Context for all methods.

pulse

Name

pulse — model a pulse, meaning an event that triggers

Synopsis

C and DML

#include <simics/devs/signal.h> // in C
import "simics/devs/signal.dml"; // in DML

SIM_INTERFACE(pulse) {
        void (*pulse)(conf_object_t *NOTNULL obj);
};

#define PULSE_INTERFACE "pulse"

Python

import simics

class simics.pulse_interface_t(pulse=None)

Execution Context

Cell Context for all methods.

ram, rom

Name

ram, rom — provide random access memory

Synopsis

C and DML

#include <simics/device-api.h> // in C
// always available in DML

typedef struct page page_t;

#include <simics/devs/ram.h> // in C
import "simics/devs/ram.dml"; // in DML

typedef enum {
        Sim_Ram_Op_Fetch = 1,           /* Read is an instruction fetch. */
        Sim_Ram_Op_Non_Coherent = 2,    /* Operation should not cause
                                           atomic reservations to be lost. */
} ram_operation_flags_t;

SIM_INTERFACE(ram) {
#ifndef PYWRAP
        /* The get_page is method is obsolete and should be left
           unimplemented. */
        page_t *(*get_page)(conf_object_t *NOTNULL obj,
                            physical_address_t addr);
#endif
        void (*fill)(conf_object_t *NOTNULL obj,
                     physical_address_t start, uint64 length, uint8 value);

        exception_type_t (*read)(conf_object_t *NOTNULL obj,
                                 conf_object_t *initiator,
                                 uint64 addr, buffer_t data,
                                 ram_operation_flags_t flags);

        exception_type_t (*write)(conf_object_t *NOTNULL obj,
                                  conf_object_t *initiator,
                                  uint64 addr, bytes_t data,
                                  ram_operation_flags_t flags);

        exception_type_t (*touch)(conf_object_t *NOTNULL obj,
                                  conf_object_t *initiator,
                                  uint64 addr, uint64 size,
                                  read_or_write_t rw,
                                  ram_operation_flags_t flags);

        uint64 (*size)(conf_object_t *NOTNULL obj);
};
#define RAM_INTERFACE "ram"

Python

import simics

class simics.page_t
simics.Sim_Ram_Op_Fetch
simics.Sim_Ram_Op_Non_Coherent
class simics.ram_interface_t(fill=None, read=None, write=None, touch=None,
        size=None)

Description

The ram interface is implemented by classes that provide random access read/write memory. The rom interface is identical to ram but provides read only memory (writes are dropped by the memory system).

#define ROM_INTERFACE "rom"
typedef ram_interface_t rom_interface_t;

Both the ram and rom interfaces are Simics internal, and should not be used by user-defined classes.

The get_page method is obsolete and should not be implemented.

The fill method fills a range with a specified byte value.

The read method reads a number of bytes from address addr into the buffer data. The number of bytes read is given by the buffer size.

The write method writes the bytes in data to address addr.

The touch method is similar to the read and write methods, except that no data is actually transferred; the method triggers side effects like revoking conflicting direct-memory permissions from affected pages. The rw argument determines whether the operation is a handled as a read or as a write.

The flags argument is a bitmask which modify the behavior of read, write and touch operations in various ways.

The size method returns the memory size in bytes; that is, the highest usable address plus one.

Execution Context

Cell Context for all methods.

riscv_coprocessor

Name

riscv_coprocessor — RISC-V coprocessor interface

Synopsis

C and DML

#include <simics/arch/risc-v.h> // in C
import "simics/arch/risc-v.dml"; // in DML

SIM_INTERFACE(riscv_coprocessor) {
        uint64 (*read_register)(conf_object_t *obj, uint64 number);
        void (*write_register)(conf_object_t *obj, uint64 number, uint64 value);
};

#define RISCV_COPROCESSOR_INTERFACE "riscv_coprocessor"

Python

import simics

class simics.riscv_coprocessor_interface_t(read_register=None,
        write_register=None)

Description

This interface makes it possible for RISC-V processors to read and write externally defined Control and Status Registers (CSRs) like mtime.

Execution Context

Threaded Context for all methods.

riscv_csr_access_type_t, riscv_csr_access_cb_t, riscv_reset_cb_t, riscv_custom_csr

Name

riscv_csr_access_type_t, riscv_csr_access_cb_t, riscv_reset_cb_t, riscv_custom_csr — interface for implementation of custom RISC-V CSR

Synopsis

C and DML

#include <simics/arch/risc-v-customize.h> // in C
import "simics/arch/risc-v-customize.dml"; // in DML

typedef enum {
        /* Access through csr/csri instruction */
        Riscv_CSR_Instruction_Access = Sim_Gen_Spr_Instruction_Access,

        /* Access through attribute */
        Riscv_Attribute_Access = Sim_Gen_Spr_Attribute_Access,

        /* Access through int_register_interface */
        Riscv_Int_Register_Access = Sim_Gen_Spr_Int_Register_Access,
} riscv_csr_access_type_t;

typedef uint64 (*riscv_csr_access_cb_t)(conf_object_t *obj,
                                        conf_object_t *cpu,
                                        uint32 csr_address,
                                        uint64 value,
                                        uint64 write_mask,
                                        riscv_csr_access_type_t type);

typedef uint64 (*riscv_reset_cb_t)(conf_object_t *obj,
                                   conf_object_t *cpu);

SIM_INTERFACE(riscv_custom_csr) {

        bool (*register_csr)(conf_object_t *cpu,
                             conf_object_t *ext_obj,
                             uint32 csr_address,
                             const char *name,
                             const char *description,
                             riscv_csr_access_cb_t access);

        void (*register_reset)(conf_object_t *cpu,
                               conf_object_t *csr_obj,
                               riscv_reset_cb_t reset_func);
};

#define RISCV_CUSTOM_CSR_INTERFACE "riscv_custom_csr"

Python

import simics

simics.Riscv_Int_Register_Access
simics.Riscv_CSR_Instruction_Access
simics.Riscv_Attribute_Access
class simics.riscv_custom_csr_interface_t(register_csr=None, register_reset=None)

Description

The riscv_custom_csr interface lets other Simics objects implement custom Control and Status Registers (CSRs) and get callback for each access.

For the methods below, cpu is the RISC-V CPU model that is extended and ext_obj is the extension object.

The register_csr method registers a custom CSR at csr_address. The arguments name and description are for disassembly and int_register interface. The argument access is the function implementing the CSR access. Return true if CSR is successfully registered.

The type riscv_csr_access_type_t value shows the kind of access to handle.

access is a callback of type riscv_csr_access_cb_t that will be called for each access to the custom CSR.

The register_reset method registers a reset callback for the extension. The reset_func callback will be called in connection with the core CPU reset flow.

Execution Context

Global Context for all methods.

riscv_instruction_action

Name

riscv_instruction_action — interface implemented by RISC-V cpus and used to model custom instructions

Synopsis

C and DML

#include <simics/arch/risc-v-customize.h> // in C
import "simics/arch/risc-v-customize.dml"; // in DML

SIM_INTERFACE(riscv_instruction_action) {
        uint64 (*read_x_register)(conf_object_t *cpu, uint32 number);
        void (*write_x_register)(conf_object_t *cpu, uint32 number, uint64 value);
        const char * (*name_x_register)(conf_object_t *cpu, uint32 number);

        uint64 (*read_csr)(conf_object_t *cpu, uint32 address);
        void (*write_csr)(conf_object_t *cpu, uint32 address, uint64 value);

        // Logical address
        uint64 (*read_memory)(conf_object_t *cpu, uint64 address,
                              uint32 size);
        void (*write_memory)(conf_object_t *cpu, uint64 address,
                             uint32 size, uint64 value);

        void (*load_memory_buf)(conf_object_t *cpu, uint64 address, buffer_t buf);
        void (*store_memory_buf)(conf_object_t *cpu, uint64 address, bytes_t buf);

        riscv_cpu_mode_t (*get_current_cpu_mode)(conf_object_t *cpu);

        void (*raise_exception)(conf_object_t *cpu, uint64 code, uint64 tval);
};

#define RISCV_INSTRUCTION_ACTION_INTERFACE "riscv_instruction_action"

Python

import simics

class simics.riscv_instruction_action_interface_t(read_x_register=None,
        write_x_register=None, name_x_register=None, read_csr=None,
        write_csr=None, read_memory=None, write_memory=None,
        load_memory_buf=None, store_memory_buf=None,
        get_current_cpu_mode=None, raise_exception=None)

Description

The riscv_instruction_action interface helps with implementing semantics for user defined instruction.

The cpu argument in all methods below is the processor object implementing this interface.

X registers

read_X_register return the current value of X register number.

write_X_register updates the value of X register number to value.

To help with disassembly name_X_register returns the name of the X register number.

Control and status registers, CSRs

These accesses are not seen as instruction accesses, all access checks are bypassed and no exception will be thrown.

read_CSR returns current value of the CSR at address.

write_CSR updates the value of the CSR at address to

value. Note: not all bits of all CSRs is writable.

Memory accesses using logical address

A logical address is passed through MMU based on current mode. This means that an access can raise exception for page fault or illegal access.

read_memory returns a value of size bytes zero extended to 64 bits from memory at address

write_memory writes size bytes to memory at address.

Both read_memory and write_memory can raise exception for unaligned data access if the core does not support unaligned accesses.

load_memory_buf loads buf.len bytes from address to buf.

store_memory_buf writes buf.len bytes from buf to address.

These methods do not raise exception for unaligned accesses, instead large and/or unaligned accesses are broken down to multiple smaller aligned accesses.

Other

get_current_cpu_mode returns current cpu mode.

raise_exception raises exception with xCAUSE CSR set to code and xTVAL CSR set to tval.

Execution Context

Threaded Context for all methods. Must only be called from within an instruction emulation callback registered using the cpu_instruction_decoder interface.

sata

Name

sata — interface implemented by SATA objects

Synopsis

C and DML

#include <simics/devs/sata-interface.h> // in C
import "simics/devs/sata-interface.dml"; // in DML

SIM_INTERFACE(sata) {
        void (*receive_fis)(conf_object_t *obj, const bytes_t fis);
};

#define SATA_INTERFACE "sata"

Python

import simics

class simics.sata_interface_t(receive_fis=None)

Description

This interface is implemented by SATA objects that provide an interface for serial data delivery.

This interface can be used in both direction in SATA communication. The receive_fis function is used by a device to send a SATA FIS to the SATA controller(HBA). The same function is used when sending a SATA FIS from HBA to SATA device. The FIS should be a bytes_t containing a complete SATA FIS. Different types of FIS may have different length. Please follow SATA specification when determine the length and content of the FIS.

Execution Context

Cell Context for all methods.

scale_factor_listener

Name

scale_factor_listener — interface used for modeling changes in frequency scale factors

Synopsis

C and DML

#include <simics/devs/frequency.h> // in C
import "simics/devs/frequency.dml"; // in DML

SIM_INTERFACE(scale_factor_listener) {
        void (*set)(conf_object_t *NOTNULL obj, uint64 numerator,
                    uint64 denominator);
};

#define SCALE_FACTOR_LISTENER_INTERFACE "scale_factor_listener"

Python

import simics

class simics.scale_factor_listener_interface_t(set=None)

Description

The scale_factor_listener interface is used for modeling changes in scale factors. It is mainly used by the frequency_bus device, to allow an external device to affect how much the bus scales its input frequency.

The scale_factor_listener has exactly the same semantics as the frequency_listener interface, the two interfaces only differ in convention: The parameters to set are typically a scale factor rather close to 1, while the parameters of the frequency_listener method set represent a base frequency in Hz, which is typically significantly larger than 1000000.

See the documentation on the frequency_listener interface for more information.

Execution Context

Cell Context for all methods.

TTY_ABORT, serial_device

Name

TTY_ABORT, serial_device — interface used to connect serial devices together

Synopsis

C and DML

#include <simics/devs/serial-device.h> // in C
// not available in DML

TTY_ABORT;

import "simics/devs/serial-device.dml"; // in DML

SIM_INTERFACE(serial_device) {
        int (*write)(conf_object_t *obj, int value);
        void (*receive_ready)(conf_object_t *obj);
};

#define SERIAL_DEVICE_INTERFACE "serial_device"

Python

import simics

class simics.serial_device_interface_t(write=None, receive_ready=None)

Description

Interface used to connect serial devices together. It can be implemented both by devices such as UARTs and text consoles, and by links.

A character (byte) is sent with the write function; obj is the receiving device or link, and value is either a data byte, or the out-of-band value TTY_ABORT.

The receiver will return the number of characters accepted; i.e. 1 on success and 0 if it could not handle the new byte. If the receiver returns 0, it must later call receive_ready in the sender’s serial_device interface to signal that new bytes can now be accepted. A serial device must handle the case where the receive_ready function is called although it has no more bytes to send.

Execution Context

Cell Context for all methods.

serial_peripheral_interface_flags_t

Name

serial_peripheral_interface_flags_t — type used with serial_peripheral_interface_slave interface

Synopsis

C and DML

#include <simics/devs/serial-peripheral-interface.h> // in C
import "simics/devs/serial-peripheral-interface.dml"; // in DML

typedef enum serial_peripheral_interface_flags {
        SPI_Flags_CPHA = 0x1,
        SPI_Flags_CPOL = 0x2
} serial_peripheral_interface_flags_t;

Python

import simics

simics.SPI_Flags_CPOL
simics.SPI_Flags_CPHA

Description

The serial_peripheral_interface_flags_t type is used to describe some properties of an SPI connection. The type is a bitfield, currently defining two values, CPOL and CPHA. If a master device connects to a slave using a CPOL/CPHA combination incompatible with the slave device, then the results of any SPI transfer are undefined.

The SPI_Flags_CPOL bit defines the polarity of the clock pin (SCK): A value of zero means that the pin is low when the bus is idle, while a value of one means that the pin is high when the bus is idle.

The SPI_Flags_CPHA bit defines the phase of the clock pin. If the CPHA and CPOL bits are equal, data bits are read on the falling edge of the SCK pin and changed on the rising edge of the pin; if the bits are not equal, data bits are read on the rising edge and changed on the falling edge of the SCK pin.

See Also

serial_peripheral_interface_slave

serial_peripheral_interface_master

Name

serial_peripheral_interface_master — interface implemented by SPI master devices

Synopsis

C and DML

#include <simics/devs/serial-peripheral-interface.h> // in C
import "simics/devs/serial-peripheral-interface.dml"; // in DML

SIM_INTERFACE(serial_peripheral_interface_master) {
        void (*spi_response)(conf_object_t *obj, int bits, dbuffer_t *payload);
};

#define SERIAL_PERIPHERAL_INTERFACE_MASTER_INTERFACE \
        "serial_peripheral_interface_master"

Python

import simics

class simics.serial_peripheral_interface_master_interface_t(spi_response=None)

Description

The serial_peripheral_interface_master interface is implemented by all SPI master devices. The interface contains a single function spi_response, called by the slave device in response to a spi_request call via serial_peripheral_interface_slave. The parameters bits and payload have the same meaning as in the spi_request call, and a SPI response should always have the same length in bits as the corresponding request.

Execution Context

Cell Context for all methods.

See Also

serial_peripheral_interface_slave

serial_peripheral_interface_slave

Name

serial_peripheral_interface_slave — interface implemented by all SPI slave devices

Synopsis

C and DML

#include <simics/devs/serial-peripheral-interface.h> // in C
import "simics/devs/serial-peripheral-interface.dml"; // in DML

SIM_INTERFACE(serial_peripheral_interface_slave) {
        void (*spi_request)(conf_object_t *obj, int first, int last,
                            int bits, dbuffer_t *payload);
        void (*connect_master)(conf_object_t *obj, conf_object_t *master,
                               const char *port,
                               serial_peripheral_interface_flags_t flags);
        void (*disconnect_master)(conf_object_t *obj, conf_object_t *master);
};

#define SERIAL_PERIPHERAL_INTERFACE_SLAVE_INTERFACE \
        "serial_peripheral_interface_slave"

Python

import simics

class simics.serial_peripheral_interface_slave_interface_t(spi_request=None,
        connect_master=None, disconnect_master=None)

Description

The serial_peripheral_interface_slave interface is implemented by all SPI slave devices.

The connect_master and disconnect_master functions are used to select which master device is connected. At most one master device can be connected to a slave device at once. The flags parameter to connect_master should be set according to the documentation of the serial_peripheral_interface_flags_t type.

An SPI transfer consists of a number of consecutive calls to the spi_request function. The parameters first and last represent the rise and fall of the Slave Select (SS) pin: first is true on the first spi_request call of a transfer, while last is true on the last call of a transfer.

The bits and payload parameters describe the data sent by the master device. bits defines the number of bits to send, while payload defines the data to transfer. The size of the payload buffer should be ceil(bits / 8) bytes. The first byte corresponds to the first 8 sent bits, and the least significant bit in each byte corresponds to the first sent bit. For example, the 11-bit sequence (first) 11011111101 (last) will be represented as two bytes, 0xfb followed by 0x5.

Execution Context

Cell Context for all methods.

See Also

serial_peripheral_interface_master, serial_peripheral_interface_flags_t

shared_memory_map_demap

Name

shared_memory_map_demap — Interface for mapping/unmapping shared memory

Synopsis

C and DML


SIM_INTERFACE(shared_memory_map_demap) {
    void (*map)(conf_object_t* obj, uint64 addr, uint64 size);
    void (*unmap)(conf_object_t* obj, uint64 addr);
};


#define SHARED_MEMORY_MAP_DEMAP_INTERFACE "shared_memory_map_demap"

Description

Interface to inform a device to map or demap a shared memory region into its address space.

map Called to map a region of shared memory into the peripheral’s address space.

unmap Called to unmap a region of shared memory from the peripheral’s address space.

Execution Context

Cell Context for all methods.

signal

Name

signal — model a logical signal

Synopsis

C and DML

#include <simics/devs/signal.h> // in C
import "simics/devs/signal.dml"; // in DML

SIM_INTERFACE(signal) {
        void (*signal_raise)(conf_object_t *NOTNULL obj);
        void (*signal_lower)(conf_object_t *NOTNULL obj);
};

#define SIGNAL_INTERFACE "signal"

Python

import simics

class simics.signal_interface_t(signal_raise=None, signal_lower=None)

Description

The signal interface is for modeling a logical signal, such as a reset or interrupt. Signals are always active high in Simics with respect to their function. This may not correspond to the actual electrical level in a real system.

A signal connection has one initiator and one target object, where the initiator calls methods the interface implemented by the target.

The initiator object should have a configuration attribute that pointing to the target object or to an interface port of the target. This attribute, like all other attributes representing object connections, should be of the object kind, or a list of two entries where the first is an object and the second a string representing the name of the port.

The initiator should call signal_raise() to raise the signal level to its active level in the target. Once raised, the same initiator may not call signal_raise() again without an intervening call to signal_lower(). Similarly, an already low signal may not be lowered again by a signal_lower() call from the same initiator. The two functions represent the rising and the falling edge of the signal.

The target should handle the case where a signal is lowered directly after it has been raised and treat this call sequence as a valid pulse even within a single clock cycle. The target should also allow the signal to remain raised for some time before it is lowered.

While a target is disconnected, the input signal level is assumed to be low. When an initiator connects to a target by hot plugging, signal_raise() should be called if the output signal from the initiator was high. If the signal was low, then no function in the target should be called.

If the signal level is high on disconnect, then the initiator has to call signal_lower() before disconnecting from the target. Connect and disconnect is typically done by changing the attribute in the initiator that identifies the target object.

When an initiator is reset, it should call signal_lower() if the actual hardware also lowers the output signal on a reset. The target, on the other hand, should not reset its remembered value of the input.

When a connection attribute is restored from a checkpoint or during reverse execution, no function should be called in the signal interface of the target since the actual signal level does not change. The attribute setter code can distinguish between hot-plugging and state restoring by using SIM_object_is_configured and SIM_is_restoring_state. See the latter of the two for more documentation.

When an object is first created and the initial signal level is high, the initiator has to call the signal_raise() function in the target. This can not be done earlier than in finalize (C/C++) or in post_init (DML) since the target has to be fully configured. Again, this should not be done when restoring a checkpoint.

There must only be a single initiator connected to a target, with the exception of the signal-bus that may have several initiators.

A target that needs more than one input signal should use ports to implement several signal interfaces.

Execution Context

Cell Context for all methods.

simple_dispatcher

Name

simple_dispatcher — interface for subscribing to frequency related changes

Synopsis

C and DML

#include <simics/devs/frequency.h> // in C
import "simics/devs/frequency.dml"; // in DML

SIM_INTERFACE(simple_dispatcher) {
        void (*subscribe)(conf_object_t *NOTNULL bus,
                          conf_object_t *NOTNULL listener,
                          const char *listener_port);
        void (*unsubscribe)(conf_object_t *NOTNULL bus,
                            conf_object_t *NOTNULL listener,
                            const char *listener_port);
};

#define SIMPLE_DISPATCHER_INTERFACE "simple_dispatcher"

Python

import simics

class simics.simple_dispatcher_interface_t(subscribe=None, unsubscribe=None)

Description

The simple_dispatcher interface is used for subscribing to changes of some monitored state. The interface is currently used for subscribing to changes in frequencies and to changes in frequency scale factors, via the interfaces frequency_listener and scale_factor_listener, respectively.

A device subscribes with the subscribe function. Before this function returns, it should send a signal to the calling object, telling the current state. After this, signals should be sent whenever the monitored state changes.

The function unsubscribe should be used to unsubscribe from monitored changes. A listener may not subscribe or unsubscribe twice on the same port.

Execution Context

Global Context for all methods.

simple_interrupt

Name

simple_interrupt — obsolete interface used with interrupts

Synopsis

C and DML

#include <simics/devs/interrupt.h> // in C
import "simics/devs/interrupt.dml"; // in DML

SIM_INTERFACE(simple_interrupt) {
        void (*interrupt)(conf_object_t *NOTNULL obj, int value);
        void (*interrupt_clear)(conf_object_t *NOTNULL obj, int value);
};

#define SIMPLE_INTERRUPT_INTERFACE "simple_interrupt"

Python

import simics

class simics.simple_interrupt_interface_t(interrupt=None, interrupt_clear=None)

Description

A device calls interrupt to logically raise an interrupt and interrupt_clear to lower an interrupt.

The first argument is the object to interrupt, usually a cpu. The integer argument to both functions may indicate an interrupt level or interrupt pin depending on the receiving device.

On ARM the integer argument indicates whether the interrupt is normal or fast, by being either ARM_INT_IRQ or ARM_INT_FIQ defined by the ARM API (by including <simics/arch/arm.h>).

Obsoleted by the signal interface.

Execution Context

Cell Context for all methods.

smm_instrumentation_subscribe

Name

smm_instrumentation_subscribe — x86 specific interface for smm mode instrumentation

Synopsis

C and DML

#include <simics/arch/x86-instrumentation.h> // in C
import "simics/arch/x86-instrumentation.dml"; // in DML

SIM_INTERFACE(smm_instrumentation_subscribe) {
        cpu_cb_handle_t *(*register_smm_enter_before_cb)(
                conf_object_t *cpu,
                conf_object_t *connection,
                smm_switch_cb_t cb,
                lang_void *user_data);
        cpu_cb_handle_t *(*register_smm_enter_after_cb)(
                conf_object_t *cpu,
                conf_object_t *connection,
                smm_switch_cb_t cb,
                lang_void *user_data);
        cpu_cb_handle_t *(*register_smm_leave_before_cb)(
                conf_object_t *cpu,
                conf_object_t *connection,
                smm_switch_cb_t cb,
                lang_void *user_data);
        cpu_cb_handle_t *(*register_smm_leave_after_cb)(
                conf_object_t *cpu,
                conf_object_t *connection,
                smm_switch_cb_t cb,
                lang_void *user_data);
};
#define SMM_INSTRUMENTATION_SUBSCRIBE_INTERFACE \
        "smm_instrumentation_subscribe"

Python

import simics

class simics.smm_instrumentation_subscribe_interface_t(register_smm_enter_before_cb=None,
        register_smm_enter_after_cb=None, register_smm_leave_before_cb=None,
        register_smm_leave_after_cb=None)

Description

This interface allows a user to keept track of System Management Mode switches in the processor.

The register_smm_enter_before_cb registers a callback of type smm_switch_cb_t that will be called before the processor enters System Management Mode.

The register_smm_enter_after_cb registers a callback of type smm_switch_cb_t that will be called after the processor has entered System Management Mode.

The register_smm_leave_before_cb registers a callback of type smm_switch_cb_t that will be called before the processor leaves System Management Mode.

The register_smm_leave_after_cb registers a callback of type smm_switch_cb_t that will be called after the processor has left System Management Mode.

Execution Context

Global Context for all methods.

sparc_v8_ecc_fault_injection

Name

sparc_v8_ecc_fault_injection — interface for error injection with SPARC V8

Synopsis

C and DML

#include <simics/arch/sparc-v8.h> // in C
// not available in DML

SIM_INTERFACE(sparc_v8_ecc_fault_injection) {
        void (*inject_instr_access_exception)(conf_object_t *cpu);
        void (*inject_data_access_exception)(conf_object_t *cpu);
        void (*inject_reg_access_error)(conf_object_t *cpu);
};
#define SPARC_V8_ECC_FAULT_INJECTION_INTERFACE "sparc_v8_ecc_fault_injection"

Description

Support the injection of uncorrectable ECC faults. It can be used to inject

  1. V8_Exc_Data_Access_Exception,
  2. V8_Exc_Instruction_Access_Exception, and
  3. V8_Exc_R_Register_Access_Error. The functions in this interface can only be called by breakpoint callback functions. Once an ecc fault is injected, new ecc faults can not be injected until the current one is handled.

The inject_data_access_exception plants an V8_Exc_Data_Access_Error for memory access on a location. The fault is injected when the breakpoint callback function of the location is called.

The inject_instr_access_exception plants an V8_Exc_Instruction_Access_Exception for an instruction, and this fault is injected when the breakpoint callback function of the instruction location is called.

The inject_data_access_exception is used for injecting V8_Exc_R_Register_Access_Error for a register access. It is right now not implemented.

Execution Context

Cell Context for all methods.

sparc_v8

Name

sparc_v8 — interface for SPARC V8 specific functions

Synopsis

C and DML

#include <simics/arch/sparc-v8.h> // in C
// not available in DML

SIM_INTERFACE(sparc_v8) {
        uint64 (*read_window_register)(conf_object_t *cpu, int window, int reg);

        void (*write_window_register)(conf_object_t *cpu,
                                      int window, int reg, uint64 value);
        void (*power_down)(conf_object_t *cpu);
};
#define SPARC_V8_INTERFACE "sparc_v8"

Description

SPARC V8 specific functions.

This interface is implemented by SPARC V8 processors to provide various functionality that is specific for this class of processors.

The read_window_register and write_window_register functions can be used to access registers in any register window.

The register number when accessing windowed registers is 0 - 7 for accesses to the global registers, 8 - 15 for the out registers of the selected window, 16 - 23 for the local registers, and 24 - 31 for the in registers.

The power_down function is used to command the processor to enter power down mode. During power down mode, the processor will not execute any instructions, it will instead fast forward the execution to the next event. If the event is an external interrupt the power down mode is exited and execution resumed, in other cases the event will be handled and the processor will remain in power down mode and fast forward to the next event.

One use for the power_down function is for example to have an external device such as an memory mapped PMU force the processor into power down mode.

Execution Context

Cell Context for all methods.

spr

Name

spr — interface for ppc special function registers

Synopsis

C and DML

#include <simics/arch/ppc.h> // in C
import "simics/arch/ppc.dml"; // in DML

SIM_INTERFACE(spr) {
        void (*register_user_handlers)(
                conf_object_t *cpu,
                int64 spr_number,
                gen_spr_user_getter_func_t getter,
                lang_void *user_getter_data,
                gen_spr_user_setter_func_t setter,
                lang_void *user_setter_data,
                int privilege_checks);
        void (*unregister_user_handlers)(
                conf_object_t *cpu,
                int64 spr_number);

        void (*set_target_value)(
                conf_object_t *cpu,
                uint64 value);

        void (*stash_value)(
                conf_object_t *cpu,
                int64 spr_number,
                uint64 value);
        uint64 (*fetch_value)(
                conf_object_t *cpu,
                int64 spr_number);

        gen_spr_ret_t (*default_getter)(
                conf_object_t *cpu,
                int64 spr_number,
                gen_spr_access_type_t type);
        gen_spr_ret_t (*default_setter)(
                conf_object_t *cpu,
                int64 spr_number,
                uint64 value,
                gen_spr_access_type_t type);

        const char *(*get_name)(
                conf_object_t *cpu,
                int64 spr_number);
        int64 (*get_number)(
                conf_object_t *cpu,
                const char *spr_name);

};
#define SPR_INTERFACE "spr"

Python

import simics

class simics.spr_interface_t(register_user_handlers=None,
        unregister_user_handlers=None, set_target_value=None,
        stash_value=None, fetch_value=None, default_getter=None,
        default_setter=None, get_name=None, get_number=None)

Description

The register_spr_user_handlers function will register user implemented get and set functions that will be called every time a read or write access is made to the SPR with number spr. The getter and setter function is of the type gen_spr_user_getter_func_t.

The type parameter in the get and set functions is of the type gen_spr_access_type_t.

Both the get and the set functions must return a value of the type gen_spr_ret_t.

If privilege_checks is not zero, Simics will do privilege checks when a mfspr/mtspr instruction is executed. If this does not produce the desired results, you can register the SPR handlers with privilege_checks set to zero, and do you own checks in your handlers.

The function unregister_spr_user_handlers will remove any registered user handlers for a particular SPR.

The function spr_set_target_value should be called from the get function. The value will be written to the target register for instruction accesses, and returned for attribute and int register interface accesses. If this function is not called, the target register is not changed for instruction accesses (and the mfspr thus acts as a nop).

The functions spr_stash_value and spr_fetch_value can be used to store a SPR value in the processor. This is useful if only the getter (or only the setter) has been overridden with a user handler.

Sometimes it may be desirable to let the processor take care of the access. The functions spr_default_getter and spr_default_setter exist for this purpose.

The function spr_get_name takes spr_number as parameter and returns the name of the SPR.

The function spr_get_number takes the spr_name and returns the SPR number, or -1 if the register does not exist.

Note that the following registers cannot be overridden with user handlers: xer, lr and ctr.

Execution Context

Global Context
register_user_handlers
unregister_user_handlers
Cell Context
set_target_value
stash_value
fetch_value
default_getter
default_setter
get_name
get_number

telemetry_class_id_t, telemetry_id_t, telemetry

Name

telemetry_class_id_t, telemetry_id_t, telemetry — interface for accessing or providing arbitrary data

Synopsis

C and DML

#include <simics/devs/telemetry-interface.h> // in C
import "simics/devs/telemetry-interface.dml"; // in DML

typedef int telemetry_class_id_t;
typedef int telemetry_id_t;

SIM_INTERFACE(telemetry) {
        telemetry_class_id_t (*get_telemetry_class_id)(conf_object_t *obj,
                                                       const char *telemetry_class_name);
        const char *(*get_telemetry_class_name)(conf_object_t *obj,
                                                telemetry_class_id_t telemetry_class_id);
        const char *(*get_telemetry_class_description)(conf_object_t *obj,
                                                      telemetry_class_id_t telemetry_class_id);
        telemetry_id_t (*get_telemetry_id)(conf_object_t *obj,
                                           telemetry_class_id_t telemetry_class_id,
                                           const char *telemetry_name);
        const char *(*get_telemetry_name)(conf_object_t *obj,
                                          telemetry_class_id_t telemetry_class_id,
                                          telemetry_id_t telemetry_id);
        const char *(*get_telemetry_description)(conf_object_t *obj,
                                                 telemetry_class_id_t telemetry_class_id,
                                                 telemetry_id_t telemetry_id);
        attr_value_t (*get_value)(conf_object_t *obj,
                                  telemetry_class_id_t telemetry_class_id,
                                  telemetry_id_t telemetry_id);
};

#define TELEMETRY_INTERFACE "telemetry"

Python

import simics

class simics.telemetry_interface_t(get_telemetry_class_id=None,
        get_telemetry_class_name=None, get_telemetry_class_description=None,
        get_telemetry_id=None, get_telemetry_name=None,
        get_telemetry_description=None, get_value=None)

Description

The telemetry interface is used to fetch telemetry data.

A model implements one or more telemetry-classes. These are identified by an identifier (class ID) and a name. The telemetries also has a name and an identifier (telemetry ID).

This layout forms a two level hierarchy with classes and their telemetries. The class and telemetry ID’s are represented as integers and must be part of a contiguous range starting from zero, i.e., the hierarchy can be viewed as a table with telemetries, where the row numbers (>= 0), represents the class ID’s, and the column numbers (>=0) represents the telemetry ID’s. For unknown ID’s NULL should be returned.

Both telemetry_class_id and telemetry_id can be enumerated using the functions get_telemetry_class_name and get_telemetry_name by starting with an ID of zero and go upp until NULL is returned. A model should not log an error when an invalid ID is presented (but logging info on level 3 makes sense for debug purposes). Error handling for missing expected telemetry IDs should be handled in the model requesting and retrieving the telemetry value.

The get_telemetry_class_id function returns the telemetry_class_id for the telemetry class with name telemetry_class_name. If no telemetry class with that name is found or that telemetry class is not enabled a negative number is returned.

The get_telemetry_class_name returns the name of the corresponding telemetry_class_id. If no telemetry class is found with that id the value NULL is returned.

The get_telemetry_class_description can return a description string for the telemetry_class_id. If no telemetry class is found with that id the value NULL is returned.

get_telemetry_id returns the telemetry_id for the telemetry with name telemetry_name belonging to telemetry_class_id. If no telemetry with that name is found in the telemetry class a negative number is returned.

get_telemetry_name returns the name of the corresponding telemetry_id belonging to telemetry_class_id. If no telemetry with that id is found in the telemetry class the value NULL is returned.

get_telemetry_description can return a description string for the telemetry_id belonging to telemetry_class_id. If no telemetry with that id the value is found NULL is returned.

get_value function returns the value for the telemetry_id within telemetry_class_id.

All known telemetry_classes are not always enabled in all models, i.e. get_telemetry_class_name can return a valid name for some telemetry_class_id but get_telemetry_id on that name may still return an invalid identifier if that telemetry_class is not enabled in the model.

The identifiers may vary between invocations of the model and must not be stored between runs.

The command list-telemetry-classes can be helpful while developing with the telemetry-interface.

Execution Context

Global Context for all methods.

transaction_translator

Name

transaction_translator — interface used to inspect and/or modify transactions

Synopsis

C and DML

#include <simics/devs/translator.h> // in C
import "simics/devs/translator.dml"; // in DML

SIM_INTERFACE(transaction_translator) {
        exception_type_t (*translate)(
                conf_object_t *NOTNULL obj,
                uint64 addr,
                access_t access,
                transaction_t *t,
                exception_type_t (*NOTNULL callback)(
                        translation_t translation,
                        transaction_t *transaction,
                        cbdata_call_t data),
                cbdata_register_t data);
};

#define TRANSACTION_TRANSLATOR_INTERFACE "transaction_translator"

Python

import simics

class simics.transaction_translator_interface_t(translate=None)

Description

The transaction_translator interface is implemented by objects which would like to inspect and/or modify transactions before forwarding them to devices or address spaces. In Simics documentation, such objects are usually called translator objects or, simply, translators. In comparison with the simpler translator interface, the transaction_translator interface provides an opportunity to inspect/modify transactions. We recommend using the translator interface when the additional functionality is not needed.

The interface has one method called translate. The arguments passed to this method describe the access and thus allow a translator to perform a proper translation. Here is a short description of the translate method’s parameters:

All these arguments are described in detail below.

The transactions done by the translators may be cached by Simics. To ensure efficient flushing of Simics internal caches we recommend that the objects implementing the transaction_translator interface implement also the translation_flush interface. The absence of the translation_flush interface may lead to a substantial decrease of simulation speed.

Whenever a previously returned translation becomes invalid the translator objects are expected to use either SIM_map_target_flush (preferably) or SIM_translation_changed function to ensure that Simics will flush any cached translations. Please refer to the documentation of these functions for the information about how they should be used.

An object implementing the transaction_translator interface should invoke callback passing to it tree arguments: translation, transaction and data. The translation argument describes the translation that was done, i.e. the transaction destination. Please refer to the translation_t documentation for the complete description. The transaction argument is either the original transaction passed to the transaction_translator interface or, if a translator object wants to append atoms to the t transaction, a new transaction created via transaction chaining. The transaction chaining is described in detail in the “Transaction Chaining” chapter of the Model Builder's User Guide Finally, the data argument is a parameter which should be passed as it is when callback is invoked by the translator object. Simics will report an error if a translator object doesn’t invoke callback from the translate method of the transaction_translator.

If it is needed, a translator may route transactions based on the value of certain transaction’s atoms. The initiator atom is a good example of such an atom. Please note that not all atoms are suited for routing transactions based on their value. This should be checked in the documentation for the specific atom.

The callback function returns transaction completion status. This status should be usually returned as it is by the translate method. The status value is also needed in the case when a translator object appends atoms via transaction chaining with a non-zero completion atom. In that case the returned status should be used when the SIM_monitor_chained_transaction function is called.

Please note that memory accesses in Simics are not always issued with the transactions of the transaction_t type. For example, memory access can be done with the use of the legacy generic_transaction_t type. One more such example is lookup accesses which are done via the direct_memory_lookup interface. All such accesses are converted, if it is needed, and presented to the translator object via the t parameter.

The access parameter specifies access types in the form of a bitmask. Its value may be of interest if a translation is done differently based on whether it is a read, write or instruction fetch transaction. It can be noted that a transaction itself already contains information whether it is a read, write or an instruction fetch. Usually, the access parameter just reflects that value. However, for lookup accesses done via the direct_memory_lookup interface the access argument may have more bits set. If a translation which are valid for all requested accesses cannot be performed, then a null value should be set in the target of the translation argument passed to callback. In this case, the requestor is expected to repeat the interface call with just a single bit set in the access mask, e.g. Sim_Access_Read.

Execution Context

Cell Context for all methods.

See Also

translation_t, translation_flush interface, SIM_map_target_flush

translate

Name

translate — implemented by objects that bridge between memory spaces

Synopsis

C and DML

#include <simics/devs/memory-space.h> // in C
import "simics/devs/memory-space.dml"; // in DML

SIM_INTERFACE(translate) {
        conf_object_t *(*translate)(conf_object_t *NOTNULL obj,
                                    generic_transaction_t *NOTNULL mem_op,
                                    map_info_t mapinfo);
};

#define TRANSLATE_INTERFACE "translate"

Python

import simics

class simics.translate_interface_t(translate=None)

Description

The translate interface is implemented by objects that bridge between memory spaces.

There is the translator interface which is a more restricted version of the translate interface and should be used when possible. It allows for better control of memory operations in the Simics core and can therefore allow optimizations in the memory handling.

The return value of the translate method should be a memory space, to which the access is translated at the offset given by the physical address of mem_op. If the return value is NULL, then the access is translated to the default target provided in the configuration (in a memory-space object, this is the 6th index, target, of an entry in the map attribute).

During a translation, the translator may modify the physical address of mem_op, but may have no other side-effects. This is because the caller can choose to cache the translation, in which case the translator is bypassed in subsequent accesses.

The translator can use SIM_mem_op_ensure_future_visibility to inhibit caching. Inhibiting caching can be useful for debugging, but typically comes with a significant performance cost if there is RAM behind the translator.

The addition of the direct_memory interface in Simics 5 results in new typical access patterns for the translate interface. Where previously non-inquiry accesses of any size would result in caching in initiating CPU objects, with the use of direct_memory no such implicit caching ever takes place. Instead, caching requests are separate and fed through the translate method as inquiry accesses of the size that is intended to be cached. This means that for a translate object to work properly in a configuration with CPUs using direct_memory, inquiry accesses must be properly handled. Routing such inquiry accesses to non-memory, terminating them in the translator (which is not an allowed behavior for a translate object), or calling SIM_mem_op_ensure_future_visibility on them results in the requesting CPU not being able to cache the requested memory region.

Using the translate interface in models is error prone and usually not recommended unless all alternatives have been exhausted. Explicit map and demap operations in a memory space avoid the problems with translate interface implementation correctness.

The usage of the translate interface is by necessity less optimal than the usage of the memory-space class as a call out from the simulation kernel should be made. That said when the translate() method is called the transaction may be cached in the STC if the user code does not explicitly block such caching, though depending on a number of factors it may not always be cached. If the translation is cached in the STC then performance is the same as with a memory-space.

There are two reasons to use the translate interface rather than a simple memory-space: 1) To implement something that the memory-space does not support, such as different read and write translations, or manipulation of the transaction, or 2) the translation is accessed infrequently, but updated on most accesses.

Up to and including Simics 4.8, CPU models would cache memory for transactions that pass through a translator in blocks that are larger than the size provided in the transaction. This meant that a translator needed to invalidate caches even if a translation changed that had strictly not passed through the interface. For correctness, when any state that had an effect on the translation logic changed, the translator would therefore invalidate all mappings in all initiators, even for mappings that are outside of what has passed through the translator. These types of workarounds are no longer required since Simics 5.

Execution Context

Cell Context for all methods.

translation_flush

Name

translation_flush — optional interface used with address translation

Synopsis

C and DML

#include <simics/devs/translator.h> // in C
import "simics/devs/translator.dml"; // in DML

SIM_INTERFACE(translation_flush) {
        bool (*flush_range)(
                conf_object_t *obj,
                uint64 base,
                uint64 size,
                access_t access,
                const map_target_t *default_target);
};

#define TRANSLATION_FLUSH_INTERFACE "translation_flush"

Python

import simics

class simics.translation_flush_interface_t(flush_range=None)

Description

The translation_flush interface is an optional interface which can be implemented by objects implementing the transaction_translator or translator interface. The interface is used by Simics an optimization when Simics flushes its simulation caches. Simics caches translations returned by translators but quite often this cache needs to be invalidated, usually, due to the changes in the memory map of the target system. In such cases Simics may use this interface (if it is available) to do a fine-grain invalidation of its simulation caches.

The translation_flush interface has one method, flush_range, which will be called whenever there is a need to flush simulation caches. The flush_range method has the following parameters:

In the flush_range method, the translator object is expected to flush all previously returned destinations of the translation requests that the translator did for the [base, base+size) range. The flushing is done by calling the SIM_map_target_flush function for the destination map target(s). If no translation requests were processed to the range since the last invocation of the flush_range method then no flushing is needed, and the flush_range may immediately return the true value.

Please note that there is no need to call the SIM_map_target_flush function for the translations which were tagged with the Sim_Translation_Dynamic flag. Either, no invalidation is needed for the parts of the range where nothing is mapped.

The return value is used to report whether the invalidation request completed successfully, i.e. whether all calls to the SIM_map_target_flush function succeeded (i.e. returned the true value). If a call to the SIM_map_target_flush fails (i.e. the false value is returned) then the flush_range function is expected to return immediately with the false return value. If, for some reason, the translator cannot invalidate all possible destinations, then it can just immediately return the false value.

If false is returned, then all translations in the simulator will typically be flushed, which could be an expensive operation.

Example

Here is pseudo code providing a sample implementation of the flush_range method:

bool flush_range(obj, base, size, access):
    for (map_target, start, size) in destinations(obj, base, size, access):
        if not SIM_map_target_flush(map_target, start, size, access):
            return False
    return True

Execution Context

Cell Context

translator

Name

translator — interface implemented for address translation

Synopsis

C and DML

#include <simics/devs/translator.h> // in C
import "simics/devs/translator.dml"; // in DML

SIM_INTERFACE(translator) {
        translation_t (*translate)(conf_object_t *NOTNULL obj,
                                   physical_address_t addr,
                                   access_t access,
                                   const map_target_t *default_target);
};

#define TRANSLATOR_INTERFACE "translator"

Python

import simics

class simics.translator_interface_t(translate=None)

Description

The translator interface is implemented by objects which perform address translations or map memory transactions to devices or address spaces.

The translate method takes a physical address addr and returns a value of the type translation_t which describes the translation for an address range which must include addr. Please refer to the translation_t documentation for a complete description of the return value and more information regarding the implementation of translator objects.

A translator can translate read transactions, write transactions and instruction fetches differently. The access parameter is set to all requested access types in the form of a bitmask. The translator should return null in the target field if a translation valid for all requested accesses cannot be performed; when this happens, the requestor is expected to repeat the interface call with just a single bit set in the access mask, e.g. Sim_Access_Read.

The default_target parameter is a default target, which can be NULL, of the translator mapping (i.e., the target field of the respective memory-space's map entry specifying mapping).

Execution Context

Cell Context

See Also

translation_t, SIM_map_target_flush

uint64_state

Name

uint64_state — interface used in transferring state between devices

Synopsis

C and DML

#include <simics/model-iface/state.h> // in C
import "simics/model-iface/state.dml"; // in DML

SIM_INTERFACE(uint64_state) {
        void (*set)(conf_object_t *NOTNULL obj, uint64 level);
};
#define UINT64_STATE_INTERFACE "uint64_state"

Python

import simics

class simics.uint64_state_interface_t(set=None)

Description

Interface to transfer a state representable in an uint64 from one device to another. Examples of what the state might represent includes:

The initiator should call set when the value changes, and after a new target is connected. The object implementing uint64_state should accept multiple calls to set with the same level, and may let this trigger side-effects. Therefore, any repeated calls must be deterministic; in particular, set must not be called while restoring a checkpoint.

A device implementing this interface may choose to only accept a certain set of integer values; it is then an error to send any other values to the set method. A user must therefore be careful to read the documentation of both the source and destination object to make sure they are compatible.

No interface call needs to be done after disconnecting a target; the target needs to be notified of this through some other channel (typically via a connector)

The uint64_state interface should be used instead of the deprecated multi_level_signal interface when writing new models.

Execution Context

Cell Context for all methods.

usb_device

Name

usb_device — interface implemented by USB devices

Synopsis

C and DML

#include <simics/devs/usb.h> // in C
import "simics/devs/usb.dml"; // in DML

SIM_INTERFACE(usb_device) {
        usb_transfer_completion_t (*submit_transfer)(conf_object_t *dev_obj,
                                                     usb_transfer_t *transfer);
        void (*abort_transfer)(conf_object_t *dev_obj,
                               usb_transfer_t *transfer);
        void (*reset)(conf_object_t *dev_obj);
};

#define USB_DEVICE_INTERFACE "usb_device"

Python

import simics

class simics.usb_device_interface_t(submit_transfer=None, abort_transfer=None,
        reset=None)

Description

The usb_device_interface_t interface is implemented by all USB devices. It is used by the USB host to communicate with the USB devices. The interface is Simics internal, and may be changed in future versions of Simics. It should not be used by user-defined classes.

The submit_transfer function is used by the USB host controller to send a new transfer to a USB device. Transfers are the basic means of communication between the USB host controller and the USB devices. A transfer contains all information needed to handle control, bulk, interrupt, and isochronous transfers. A transfer to a USB device simply moves the control from the USB host to the USB device. The USB device can then decide when to send back any useful data to the USB host. The USB device receives a pointer to the transfer to handle. It can either handle the transfer immediately or send the transfer back later using the complete_transfer function in the usb interface, which is implemented by the USB host.

The USB device must return USB_Transfer_Completed when it handles the transfer immediately, i.e., it has filled the required fields in the transfer structure. The USB device must return USB_Transfer_Not_Ready for unfinished transfers, i.e., the USB device does not have any interesting data to deliver at this point. The isochronous and interrupt transfers contain a field indicating how long time the USB host expects the USB device to wait before returning the transfer. Note that it is just an indication on how often this transfer is scheduled in the periodic list and USB devices can complete the transfers at any time. A value of 0 means that the USB host does have any expectations about the return time.

The abort_transfer function tells the USB device to abort a transfer previously issued by the USB host. The USB device should not call the complete_transfer function for a request that has been aborted.

The reset function is used by the USB host to reset the USB device.

The USB host expects the device to return the same transfer pointer it received when completing, i.e., the transfer pointer is used to identify uniquely a transfer.

Execution Context

Cell Context for all methods.

usb

Name

usb — interface used in communication with USB hosts

Synopsis

C and DML

#include <simics/devs/usb.h> // in C
import "simics/devs/usb.dml"; // in DML

SIM_INTERFACE(usb) {
        int (*connect_device)(conf_object_t *bus_obj,
                              conf_object_t *NOTNULL dev_obj,
                              usb_speed_t speed);
        int (*disconnect_device)(conf_object_t *bus_obj,
                                 conf_object_t *NOTNULL dev_obj);
        void (*complete_transfer)(conf_object_t *bus_obj,
                                  conf_object_t *NOTNULL dev_obj,
                                  usb_transfer_t *NOTNULL transfer);
};

#define USB_INTERFACE "usb"

Python

import simics

class simics.usb_interface_t(connect_device=None, disconnect_device=None,
        complete_transfer=None)

Description

The usb_interface_t interface is implemented by all USB hosts. USB devices use the interface to communicate with the USB host. The interface is Simics internal, and may be changed in future versions of Simics. It should not be used by user-defined classes.

The connect_device function is called by the USB device to connect to the USB. The host returns the physical port to which the device is connected, or -1 on connection error (for example, if all ports are occupied). Parameter to connect_device is the maximum data speed for the USB device.

The disconnect_device function is called by the USB device when it wants to disconnect from the USB. The host returns 0 on success.

The complete_transfer function is called by a USB device when it has completed a transfer. Refer to the usb_device interface documentation to know more about how a transfer is sent to the USB device.

Execution Context

Global Context
connect_device
disconnect_device Cell Context
complete_transfer

vectored_interrupt

Name

vectored_interrupt — interface used with vectored interrupts

Synopsis

C and DML

#include <simics/devs/vectored-interrupt.h> // in C
import "simics/devs/vectored-interrupt.dml"; // in DML

SIM_INTERFACE(vectored_interrupt) {
        void (*set_level)(conf_object_t *NOTNULL obj,
                          conf_object_t *NOTNULL source, int level);
};
#define VECTORED_INTERRUPT_INTERFACE "vectored_interrupt"

Python

import simics

class simics.vectored_interrupt_interface_t(set_level=None)

Description

This interface is typically implemented by processors with interrupts that have vectors and priorities supplied by their sources.

The set_level method sets the interrupt level on the target object; zero indicates that no interrupt is requested. The interrupt source should implement the vectored_interrupt_source interface.

Execution Context

Cell Context for all methods.

vectored_interrupt_source

Name

vectored_interrupt_source — interface implemented by interrupt sources

Synopsis

C and DML

#include <simics/devs/vectored-interrupt.h> // in C
import "simics/devs/vectored-interrupt.dml"; // in DML

SIM_INTERFACE(vectored_interrupt_source) {
        int (*acknowledge)(conf_object_t *NOTNULL obj,
                           conf_object_t *NOTNULL target, int level);
};
#define VECTORED_INTERRUPT_SOURCE_INTERFACE "vectored_interrupt_source"

Python

import simics

class simics.vectored_interrupt_source_interface_t(acknowledge=None)

Description

This interface is implemented by interrupt sources that use the vectored_interrupt interface.

The acknowledge method is called to acknowledge a requested interrupt of the given level on the interrupt target. It should return an interrupt vector number, -1 if no vector is supplied, or -2 if the object does not accept the acknowledgement.

Execution Context

Cell Context for all methods.

virtiofs_fuse

Name

virtiofs_fuse — FUSE request handler interface

Synopsis

C and DML


SIM_INTERFACE(virtiofs_fuse)
{
        buffer_t (*handle_request)(conf_object_t * obj, bytes_t req);
};

#define VIRTIOFS_FUSE_INTERFACE "virtiofs_fuse"

Description

This interface is intended for implementing a FUSE request handler.

handle_request This method takes a FUSE request in req. It then returns a buffer_t object with the FUSE response. The caller of handle_request must free the data field in the returned buffer_t object.

Execution Context

Cell Context for all methods.

vmp

Name

vmp — control VMP from a user perspective

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(vmp) {
        bool (*class_has_support)(conf_object_t *obj);
        bool (*host_support)(conf_object_t *obj);
        bool (*compatible_config)(conf_object_t *obj);
        bool (*enable)(conf_object_t *obj);
        void (*disable)(conf_object_t *obj);
        bool (*enabled)(conf_object_t *obj);
        void (*set_threshold)(conf_object_t *obj, int threshold);
        bool (*get_feature)(conf_object_t *obj, vmp_feature_t feature);
        bool (*set_feature)(conf_object_t *obj, vmp_feature_t feature, bool val);
        uint64 (*get_info)(conf_object_t *obj, vmp_info_t info);
};
#define VMP_INTERFACE "vmp"

Python

import simics

class simics.vmp_interface_t(class_has_support=None, host_support=None,
        compatible_config=None, enable=None, disable=None, enabled=None,
        set_threshold=None, get_feature=None, set_feature=None,
        get_info=None)

Description

This is an internal interface between VMP and the Simics Base package, and it may change at any time without notice.

The vmp interface is used to control enabling of VMP and VMP features from a user perspective. Models should use x86_vmp_control for potential blocking of VMP.

Execution Context

Cell Context for all methods.

vmx_instrumentation_subscribe

Name

vmx_instrumentation_subscribe — x86 specific interface for vmx mode instrumentation

Synopsis

C and DML

#include <simics/arch/x86-instrumentation.h> // in C
import "simics/arch/x86-instrumentation.dml"; // in DML

SIM_INTERFACE(vmx_instrumentation_subscribe) {
        cpu_cb_handle_t *(*register_vmx_mode_leave_cb)(
                conf_object_t *cpu,
                conf_object_t *connection,
                vmx_mode_switch_cb_t cb,
                lang_void *user_data);
        cpu_cb_handle_t *(*register_vmx_mode_enter_cb)(
                conf_object_t *cpu,
                conf_object_t *connection,
                vmx_mode_switch_cb_t cb,
                lang_void *user_data);
};

#define VMX_INSTRUMENTATION_SUBSCRIBE_INTERFACE \
        "vmx_instrumentation_subscribe"

Python

import simics

class simics.vmx_instrumentation_subscribe_interface_t(register_vmx_mode_leave_cb=None,
        register_vmx_mode_enter_cb=None)

Description

This x86 specific interface allows a user to keept track of VMX mode switches in the processor.

The register_vmx_mode_leave_cb registers a callback of type vmx_mode_switch_cb_t that will be called before the processor leaves a particular VMX mode.

The register_vmx_mode_enter_cb registers a callback of type vmx_mode_switch_cb_t that will be called after the processor enters a particular VMX mode.

The different VMX modes are defined by vmx_mode_t.

The vmcs_address argument specifies the Virtual Machine Control Structure address that is currently being used. If not available, it will be passed as (physical_address_t)(-1).

When leaving a mode and then entering another mode, the mode can actually be reported as to be the same in certain situations. This is not a bug, it is a consequent of how Simics is implemented. It would require a lot of extra code to filter those out.

The user_data argument is the callback user data, passed to the register methods.

Execution Context

Global Context for all methods.

x86_access_type

Name

x86_access_type — information about the x86_access_type_t enum

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(x86_access_type) {
        const char *(*get_enum_name)(conf_object_t *obj, x86_access_type_t at);
        const char *(*get_short_name)(conf_object_t *obj, x86_access_type_t at);
        const char *(*get_description)(conf_object_t *obj, x86_access_type_t at);
        bool (*implicit)(conf_object_t *obj, x86_access_type_t at);
};

#define X86_ACCESS_TYPE_INTERFACE "x86_access_type"

Python

import simics

class simics.x86_access_type_interface_t(get_enum_name=None, get_short_name=None,
        get_description=None, implicit=None)

Description

This interface is used to query information about the x86_access_type_t enum. The get_enum_name method returns the C enum name for the access type. get_short_name returns a corresponding short name. More than one access type may have the same short name. The get_description returns a longer description of the access type. The implicit function returns true if the access type is considered implicit or false if it is considered explicit. This information is used by the cpu_instrumentation_subscribe interface to separate accesses in the two different categories.

Execution Context

Cell Context for all methods.

x86_address_query

Name

x86_address_query — interface for x86 specific address queries

Synopsis

C and DML

#include <simics/arch/x86-instrumentation.h> // in C
import "simics/arch/x86-instrumentation.dml"; // in DML

SIM_INTERFACE(x86_address_query) {
        x86_seg_t (*segment)(
                conf_object_t *cpu, address_handle_t *handle);
        page_crossing_info_t (*get_page_crossing_info)(
                conf_object_t *cpu, address_handle_t *handle);
};
#define X86_ADDRESS_QUERY_INTERFACE "x86_address_query"

Python

import simics

class simics.x86_address_query_interface_t(segment=None,
        get_page_crossing_info=None)

Description

The x86_address_query interface is used to query information about an address for the x86 architecture and should be used from a cpu_address_cb_t callback.

The segment is used to get the segment register used in the address calculation. The handle is the address handle passed to cpu_address_cb_t.

If the access crosses a page boundary the access will be split into two calls. The get_page_crossing_info can be used to distinguish the different cases from each other. The value returned is of type page_crossing_info_t and is one of: Sim_Page_Crossing_None (no crossing access), Sim_Page_Crossing_First (first part of a crossing access), Sim_Page_Crossing_Second (second part of a crossing access).

Execution Context

Cell Context for all methods, but must be called from a callback receiving a handle of type address_handle_t.

x86_cache_flush

Name

x86_cache_flush — flush x86 specific caches

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(x86_cache_flush) {
        void (*flush)(conf_object_t *obj, conf_object_t *cpu, bool writeback);
};
#define X86_CACHE_FLUSH_INTERFACE "x86_cache_flush"

Python

import simics

class simics.x86_cache_flush_interface_t(flush=None)

Description

The x86 cache flush interface is implemented by objects which need to do some special handling when the cpu flushes the cache.

The flush method is invoked when the cpu executes an invd or a wbinvd instruction. The writeback parameter is set for the later instruction.

Execution Context

Cell Context for all methods.

cpuid_ret_t, x86_cpuid

Name

cpuid_ret_t, x86_cpuid — customize responses to CPUID requests

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef struct {
	int taken;
	uint64 out_a;
	uint64 out_b;
	uint64 out_c;
	uint64 out_d;
} cpuid_ret_t;

SIM_INTERFACE(x86_cpuid) {
	cpuid_ret_t (*cpuid)(conf_object_t *obj, conf_object_t *cpu,
                             uint32 in_eax, uint32 in_ebx, uint32 in_ecx,
                             uint32 in_edx);
};
#define X86_CPUID_INTERFACE "x86_cpuid"

Python

import simics

class simics.cpuid_ret_t(taken=0, out_a=0, out_b=0, out_c=0, out_d=0)
class simics.x86_cpuid_interface_t(cpuid=None)

Description

The CPUID interface makes it possible to customize responses to CPUID requests. The cpuid method should set taken to nonzero if it managed to handle the request, zero otherwise. When taken is non-zero, then the returned values in out_a, out_b, out_c, and out_d will be written to the first four general purpose registers. Assigning external handlers to the leaf range reserved for MAGIC instruction implementation has no effect, because the MAGIC implementation always takes priority.

Execution Context

Cell Context for all methods.

cpuid_value_t, x86_cpuid_query

Name

cpuid_value_t, x86_cpuid_query — query values returned by the CPUID instruction

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef struct {
        uint64 a, b, c, d;
} cpuid_value_t;

SIM_INTERFACE(x86_cpuid_query) {
        cpuid_value_t (*cpuid_query)(conf_object_t *obj, uint32 leaf,
                                     uint32 subleaf);
};
#define X86_CPUID_QUERY_INTERFACE "x86_cpuid_query"

Python

import simics

class simics.cpuid_value_t(a=0, b=0, c=0, d=0)
class simics.x86_cpuid_query_interface_t(cpuid_query=None)

Description

This interface is implemented by CPUs and can be used to query the values that would be returned by the CPUID instruction. The interface calculates the return value both from built in default values and from any handlers that would be installed using the x86_cpuid interface.

This is a preliminary interface. Based on feedback, this interface can and will be changed without regard for the usual ABI compatibility rules.

Execution Context

Cell Context for all methods.

x86_cstate_event_t

Name

x86_cstate_event_t — Enumeration of all supported reasons for a C-state change

Synopsis

C and DML


typedef enum {
        X86_Cstate_Event_Unspecified,
        X86_Cstate_Event_Hlt,
        X86_Cstate_Event_Mwait,
        X86_Cstate_Event_External,
        X86_Cstate_Event_Wakeup,
        X86_Cstate_Event_MonitorWakeup,
        X86_Cstate_Event_IntrWakeup,
        X86_Cstate_Event_MwaitTimerWakeup,
        X86_Cstate_Event_Max
} x86_cstate_event_t;

x86_cstate_t, x86_cstate

Name

x86_cstate_t, x86_cstate — interface used with x86 power states

Synopsis

C and DML

#include <simics/devs/x86-cstate-iface.h> // in C
import "simics/devs/x86-cstate-iface.dml"; // in DML

typedef struct {
        uint32 state;
        uint32 sub_state;
} x86_cstate_t;

SIM_INTERFACE(x86_cstate) {
        x86_cstate_t (*get_cstate)(conf_object_t *cpu_obj);
        void (*set_cstate)(conf_object_t *cpu_obj,
                           uint32 state, uint32 sub_state);
};

#define X86_CSTATE_INTERFACE "x86_cstate"

Python

import simics

class simics.x86_cstate_t(state=0, sub_state=0)
class simics.x86_cstate_interface_t(get_cstate=None, set_cstate=None)

Description

The methods in this interface can be used to read or change the current power state the CPU is in. A state value of 0 corresponds to C0, a value of 1 corresponds to C1, etc. HLT will be reported as state 1, substate 0. MWAIT will reported based upon the eax hint, decoded as state = (eax[7:4] + 1) mod 16, substate = eax[3:0].

set_cstate will perform side-effects such as putting the processor to sleep or waking it up, and call the registered cstate listeners.

Execution Context

Cell Context for all methods.

x86_cstate_notification

Name

x86_cstate_notification — interface used with x86 power states

Synopsis

C and DML

#include <simics/devs/x86-cstate-iface.h> // in C
import "simics/devs/x86-cstate-iface.dml"; // in DML

SIM_INTERFACE(x86_cstate_notification) {
        void (*notification)(conf_object_t *listener, conf_object_t *cpu,
                             uint32 state, uint32 sub_state);
};

#define X86_CSTATE_NOTIFICATION_INTERFACE "x86_cstate_notification"

Python

import simics

class simics.x86_cstate_notification_interface_t(notification=None)

Description

Objects registered in the CPU’s cstate_listeners attribute will be called via the notification method whenever the CPU’s cstate changes. Only changes caused by instruction execution or calls to the x86_cstate.set_cstate function will trigger a notification, not attribute accesses. See the x86_cstate interface for how the C-state is encoded in the parameters.

Execution Context

Cell Context.

x86_cstate_notification_v2

Name

x86_cstate_notification_v2 — Interface to notifyabout C-state transitions

Synopsis

C and DML


SIM_INTERFACE(x86_cstate_notification_v2) {
        void (*notification)(conf_object_t *listener, conf_object_t *cpu,
                const x86_cstate_notify_info_t *info);
};

#define X86_CSTATE_NOTIFICATION_V2_INTERFACE "x86_cstate_notification_v2"

Description

The interface is used to notify the listener about the processor C-state transitions.

The info contains information about the source of change and current C-state of the processor cpu.

A state value of 0 corresponds to C0, a value of 1 corresponds to C1, etc. HLT is reported as state 1, substate 0. MWAIT is reported based upon the eax hint, decoded as state = (eax[7:4] + 1) mod 16, substate = eax[3:0].

x86_cstate_notify_info_t

Name

x86_cstate_notify_info_t — Contains C-state event info

Synopsis

C and DML


typedef struct {
        x86_cstate_event_t  event;
        uint32              state;
        uint32              sub_state;
} x86_cstate_notify_info_t;

x86_doma_cstate_info_v2_t

Name

x86_doma_cstate_info_v2_t — Info about cstates

Synopsis

C and DML


typedef struct {
        uint32 state;
        uint32 sub_state;
        uint64 deadline;
        uint64 tsc;
} x86_doma_cstate_info_v2_t;

x86_doma_cstate_v3

Name

x86_doma_cstate_v3 — Interface that provides callbacks on cstate changes

Synopsis

C and DML


SIM_INTERFACE(x86_doma_cstate_v3)
{
        void (*notify_sleep)(conf_object_t *listener, conf_object_t *cpu,
                const x86_doma_cstate_info_v2_t *info);
        void (*notify_resume)(conf_object_t *listener,
                const x86_doma_cstate_info_v2_t *info);
        void (*notify_waiting_interrupt)(conf_object_t *listener,
                bool is_waiting);
        void (*notify_reset)(conf_object_t *listener);
};

#define X86_DOMA_CSTATE_V3_INTERFACE "x86_doma_cstate_v3"

Description

For notify_sleep, and notify_resume, the cstate information is in the info x86_doma_cstate_info_v2_t argument.

x86_ept

Name

x86_ept — provides insight into the Extended Page Table (EPT)

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(x86_ept) {
        physical_block_t (*guest_physical_to_physical)(
                conf_object_t *obj,
                generic_address_t address,
                x86_processor_mode_t cpu_mode,
                access_t access);
        bool (*is_ept_active)(conf_object_t* obj);
};

#define X86_EPT_INTERFACE "x86_ept"

Python

import simics

class simics.x86_ept_interface_t(guest_physical_to_physical=None,
        is_ept_active=None)

Description

The interface provides insight into the Extended Page Table (EPT) address translation performed by target processors for virtual machine operations. It takes a result of the first level translation (the classical paging), called a guest physical address, and returns matching host physical address.

The guest_physical_to_physical function translates a guest physical address to a host physical address. The cpu_mode argument sets the processor mode for the lookup. Access type is defined by access. The function returns a physical_block_t struct with valid bit and the address. The host physical address is valid when the valid flag is not 0. The function also returns block_start and block_end. The start and end of a block has the same linear mapping as the translated address. The range is inclusive, so block_end should be the address of the last byte of the block. This information can be used to figure out how often the function needs to be called for traversing larger address ranges.

If the chosen processor’s current mode does not use EPT translation, the function should use the identity mapping between guest and host physical addresses. An example of such situation would be an x86 processor outside of VMX non-root mode or with EPT controls disabled.

To check if the processor’s current VMCS state has EPT enabled, is_ept_active function should be used.

Execution Context

Cell Context for all methods.

x86_eri_v1

Name

x86_eri_v1 — For read/write of ERI registers

Synopsis

C and DML


SIM_INTERFACE(x86_eri_v1) {
        void (*read)(conf_object_t *listener,
                uint64 reg_num, eri_transaction_t *data);
        void (*write)(conf_object_t *listener,
                uint64 reg_num, eri_transaction_t *data);
};

#define X86_ERI_V1_INTERFACE "x86_eri_v1"

Description

The interface is used to read/writer external registers.

data (with type eri_transaction_t) is owned by caller. Callee always fills field valid to cate transaction result. Field val contains the result of read method input for write method.

x86_eri_v2

Name

x86_eri_v2 — For read/write of ERI registers

Synopsis

C and DML


SIM_INTERFACE(x86_eri_v2) {
        void (*read)(conf_object_t *listener, eri_v2_transaction_t *data);
        void (*write)(conf_object_t *listener, eri_v2_transaction_t *data);
};

#define X86_ERI_V2_INTERFACE "x86_eri_v2"

Description

The interface is used to read/writer external registers.

data (with type eri_v2_transaction_t) is owned by caller. Callee always fills field valid to cate transaction result. Field val contains the result of read method input for write method.

x86_exception

Name

x86_exception — raise x86 exceptions

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(x86_exception) {
        void (*DE_fault)(conf_object_t *cpu);

        void (*BR_fault)(conf_object_t *cpu);
        void (*UD_fault)(conf_object_t *cpu);
        void (*NM_fault)(conf_object_t *cpu);
        void (*DF_abort)(conf_object_t *cpu, const char *desc);

        void (*TS_fault)(conf_object_t *cpu, uint16 sel);
        void (*NP_fault)(conf_object_t *cpu, uint16 sel_vec, bool is_vec);

        void (*SS_fault)(conf_object_t *cpu, uint16 sel);
        void (*GP_fault)(conf_object_t *cpu, uint16 sel_vec, bool is_vec,
                         const char *desc);
        void (*PF_fault)(conf_object_t *cpu, linear_address_t laddr,
                         uint32 ecode);
        void (*MF_fault)(conf_object_t *cpu);
        void (*AC_fault)(conf_object_t *cpu);
        void (*XM_fault)(conf_object_t *cpu);
};
#define X86_EXCEPTION_INTERFACE "x86_exception"

Python

import simics

class simics.x86_exception_interface_t(DE_fault=None, BR_fault=None,
        UD_fault=None, NM_fault=None, DF_abort=None, TS_fault=None,
        NP_fault=None, SS_fault=None, GP_fault=None, PF_fault=None,
        MF_fault=None, AC_fault=None, XM_fault=None)

Description

This interface is internal and may change without notice.

The methods in this interface are used to raise exceptions from the instrumentation replace or user decoder functionality (it is illegal to invoke these methods from any other context). The methods perform longjmps and do not return.

Execution Context

The methods in this interface may only be called from user decoder service routines.

x86_exception_query

Name

x86_exception_query — interface for x86 specific exception queries

Synopsis

C and DML

#include <simics/arch/x86-instrumentation.h> // in C
import "simics/arch/x86-instrumentation.dml"; // in DML

SIM_INTERFACE(x86_exception_query) {
        uint8 (*vector)(
                conf_object_t *cpu, exception_handle_t *handle);
        x86_exception_source_t (*source)(
                conf_object_t *cpu, exception_handle_t *handle);
        uint32 (*error_code)(
                conf_object_t *cpu, exception_handle_t *handle);
};
#define X86_EXCEPTION_QUERY_INTERFACE "x86_exception_query"

Python

import simics

class simics.x86_exception_query_interface_t(vector=None, source=None,
        error_code=None)

Description

The x86_exception_query interface is used to query information about an exception for the x86 architecture and should be used from a cpu_exception_cb_t callback.

The vector method is used to get the exception vector. The source method is used to get the source of the exception and the error_code method is used to get the error code of the exception.

Execution Context

Cell Context for all methods, but must be called from a callback receiving a handle of type exception_handle_t.

x86_execution_mode_t, x86_execution_mode

Name

x86_execution_mode_t, x86_execution_mode — provides insight into the processor execution mode

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef struct x86_execution_mode {
        uint64 ac:1,
               seam:1,
               sgx:1,
               smm:1,
               vmx_root:1,
               vmx_non_root:1;
} x86_execution_mode_t;

SIM_INTERFACE(x86_execution_mode) {
        x86_execution_mode_t (*get_execution_mode)(conf_object_t *obj);
};

#define X86_EXECUTION_MODE_INTERFACE "x86_execution_mode"

Python

import simics

class simics.x86_execution_mode_t
class simics.x86_execution_mode_interface_t(get_execution_mode=None)

Description

The interface provides insight into the processor execution mode.

The get_execution_mode returns the current processor execution mode. Note that several fields in the returned x86_execution_mode_t structure can be non-zero simultaneously.

Execution Context

Cell Context for all methods.

x86_external_reset

Name

x86_external_reset — interface that notifies clients of reset

Synopsis

C and DML


SIM_INTERFACE(x86_external_reset) {
        void (*triple_fault_event)(conf_object_t *obj);
};
#define X86_EXTERNAL_RESET_INTERFACE "x86_external_reset"

Description

The interface is used to notify platform devices about reset events that happened inside a CPU.

The triple_fault_event method is used to inform obj that a reset happened due to a triple fault.

Execution Context

Cell Context for all methods.

x86_instruction_query

Name

x86_instruction_query — interface for x86 specific instrumentation queries

Synopsis

C and DML

#include <simics/arch/x86-instrumentation.h> // in C
import "simics/arch/x86-instrumentation.dml"; // in DML

SIM_INTERFACE(x86_instruction_query) {
        linear_address_t (*linear_address)(conf_object_t *cpu,
                                           instruction_handle_t *handle);
};

#define X86_INSTRUCTION_QUERY_INTERFACE "x86_instruction_query"

Python

import simics

class simics.x86_instruction_query_interface_t(linear_address=None)

Description

The x86_instruction_query interface is used to query additional information about an instruction for the x86 architecture and is a complement to the cpu_instruction_query interface.

The linear_address is used to get the linear address of the instruction.

Execution Context

Threaded Context for all methods, but must be called from a callback receiving a handle of type instruction_handle_t.

x86_instrumentation_subscribe

Name

x86_instrumentation_subscribe — interface for x86 specific instrumentation subscribe

Synopsis

C and DML

#include <simics/arch/x86-instrumentation.h> // in C
import "simics/arch/x86-instrumentation.dml"; // in DML

SIM_INTERFACE(x86_instrumentation_subscribe) {
        cpu_cb_handle_t *(*register_mode_switch_cb)(
                conf_object_t *cpu, conf_object_t *connection,
                x86_mode_switch_cb_t cb,
                lang_void *user_data);
        cpu_cb_handle_t *(*register_illegal_instruction_cb)(
                conf_object_t *NOTNULL cpu,
                conf_object_t *connection,
                cpu_instruction_decoder_cb_t cb,
                cpu_instruction_disassemble_cb_t disass_cb,
                lang_void *data);
};
#define X86_INSTRUMENTATION_SUBSCRIBE_INTERFACE \
        "x86_instrumentation_subscribe"

Python

import simics

class simics.x86_instrumentation_subscribe_interface_t(register_mode_switch_cb=None,
        register_illegal_instruction_cb=None)

Description

The x86_instrumentation_subscribe interface is an x86 specific complement to the cpu_instrumentation_subscribe interface. It is implemented by processor objects that support instrumentation. It has the same requirements as the cpu_instrumentation_subscribe interface.

The register_mode_switch_cb method is used to register a callback that is called whenever the processor cpu changes execution mode. The connection argument is the user object that registers the callback. This object will be passed to the callback when it is called. cb is the callback and user_data is user data for the callback. The callback has the type [x86_mode_switch_cb_t].

register_illegal_instruction_cb lets a user to implement new instructions. The cb argument is a callback function that will be called every time Simics does not decode an instruction. Allows new x86 instructions to be implemented which otherwise cause illegal instruction exception. Compared to register_instruction_decoder_cb method of cpu_instrumentation_subscribe interface this interface cannot change any instruction that correctly decodes according to the existing instruction set architecture. From this callback the user can accept the instruction or deny it. In most cases this only happens once per instruction address since Simics usually caches decoding results in the internal instruction cache. If the cache is flushed the callback may be called again. This instrumentation feature (if used alone) does not prevent VMP execution since illegal instructions cause exit while running inside VMP mode. The type of the callback is cpu_instruction_decoder_cb_t

The instruction bytes are read by using the get_instruction_bytes method of the cpu_instruction_query interface together with the iq_handle. The returned value is of a cpu_bytes_t type. To access the bytes use the data and the size members in the returned value.

If the decoder requires more bytes (i.e., because the new instruction is longer), a negative integer value should be returned by the cb function, indicating the number of bytes needed. For example, if the available bytes are 3 but the decoder need at least 4 bytes, -4 should be returned. The callback will then be called again with more available bytes (this can be repeated if the new instruction requires even more bytes at this point). Note that requesting more data than actual needed can cause spurious page faults if the data crosses a page boundary.

If the instruction is accepted by the callback a positive integer number should be returned corresponding to the length of the instruction. In this case the register_emulation_cb method of the cpu_instruction_decoder interface should be called to set the actual (user) function that Simics will call each time the instruction is executed.

If the cb callback should ignore the instruction the number 0 should be returned. This means that any other registered decoder will have a chance to decode the instruction. If no decoder accepts it, Simics will generate illegal instruction exception.

The register_emulation_cb method also needs the decoder_handle which is available in the dedoder callback. For more information, see the documentation of the cpu_instruction_decoder interface.

A disass_cb argument should also be passed to the register_illegal_instruction_cb method. This function is called every time Simics wants to disassemble an instruction. For every accepted instruction a corresponding disassembly string should be returned by this function. The callback should be of type cpu_instruction_disassemble_cb_t.

obj is the object registering the register_illegal_instruction_cb and cpu is the processor disassembling the instruction. addr is the address of the instruction in a generic form. This means that it is typically a physical address or a logical address depending on the context of the disassembling. The address can be used for offset calculations, i.e., displaying an absolute address instead of a relative one, for example in a branch instruction. The bytes argument should be used to read instruction bytes. The return value is of type tuple_int_string_t and should be filled with the instruction length and an allocated (e.g., malloc) string representing the disassembly of the instruction. The ownership of the string is transferred to the calling environment which will free it when it is no longer needed.

If too few bytes are passed for the instruction to be disassembled a negative value should be returned for the length indicating the needed bytes. The disass_cb is then called again with more bytes. If the instruction is rejected a length of 0 should be returned and the string should be set to NULL.

To remove the callback used one of the methods remove_callback or remove_connection_callbacks in the cpu_instrumentation_subscribe interface.

The callback can also be enabled and disabled with the corresponding methods in the cpu_instrumentation_subscribe interface.

Execution Context

Global Context for all methods.

x86_instrumentation_subscribe_v2

Name

x86_instrumentation_subscribe_v2 — interface for x86 specific instrumentation subscribe

Synopsis

C and DML

#include <simics/arch/x86-instrumentation.h> // in C
import "simics/arch/x86-instrumentation.dml"; // in DML

SIM_INTERFACE(x86_instrumentation_subscribe_v2) {
        cpu_cb_handle_t *(*register_mode_enter_cb)(
                conf_object_t *cpu, conf_object_t *connection,
                x86_mode_switch_cb_t cb,
                lang_void *user_data);
        cpu_cb_handle_t *(*register_mode_leave_cb)(
                conf_object_t *cpu, conf_object_t *connection,
                x86_mode_switch_cb_t cb,
                lang_void *user_data);
        cpu_cb_handle_t *(*register_illegal_instruction_cb)(
                conf_object_t *NOTNULL cpu,
                conf_object_t *connection,
                cpu_instruction_decoder_cb_t cb,
                cpu_instruction_disassemble_cb_t disass_cb,
                lang_void *data);
};

#define X86_INSTRUMENTATION_SUBSCRIBE_V2_INTERFACE \
        "x86_instrumentation_subscribe_v2"

Python

import simics

class simics.x86_instrumentation_subscribe_v2_interface_t(register_mode_enter_cb=None,
        register_mode_leave_cb=None, register_illegal_instruction_cb=None)

Description

The x86_instrumentation_subscribe_v2 interface is an x86 specific complement to the cpu_instrumentation_subscribe interface. It is implemented by x86 processor objects that support instrumentation. It works in the same way as the cpu_instrumentation_subscribe interface, and the methods remove/enabled/disable_callback and remove/enabled/disable_connection_callbacks in that interface should be used to operate on callbacks in this interface as well, using the cpu_cb_handle_t handle.

The v2 variant fixes some problems with the x86_instrumentation_subscribe. In that interface, the register_mode_switch_cb method was invoked when the new mode had already been set up. This means that if you need to do some bookkeeping when leaving a mode, that mode had already been switched out in the callback. For instance, descriptor registers has already been changed.

This interface adds two methods to handle this, register_mode_leave_cb and register_mode_enter_cb. The leave variant is called when the processor still is located in the previous mode, but about to enter a new mode, and the enter variant is called when the processor has switched to the new mode (corresponds to the register_mode_switch_cb in the old x86_instrumentation_subscribe interface).

The register_illegal_instruction_cb works as in the x86_instrumentation_subscribe interface.

Execution Context

Global Context for all methods.

x86_pin_t, tagged_linear_address_t, x86

Name

x86_pin_t, tagged_linear_address_t, x86 — x86 specific functionality

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef enum {
        Pin_Init,
        Pin_Smi,
        Pin_Nmi,
        Pin_Ignne,
        Pin_Mcerr,
        Pin_Cmci
        /* Do not add new pins. Instead, define individual signal ports */
} x86_pin_t;

typedef struct {
        bool             valid;
        linear_address_t addr;
} tagged_linear_address_t;

SIM_INTERFACE(x86) {
        void (*set_pin_status)(conf_object_t *obj,
                               x86_pin_t pin, int status);
        void (*start_up)(conf_object_t *obj, uint32 start_address);
        int  (*interrupt)(conf_object_t *obj,
                          int (*ack)(conf_object_t *obj),
                          conf_object_t *data);
        void (*uninterrupt)(conf_object_t *obj,
                            int (*ack)(conf_object_t *obj));
        int  (*has_pending_interrupt)(conf_object_t *obj);
        int  (*has_waiting_interrupt)(conf_object_t *obj);
        tagged_linear_address_t (*logical_to_linear)(conf_object_t *obj,
                                                     int segment,
                                                     logical_address_t addr);
        physical_address_t (*linear_to_physical)(conf_object_t *obj,
                                                 data_or_instr_t d_or_i,
                                                 linear_address_t addr);
        void (*enter_acpi_c2_state)(conf_object_t *obj);
};

#define X86_INTERFACE "x86"

Python

import simics

simics.Pin_Mcerr
simics.Pin_Cmci
simics.Pin_Smi
simics.Pin_Init
simics.Pin_Nmi
simics.Pin_Ignne
class simics.tagged_linear_address_t(valid=False, addr=0)
class simics.x86_interface_t(set_pin_status=None, start_up=None, interrupt=None,
        uninterrupt=None, has_pending_interrupt=None,
        has_waiting_interrupt=None, logical_to_linear=None,
        linear_to_physical=None, enter_acpi_c2_state=None)

Description

The x86 interface exports functionality used by several other objects to interact with the processor. The set_pin_status function is used to set/clear certain processor pins.

The start_up function is used by the local APIC to bring the processor obj out of the waiting for start-up IPI state, with a start address of start_address.

The interrupt function tells the CPU that an interrupt is waiting. The interrupt vector number is given by the ack callback function. It is not allowed to call the ack callback during the interrupt call itself. The data object should implement the interrupt_cpu interface. Note that the interrupt_cpu interface defines the ack function, which should be the same as the ack argument. It is recommended that new implementations does not use rely on the ack argument, but rather looks up the callback through the interrupt_cpu interface from the object given by the data argument. The interrupt function returns 1 if the interrupt is accepted, and 0 if it is not accepted because there is already an interrupt queued up to be processed. If 0 is returned, the caller should retry the call after one step. It should wait one step since the handling of an interrupt takes one step.

If a checkpoint was taken when an interrupt was waiting, the acknowledge callback function can be recovered by looking up the interrupt_cpu interface at the APIC object given in the data parameter.

If the interrupt was cancelled before it was acknowledged, the uninterrupt function is used. It is also called by the acknowledge callback. Thus, each invocation of interrupt is followed by exactly one call to uninterrupt at all times. The ack parameter is unused and should be ignored. When the processor is reset, it forgets a waiting interrupt so it is not necessary to call uninterrupt during a reset.

The functions in the interrupt_ack interface provides almost the same functionality as the interrupt and uninterrupt functions in this interface. The only difference is that the interrupt function in this interface returns 0 when the interrupt cannot be handled which allows the device to retry later.

The has_pending_interrupt and has_waiting_interrupt calls should return information about interrupts in progress. An interrupt is said to be pending if it is acked by the processor and will be taken before execution of the next instruction. An interrupt is waiting if the logical interrupt line is high, but the interrupt has not yet been acked. These functions are used for sanity checks by the APIC. The APIC should keep track of posted interrupts by itself. These functions return 1 if an interrupt is pending/waiting, and 0 otherwise.

The logical_to_linear function returns the translated linear address from the given logical address and segment register number. The function uses the current content of control registers and segment registers to calculate the linear address. The tagged return value is marked invalid if no valid translation exists, for example if the passed logical address is beyond the segment limit of the passed segment or if it is non-canonical. The encoding of segment is 0 for ES, 1 for CS, 2 for SS, 3 for DS, 4 for FS, and 5 for GS.

The linear_to_physical function returns the physical address corresponding to the given linear address. The function uses the current content of control registers, TLBs and possibly page tables to calculate the physical address. A return value of -1 signals that no valid mapping exists.

enter_acpi_c2_state is called from the chipset power module to request the CPU to enter an energy-saving state.

Execution Context

Cell Context for all methods.

x86_alignment_t, x86_read_physical_ret_t, x86_memory_access

Name

x86_alignment_t, x86_read_physical_ret_t, x86_memory_access — access x86 memory from user decoder service routines

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef enum {
        X86_Alignment_Not_Required,
        X86_Alignment_Required
} x86_alignment_t;

typedef struct {
        uint64 value;
        exception_type_t exception;
} x86_read_physical_ret_t;

SIM_INTERFACE(x86_memory_access) {
        uint64 (*read_logical)(
                conf_object_t *cpu,
                logical_address_t offs,
                x86_seg_t seg,
                unsigned len,
                x86_processor_mode_t mode,
                x86_access_type_t access_type);
#if !defined(PYWRAP)
        void (*read_logical_buf)(
                conf_object_t *cpu,
                logical_address_t offs,
                x86_seg_t seg,
                unsigned len,
                void *p,
                x86_processor_mode_t mode,
                x86_access_type_t access_type,
                x86_alignment_t alignment);
#endif
        void (*write_logical)(
                conf_object_t *cpu,
                logical_address_t offs,
                x86_seg_t seg,
                unsigned len,
                uint64 val,
                x86_processor_mode_t mode,
                x86_access_type_t access_type);
#if !defined(PYWRAP)
        void (*write_logical_buf)(
                conf_object_t *cpu,
                logical_address_t offs,
                x86_seg_t seg,
                unsigned len,
                const void *p,
                x86_processor_mode_t mode,
                x86_access_type_t access_type,
                x86_alignment_t alignment);
#endif
};
#define X86_MEMORY_ACCESS_INTERFACE "x86_memory_access"

Python

import simics

simics.X86_Alignment_Required
simics.X86_Alignment_Not_Required
class simics.x86_memory_access_interface_t(read_logical=None, write_logical=None)

Description

This interface is internal and may change without notice.

The x86_memory_access interface is used to access memory from user decoder service routines. If an exception condition occurs, a longjmp is taken. The interface methods may only be invoked from user decoder service routines.

Execution Context

The methods in this interface may only be called from user decoder service routines.

x86_memory_operation

Name

x86_memory_operation — access memory from a user instruction

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(x86_memory_operation) {
        uint64 (*read_logical)(
                conf_object_t *cpu,
                x86_seg_t seg,
                logical_address_t offs,
                unsigned size,
                x86_processor_mode_t mode,
                x86_access_type_t access_type);
#if !defined(PYWRAP)
        void (*read_logical_buf)(
                conf_object_t *cpu,
                uint8 *dst,
                x86_seg_t seg,
                logical_address_t offs,
                unsigned size,
                x86_processor_mode_t mode,
                x86_access_type_t access_type);
#endif
        void (*write_logical)(
                conf_object_t *cpu,
                uint64 val,
                x86_seg_t seg,
                logical_address_t offs,
                unsigned size,
                x86_processor_mode_t mode,
                x86_access_type_t access_type);
#if !defined(PYWRAP)
        void (*write_logical_buf)(
                conf_object_t *cpu,
                const uint8 *src,
                x86_seg_t seg,
                logical_address_t offs,
                unsigned size,
                x86_processor_mode_t mode,
                x86_access_type_t access_type);
#endif
        x86_read_physical_ret_t (*read_physical)(
                conf_object_t *cpu,
                physical_address_t address,
                unsigned size,
                x86_access_type_t access_type);
#if !defined(PYWRAP)
        exception_type_t (*read_physical_buf)(
                conf_object_t *cpu,
                uint8 *dst,
                physical_address_t address,
                unsigned size,
                x86_access_type_t access_type);
#endif
        exception_type_t (*write_physical)(
                conf_object_t *cpu,
                uint64 val,
                physical_address_t address,
                unsigned size,
                x86_access_type_t access_type);
#if !defined(PYWRAP)
        exception_type_t (*write_physical_buf)(
                conf_object_t *cpu,
                const uint8 *src,
                physical_address_t address,
                unsigned size,
                x86_access_type_t access_type);
#endif
};

#define X86_MEMORY_OPERATION_INTERFACE "x86_memory_operation"

Description

The x86_memory_operation interface is used to access memory from a user instruction. See the cpu_instrumentation_subscribe and cpu_instruction_decoder for more information. It is designed to be more efficient than the x86_memory_access. If an exception condition occurs, a longjmp is taken. The interface methods may only be invoked from user instruction.

Execution Context

Cell Context for all methods, but must be called from an invoke function set by the register_emulation_cb method in the cpu_instruction_decoder interface.

x86_memory_query

Name

x86_memory_query — interface for x86 specific memory instrumentation queries

Synopsis

C and DML

#include <simics/arch/x86-instrumentation.h> // in C
import "simics/arch/x86-instrumentation.dml"; // in DML

SIM_INTERFACE(x86_memory_query) {
        linear_address_t (*linear_address)(conf_object_t *cpu,
                                           memory_handle_t *handle);
        x86_seg_t (*segment)(conf_object_t *cpu, memory_handle_t *handle);
        x86_access_type_t (*access_type)(conf_object_t *obj,
                                         memory_handle_t *handle);
        x86_memory_type_t (*memory_type)(conf_object_t *obj,
                                         memory_handle_t *handle);
};

#define X86_MEMORY_QUERY_INTERFACE "x86_memory_query"

Python

import simics

class simics.x86_memory_query_interface_t(linear_address=None, segment=None,
        access_type=None, memory_type=None)

Description

The x86_memory_query interface is used to query additional information about an instruction for the x86 architecture and is a complement to the cpu_memory_query interface.

The linear_address is used to get the linear address of the access.

The segment function is used to get the segment register used in the access.

The access_type returns the x86_access_type_t of the access and the memory_type returns the x86_memory_type_t of the access.

Execution Context

Cell Context for all methods, but must be called from a callback receiving a handle of type memory_handle_t.

x86_monitor

Name

x86_monitor — interface for supporting MONITOR/MWAIT instructions

Synopsis

C and DML


SIM_INTERFACE(x86_monitor) {
    bool (*arm)(conf_object_t *obj, conf_object_t *listener,
                physical_address_t start_address, physical_address_t length);
    bool (*disarm)(conf_object_t *obj, conf_object_t *listener);
};

#define X86_MONITOR_INTERFACE "x86_monitor"

Description

This interface is meant to be implemented by an uncore device to support implementation of MONITOR/MWAIT instruction pair. A listener (e.g. a cpu) uses this interface to setup monitored write-back memory range. All listeners subscribed to a particular write-back memory range will be notified via x86_monitor_notification when a memory write transaction hits the monitored memory range.

This interface is internal and may change without notice.

The arm method is to subscribe for notifications about writes to a write-back memory range starting from start_address1 up to start_address + length - 1, returns true on success. Thedisarmunsubscribeslistener`, so the latter won’t be notified about writes to a monitored memory range, returns true on success.

Execution Context

Cell Context for all methods.

x86_monitor_notification

Name

x86_monitor_notification — interface for getting a callback for writes to write-ack memory

Synopsis

C and DML


SIM_INTERFACE(x86_monitor_notification) {
        bool (*notify)(conf_object_t *obj);
};

#define X86_MONITOR_NOTIFICATION_INTERFACE "x86_monitor_notification"

Description

This interface is meant to be implemented by a processor to support complex cases of MONITOR/MWAIT instruction pair. A processor will be notified about writes to the monitored write-back memory range through the notify method. The return value indicates whether to unsubscribe from notifications or not. See x86_monitor to find out how to subscribe for write notifications to a write-back memory range.

Execution Context

Cell Context.

x86_msr_access_type_t, x86_msr_ret_t, x86_msr_getter_ret_t, x86_msr

Name

x86_msr_access_type_t, x86_msr_ret_t, x86_msr_getter_ret_t, x86_msr — x86 msr interface

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef enum {
        /* Access from a rdmsr/wrmsr instruction */
        Sim_X86_Msr_Instruction_Access = Sim_Gen_Spr_Instruction_Access,

        /* Access through attribute */
        Sim_X86_Msr_Attribute_Access = Sim_Gen_Spr_Attribute_Access,

        /* Access through int_register interface */
        Sim_X86_Msr_Int_Register_Access = Sim_Gen_Spr_Int_Register_Access,

        /* Access during VMX entry/exit */
        Sim_X86_Msr_VMX_Access,

        /* Architectural access without side effects within the CPU model, only
           reads or writes the register value. However, if it is sent to the
           platform as a non-inquiry access, that may cause side effects. */
        Sim_X86_Msr_Architectural_Access
} x86_msr_access_type_t;

typedef enum {
        Sim_X86_Msr_Ok = Sim_Gen_Spr_Ok,        /* Access was OK */
        Sim_X86_Msr_GP_Fault,                   /* Raise #GP fault */
        Sim_X86_Msr_Not_Handled                 /* Pass on to next handler */
} x86_msr_ret_t;

typedef struct {
        x86_msr_ret_t status;
        uint64 value;
} x86_msr_getter_ret_t;

SIM_INTERFACE(x86_msr) {
        void (*register_handlers)(
                conf_object_t *cpu,
                int64 number,
                x86_msr_getter_func_t getter,
                lang_void *getter_data,
                x86_msr_setter_func_t setter,
                lang_void *setter_data,
                const char *name);
        void (*unregister_handlers)(
                conf_object_t *cpu,
                int64 number);
        x86_msr_getter_ret_t (*get)(
                conf_object_t *cpu,
                int64 number,
                x86_msr_access_type_t type);
        x86_msr_ret_t (*set)(
                conf_object_t *cpu,
                int64 number,
                uint64 value,
                x86_msr_access_type_t type);
        const char *(*get_name)(
                conf_object_t *cpu,
                int64 number);
        int64 (*get_number)(
                conf_object_t *cpu,
                const char *name);
        attr_value_t (*get_all_valid_numbers)(
                conf_object_t *cpu);
};
#define X86_MSR_INTERFACE "x86_msr"

Python

import simics

simics.Sim_X86_Msr_Attribute_Access
simics.Sim_X86_Msr_Architectural_Access
simics.Sim_X86_Msr_Int_Register_Access
simics.Sim_X86_Msr_Instruction_Access
simics.Sim_X86_Msr_VMX_Access
simics.Sim_X86_Msr_GP_Fault
simics.Sim_X86_Msr_Ok
simics.Sim_X86_Msr_Not_Handled
class simics.x86_msr_getter_ret_t(status=0, value=0)
class simics.x86_msr_interface_t(register_handlers=None, unregister_handlers=None,
        get=None, set=None, get_name=None, get_number=None,
        get_all_valid_numbers=None)

Description

The register_handlers function will register get and set functions that will be called every time a read or write access is made to the MSR with number msr.

typedef x86_msr_getter_ret_t (*x86_msr_getter_func_t)(
        conf_object_t *cpu,
        int64 number,
        x86_msr_access_type_t type,
        lang_void *user_data);

typedef x86_msr_ret_t (*x86_msr_setter_func_t)(
        conf_object_t *cpu,
        int64 spr_number,
        uint64 value,
        x86_msr_access_type_t type,
        lang_void *user_data);

The type parameter in the get and set functions is one of the following, depending on where from the access originated.

The getter function returns the status just like the setter together with the read MSR value. A getter or setter may return the Sim_X86_MSR_Not_Handled return code, in which case the access will pass through to the earlier registered handler (or the default handler if there is no earlier registered handler).

The function unregister_handlers will remove any non-default handlers for a particular MSR.

The get and set functions get and set MSRs, using both model default MSR handlers and handlers installed through this interface.

The function get_name takes number as parameter and returns the name of the MSR.

The function get_number takes the name and returns the MSR number.

The function get_all_valid_numbers returns a list of integers corresponding to all the valid MSRs, including both model default MSRs and MSRs installed through this interface.

Execution Context

Cell Context for all methods.

x86_pkg_cstate

Name

x86_pkg_cstate — interface used with x86 power states

Synopsis

C and DML

#include <simics/devs/x86-cstate-iface.h> // in C
import "simics/devs/x86-cstate-iface.dml"; // in DML

SIM_INTERFACE(x86_pkg_cstate) {
        x86_cstate_t (*get_pkg_cstate)(conf_object_t *cpu_obj);
        void (*set_pkg_cstate)(conf_object_t *cpu_obj,
                           uint32 state, uint32 sub_state);
        void (*pkg_cstate_update)(conf_object_t *cpu_obj,
                           bool notify);
};

#define X86_PKG_CSTATE_INTERFACE "x86_pkg_cstate"

Python

import simics

class simics.x86_pkg_cstate_interface_t(get_pkg_cstate=None, set_pkg_cstate=None,
        pkg_cstate_update=None)

Description

The methods in this interface can be used to read or change the current power state the CPU is in. A state value of 0 corresponds to C0, a value of 1 corresponds to C1, etc. HLT will be reported as state 1, substate 0. MWAIT will reported based upon the eax hint, decoded as state = (eax [7:4] + 1) mid 16, substate = eax[3:0].

pkg_cstate_update will perform side-effects such as putting the processor to sleep or waking it up, and call the cstate notification listeners.

Execution Context

Cell Context for all methods.

x86_rar_interrupt

Name

x86_rar_interrupt — interface for providing CPU with RAR interrupt info

Synopsis

C and DML


SIM_INTERFACE(x86_rar_interrupt) {
    bool (*is_rar_requested)(conf_object_t *obj);
    int (*ack_rar)(conf_object_t *obj);
};
#define X86_RAR_INTERRUPT_INTERFACE "x86_rar_interrupt"

Description

Methods of this interface are used to provide CPU with information about RAR interrupt status from APIC

The is_rar_requested method returns whether a RAR event is pending.

The ack_rar method acknowledges RAR interrupt.

Execution Context

Cell Context for all methods.

x86_xmode_info_t, ymm_reg_t, xmm_reg_t, x86_exec_mode_t, x86_detailed_exec_mode_t, x86_fpu_reg_t, x86_fpu_env_t, x86_seg_t, x86_reg_access

Name

x86_xmode_info_t, ymm_reg_t, xmm_reg_t, x86_exec_mode_t, x86_detailed_exec_mode_t, x86_fpu_reg_t, x86_fpu_env_t, x86_seg_t, x86_reg_access — access x86 register state

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef struct {
        bool efer_lma;
        bool cs_l;
        bool cs_d;
        bool ss_b;
} x86_xmode_info_t;

typedef struct {
        uint64 llo64;
        uint64 lhi64;
        uint64 hlo64;
        uint64 hhi64;
} ymm_reg_t;

typedef struct {
        uint64 lo64;
        uint64 hi64;
} xmm_reg_t;

typedef enum {
        X86_Exec_Mode_Real,
        X86_Exec_Mode_V86,
        X86_Exec_Mode_Prot,
        X86_Exec_Mode_Compat,
        X86_Exec_Mode_64
} x86_exec_mode_t;

typedef enum {
        X86_Detailed_Exec_Mode_Real_16,
        X86_Detailed_Exec_Mode_Real_32,
        X86_Detailed_Exec_Mode_V86,
        X86_Detailed_Exec_Mode_Protected_16,
        X86_Detailed_Exec_Mode_Protected_32,
        X86_Detailed_Exec_Mode_Protected_64,
        X86_Detailed_Exec_Mode_Compatibility_16,
        X86_Detailed_Exec_Mode_Compatibility_32,
} x86_detailed_exec_mode_t;

typedef struct {
        uint64 low;
        uint16 high;
} x86_fpu_reg_t;

typedef struct {
        uint16 cw;
        uint16 sw;
        uint16 tag;
        uint16 opc;
        uint64 last_instr_ptr;
        uint64 last_operand_ptr;
        uint16 last_instr_sel;
        uint16 last_operand_sel;
        uint32 pad;
} x86_fpu_env_t;

typedef enum {
        X86_Seg_ES,
        X86_Seg_CS,
        X86_Seg_SS,
        X86_Seg_DS,
        X86_Seg_FS,
        X86_Seg_GS,
        X86_Seg_LDTR,
        X86_Seg_TR,
        X86_Seg_None,
} x86_seg_t;

SIM_INTERFACE(x86_reg_access) {
        uint64 (*get_gpr)(conf_object_t *cpu, unsigned index);
        void (*set_gpr)(conf_object_t *cpu, unsigned index, uint64 val);

        uint64 (*get_rip)(conf_object_t *cpu);
        void (*set_rip)(conf_object_t *cpu, uint64 rip);

        uint64 (*get_rflags)(conf_object_t *cpu);
        void (*set_rflags)(conf_object_t *cpu, uint64 rflags);

        /* Possibly faster method for setting only cf,pf,af,zf,sf,of */
        void (*set_status_flags)(conf_object_t *cpu, uint16 flags);

        /* Regular segment registers */
        x86_seg_reg_t (*get_seg)(conf_object_t *cpu, x86_seg_t n);
        void (*set_seg)(conf_object_t *cpu, x86_seg_t n, x86_seg_reg_t seg);

        /* IDTR and GDTR */
        x86_system_seg_reg_t (*get_system_seg)(conf_object_t *cpu,
                                               x86_system_seg_t n);
        void (*set_system_seg)(conf_object_t *cpu, x86_system_seg_t n,
                               x86_system_seg_reg_t seg);

        /* Control registers */
        uint64 (*get_cr)(conf_object_t *cpu, x86_cr_t n);
        void (*set_cr)(conf_object_t *cpu, x86_cr_t n, uint64 val);
        uint64 (*get_efer)(conf_object_t *cpu);
        void (*set_efer)(conf_object_t *cpu, uint64 efer);
        uint64 (*get_xcr)(conf_object_t *cpu, x86_xcr_t n);
        void (*set_xcr)(conf_object_t *cpu, x86_xcr_t n, uint64 val);

        /* x87 FPU */
        x86_fpu_reg_t (*get_freg)(conf_object_t *cpu, unsigned index);
        void (*set_freg)(conf_object_t *cpu, unsigned index, x86_fpu_reg_t freg);
        x86_fpu_env_t (*get_fpu_env)(conf_object_t *cpu);
        void (*set_fpu_env)(conf_object_t *cpu, x86_fpu_env_t state);

        /* SIMD */
        xmm_reg_t (*get_xmm)(conf_object_t *cpu, unsigned index);
        void (*set_xmm)(conf_object_t *cpu, unsigned index, xmm_reg_t val);
        ymm_reg_t (*get_ymm)(conf_object_t *cpu, unsigned index);
        void (*set_ymm)(conf_object_t *cpu, unsigned index, ymm_reg_t val);
        uint32 (*get_mxcsr)(conf_object_t *cpu);
        void (*set_mxcsr)(conf_object_t *cpu, uint32 mxcsr);

        /* Debug registers */
        uint64 (*get_dr)(conf_object_t *cpu, x86_dr_t n);
        void (*set_dr)(conf_object_t *cpu, x86_dr_t n, uint64 val);

        /* SMM */
        bool (*get_in_smm)(conf_object_t *cpu);
        void (*set_in_smm)(conf_object_t *cpu, bool val);
        uint64 (*get_smm_base)(conf_object_t *cpu);
        void (*set_smm_base)(conf_object_t *cpu, uint64 val);

        /* Monitor/Mwait */
        x86_monitor_info_t (*get_monitor_info)(conf_object_t *cpu);
        void (*set_monitor_info)(conf_object_t *cpu, x86_monitor_info_t val);
        x86_mwait_info_t (*get_mwait_info)(conf_object_t *cpu);
        void (*set_mwait_info)(conf_object_t *cpu, x86_mwait_info_t val);

        /* Non-register state */
        x86_activity_t (*get_activity_state)(conf_object_t *cpu);
        void (*set_activity_state)(conf_object_t *cpu, x86_activity_t val);
        x86_intstate_t (*get_interruptibility_state)(conf_object_t *cpu);
        void (*set_interruptibility_state)(conf_object_t *cpu,
                                           x86_intstate_t val);

        /* A debug exception is pending if triggered by the last instruction,
           but not yet taken. */
        x86_pending_debug_exc_t (*get_pending_debug_exc)(conf_object_t *cpu);
        void (*set_pending_debug_exc)(conf_object_t *cpu,
                                      x86_pending_debug_exc_t val);

        /* Derived state for fast/easy access */
        x86_xmode_info_t (*get_xmode_info)(conf_object_t *cpu);
        x86_exec_mode_t (*get_exec_mode)(conf_object_t *cpu);

        /* This is configuration info. No need for a set method. */
        uint32 (*get_mxcsr_mask)(conf_object_t *cpu);

        /* Extension state dirty bit modification (for XSAVE) */
        uint64 (*get_ext_state_dirty_bits)(conf_object_t *cpu);
        void (*or_ext_state_dirty_bits)(conf_object_t *cpu, uint64 dirty_bits);
        void (*and_ext_state_dirty_bits)(conf_object_t *cpu, uint64 dirty_bits);

        /* PDPTE registers used in PAE paging mode */
        uint64 (*get_pdpte)(conf_object_t *cpu, int num);
        void (*set_pdpte)(conf_object_t *cpu, int num, uint64 val);

        uint32 (*get_vmx_mode)(conf_object_t *cpu);
};
#define X86_REG_ACCESS_INTERFACE "x86_reg_access"

Python

import simics

class simics.x86_xmode_info_t(efer_lma=False, cs_l=False, cs_d=False, ss_b=False)
class simics.ymm_reg_t(llo64=0, lhi64=0, hlo64=0, hhi64=0)
class simics.xmm_reg_t(lo64=0, hi64=0)
simics.X86_Exec_Mode_Real
simics.X86_Exec_Mode_Compat
simics.X86_Exec_Mode_Prot
simics.X86_Exec_Mode_V86
simics.X86_Exec_Mode_64
simics.X86_Detailed_Exec_Mode_Real_16
simics.X86_Detailed_Exec_Mode_Real_32
simics.X86_Detailed_Exec_Mode_V86
simics.X86_Detailed_Exec_Mode_Protected_64
simics.X86_Detailed_Exec_Mode_Compatibility_32
simics.X86_Detailed_Exec_Mode_Protected_32
simics.X86_Detailed_Exec_Mode_Protected_16
simics.X86_Detailed_Exec_Mode_Compatibility_16
class simics.x86_fpu_reg_t(low=0, high=0)
class simics.x86_fpu_env_t(cw=0, sw=0, tag=0, opc=0, last_instr_ptr=0,
        last_operand_ptr=0, last_instr_sel=0, last_operand_sel=0, pad=0)
simics.X86_Seg_CS
simics.X86_Seg_LDTR
simics.X86_Seg_GS
simics.X86_Seg_FS
simics.X86_Seg_None
simics.X86_Seg_ES
simics.X86_Seg_DS
simics.X86_Seg_SS
simics.X86_Seg_TR
class simics.x86_reg_access_interface_t(get_gpr=None, set_gpr=None, get_rip=None,
        set_rip=None, get_rflags=None, set_rflags=None,
        set_status_flags=None, get_seg=None, set_seg=None,
        get_system_seg=None, set_system_seg=None, get_cr=None, set_cr=None,
        get_efer=None, set_efer=None, get_xcr=None, set_xcr=None,
        get_freg=None, set_freg=None, get_fpu_env=None, set_fpu_env=None,
        get_xmm=None, set_xmm=None, get_ymm=None, set_ymm=None,
        get_mxcsr=None, set_mxcsr=None, get_dr=None, set_dr=None,
        get_in_smm=None, set_in_smm=None, get_smm_base=None,
        set_smm_base=None, get_monitor_info=None, set_monitor_info=None,
        get_mwait_info=None, set_mwait_info=None, get_activity_state=None,
        set_activity_state=None, get_interruptibility_state=None,
        set_interruptibility_state=None, get_pending_debug_exc=None,
        set_pending_debug_exc=None, get_xmode_info=None, get_exec_mode=None,
        get_mxcsr_mask=None, get_ext_state_dirty_bits=None,
        or_ext_state_dirty_bits=None, and_ext_state_dirty_bits=None,
        get_pdpte=None, set_pdpte=None, get_vmx_mode=None)

Description

This interface is internal and may change without notice.

The x86_reg_acc_access interface can be used to access x86 register state in an efficient manner. The interface is intended to be used from user decoder service routines.

Execution Context

Cell Context for all methods.

x86_sai

Name

x86_sai — interface for retrieving current sai

Synopsis

C and DML


SIM_INTERFACE(x86_sai) {
    uint64  (*get_current_sai)(conf_object_t *obj);
};
#define X86_SAI_INTERFACE "x86_sai"

x86_smm

Name

x86_smm — custom SMRAM state save map

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(x86_smm) {
        void (*save_state)(conf_object_t *obj, conf_object_t *cpu);
        void (*restore_state)(conf_object_t *obj, conf_object_t *cpu);
};
#define X86_SMM_INTERFACE "x86_smm"

Python

import simics

class simics.x86_smm_interface_t(save_state=None, restore_state=None)

Description

This interface is internal and may change without notice.

The smm interface is used to implement a custom SMRAM state save map.

The save_state method is invoked when SMM mode is entered before any cpu state has been modified. The method should save the current cpu state to the SMRAM state save map.

The restore_state method is invoked during execution of the rsm instruction. The method should restore the cpu state from the SMRAM state save map.

The x86_smm_state interface implemented by the cpu can be used to facilitate cpu state changes and SMRAM access.

Execution Context

Cell Context for all methods.

x86_smm_event_type_t, x86_smm_phase_type_t, x86_smm_notification

Name

x86_smm_event_type_t, x86_smm_phase_type_t, x86_smm_notification — interface for registering callbacks on SMI

Synopsis

C and DML


typedef enum x86_smm_event_type {
    X86_Smm_Enter,
    X86_Smm_Leave
} x86_smm_event_type_t;

typedef enum x86_smm_phase_type {
    X86_Smm_Phase0,
    X86_Smm_Phase1
} x86_smm_phase_type_t;

SIM_INTERFACE(x86_smm_notification) {
        void (*notification)(conf_object_t *listener, conf_object_t *cpu,
                             x86_smm_event_type_t event,
                             x86_smm_phase_type_t phase);
};
#define X86_SMM_NOTIFICATION_INTERFACE "x86_smm_notification"

Description

Objects registered in processor’s smm_listeners attribute will be called via the notification method whenever the CPU’s enters and leaves SMI handler. SMI handler entry occurs on SMI processing. SMI handler exit occurs by RSM instruction execution. Please note that for both SMI handler entry and SMI handler exit notification method will be invoked twice: at the beginning of the entry/exit and at the end when CPU state was already modified. event argument says if entry/exit is performed, phase argument equals to X86_Smm_Phase0 for the beginning of the event and to X86_Smm_Phase1 for the end.

Execution Context

Cell Context.

x86_smm_state

Name

x86_smm_state — access x86 smm state

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(x86_smm_state) {
        void (*get_state)(conf_object_t *cpu, smm_reg_state_t *state);
        void (*set_state)(conf_object_t *cpu, const smm_reg_state_t *state);

        uint64 (*smram_read)(conf_object_t *obj,
                             unsigned smram_offs, unsigned len);
        void (*smram_write)(conf_object_t *obj,
                            unsigned smram_offs, unsigned len, uint64 val);
};
#define X86_SMM_STATE_INTERFACE "x86_smm_state"

Python

import simics

class simics.x86_smm_state_interface_t(get_state=None, set_state=None,
        smram_read=None, smram_write=None)

Description

This interface is internal and may change without notice.

The smm state interface is implemented by the cpu and is typically used by objects implementing the x86_smm interface.

The get_state method saves the cpu state in the state struct. This method is intended to be used during SMM entry.

The set_state method restores the cpu state from the state struct. This method is intended to be used during SMM exit.

The smram_read and smram_write methods can be used to access the SMRAM during SMM entry/exit.

Execution Context

Cell Context for all methods.

tagged_physical_address_t, x86_tlb

Name

tagged_physical_address_t, x86_tlb — used to communicate between x86 cpu and its TLB

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef struct {
        int                  valid;
        physical_address_t   paddr;
} tagged_physical_address_t;

SIM_INTERFACE(x86_tlb) {
        void (*flush_all)(conf_object_t *obj,
                            int keep_global_entries);
        void (*flush_page)(conf_object_t *obj,
                           linear_address_t laddr);
        int (*lookup)(conf_object_t *obj,
                      x86_memory_transaction_t *mem_tr);
        void (*add)(conf_object_t *obj,
                    processor_mode_t mode,
                    read_or_write_t read_or_write,
                    data_or_instr_t data_or_instr,
                    int global_page,
                    x86_memory_type_t pat_type,
                    x86_memory_type_t mtrr_type,
                    linear_address_t laddr,
                    physical_address_t paddr,
                    int page_size);
        tagged_physical_address_t (*itlb_lookup)(conf_object_t *obj,
                                                 linear_address_t laddr,
                                                 processor_mode_t mode);
        void (*set_pae_mode)(conf_object_t *obj, bool pae_mode);
};

#define X86_TLB_INTERFACE "x86_tlb"

Python

import simics

class simics.tagged_physical_address_t
class simics.x86_tlb_interface_t(flush_all=None, flush_page=None, lookup=None,
        add=None, itlb_lookup=None, set_pae_mode=None)

Description

The x86 tlb interface is used for communication between an x86 cpu and its TLB. The TLB is implemented as a separate class for greater flexibility. The TLB object does no memory operations itself.

All functions in the interface get the object implementing the interface as their first parameter.

flush_all is called when all TLB entries should be flushed. If keep_global_entries is set, then TLB entries with their global bit set should not be flushed.

flush_page is invoked when pages containing laddr are to be removed from the TLB.

lookup is used by the CPU when a memory access misses the STC. It must return true (non-zero) if and only if the memory operation specified by mem_tr hits the TLB and does not raise an exception. The mode, linear_address are valid when the method is invoked. The other fields passed through mem_tr are undefined. If the method returns true, the s.physical_address, pat_type, and mtrr_type fields of mem_tr must be updated by lookup.

An access that misses in lookup but does not raise a fault is inserted into the TLB with add. The page_size encoding is 0 for 4 kb pages, 1 for 2 Mb pages, and 2 for 4 Mb pages.

itlb_lookup is a simplified version of lookup used only for instruction TLB lookups. If the lookup is successful valid and paddr should be set, otherwise valid should be cleared.

set_pae_mode is invoked when the cpu changes the PAE enable bit.

It class implementing the interface must make sure that only addresses mapped in the TLB are present in the STCs.

This interface may be changed or replaced with an architecture independent interface in future versions of Simics.

Execution Context

Cell Context for all methods.

x86_tlb_attrs_t, x86_tlb_entry_t, x86_tlb_v2

Name

x86_tlb_attrs_t, x86_tlb_entry_t, x86_tlb_v2 — used to communicate between x86 cpu and its TLB

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef struct {
        access_t supervisor_access;
        access_t user_access;
        bool global_page;
        x86_memory_type_t pat_type;
        x86_memory_type_t mtrr_type;
        unsigned page_size_k;
} x86_tlb_attrs_t;

typedef struct {
        linear_address_t        linear_page_start;
        physical_address_t      physical_page_start;
        x86_tlb_attrs_t         attrs;
} x86_tlb_entry_t;

SIM_INTERFACE(x86_tlb_v2) {
        void (*flush_all)(conf_object_t *obj,
                          int keep_global_entries);
        void (*flush_page)(conf_object_t *obj,
                           linear_address_t laddr);
        const x86_tlb_entry_t *(*lookup)(conf_object_t *obj,
                                         x86_memory_transaction_t *mem_tr);
        void (*add)(conf_object_t *obj,
                    linear_address_t laddr,
                    physical_address_t paddr,
                    x86_tlb_attrs_t attrs);
        tagged_physical_address_t (*itlb_lookup)(conf_object_t *obj,
                                                 linear_address_t laddr,
                                                 processor_mode_t mode);
};

#define X86_TLB_V2_INTERFACE "x86_tlb_v2"

Python

import simics

class simics.x86_tlb_attrs_t
class simics.x86_tlb_entry_t
class simics.x86_tlb_v2_interface_t(flush_all=None, flush_page=None, lookup=None,
        add=None, itlb_lookup=None)

Description

The x86_tlb_v2 interface is used for communication between an x86 cpu and its TLB. The TLB is implemented as a separate class for greater flexibility. The TLB object does no memory operations itself.

flush_all is called when all TLB entries should be flushed. If keep_global_entries is set, then TLB entries with their global bit set should not be flushed.

flush_page is invoked when pages containing laddr are to be removed from the TLB.

lookup is used by the CPU when a memory access misses the STC. It returns the matching TLB entry if the memory operation specified in mem_tr hits the TLB and does not raise an exception. Otherwise NULL is returned. The mode, linear_address, and type fields in mem_tr need to be valid when the method is invoked. The other fields passed through mem_tr are not to be used by the method and can carry any value. If the method returns true, the s.physical_address, pat_type, and mtrr_type fields of mem_tr must be updated by lookup.

Pages are added to the TLB with add. The supervisor_access field in attrs argument specifies the allowed access types in supervisor mode and user_access in attrs specifies the allowed access types in user mode.

itlb_lookup is a simplified version of lookup used only for instruction TLB lookups. If the lookup is successful valid and paddr should be set, otherwise valid should be cleared.

The class implementing the interface must make sure that only addresses mapped in the TLB are present in the STCs.

Execution Context

Cell Context for all methods.

x86_tlb_attrs_v3_t, x86_tlb_entry_v3_t, x86_tlb_inv_t, x86_tlb_v3

Name

x86_tlb_attrs_v3_t, x86_tlb_entry_v3_t, x86_tlb_inv_t, x86_tlb_v3 — used to communicate between x86 cpu and its TLB

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

typedef struct {
        uint64 pte_attrs;
        x86_memory_type_t pat_type;
        x86_memory_type_t mtrr_type;
        unsigned page_size_k;
} x86_tlb_attrs_v3_t;

typedef struct {
        linear_address_t        linear_page_start;
        physical_address_t      physical_page_start;
        x86_tlb_attrs_v3_t      attrs;
} x86_tlb_entry_v3_t;

typedef enum {
        X86_Tlb_Invalidate_Page = 0,
        X86_Tlb_Invalidate_Address_Space = 4,
        X86_Tlb_Invalidate_Address_Space_NonGlobal = 1,
        X86_Tlb_Invalidate_All = 2,
        X86_Tlb_Invalidate_All_NonGlobal = 3
} x86_tlb_inv_t;

SIM_INTERFACE(x86_tlb_v3) {
        void (*add)(conf_object_t *obj,
                    uint64 hint,
                    linear_address_t laddr,
                    physical_address_t paddr,
                    x86_tlb_attrs_v3_t attrs);
        const x86_tlb_entry_v3_t *(*lookup)(conf_object_t *obj,
                                            uint64 hint,
                                            x86_memory_transaction_t *mem_tr);
        tagged_physical_address_t (*itlb_lookup)(conf_object_t *obj,
                                                 uint64 hint,
                                                 linear_address_t laddr,
                                                 processor_mode_t mode);
        void    (*invalidate_page)(conf_object_t *obj,
                                   uint64 hint,
                                   linear_address_t laddr);
        void    (*invalidate)(conf_object_t *obj,
                              uint32 type,
                              uint64 hint,
                              linear_address_t la);
};

#define X86_TLB_V3_INTERFACE "x86_tlb_v3"

Python

import simics

class simics.x86_tlb_attrs_v3_t(pte_attrs=0, pat_type=X86_None,
        mtrr_type=X86_None, page_size_k=0)
class simics.x86_tlb_entry_v3_t
simics.X86_Tlb_Invalidate_All_NonGlobal
simics.X86_Tlb_Invalidate_All
simics.X86_Tlb_Invalidate_Address_Space_NonGlobal
simics.X86_Tlb_Invalidate_Address_Space
simics.X86_Tlb_Invalidate_Page
class simics.x86_tlb_v3_interface_t(add=None, lookup=None, itlb_lookup=None,
        invalidate_page=None, invalidate=None)

Description

The x86_tlb_v3 interface is used for communication between an x86 cpu and its TLB. The TLB is implemented as a separate class for greater flexibility. The TLB object does no memory operations itself.

Pages are added to the TLB with add. Process context identifier, linear and physical address for translation specified using arguments hint, laddr and paddr correspondingly. The fields in attrs argument used for specification of allowed access types and additional page attributes.

lookup is used by the CPU when a memory access misses the STC. It returns the matching TLB entry if the memory operation specified in mem_tr hits the TLB and does not raise an exception. Otherwise NULL is returned. The hint argument specifies process context identifier. The mode, linear_address, and type fields in mem_tr need to be valid when the method is invoked. The other fields passed through mem_tr are not to be used by the method and can carry any value. If the method returns not NULL, the s.physical_address, pat_type, and mtrr_type fields of mem_tr must be updated by lookup.

itlb_lookup is a simplified version of lookup used only for instruction TLB lookups. If the lookup is successful valid and paddr should be set, otherwise valid should be cleared.

invalidate_page is used to remove from TLB page corresponding to given linear address specified by argument laddr in process context with identifier from argument hint.

invalidate is invoked when value of CR4.PCIDE bit set and CPU executes INVPCID instruction. Direct and indirect operands of instruction transferred in hint, la and type arguments. TLB entries flushed according to INVPCID instruction description. New invalidation type X86_Tlb_Invalidate_Address_Space added to implement flush_all function from previous interfaces. The method also can be used to flush required TLB entries in any required cases.

The class implementing the interface must make sure that only addresses mapped in the TLB are present in the STCs.

Execution Context

Cell Context for all methods.

x86_txt_chipset

Name

x86_txt_chipset — interface to Intel® Trusted Execution Technology (Intel® TXT)

Synopsis

C and DML


SIM_INTERFACE(x86_txt_chipset) {
        void (*signal_txt_msg)(conf_object_t *obj, txt_msg_t txt_msg,
                uint8 package_id);

        //supporting method to report platform capabilities to processor
        bool (*get_platform_feature)(conf_object_t *obj, int feature);

        //get list of cpus (threads) available in the current system
        attr_value_t (*get_platform_cpus)(conf_object_t *obj);
};

#define X86_TXT_CHIPSET_INTERFACE "x86_txt_chipset"

Description

This interface is meant to be implemented by Intel® Trusted Execution Technology (Intel® TXT) chipset. Refer to the “Intel® Trusted Execution Technology Software Development Guide Measured Launched Environment Developer’s Guide” document for explanation of interactions between CPU and Intel® TXT chipset.

This interface is internal and may change without notice.

The signal_txt_msg method is to send TXT-specific message to chipset. The get_platform_feature method is to query the chipset for supported Intel® TXT features. The get_platform_cpus method returns a list of all logical processors connected to the chipset.

Execution Context

Cell Context for all methods.

x86_unplug

Name

x86_unplug — interface for plug and and plug of CPU cores/threads

Synopsis

C and DML


SIM_INTERFACE(x86_unplug) {
        int (*unplug_core)(conf_object_t *obj);
        int (*replug_core)(conf_object_t *obj);
        int (*disable_ht_package)(conf_object_t *obj);
        int (*enable_ht_package)(conf_object_t *obj);
};
#define X86_UNPLUG_INTERFACE "x86_unplug"

Description

The methods of the interface are intended to be used by a platform to unplug (and optionally re-plug) CPU cores/threads, effectively hiding them from the #RESET/INIT signals.

This interface is internal and may change without notice.

The unplug_core method is to disable an operating core with all threads on it. The replug_core method is to enable a core previously unplugged with all threads on it. The disable_ht_package method is to disable every secondary thread. The enable_ht_package method is to enable every secondary thread.

Values returned from these methods indicate success (1) or failure (0).

Execution Context

Cell Context for all methods.

x86_unplug_v2

Name

x86_unplug_v2 — interface for plug and and plug of CPU cores/threads

Synopsis

C and DML


SIM_INTERFACE(x86_unplug_v2) {
        int (*unplug_core)(conf_object_t *obj);
        int (*replug_core)(conf_object_t *obj);
        int (*disable_core_ht)(conf_object_t *obj);
        int (*enable_core_ht)(conf_object_t *obj);
        bool (*core_is_plugged)(conf_object_t *obj);
        bool (*core_ht_is_enabled)(conf_object_t *obj);
        void (*set_alive_logical_processors)(conf_object_t *obj, int count);
        int (*get_alive_logical_processors)(conf_object_t *obj);
};
#define X86_UNPLUG_V2_INTERFACE "x86_unplug_v2"

Description

The methods of the interface are intended to be used by a platform to unplug (and optionally re-plug) CPU cores/threads, effectively hiding them from the #RESET/INIT signals.

This interface is internal and may change without notice.

The unplug_core method is to disable an operating core with all threads on it. The replug_core method is to enable a core previously unplugged with all threads on it. The disable_core_ht method is to disable HT in the core (not the package). The enable_core_ht method is to enable HT in the core (not the package). The core_is_plugged method returns true if core is plugged. The core_ht_is_enabled method returns true if HT is enabled in the core (not the package). The set_alive_logical_processors method updates number of alive processors reported through CPUID. The get_alive_logical_processors method returns number of alive processors reported through CPUID.

Values returned from enable and disable methods indicate success (1) or failure (0).

Execution Context

Cell Context for all methods.

x86_vmp_control

Name

x86_vmp_control — block VMP from being used

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(x86_vmp_control) {
        unsigned (*get_block_count)(conf_object_t *cpu);
        void (*set_block_count)(conf_object_t *cpu, unsigned cnt);
};
#define X86_VMP_CONTROL_INTERFACE "x86_vmp_control"

Python

import simics

class simics.x86_vmp_control_interface_t(get_block_count=None,
        set_block_count=None)

Description

This interface is internal and may change without notice.

The x86_vmp_control interface can be used to prevent VMP from being used.

The set_block_count method sets the VMP block count. If the VMP block count is non-zero, VMP will not be used for simulation.

The get_block_count method returns VMP block count.

Execution Context

Cell Context for all methods.

xed_access

Name

xed_access — call into the call Intel\reg; XED library

Synopsis

C and DML

#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML

SIM_INTERFACE(xed_access) {
        int (*get_last)(conf_object_t *obj, xed_data_type_t type);
        int (*decode)(conf_object_t *obj, xed_data_type_t type, bytes_t bytes);
        const char *(*to_string)(conf_object_t *obj, xed_data_type_t type,
                                 int value);
};

#define XED_ACCESS_INTERFACE "xed_access"

Python

import simics

class simics.xed_access_interface_t(get_last=None, decode=None, to_string=None)

Description

This interface is internal and may change without notice.

The xed_access interface is implemented by a processor model. The interface can be used to call Intel® X86 Encoder Decoder (Intel\reg; XED) library built into the processor model.

Execution Context

Cell Context for all methods.

xtensa_export_state

Name

xtensa_export_state — TIE interface for the export state type

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_export_state) {
        void (*register_export_state)(conf_object_t *obj,
                                      lang_void *user_object,
                                      lang_void *export_state_func);
};
#define XTENSA_EXPORT_STATE_INTERFACE "xtensa_export_state"

Python

import simics

class simics.xtensa_export_state_interface_t(register_export_state=None)

Description

OBSOLETE!

External Xtensa TIE interface for the export state type. user_object is the user object to use in the export_state_func callback.

The type of the export_state_func is defined in the xtensa/tie/cstub-extif.h file in the Xtensa model build directory.

Execution Context

Cell Context for all methods.

xtensa_import_wire

Name

xtensa_import_wire — TIE interface for the import wire type

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_import_wire) {
        void (*register_import_wire)(conf_object_t *obj,
                                     lang_void *user_object,
                                     lang_void *import_wire_func);
};
#define XTENSA_IMPORT_WIRE_INTERFACE "xtensa_import_wire"

Python

import simics

class simics.xtensa_import_wire_interface_t(register_import_wire=None)

Description

External Xtensa TIE interface for the import wire type. A callback should be registered in order to send data to the object obj that implements the interface, typically a processor. The callback is called when the wire is accessed. The user_object is the user object to use in the import_wire_func callback.

The type of the import_wire_func is defined in the xtensa/tie/cstub-extif.h file in the Xtensa model build directory.

Execution Context

Cell Context for all methods.

xtensa_input_queue

Name

xtensa_input_queue — TIE interface for the input queue type

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_input_queue) {
        void (*register_input_queue)(conf_object_t *obj,
                                     lang_void *user_object,
                                     lang_void *empty_callback,
                                     lang_void *data_callback);
};
#define XTENSA_INPUT_QUEUE_INTERFACE "xtensa_input_queue"

Python

import simics

class simics.xtensa_input_queue_interface_t(register_input_queue=None)

Description

OBSOLETE!

External Xtensa TIE interface for the input queue type. Two callbacks should be registered in order to send data to the object obj that implements the interface, typically a processor. When the queue is accessed the callbacks are called. user_object is the user object to use in the empty_callback and data_callback callbacks.

The types of the empty_callback callback and data_callback are defined in the xtensa/tie/cstub-extif.h file in the Xtensa model build directory. The empty_callback should return 1 if the queue is empty, otherwise 0. The data_callback is used for sending the data.

Execution Context

Cell Context for all methods.

xtensa_internal_memories

Name

xtensa_internal_memories — interface implemented by all Xtensa cores

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_internal_memories) {
        attr_value_t (*iram_mappings)(conf_object_t *obj);
        attr_value_t (*irom_mappings)(conf_object_t *obj);
        attr_value_t (*dram_mappings)(conf_object_t *obj);
        attr_value_t (*drom_mappings)(conf_object_t *obj);
};
#define XTENSA_INTERNAL_MEMORIES_INTERFACE "xtensa_internal_memories"

Python

import simics

class simics.xtensa_internal_memories_interface_t(iram_mappings=None,
        irom_mappings=None, dram_mappings=None, drom_mappings=None)

Description

This interface is implemented by all Xtensa cores. The methods correspond to the iram, irom, dram and drom attributes, reporting where the internal memories are located, in the form of: [[paddr_start, paddr_stop]*]. This is static and will never change, but is differently configured for each Xtensa cores.

Execution Context

Cell Context for all methods.

xtensa_lookup

Name

xtensa_lookup — Xtensa TIE interface for the lookup type

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_lookup) {
        void (*register_lookup)(conf_object_t *obj,
                                lang_void *user_object,
                                lang_void *lookup_func);
};
#define XTENSA_LOOKUP_INTERFACE "xtensa_lookup"

Python

import simics

class simics.xtensa_lookup_interface_t(register_lookup=None)

Description

OBSOLETE!

External Xtensa TIE interface for the lookup type. user_object is the user object to use in the lookup_func callback.

The type of the lookup_func is defined in the xtensa/tie/cstub-extif.h file in the Xtensa model build directory.

Execution Context

Cell Context for all methods.

xtensa_mpu_lookup_t, xtensa_mpu_lookup

Name

xtensa_mpu_lookup_t, xtensa_mpu_lookup — interface used with xtensa MPU

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

typedef struct xtensa_mpu_lookup {
        bool background;                 /* If false, a foreground hit */
        uint16 region;                   /* The foreground/background region */
        uint32 start;
        uint32 end;
        /* Permissions */
        bool sr;                             /* supervisor-read */
        bool sw;                             /* supervisor-write */
        bool sx;                             /* supervisor-execute */
        bool ur;                             /* user-read */
        bool uw;                             /* user-write */
        bool ux;                             /* user-execute */
} xtensa_mpu_lookup_t;

SIM_INTERFACE(xtensa_mpu_lookup) {
        xtensa_mpu_lookup_t (*mpu_region)(conf_object_t *obj, uint32 address);
};
#define XTENSA_MPU_LOOKUP_INTERFACE "xtensa_mpu_lookup"

Python

import simics

class simics.xtensa_mpu_lookup_t(background=False, region=0, start=0, end=0,
        sr=False, sw=False, sx=False, ur=False, uw=False, ux=False)
class simics.xtensa_mpu_lookup_interface_t(mpu_region=None)

Description

This interface is implemented by the Xtensa core which is configured with an MPU. The primary use of this interface, is the iDMA device which will need to do various protection checks for the DMA transfers.

The mpu_region returns region data that hits for the specified address. If the address hits in a background mapping, the end address will be when a foreground mapping overrides the background mapping.

Execution Context

Cell Context for all methods.

xtensa_output_queue

Name

xtensa_output_queue — TIE interface for the output queue type

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_output_queue) {
        void (*register_output_queue)(conf_object_t *obj,
                                      lang_void *user_object,
                                      lang_void *full_callback,
                                      lang_void *data_callback);
};
#define XTENSA_OUTPUT_QUEUE_INTERFACE "xtensa_output_queue"

Python

import simics

class simics.xtensa_output_queue_interface_t(register_output_queue=None)

Description

OBSOLETE!

External Xtensa TIE interface for the output queue type. Two callbacks should be registered in order to receive data from the object obj that implements the interface, typically a processor. When the queue is accessed the callbacks are called. user_object is the user object to use in the full_callback and data_callback callbacks.

The types of the full_callback and data_callback are defined in the xtensa/tie/cstub-extif.h file in the Xtensa model build directory. The full_callback should return 1 if the queue is full, otherwise 0. The data_callback is used for receiving the data.

Execution Context

Cell Context for all methods.

xtensa_reset_configure

Name

xtensa_reset_configure — interface implemented by Xtensa cores

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_reset_configure) {
        bool (*set_reset_prid)(conf_object_t *obj, uint16 prid_value);
        bool (*set_alternative_reset_vector)(conf_object_t *obj, uint32 vector_address);
};
#define XTENSA_RESET_CONFIGURE_INTERFACE "xtensa_reset_configure"

Python

import simics

class simics.xtensa_reset_configure_interface_t(set_reset_prid=None,
        set_alternative_reset_vector=None)

Description

This interface is implemented by the Xtensa core, allowing external devices to programmatically change some aspects of how the reset should be handled during run-time.

The set_reset_prid method sets the corresponding PRID register, which gets assigned during reset. The value is also exposed by the reset_prid attribute.

The set_alternative_reset_vector method sets the address from which the alternative reset starts executing after reset, when the reset_select pin is high. The value is also exposed in the alternative_reset_vector attribute.

Both methods return a bool, indicating if they were successful or not. A false return indicates that the associated Xtensa options are not included in the model.

Execution Context

Threaded Context for all methods.

xtensa_tie_export_state

Name

xtensa_tie_export_state — interface for tie communication with xtensa

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_tie_export_state) {
        void (*data)(conf_object_t *obj, uint32 bit_width, const uint32 *out_data);
};
#define XTENSA_TIE_EXPORT_STATE_INTERFACE "xtensa_tie_export_state"

Description

An export_state is a way for the Xtensa core to push data to a device implementing this interface.

The data method contains the transferred data out from the Xtensa CPU. The out_data pointer holds the data that can be read, but only bit_width bits should be examined.

Execution Context

Cell Context for all methods.

xtensa_tie_import_wire

Name

xtensa_tie_import_wire — interface for tie communication with xtensa

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_tie_import_wire) {
        void (*data)(conf_object_t *obj, uint32 bit_width, uint32 *in_data);
};
#define XTENSA_TIE_IMPORT_WIRE_INTERFACE "xtensa_tie_import_wire"

Description

The import_wire supports reading data from a device implementing this interface.

The data method requests a in_data pointer to be filled with bit_width of data by the device.

Execution Context

Cell Context for all methods.

xtensa_tie_input_queue

Name

xtensa_tie_input_queue — interface for tie communication with xtensa

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_tie_input_queue) {
        bool (*empty)(conf_object_t *obj);
        void (*data)(conf_object_t *obj, uint32 bit_width, bool is_peek, uint32 *in_data);
};
#define XTENSA_TIE_INPUT_QUEUE_INTERFACE "xtensa_tie_input_queue"

Description

The input_queue represents a way for the Xtensa CPU to read data from a queue implemented in a device.

The empty method indicates if there is anything to read in the queue or not.

The data method is used to read data from the input queue implemented in the device, the device should write the next data in queue to the in_data pointer and fill it with bit_width bits of data.

If is_peek is true, the data should be returned, but not removed from the queue.

Execution Context

Cell Context for all methods.

xtensa_tie_lookup

Name

xtensa_tie_lookup — interface for tie communication with xtensa

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_tie_lookup) {
        void (*data)(conf_object_t *obj,
                     uint32 out_width, const uint32 *out_data,
                     uint32 in_width, uint32 *in_data);
};
#define XTENSA_TIE_LOOKUP_INTERFACE "xtensa_tie_lookup"

Description

A lookup is a bidirectional communication between the Xtensa and the device implementing this interface. When the data method is received by the device, the out_data pointer contains out_width bits of data (from the Xtensa core) that the device should read and take action upon. As a response, the device should fill in in_width of bits in the in_data buffer, providing the result of the lookup back to the Xtensa instruction.

Execution Context

Cell Context for all methods.

xtensa_tie_output_queue

Name

xtensa_tie_output_queue — interface for tie communication with xtensa

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_tie_output_queue) {
        bool (*full)(conf_object_t *obj);
        void (*data)(conf_object_t *obj, uint32 bit_width, bool reserve_only, const uint32 *out_data);
};
#define XTENSA_TIE_OUTPUT_QUEUE_INTERFACE "xtensa_tie_output_queue"

Description

The output_queue allows the Xtensa to push data on a queue which the device needs to implement.

With the full method the Xtensa CPU might ask if the queue is currently full or not.

To data method is used to push data on the output queue of the device. out_data is a pointer to the pushed data and bit_width how many bits that is pushed on the queue. If reserve_only is true, no data is present but the device should just allocate space for the data.

Execution Context

Cell Context for all methods.

xtensa_wwdt_config

Name

xtensa_wwdt_config — internal interface for WWDT communication

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

SIM_INTERFACE(xtensa_wwdt_config) {
        bool (*has_wwdt)(conf_object_t *obj);
        uint32 (*reset_val)(conf_object_t *obj);
        uint32 (*hb_reset_val)(conf_object_t *obj);
        uint32 (*ikey)(conf_object_t *obj);
        uint32 (*bkey)(conf_object_t *obj);
        uint32 (*rkey)(conf_object_t *obj);
        uint32 (*kkey)(conf_object_t *obj);
        uint32 (*ekey)(conf_object_t *obj);
        uint32 (*c1key)(conf_object_t *obj);
        uint32 (*c2key)(conf_object_t *obj);
        uint32 (*t1key)(conf_object_t *obj);
        uint32 (*t2key)(conf_object_t *obj);
};
#define XTENSA_WWDT_CONFIG_INTERFACE "xtensa_wwdt_config"

Python

import simics

class simics.xtensa_wwdt_config_interface_t(has_wwdt=None, reset_val=None,
        hb_reset_val=None, ikey=None, bkey=None, rkey=None, kkey=None,
        ekey=None, c1key=None, c2key=None, t1key=None, t2key=None)

Description

This interface is implemented by the Xtensa core which holds the configuration of the Windowed Watchdog Timer. The device itself is not part of the core, but implemented as an external device which fetches these values for correct device simulation, making the wwdt device generic for all configurations.

The has_wwdt method reports if the wwdt option is included in the core at all. The rest of the member functions extract configuration details from the core, if the core does not have wwdt enabled, all are zeros.

Execution Context

Cell Context for all methods.

xtensa_wwdt_faultinfo_t, xtensa_wwdt_faultinfo

Name

xtensa_wwdt_faultinfo_t, xtensa_wwdt_faultinfo — interface used with Xtensa WWDT timer

Synopsis

C and DML

#include <simics/arch/xtensa.h> // in C
import "simics/arch/xtensa.dml"; // in DML

typedef enum {
        Wwdt_Info_Derr_Inj_Dis = 1 << 7,
        Wwdt_Info_Tfv_Err      = 1 << 6,
        Wwdt_Info_Err_Inj      = 1 << 5,
        Wwdt_Info_Oor_Exp      = 1 << 4,
        Wwdt_Info_Oor_Kick     = 1 << 3,
        Wwdt_Info_Ill_Kick     = 1 << 2,
        Wwdt_Info_Cnt_Exp      = 1 << 1,
        Wwdt_Fault_Asserted    = 1 << 0,
} xtensa_wwdt_faultinfo_t;

SIM_INTERFACE(xtensa_wwdt_faultinfo) {
        uint8 (*status)(conf_object_t *obj);
};
#define XTENSA_WWDT_FAULTINFO_INTERFACE "xtensa_wwdt_faultinfo"

Python

import simics

simics.Wwdt_Info_Tfv_Err
simics.Wwdt_Info_Derr_Inj_Dis
simics.Wwdt_Info_Oor_Kick
simics.Wwdt_Info_Err_Inj
simics.Wwdt_Info_Cnt_Exp
simics.Wwdt_Fault_Asserted
simics.Wwdt_Info_Ill_Kick
simics.Wwdt_Info_Oor_Exp
class simics.xtensa_wwdt_faultinfo_interface_t(status=None)

Description

This interface is implemented by the wwdt timer allowing the SoC device to read out the status register. On real hardware the Wwdt_faultInfo is an eight bit output towards the device. However, in a simulator it makes more sense to allow the SoC-device to read the status when needed, instead of pushing out the new contents when bits changes. The uint8 value returned is a bitmask with the bits defined in xtensa_wwdt_faultinfo_t.

Execution Context

Cell Context for all methods.

Obsolete Device API Functions Model to Simulator Interfaces