ReadAs
Jump to navigation
Jump to search
ReadAs is a functionality provided by an unknown device.
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 any accessible memory map.
Configuration registers for cmep
Register | Description |
---|---|
0xE0020040 | Address |
0xE0020044 | Data (in/out) |
0xE0020048 | Mode |
Modes
Mode is a bitfield. You can enable/disable some readAs features as well as change the used DMAC channel.
Bit | Description |
---|---|
0 | Write data to address |
1 | Mode 2 - Alternative Secure? |
2 | Mode 4 - Non-secure? |
3 | Read/Write address byte 0 |
4 | Read/Write address byte 1 and allow non-0x10-aligned address read |
5 | Read/Write address byte 2 |
6 | Read/Write address byte 3 |
30 | ?? hangs with bits 0 and 2 |
While write mode always respects bits 3-6, read mode seems to have a set of address ranges that always read all 4 bytes.
Usage example
#define READAS_REG 0xE0020040 // readas32 device #define READAS_DEV_S 0 // default secure #define READAS_MODE_WRITE 0b1 // write mode #define READAS_DEV_UNK 0b10 // masks DRAM and DRAM regs, from ARM bus #define READAS_DEV_NS 0b100 // non-secure // below options only apply to write mode and some offsets in read mode #define READAS_B0 0b1000 #define READAS_B1 0b10000 // or READAS_NOALIGN in incompatible read offsets #define READAS_B2 0b100000 #define READAS_B3 0b1000000 #define READAS_32 (READAS_B0 | READAS_B1 | READAS_B2 | READAS_B3) typedef struct { unsigned int addr; unsigned int resp; unsigned int mode; } __attribute__((packed)) e002_readas32; static volatile e002_readas32* const READAS32 = (void*)READAS_REG; // read from [addr] with mode [mode] static u32_t readAs(u32_t addr, u32_t mode) { READAS32->addr = addr; READAS32->resp = 0xDEADBABE; READAS32->mode = mode; while (READAS32->resp == 0xDEADBABE) {} // wait until READAS replies return READAS32->resp; } // write to [addr] with mode [mode] static void writeAs(u32_t addr, u32_t data, u32_t mode) { READAS32->addr = addr; READAS32->resp = data; READAS32->mode = mode | READAS_MODE_WRITE; }
Ranges
Results after a full memcmp:
- mode 0 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 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 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
- 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 zeroed (both in type 1 and type 8 cmep reset).