Clarify switch_app reads and writes; add read test to testfw

This commit is contained in:
Daniel Lublin 2022-10-26 11:38:58 +02:00
parent 4b4f014d38
commit 85ef93cd3c
No known key found for this signature in database
GPG Key ID: 75BD0FEB8D3E7830
2 changed files with 50 additions and 37 deletions

View File

@ -165,9 +165,9 @@ Procedure:
1. The host sends `FW_CMD_RUN_APP` to the device. 1. The host sends `FW_CMD_RUN_APP` to the device.
2. The firmware responds with `FW_RSP_RUN_APP` 2. The firmware responds with `FW_RSP_RUN_APP`
3. The firmware writes a non-zero to `SWITCH_APP`, and executes 3. The firmware writes to `SWITCH_APP`, and executes assembler code
assembler code that writes zeros to stack and data of the that writes zeros to stack and data of the firmware, then jumps
firmware, then jumps to what's in APP_ADDR. to what's in APP_ADDR.
4. The device is now in application mode and is executing the 4. The device is now in application mode and is executing the
application. application.
@ -324,39 +324,40 @@ Assigned core prefixes:
*Nota bene*: MMIO accesses should be 32 bit wide, e.g use `lw` and *Nota bene*: MMIO accesses should be 32 bit wide, e.g use `lw` and
`sw`. Exceptions are `FW_RAM` and `QEMU_DEBUG`. `sw`. Exceptions are `FW_RAM` and `QEMU_DEBUG`.
| *name* | *fw* | *app | *size* | *type* | *content* | *description* | | *name* | *fw* | *app* | *size* | *type* | *content* | *description* |
|-------------------|-------|------------|--------|----------|-----------|-----------------------------------------------------------------------| |-------------------|-------|-----------|--------|----------|-----------|------------------------------------------------------------------------|
| `TRNG_STATUS` | r | r | | | | TRNG_STATUS_READY_BIT is 1 when an entropy word is available. | | `TRNG_STATUS` | r | r | | | | TRNG_STATUS_READY_BIT is 1 when an entropy word is available. |
| `TRNG_ENTROPY` | r | r | 4B | u32 | | Entropy word. Reading a word will clear status. | | `TRNG_ENTROPY` | r | r | 4B | u32 | | Entropy word. Reading a word will clear status. |
| `TIMER_CTRL` | r/w | r/w | | | | If TIMER_STATUS_READY_BIT in TIMER_STATUS is 1 then writing here | | `TIMER_CTRL` | r/w | r/w | | | | If TIMER_STATUS_READY_BIT in TIMER_STATUS is 1, writing anything here |
| | | | | | | starts the timer. If the same bit is 0 then writing stops the timer. | | | | | | | | starts the timer. If the same bit is 0 then writing stops the timer. |
| `TIMER_STATUS` | r | r | | | | TIMER_STATUS_READY_BIT is 1 when timer is ready to start running. | | `TIMER_STATUS` | r | r | | | | TIMER_STATUS_READY_BIT is 1 when timer is ready to start running. |
| `TIMER_PRESCALER` | r/w | r/w | 4B | | | Prescaler init value. Write blocked when running. | | `TIMER_PRESCALER` | r/w | r/w | 4B | | | Prescaler init value. Write blocked when running. |
| `TIMER_TIMER` | r/w | r/w | 4B | | | Timer init or current value while running. Write blocked when running.| | `TIMER_TIMER` | r/w | r/w | 4B | | | Timer init or current value while running. Write blocked when running. |
| `UDS_FIRST` | r[^3] | invisible | 4B | u8[32] | | First word of Unique Device Secret key. | | `UDS_FIRST` | r[^3] | invisible | 4B | u8[32] | | First word of Unique Device Secret key. |
| `UDS_LAST` | | invisible | | | | The last word of the UDS | | `UDS_LAST` | | invisible | | | | The last word of the UDS |
| `UART_BITRATE` | r/w | | | | | TBD | | `UART_BITRATE` | r/w | | | | | TBD |
| `UART_DATABITS` | r/w | | | | | TBD | | `UART_DATABITS` | r/w | | | | | TBD |
| `UART_STOPBITS` | r/w | | | | | TBD | | `UART_STOPBITS` | r/w | | | | | TBD |
| `UART_RX_STATUS` | r | r | 1B | u8 | | Non-zero when there is data to read | | `UART_RX_STATUS` | r | r | 1B | u8 | | Non-zero when there is data to read |
| `UART_RX_DATA` | r | r | 1B | u8 | | Data to read. Only LSB contains data | | `UART_RX_DATA` | r | r | 1B | u8 | | Data to read. Only LSB contains data |
| `UART_TX_STATUS` | r | r | 1B | u8 | | Non-zero when it's OK to write data | | `UART_TX_STATUS` | r | r | 1B | u8 | | Non-zero when it's OK to write data |
| `UART_TX_DATA` | w | w | 1B | u8 | | Data to send. Only LSB contains data | | `UART_TX_DATA` | w | w | 1B | u8 | | Data to send. Only LSB contains data |
| `TOUCH_STATUS` | r/w | r/w | | | | TOUCH_STATUS_EVENT_BIT is 1 when touched. After detecting a touch | | `TOUCH_STATUS` | r/w | r/w | | | | TOUCH_STATUS_EVENT_BIT is 1 when touched. After detecting a touch |
| | | | | | | event (reading a 1), write anything here to acknowledge it. | | | | | | | | event (reading a 1), write anything here to acknowledge it. |
| `FW_RAM` | r/w | invisible | 1 kiB | u8[1024] | | Firmware-only RAM. | | `FW_RAM` | r/w | invisible | 1 kiB | u8[1024] | | Firmware-only RAM. |
| `UDA` | r | invisible | 16B | u8[16] | | Unique Device Authentication key. | | `UDA` | r | invisible | 16B | u8[16] | | Unique Device Authentication key. |
| `UDI` | r | r | 8B | u64 | | Unique Device ID (UDI). | | `UDI` | r | r | 8B | u64 | | Unique Device ID (UDI). |
| `QEMU_DEBUG` | w | w | | u8 | | Debug console (only in QEMU) | | `QEMU_DEBUG` | w | w | | u8 | | Debug console (only in QEMU) |
| `NAME0` | r | r | 4B | char[4] | "tk1 " | ID of core/stick | | `NAME0` | r | r | 4B | char[4] | "tk1 " | ID of core/stick |
| `NAME1` | r | r | 4B | char[4] | "mkdf" | ID of core/stick | | `NAME1` | r | r | 4B | char[4] | "mkdf" | ID of core/stick |
| `VERSION` | r | r | 4B | u32 | 1 | Current version. | | `VERSION` | r | r | 4B | u32 | 1 | Current version. |
| `SWITCH_APP` | w | invisible? | 1B | u8 | | Switch to application mode. Write non-zero to trigger. | | `SWITCH_APP` | r/w | r | 1B | u8 | | Write anything here to trigger the switch to application mode. Reading |
| `LED` | w | w | 1B | u8 | | | | | | | | | | returns 0 if device is in firmware mode, 0xffffffff if in app mode. |
| `GPIO` | | | | | | | | `LED` | w | w | 1B | u8 | | |
| `APP_ADDR` | r/w | r | 4B | u32 | | Application address (0x4000_0000) | | `GPIO` | | | | | | |
| `APP_SIZE` | r/w | r | 4B | u32 | | Application size | | `APP_ADDR` | r/w | r | 4B | u32 | | Application address (0x4000_0000) |
| `CDI_FIRST` | r/w | r | 32B | u8[32] | | Compound Device Identifier (CDI). UDS+measurement... | | `APP_SIZE` | r/w | r | 4B | u32 | | Application size |
| `CDI_LAST` | | r | | | | Last word of CDI | | `CDI_FIRST` | r/w | r | 32B | u8[32] | | Compound Device Identifier (CDI). UDS+measurement... |
| `CDI_LAST` | | r | | | | Last word of CDI |
[^3]: The UDS can only be read *once* per power-cycle. [^3]: The UDS can only be read *once* per power-cycle.

View File

@ -151,10 +151,22 @@ int main()
anyfailed = 1; anyfailed = 1;
} }
uint32_t sw = *switch_app;
if (sw != 0) {
test_puts("FAIL: switch_app is not 0 in fw mode\r\n");
anyfailed = 1;
}
// Turn on application mode. // Turn on application mode.
// ------------------------- // -------------------------
*switch_app = 1; *switch_app = 1;
sw = *switch_app;
if (sw != 0xffffffff) {
test_puts("FAIL: switch_app is not 0xffffffff in app mode\r\n");
anyfailed = 1;
}
// Should NOT be able to read from UDS in app-mode. // Should NOT be able to read from UDS in app-mode.
wordcpy(uds_local, (void *)uds, 8); wordcpy(uds_local, (void *)uds, 8);
if (!memeq(uds_local, uds_zeros, 8 * 4)) { if (!memeq(uds_local, uds_zeros, 8 * 4)) {