ReadAs
Jump to navigation
Jump to search
ReadAs is a functionality provided by an unknown device special device used to perform "arbitrary" bus transactions?
It can be used to read/write data anywhere on the mapped memory. It is suspected to be a DMAC4 interface.
It is never accessed by any currently reverse-engineered code, and is not referenced in memory map.
Registers
Location
The ReadAs MMIO interface is located at physical address 0xE0020040
.
Structure
Register | Description |
---|---|
0xE0020040 | Address |
0xE0020044 | Data (in/out) |
0xE0020048 | Control |
Control register
The control register is used to configure ReadAs. Writing to the control register starts the ReadAs operation.
Bit(s) | Description |
---|---|
0 | Operation type (0: Read - 1: Write) |
2:1 | ? (maybe IA selection) |
6:3 | Bytes enable (Bit 6/5/4/3 => byte 3/2/1/0 in LE order)
Controls which bytes are read/write at target address. (bit 5 sometimes also control whether read is aligned to 0x10 or not) |
15:7 | MReqInfo<15:7>
|
24:16 | ? |
30:25 | Bus Master ID (impersonated for access) |
31 | RAZ/WI (maybe BUSY?) |
Usage example
#define READAS_REG 0xE0020040 // readas32 device #define READAS_MODE_READ 0x0 #define READAS_MODE_WRITE 0x1 #define READAS_DEV_S (0x0 << 1) // default secure #define READAS_DEV_UNK (0x1 << 1) // masks DRAM and DRAM regs, from ARM bus #define READAS_DEV_NS (0x2 << 1) // non-secure // below options only apply to write mode and some offsets in read mode #define READAS_BE_0 (0x1 << 3) //enable byte 0 (LSB) #define READAS_BE_1 (0x2 << 3) //enable byte 1 - or READAS_NOALIGN in incompatible read offsets #define READAS_BE_2 (0x4 << 3) //enable byte 2 #define READAS_BE_3 (0x8 << 3) //enable byte 3 (MSB) #define READAS_BUS_MASTER(x) (((x) & 0x3Fu) << 25) typedef struct { unsigned int addr; unsigned int val; unsigned int ctrl; } __attribute__((packed)) e002_readas32; static volatile e002_readas32* const READAS32 = (void*)READAS_REG; // read from [addr] with configuration [cfg] static u32_t readAs(u32_t addr, u32_t cfg) { READAS32->addr = addr; READAS32->val = 0xDEADBABE; READAS32->ctrl = (cfg & ~READAS_MODE_WRITE); while (READAS32->val == 0xDEADBABE) {} // wait until READAS replies return READAS32->val; } // write [data] to [addr] with configuration [cfg] static void writeAs(u32_t addr, u32_t data, u32_t cfg) { READAS32->addr = addr; READAS32->val = data; READAS32->ctrl = (cfg | READAS_MODE_WRITE); }
Ranges
Results after a full memcmp:
- mode 0 (READAS_DEV_S) vs normal cmep read --not available in mode 0: 0x00300000-0x00400000 0xE0000000-0xE0040000 0xE0058000-0xE0068000 0xE00C0000-0xE00D0000 0xE0100000-0xE0101000 0xE04D0000-0xE04DC000 0xE20A0000-0xE20B0000 0xE20C0000-0xE20D0000 0xE3110000-0xE3120000 0xE8000000-0xE8400000 - mode 2 (READAS_DEV_UNK) vs 0 --not available in mode 2: 0x40000000-0xC0000000 0xE0400000-0xE0420000 0xE04E0000-0xE04E1000 0xE3000000-0xE3020000 0xE3101000-0xE3104000 0xE5000000-0xE5020000 0xE50C0000-0xE50D0000 0xE5880000-0xE6010000 0xEC340000-0xEC370000 0xED948000-0xED970000 - mode 4 (READAS_DEV_NS) vs mode 0 --not available in mode 0 (!) 0x00000000-0x00008000 0xE0100000-0xE0101000 0xE04D0000-0xE04DC000 0xE20A0000-0xE20B0000 0xE3110000-0xE3120000 --not available in mode 4: 0x00040000-0x00060000 0x00800000-0x00820000 0xE0000000-0xE0100000 0xEC000000-0xEE700000
Notes
- On SoC v3.2+ all read modes can be disabled by writing 0x420 to physical address 0xE0010010.
- This cmep device has been updated in PS Vita SoC rev 4 compared to rev 3.2: When cmep is reset, the configuration is also zeroed (both in type 1 and type 8 cmep reset).