ReadAs: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
CelesteBlue (talk | contribs) No edit summary |
||
Line 1: | Line 1: | ||
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 can be used to read/write data anywhere on the mapped memory. It is suspected to be a DMAC4 interface. | ||
Line 34: | Line 34: | ||
| 3 || Read/Write address byte 0 | | 3 || Read/Write address byte 0 | ||
|- | |- | ||
| 4 || | | 4 || Read/Write address byte 1 and allow non-0x10-aligned address read | ||
|- | |- | ||
| 5 || Read/Write address byte 2 | | 5 || Read/Write address byte 2 | ||
Line 43: | Line 43: | ||
|} | |} | ||
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 == | == Usage example == | ||
Line 50: | Line 50: | ||
#define READAS_REG 0xE0020040 // readas32 device | #define READAS_REG 0xE0020040 // readas32 device | ||
#define | #define READAS_DEV_S 0 // default secure | ||
#define | #define READAS_MODE_WRITE 0b1 // write mode | ||
#define | #define READAS_DEV_UNK 0b10 // masks DRAM and DRAM regs, from ARM bus | ||
#define | #define READAS_DEV_NS 0b100 // non-secure | ||
// below options only apply to write mode and some offsets in read mode | // below options only apply to write mode and some offsets in read mode | ||
#define | #define READAS_B0 0b1000 | ||
#define | #define READAS_B1 0b10000 // or READAS_NOALIGN in incompatible read offsets | ||
#define | #define READAS_B2 0b100000 | ||
#define | #define READAS_B3 0b1000000 | ||
#define | #define READAS_32 (READAS_B0 | READAS_B1 | READAS_B2 | READAS_B3) | ||
typedef struct { | typedef struct { | ||
Line 75: | Line 75: | ||
READAS32->resp = 0xDEADBABE; | READAS32->resp = 0xDEADBABE; | ||
READAS32->mode = mode; | READAS32->mode = mode; | ||
while (READAS32->resp == 0xDEADBABE) {} // wait until READAS replies | |||
while (READAS32->resp == 0xDEADBABE) {} // wait until | |||
return READAS32->resp; | return READAS32->resp; | ||
} | } | ||
Line 85: | Line 83: | ||
READAS32->addr = addr; | READAS32->addr = addr; | ||
READAS32->resp = data; | READAS32->resp = data; | ||
READAS32->mode = mode | | READAS32->mode = mode | READAS_MODE_WRITE; | ||
} | } | ||
</source> | </source> |
Revision as of 01:03, 14 February 2023
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).