fel: sid: extend assembly to dump arbitrary range

To workaround a hardware erratum on the H3 SoC, we use an MMIO register
based assembly routine to dump the SID registers, if needed. This is
hard-coded to read the first four 32-bit words of the SID fuses.

For the sid-dump command we need to access any arbitrary regions of the
fuses, so extend the routine to take a start and an end address to dump.

This changes the assembly source in the thunks/ directory:
- We load the start address into r1, instead of zeroing it. The start
  address is put right after the SIO MMIO base address, at the end of
  the code.
- When storing the read value into the result buffer, we automatically
  increase the pointer register (r3), instead of adding the offset
  address, since this is now no longer zero based.
- To check for the end, we read the end pointer (stored at the end of
  the code, right after the offset), and compare against that instead of
  the hardcoded value of 16.
This assembly file was put through the thunks Makefile, and the resulting
content was copied from thunks/sid_read_root.h into fel_lib.c.

For now we are still putting the constant values of 0 and 16 in, but
this time from the C code.

Signed-off-by: Andre Przywara <osp@andrep.de>
This commit is contained in:
Andre Przywara 2023-02-21 00:29:19 +00:00
parent 056b65fbc0
commit c1f947e085
3 changed files with 38 additions and 27 deletions

View File

@ -551,9 +551,10 @@ void fel_clrsetbits_le32(feldev_handle *dev,
static void fel_get_sid_registers(feldev_handle *dev, uint32_t *result)
{
uint32_t arm_code[] = {
htole32(0xe59f0040), /* 0: ldr r0, [pc, #64] */
htole32(0xe3a01000), /* 4: mov r1, #0 */
htole32(0xe28f303c), /* 8: add r3, pc, #60 */
/* <sid_read_root_key>: */
htole32(0xe59f0044), /* 0: ldr r0, [pc, #68] */
htole32(0xe59f1044), /* 4: ldr r1, [pc, #68] */
htole32(0xe28f3048), /* 8: add r3, pc, #72 */
/* <sid_read_loop>: */
htole32(0xe1a02801), /* c: lsl r2, r1, #16 */
htole32(0xe3822b2b), /* 10: orr r2, r2, #44032 */
@ -564,14 +565,20 @@ static void fel_get_sid_registers(feldev_handle *dev, uint32_t *result)
htole32(0xe3120002), /* 20: tst r2, #2 */
htole32(0x1afffffc), /* 24: bne 1c <sid_read_wait> */
htole32(0xe5902060), /* 28: ldr r2, [r0, #96] */
htole32(0xe7832001), /* 2c: str r2, [r3, r1] */
htole32(0xe4832004), /* 2c: str r2, [r3], #4 */
htole32(0xe2811004), /* 30: add r1, r1, #4 */
htole32(0xe3510010), /* 34: cmp r1, #16 */
htole32(0x3afffff3), /* 38: bcc c <sid_read_loop> */
htole32(0xe3a02000), /* 3c: mov r2, #0 */
htole32(0xe5802040), /* 40: str r2, [r0, #64] */
htole32(0xe12fff1e), /* 44: bx lr */
htole32(0xe59f2018), /* 34: ldr r2, [pc, #24] */
htole32(0xe1510002), /* 38: cmp r1, r2 */
htole32(0x3afffff2), /* 3c: bcc c <sid_read_loop> */
htole32(0xe3a02000), /* 40: mov r2, #0 */
htole32(0xe5802040), /* 44: str r2, [r0, #64] */
htole32(0xe12fff1e), /* 48: bx lr */
/* <sid_base>: */
htole32(dev->soc_info->sid_base), /* SID base addr */
/* <offset>: */
htole32(0), /* first word to read */
/* <end>: */
htole32(16), /* where to stop to read */
/* retrieved SID values go here */
};
/* write and execute code */

View File

@ -42,7 +42,7 @@ sid_key_index .req r1
sid_read_root_key:
ldr SID_BASE, sid_base
mov sid_key_index, #0
ldr sid_key_index, offset
adr r3, sid_result /* result pointer */
sid_read_loop:
mov r2, sid_key_index, lsl #16 /* PG_INDEX value */
@ -55,10 +55,11 @@ sid_read_wait:
bne sid_read_wait /* loop while bit 1 still set */
ldr r2, [SID_BASE, #SID_RDKEY] /* read SID key value */
str r2, [r3, sid_key_index] /* store SID value */
str r2, [r3], #4 /* store SID value */
add sid_key_index, #4
cmp sid_key_index, #16
ldr r2, end
cmp sid_key_index, r2
blo sid_read_loop /* loop while (sid_key_index < 0x10) */
mov r2, #0
@ -66,7 +67,6 @@ sid_read_wait:
bx lr
sid_base: .word 0
sid_result: .word 0 /* receives the four "root key" 32-bit words */
.word 0
.word 0
.word 0
offset: .word 0
end: .word 0
sid_result: /* receives the values read from the SID registers */

View File

@ -1,7 +1,7 @@
/* <sid_read_root_key>: */
htole32(0xe59f0040), /* 0: ldr r0, [pc, #64] */
htole32(0xe3a01000), /* 4: mov r1, #0 */
htole32(0xe28f303c), /* 8: add r3, pc, #60 */
htole32(0xe59f0044), /* 0: ldr r0, [pc, #68] */
htole32(0xe59f1044), /* 4: ldr r1, [pc, #68] */
htole32(0xe28f3048), /* 8: add r3, pc, #72 */
/* <sid_read_loop>: */
htole32(0xe1a02801), /* c: lsl r2, r1, #16 */
htole32(0xe3822b2b), /* 10: orr r2, r2, #44032 */
@ -12,13 +12,17 @@
htole32(0xe3120002), /* 20: tst r2, #2 */
htole32(0x1afffffc), /* 24: bne 1c <sid_read_wait> */
htole32(0xe5902060), /* 28: ldr r2, [r0, #96] */
htole32(0xe7832001), /* 2c: str r2, [r3, r1] */
htole32(0xe4832004), /* 2c: str r2, [r3], #4 */
htole32(0xe2811004), /* 30: add r1, r1, #4 */
htole32(0xe3510010), /* 34: cmp r1, #16 */
htole32(0x3afffff3), /* 38: bcc c <sid_read_loop> */
htole32(0xe3a02000), /* 3c: mov r2, #0 */
htole32(0xe5802040), /* 40: str r2, [r0, #64] */
htole32(0xe12fff1e), /* 44: bx lr */
htole32(0xe59f2018), /* 34: ldr r2, [pc, #24] */
htole32(0xe1510002), /* 38: cmp r1, r2 */
htole32(0x3afffff2), /* 3c: bcc c <sid_read_loop> */
htole32(0xe3a02000), /* 40: mov r2, #0 */
htole32(0xe5802040), /* 44: str r2, [r0, #64] */
htole32(0xe12fff1e), /* 48: bx lr */
/* <sid_base>: */
htole32(0x00000000), /* 48: .word 0x00000000 */
/* <sid_result>: */
htole32(0x00000000), /* 4c: .word 0x00000000 */
/* <offset>: */
htole32(0x00000000), /* 50: .word 0x00000000 */
/* <end>: */
htole32(0x00000000), /* 54: .word 0x00000000 */