ReadAs: Difference between revisions

From Vita Development Wiki
Jump to navigation Jump to search
mNo edit summary
(→‎Control register: Update bits 15:7 description)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
ReadAs is a functionality provided by an unknown device.
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 any accessible memory map.
It is never accessed by any currently reverse-engineered code, and is not referenced in memory map.


== Configuration registers for cmep ==
== 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 || Mode
| 0xE0020048 || Control
|}
|}


== Modes ==
==== Control register ====


Mode is a bitfield. You can enable/disable some readAs features as well as change the used DMAC channel.
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 data to address
| 0 || Operation type (0: Read - 1: Write)
|-
|-
| 1 || Mode 2 - Alternative Secure?
| 2:1 || ? (maybe IA selection)
|-
|-
| 2 || Mode 4 - Non-secure?
| 6:3
|-
| Bytes enable (Bit 6/5/4/3 => byte 3/2/1/0 in LE order)
| 3 || Read/Write address byte 0
 
Controls which bytes are read/write at target address.
 
(bit 5 sometimes also control whether read is aligned to 0x10 or not)
|-
|-
| 4 || Read/Write address byte 1 and allow non-0x10-aligned address read
| 15:7 || <code>MReqInfo<15:7></code>
|-
|-
| 5 || Read/Write address byte 2
| 24:16 || ?
|-
|-
| 6 || Read/Write address byte 3
| 30:25 || Bus Master ID (impersonated for access)
|-
|-
| 30 || ?? hangs with bits 0 and 2
| 31 || RAZ/WI (maybe BUSY?)
|}
|}
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 57:
#define READAS_REG 0xE0020040 // readas32 device
#define READAS_REG 0xE0020040 // readas32 device


#define READAS_DEV_S 0 // default secure
#define READAS_MODE_READ  0x0
#define READAS_MODE_WRITE 0b1 // write mode
#define READAS_MODE_WRITE 0x1
#define READAS_DEV_UNK 0b10 // masks DRAM and DRAM regs, from ARM bus
 
#define READAS_DEV_NS 0b100 // non-secure
#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 READAS_B0 0b1000
#define READAS_BE_0 (0x1 << 3) //enable byte 0 (LSB)
#define READAS_B1 0b10000 // or READAS_NOALIGN in incompatible read offsets
#define READAS_BE_1 (0x2 << 3) //enable byte 1 - or READAS_NOALIGN in incompatible read offsets
#define READAS_B2 0b100000
#define READAS_BE_2 (0x4 << 3) //enable byte 2
#define READAS_B3 0b1000000
#define READAS_BE_3 (0x8 << 3) //enable byte 3 (MSB)
#define READAS_32 (READAS_B0 | READAS_B1 | READAS_B2 | READAS_B3)
 
#define READAS_BUS_MASTER(x) (((x) & 0x3Fu) << 25)


typedef struct {
typedef struct {
     unsigned int addr;
     unsigned int addr;
     unsigned int resp;
     unsigned int val;
     unsigned int mode;
     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 mode [mode]
// read from [addr] with configuration [cfg]
static u32_t readAs(u32_t addr, u32_t mode) {
static u32_t readAs(u32_t addr, u32_t cfg) {
     READAS32->addr = addr;
     READAS32->addr = addr;
     READAS32->resp = 0xDEADBABE;
     READAS32->val = 0xDEADBABE;
     READAS32->mode = mode;
     READAS32->ctrl = (cfg & ~READAS_MODE_WRITE);
     while (READAS32->resp == 0xDEADBABE) {} // wait until READAS replies
     while (READAS32->val == 0xDEADBABE) {} // wait until READAS replies
     return READAS32->resp;
     return READAS32->val;
}
}


// write to [addr] with mode [mode]
// write [data] to [addr] with configuration [cfg]
static void writeAs(u32_t addr, u32_t data, u32_t mode) {
static void writeAs(u32_t addr, u32_t data, u32_t cfg) {
     READAS32->addr = addr;
     READAS32->addr = addr;
     READAS32->resp = data;
     READAS32->val = data;
     READAS32->mode = mode | READAS_MODE_WRITE;
     READAS32->ctrl = (cfg | READAS_MODE_WRITE);
}
}
</source>
</source>
Line 92: 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 105: 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 118: 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 135: Line 145:


* On SoC v3.2+ all read modes can be disabled by writing 0x420 to physical address 0xE0010010.
* 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 zeroed (both in type 1 and type 8 cmep reset).
* 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).