hw/arm: add authenticated A6 IMG3 boot lab

Model the A6 crypto, interrupt, USB, and platform blocks needed to boot SecureROM through iBSS into iBEC Recovery.

Add local lab identity, IMG3, and APTicket tooling, patched macOS recovery utilities, UART and GDB access, and English end-user documentation.
This commit is contained in:
2026-09-01 09:51:49 -07:00
parent 47977dd34a
commit 5d9a60a926
45 changed files with 6002 additions and 265 deletions
+25 -7
View File
@@ -9,6 +9,8 @@
#define TYPE_S5L8950X_UART "s5l8950x-uart"
OBJECT_DECLARE_SIMPLE_TYPE(S5L8950XUartState, S5L8950X_UART)
#define S5L8950X_UART_RX_FIFO_SIZE 16
struct S5L8950XUartState {
SysBusDevice parent_obj;
@@ -22,7 +24,7 @@ struct S5L8950XUartState {
uint32_t ubrdiv;
uint32_t ufracval;
uint8_t rx_fifo[16];
uint8_t rx_fifo[S5L8950X_UART_RX_FIFO_SIZE];
int rx_count;
qemu_irq irq;
};
@@ -40,6 +42,9 @@ struct S5L8950XUartState {
#define UART_UBRDIV 0x28
#define UART_UFRACVAL 0x2C
#define UART_UFCON_RX_FIFO_RESET BIT(1)
#define UART_UFCON_TX_FIFO_RESET BIT(2)
static void s5l8950x_uart_update_irq(S5L8950XUartState *s)
{
if (s->rx_count > 0) {
@@ -76,7 +81,7 @@ static uint64_t s5l8950x_uart_read(void *opaque, hwaddr offset, unsigned size)
break;
case UART_UFSTAT:
/* Return rx count in low bits, no tx fifo used here */
val = s->rx_count & 0xf;
val = s->rx_count;
break;
case UART_UMSTAT:
val = 0;
@@ -89,6 +94,7 @@ static uint64_t s5l8950x_uart_read(void *opaque, hwaddr offset, unsigned size)
s->rx_count--;
memmove(s->rx_fifo, s->rx_fifo + 1, s->rx_count);
s5l8950x_uart_update_irq(s);
qemu_chr_fe_accept_input(&s->chr);
}
break;
case UART_UBRDIV:
@@ -118,7 +124,14 @@ static void s5l8950x_uart_write(void *opaque, hwaddr offset, uint64_t val, unsig
s->ucon = val;
break;
case UART_UFCON:
s->ufcon = val;
if (val & UART_UFCON_RX_FIFO_RESET) {
s->rx_count = 0;
s5l8950x_uart_update_irq(s);
qemu_chr_fe_accept_input(&s->chr);
}
/* FIFO reset bits are self-clearing; TX is unbuffered. */
s->ufcon = val & ~(UART_UFCON_RX_FIFO_RESET |
UART_UFCON_TX_FIFO_RESET);
break;
case UART_UMCON:
s->umcon = val;
@@ -151,9 +164,13 @@ static void s5l8950x_uart_write(void *opaque, hwaddr offset, uint64_t val, unsig
static const MemoryRegionOps s5l8950x_uart_ops = {
.read = s5l8950x_uart_read,
.write = s5l8950x_uart_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
.min_access_size = 1,
.max_access_size = 4,
},
.impl = {
.min_access_size = 1,
.max_access_size = 4,
},
};
@@ -162,7 +179,7 @@ static int s5l8950x_uart_can_receive(void *opaque)
{
S5L8950XUartState *s = S5L8950X_UART(opaque);
return sizeof(s->rx_fifo) - s->rx_count;
return S5L8950X_UART_RX_FIFO_SIZE - s->rx_count;
}
static void s5l8950x_uart_receive(void *opaque, const uint8_t *buf, int size)
@@ -170,7 +187,8 @@ static void s5l8950x_uart_receive(void *opaque, const uint8_t *buf, int size)
S5L8950XUartState *s = S5L8950X_UART(opaque);
int i;
for (i = 0; i < size && s->rx_count < sizeof(s->rx_fifo); i++) {
for (i = 0; i < size &&
s->rx_count < S5L8950X_UART_RX_FIFO_SIZE; i++) {
s->rx_fifo[s->rx_count++] = buf[i];
}
s5l8950x_uart_update_irq(s);