ReadAs: Difference between revisions
Jump to navigation
Jump to search
m (this device is NOT f00d-exclusive) |
(→Control register: Update bits 15:7 description) |
||
(6 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
ReadAs is a <s>functionality provided by an unknown device</s> 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 can be used to read/write data anywhere on the mapped memory. <s>It is suspected to be a DMAC4 interface.</s> | ||
It is never accessed by any currently reverse-engineered code and is not referenced in | 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 <code>0xE0020040</code>. | |||
=== Structure === | |||
{| class="wikitable" | {| class="wikitable" | ||
Line 15: | Line 21: | ||
| 0xE0020044 || Data (in/out) | | 0xE0020044 || Data (in/out) | ||
|- | |- | ||
| 0xE0020048 || | | 0xE0020048 || Control | ||
|} | |} | ||
== | ==== Control register ==== | ||
The control register is used to configure ReadAs. Writing to the control register starts the ReadAs operation. | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Bit !! Description | ! Bit(s) !! Description | ||
|- | |- | ||
| 0 || Write | | 0 || Operation type (0: Read - 1: Write) | ||
|- | |- | ||
| 1 || | | 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 || <code>MReqInfo<15:7></code> | ||
|- | |- | ||
| | | 24:16 || ? | ||
|- | |- | ||
| | | 30:25 || Bus Master ID (impersonated for access) | ||
|- | |- | ||
| | | 31 || RAZ/WI (maybe BUSY?) | ||
|} | |} | ||
== Usage example == | == Usage example == | ||
Line 50: | Line 57: | ||
#define READAS_REG 0xE0020040 // readas32 device | #define READAS_REG 0xE0020040 // readas32 device | ||
#define | #define READAS_MODE_READ 0x0 | ||
#define | #define READAS_MODE_WRITE 0x1 | ||
#define | |||
#define | #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 | // below options only apply to write mode and some offsets in read mode | ||
#define | #define READAS_BE_0 (0x1 << 3) //enable byte 0 (LSB) | ||
#define | #define READAS_BE_1 (0x2 << 3) //enable byte 1 - or READAS_NOALIGN in incompatible read offsets | ||
#define | #define READAS_BE_2 (0x4 << 3) //enable byte 2 | ||
#define | #define READAS_BE_3 (0x8 << 3) //enable byte 3 (MSB) | ||
#define | |||
#define READAS_BUS_MASTER(x) (((x) & 0x3Fu) << 25) | |||
typedef struct { | typedef struct { | ||
unsigned int addr; | unsigned int addr; | ||
unsigned int | unsigned int val; | ||
unsigned int | unsigned int ctrl; | ||
} __attribute__((packed)) e002_readas32; | } __attribute__((packed)) e002_readas32; | ||
static volatile e002_readas32* const READAS32 = (void*)READAS_REG; | static volatile e002_readas32* const READAS32 = (void*)READAS_REG; | ||
// read from [addr] with | // read from [addr] with configuration [cfg] | ||
static u32_t readAs(u32_t addr, u32_t | static u32_t readAs(u32_t addr, u32_t cfg) { | ||
READAS32->addr = addr; | READAS32->addr = addr; | ||
READAS32-> | READAS32->val = 0xDEADBABE; | ||
READAS32-> | READAS32->ctrl = (cfg & ~READAS_MODE_WRITE); | ||
while (READAS32->val == 0xDEADBABE) {} // wait until READAS replies | |||
while (READAS32-> | return READAS32->val; | ||
return READAS32-> | |||
} | } | ||
// write to [addr] with | // write [data] to [addr] with configuration [cfg] | ||
static void writeAs(u32_t addr, u32_t data, u32_t | static void writeAs(u32_t addr, u32_t data, u32_t cfg) { | ||
READAS32->addr = addr; | READAS32->addr = addr; | ||
READAS32-> | READAS32->val = data; | ||
READAS32-> | READAS32->ctrl = (cfg | READAS_MODE_WRITE); | ||
} | } | ||
</source> | </source> | ||
Line 94: | Line 102: | ||
<pre> | <pre> | ||
- mode 0 vs normal cmep read | - mode 0 (READAS_DEV_S) vs normal cmep read | ||
--not available in mode 0: | --not available in mode 0: | ||
0x00300000-0x00400000 | 0x00300000-0x00400000 | ||
Line 107: | Line 115: | ||
0xE8000000-0xE8400000 | 0xE8000000-0xE8400000 | ||
- mode 2 vs 0 | - mode 2 (READAS_DEV_UNK) vs 0 | ||
--not available in mode 2: | --not available in mode 2: | ||
0x40000000-0xC0000000 | 0x40000000-0xC0000000 | ||
Line 120: | Line 128: | ||
0xED948000-0xED970000 | 0xED948000-0xED970000 | ||
- mode 4 vs mode 0 | - mode 4 (READAS_DEV_NS) vs mode 0 | ||
--not available in mode 0 (!) | --not available in mode 0 (!) | ||
0x00000000-0x00008000 | 0x00000000-0x00008000 | ||
Line 136: | Line 144: | ||
== Notes == | == 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 | * 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). | ||
[[Category:MMIO]] |
Latest revision as of 21:11, 9 October 2024
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).