TEMU
4.4
The Terma Emulator
|
Go to the source code of this file.
Data Structures | |
struct | temu_MemorySpaceIface |
struct | temu_IRInstruction |
struct | temu_ExtIRInstruction |
struct | temu_PDCIface |
Macros | |
#define | TEMU_MEMORY_SPACE_IFACE_TYPE "temu::MemorySpaceIface" |
#define | TEMU_PDC_PSEUDO_UNKNOWN_INSTR 0 |
#define | TEMU_PDC_PSEUDO_EOP 1 |
#define | TEMU_PDC_PSEUDO_TRAMPOLINE 2 |
#define | TEMU_PDC_PSEUDO_POST_DS_0 3 |
#define | TEMU_PDC_PSEUDO_POST_DS_1 4 |
#define | TEMU_PDC_PSEUDO_ATTRIB_CHECK 5 |
#define | TEMU_PDC_PSEUDO_PROFILE 6 |
#define | TEMU_PDC_PSEUDO_PRE_TRAMPOLINE 7 |
#define | TEMU_PDC_PSEUDO_IDLE 8 |
#define | TEMU_PDC_PSEUDO_SKIP 9 |
#define | TEMU_PDC_PSEUDO_CALL 10 |
#define | TEMU_PDC_PSEUDO_CALL_AND_SKIP 11 |
#define | TEMU_PDC_PSEUDO_MULTIPAGE 12 |
#define | TEMU_PDC_PSEUDO_OP_COUNT 13 |
#define | TEMU_PDC_IFACE_TYPE "PDCIface" |
Typedefs | |
typedef enum temu_MemoryKind | temu_MemoryKind |
typedef enum temu_MemoryAttr | temu_MemoryAttr |
Memory attribute enumeration. More... | |
typedef uint8_t | temu_MemoryAttrs |
typedef struct temu_MemAccessIface | temu_MemAccessIface |
typedef enum temu_MemoryStat | temu_MemoryStat |
typedef struct temu_MemorySpaceIface | temu_MemorySpaceIface |
Enumerations | |
enum | temu_MemoryKind { teMK_RAM = 0, teMK_ROM = 1, teMK_MMIO = 2, teMK_IO = 2, teMK_MemSpace = 4, teMK_Last = 4 } |
enum | temu_MemoryAttr { teMA_Break = 1, teMA_WatchRead = 1 << 1, teMA_WatchWrite = 1 << 2, teMA_Upset = 1 << 3, teMA_Faulty = 1 << 4, teMA_User1 = 1 << 5, teMA_User2 = 1 << 6, teMA_User3 = 1 << 7 } |
Memory attribute enumeration. More... | |
enum | temu_MemoryStat { teMS_IOReads, teMS_IOWrites, teMS_SelfModifyingCodeWrites, teMS_CodeWrites, teMS_LocksTaken, teMS_IOReadTime, teMS_IOWriteTime, teMS_LockTime } |
Functions | |
TEMU_IFACE_REFERENCE_TYPE (temu_MemorySpace) | |
TEMU_IFACE_REFERENCE_TYPE (temu_PDC) | |
TEMU_API int | temu_memoryRead (void *mem, uint8_t *buff, uint64_t addr, uint32_t size, int swap) |
TEMU_API int | temu_memoryWrite (void *mem, uint64_t addr, uint8_t *buff, uint32_t size, int swap) |
TEMU_API int | temu_memoryReadData (void *obj, uint64_t addr, uint8_t *buff, unsigned unitSize, uint32_t size, unsigned flags) |
TEMU_API int | temu_memoryWriteData (void *obj, uint64_t addr, const uint8_t *buff, unsigned unitSize, uint32_t size, unsigned flags) |
TEMU_API int | temu_memoryMap (void *Obj, uint64_t Addr, uint64_t Len, void *MemObj, uint32_t Flags) |
TEMU_API int | temu_memoryMapNamedIface (void *Obj, uint64_t Addr, uint64_t Len, void *MemObj, const char *IfaceName, uint32_t Flags) |
TEMU_API int | temu_memoryMapNamedIface2 (void *Obj, uint64_t Addr, uint64_t Len, void *MemObj, const char *IfaceName, unsigned Idx, uint32_t Flags) |
TEMU_API void | temu_memorySetAttr (void *Obj, uint64_t Addr, uint64_t Len, temu_MemoryAttr Attr) |
TEMU_API void | temu_memoryClearAttr (void *Obj, uint64_t Addr, uint64_t Len, temu_MemoryAttr Attr) |
TEMU_API temu_MemoryAttrs | temu_memoryGetAttrs (void *Obj, uint64_t Addr) |
TEMU_API int | temu_memoryReadPhys16 (void *Obj, uint64_t Addr, uint16_t *Word) |
TEMU_API int | temu_memoryReadPhys16Little (void *Obj, uint64_t Addr, uint16_t *Word) |
TEMU_API int | temu_memoryReadPhys32 (void *Obj, uint64_t Addr, uint32_t *Word) |
TEMU_API int | temu_memoryReadPhys32Little (void *Obj, uint64_t Addr, uint32_t *Word) |
TEMU_API int | temu_memoryWritePhys32 (void *Obj, uint64_t Addr, uint32_t Word) |
TEMU_API int | temu_memoryWritePhys32Little (void *Obj, uint64_t Addr, uint32_t Word) |
TEMU_API uint32_t | temu_normaliseWrite32 (uint32_t OldVal, uint32_t NewVal, int Sz, int Off) |
TEMU_API uint32_t | temu_normaliseRead32 (uint32_t Value, int Sz, int Off) |
TEMU_API uint16_t | temu_normaliseRead16 (uint16_t Value, int Sz, int Off) |
TEMU_API uint16_t | temu_normaliseWrite16 (uint16_t OldVal, uint16_t NewVal, int Sz, int Off) |
TEMU_API int | temu_memoryInstallTrampoline (void *Obj, uint64_t Addr, void(*Tramp)(void *)) |
TEMU_API uint64_t | temu_irToPhys (void *obj, uintptr_t ir) |
TEMU_API uint64_t | temu_irToPhysForCpu (void *obj, int cpu, uintptr_t ir) |
#define TEMU_MEMORY_SPACE_IFACE_TYPE "temu::MemorySpaceIface" |
#define TEMU_PDC_IFACE_TYPE "PDCIface" |
#define TEMU_PDC_PSEUDO_ATTRIB_CHECK 5 |
#define TEMU_PDC_PSEUDO_CALL 10 |
#define TEMU_PDC_PSEUDO_CALL_AND_SKIP 11 |
#define TEMU_PDC_PSEUDO_EOP 1 |
#define TEMU_PDC_PSEUDO_IDLE 8 |
#define TEMU_PDC_PSEUDO_MULTIPAGE 12 |
#define TEMU_PDC_PSEUDO_OP_COUNT 13 |
#define TEMU_PDC_PSEUDO_POST_DS_0 3 |
#define TEMU_PDC_PSEUDO_POST_DS_1 4 |
#define TEMU_PDC_PSEUDO_PRE_TRAMPOLINE 7 |
#define TEMU_PDC_PSEUDO_PROFILE 6 |
#define TEMU_PDC_PSEUDO_SKIP 9 |
#define TEMU_PDC_PSEUDO_TRAMPOLINE 2 |
#define TEMU_PDC_PSEUDO_UNKNOWN_INSTR 0 |
typedef struct temu_MemAccessIface temu_MemAccessIface |
typedef enum temu_MemoryAttr temu_MemoryAttr |
Memory attribute enumeration.
The emulator provides 5 standard attributes, and 3 user defined ones. The attributes are set in the memory space (not the memory models), so it is possible to set a watch point on memory mapped devices. When an attribute is set on a page, that page will get a shadow attribute page (same size as the page), enabling attributes to be set on a per byte level.
Attributes are only checked on the address being accessed, the transaction size is not taken into account.
typedef uint8_t temu_MemoryAttrs |
typedef enum temu_MemoryKind temu_MemoryKind |
typedef struct temu_MemorySpaceIface temu_MemorySpaceIface |
typedef enum temu_MemoryStat temu_MemoryStat |
enum temu_MemoryAttr |
Memory attribute enumeration.
The emulator provides 5 standard attributes, and 3 user defined ones. The attributes are set in the memory space (not the memory models), so it is possible to set a watch point on memory mapped devices. When an attribute is set on a page, that page will get a shadow attribute page (same size as the page), enabling attributes to be set on a per byte level.
Attributes are only checked on the address being accessed, the transaction size is not taken into account.
enum temu_MemoryKind |
enum temu_MemoryStat |
TEMU_IFACE_REFERENCE_TYPE | ( | temu_MemorySpace | ) |
TEMU_IFACE_REFERENCE_TYPE | ( | temu_PDC | ) |
TEMU_API uint64_t temu_irToPhys | ( | void * | obj, |
uintptr_t | ir | ||
) |
TEMU_API uint64_t temu_irToPhysForCpu | ( | void * | obj, |
int | cpu, | ||
uintptr_t | ir | ||
) |
TEMU_API void temu_memoryClearAttr | ( | void * | Obj, |
uint64_t | Addr, | ||
uint64_t | Len, | ||
temu_MemoryAttr | Attr | ||
) |
Clears an attribute on the given memory range
Obj | Memory space object |
Addr | Physical address of start |
Len | Length of memory range |
Attr | Attribute to clear |
TEMU_API temu_MemoryAttrs temu_memoryGetAttrs | ( | void * | Obj, |
uint64_t | Addr | ||
) |
Get memory attributes for address
Obj | Memory space |
Addr | Physical addres |
TEMU_API int temu_memoryInstallTrampoline | ( | void * | Obj, |
uint64_t | Addr, | ||
void(*)(void *) | Tramp | ||
) |
Install trampoline function in PDC cache
Obj | Memory space |
Addr | Physical address |
Tramp | Trampoline function, takes CPU pointer as first argument. |
TEMU_API int temu_memoryMap | ( | void * | Obj, |
uint64_t | Addr, | ||
uint64_t | Len, | ||
void * | MemObj, | ||
uint32_t | Flags | ||
) |
temu_memoryMap Maps an object into a memory space. The object must have an interface named MemAccessIface, of the type defined as TEMU_MEM_ACCESS_IFACE_TYPE
Obj | is the memory space object |
Addr | the physical address |
Len | the length in bytes |
MemObj | is the object that is mapped into the memory space it needs to be of a class that follows the rules above |
Flags | are flags that are copied into the memory transaction object's flag field when a transaction reaches an object |
TEMU_API int temu_memoryMapNamedIface | ( | void * | Obj, |
uint64_t | Addr, | ||
uint64_t | Len, | ||
void * | MemObj, | ||
const char * | IfaceName, | ||
uint32_t | Flags | ||
) |
temu_memoryMapNamedIface Maps an object into a memory space using the named memory access interface. The interface named by IfaceName must be of the type TEMU_MEM_ACCESS_IFACE_TYPE
Obj | is the memory space object |
Addr | the physical address |
Len | the length in bytes |
MemObj | is the object that is mapped into the memory space it needs to be of a class that follows the rules above |
IfaceName | Name of the memory access interface |
Flags | are flags that are copied into the memory transaction object's flag field when a transaction reaches an object |
TEMU_API int temu_memoryMapNamedIface2 | ( | void * | Obj, |
uint64_t | Addr, | ||
uint64_t | Len, | ||
void * | MemObj, | ||
const char * | IfaceName, | ||
unsigned | Idx, | ||
uint32_t | Flags | ||
) |
TEMU_API int temu_memoryRead | ( | void * | mem, |
uint8_t * | buff, | ||
uint64_t | addr, | ||
uint32_t | size, | ||
int | swap | ||
) |
Read block of data via memory block transfer interfaces
mem | Pointer to memory space object |
buff | The buffer to which the memory should be stored |
addr | The address of the memory block to be read |
size | The size to be read |
swap | setting this to 0 indicates reading a byte array, 1 a uint16 array, 2 a uint32 array and 3 a uint64 array |
TEMU_API int temu_memoryReadData | ( | void * | obj, |
uint64_t | addr, | ||
uint8_t * | buff, | ||
unsigned | unitSize, | ||
uint32_t | size, | ||
unsigned | flags | ||
) |
Read block of data via large memory transactions.
obj | Memory space object |
addr | Physical address inside memory space |
buff | Data buffer |
unitSize | Log size of transaction unit size (0 = u8, 1 = u16, 2 = u32, 3 = u64) |
size | Number of units to transfer |
flags | Memory transaction flags (e.g. TEMU_MT_LITTLE_ENDIAN) |
TEMU_API int temu_memoryReadPhys16 | ( | void * | Obj, |
uint64_t | Addr, | ||
uint16_t * | Word | ||
) |
Issue a big endian memory read transaction (without initiator)
Obj | Memory space |
Addr | Physical address |
Word | 16 bit word that is read |
TEMU_API int temu_memoryReadPhys16Little | ( | void * | Obj, |
uint64_t | Addr, | ||
uint16_t * | Word | ||
) |
Issue a little endian memory read transaction (without initiator)
Obj | Memory space |
Addr | Physical address |
Word | 16 bit word that is read |
TEMU_API int temu_memoryReadPhys32 | ( | void * | Obj, |
uint64_t | Addr, | ||
uint32_t * | Word | ||
) |
Issue a big endian memory read transaction (without initiator)
Obj | Memory space |
Addr | Physical address |
Word | 32 bit word that is read |
TEMU_API int temu_memoryReadPhys32Little | ( | void * | Obj, |
uint64_t | Addr, | ||
uint32_t * | Word | ||
) |
Issue a little endian memory read transaction (without initiator)
Obj | Memory space |
Addr | Physical address |
Word | 32 bit word that is read |
TEMU_API void temu_memorySetAttr | ( | void * | Obj, |
uint64_t | Addr, | ||
uint64_t | Len, | ||
temu_MemoryAttr | Attr | ||
) |
Sets an attribute on the given memory range
Obj | Memory space object |
Addr | Physical address of start |
Len | Length of memory range |
Attr | Attribute to set |
TEMU_API int temu_memoryWrite | ( | void * | mem, |
uint64_t | addr, | ||
uint8_t * | buff, | ||
uint32_t | size, | ||
int | swap | ||
) |
Write block of data via memory block transfer interfaces
mem | Pointer to memory space object |
buff | The buffer to which the memory should be stored |
addr | The address, at which the write should be done |
size | The size to be read |
swap | Negative on failures. Other values indicate success. |
TEMU_API int temu_memoryWriteData | ( | void * | obj, |
uint64_t | addr, | ||
const uint8_t * | buff, | ||
unsigned | unitSize, | ||
uint32_t | size, | ||
unsigned | flags | ||
) |
Write block of data via large memory transactions.
obj | Memory space object |
addr | Physical address inside memory space |
buff | Data buffer |
unitSize | Log size of transaction unit size (0 = u8, 1 = u16, 2 = u32, 3 = u64) |
size | Number of units to transfer |
flags | Memory transaction flags (e.g. TEMU_MT_LITTLE_ENDIAN) |
TEMU_API int temu_memoryWritePhys32 | ( | void * | Obj, |
uint64_t | Addr, | ||
uint32_t | Word | ||
) |
Issue a big endian memory write transaction (without initiator)
Obj | Memory space |
Addr | Physical address |
Word | 32 bit word to write |
TEMU_API int temu_memoryWritePhys32Little | ( | void * | Obj, |
uint64_t | Addr, | ||
uint32_t | Word | ||
) |
Issue a little endian memory write transaction (without initiator)
Obj | Memory space |
Addr | Physical address |
Word | 32 bit word to write |
TEMU_API uint16_t temu_normaliseRead16 | ( | uint16_t | Value, |
int | Sz, | ||
int | Off | ||
) |
Normalise a value for reads where only 16 bit transactions are supported by the device model, but the target is allowed to read non-16 bit quantities.
Given a 32 bit register value, the function extracts the bits from it that was actually requested.
Value | Register value |
Sz | Size in log number of bytes (0 or 1) |
Off | Offset in bytes within the 32 bit word of the transaction (0 or 2) |
TEMU_API uint32_t temu_normaliseRead32 | ( | uint32_t | Value, |
int | Sz, | ||
int | Off | ||
) |
Normalise a value for reads where only 32 bit transactions are supported by the device model, but the target is allowed to read non-32 bit quantities.
Given a 32 bit register value, the function extracts the bits from it that was actually requested.
Value | Register value |
Sz | Size in log number of bytes (0, 1, or 2) |
Off | Offset in bytes within the 32 bit word of the transaction (0-3) |
TEMU_API uint16_t temu_normaliseWrite16 | ( | uint16_t | OldVal, |
uint16_t | NewVal, | ||
int | Sz, | ||
int | Off | ||
) |
Normalise a value for writes where only 16 bit transactions are supported by the device model, but the target is allowed to write non-16 bit quantity. The function mixes the old register value with the new one based on the size and offset parameter. The problem exists because the memory access interface has a value entry, which always ends up in the lower bits, so if we write to the higher bits in in a 16 bit register, then by just forwarding the the value as is to the write handler, will result in a write of the lower bits and a clear of the upper bits (for a store unsigned).
Thus a normalisation is neded where we mix the written word with the old bits. So for transaction size of 8, and an offset of8, the resulting word is (old & 0x00ff) | (new << 8)
OldVal | Old regiseter value. |
NewVal | Content in memory transaction (new value). |
Sz | Size in log number of bytes |
Off | Offset in bytes within the 16 bit word of the transaction. |
TEMU_API uint32_t temu_normaliseWrite32 | ( | uint32_t | OldVal, |
uint32_t | NewVal, | ||
int | Sz, | ||
int | Off | ||
) |
Normalise a value for writes where only 32 bit transactions are supported by the device model, but the target is allowed to write non-32 bit quantity. The function mixes the old register value with the new one based on the size and offset parameter. The problem exists because the memory access interface has a value entry, which always ends up in the lower bits, so if we write to the higher bits in in a 32 bit register, then by just forwarding the the value as is to the write handler, will result in a write of the lower bits and a clear of the upper bits (for a store unsigned).
Thus a normalisation is needed where we mix the written word with the old bits. So for transaction size of 16, and an offset of 16, the resulting word is (old & 0x0000ffff) | (new << 16)
OldVal | Old regiseter value. |
NewVal | Content in memory transaction (new value). |
Sz | Size in log number of bytes |
Off | Offset in bytes within the 32 bit word of the transaction. |