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
+31
View File
@@ -18,6 +18,17 @@
/* Recovery/DFU button sampled by SecureROM as GPIO 0x1906. */
#define S5L8950X_GPIO_DFU_OFFSET (((0x19 * 8) + 6) * sizeof(uint32_t))
/*
* SecureROM packs these four board straps into bits [11:8] of the
* boot-policy word at 0x3f106000. Profile 2 is the authenticated A6
* production path used by this n41ap machine.
*/
#define S5L8950X_GPIO_STRAP_0_OFFSET (((0x02 * 8) + 2) * sizeof(uint32_t))
#define S5L8950X_GPIO_STRAP_1_OFFSET (((0x19 * 8) + 5) * sizeof(uint32_t))
#define S5L8950X_GPIO_STRAP_2_OFFSET (((0x1a * 8) + 0) * sizeof(uint32_t))
#define S5L8950X_GPIO_STRAP_3_OFFSET (((0x1a * 8) + 1) * sizeof(uint32_t))
/* iBEC samples GPIO 1 as an active-low boot/power button. */
#define S5L8950X_GPIO_BOOT_BUTTON_OFFSET sizeof(uint32_t)
#define S5L8950X_GPIO_INPUT_LEVEL BIT(0)
OBJECT_DECLARE_SIMPLE_TYPE(S5L8950XGPIOState, S5L8950X_GPIO)
@@ -27,6 +38,7 @@ struct S5L8950XGPIOState {
MemoryRegion iomem;
uint32_t regs[S5L8950X_GPIO_NUM_REGS];
bool force_dfu;
uint8_t board_straps;
};
static uint64_t s5l8950x_gpio_read(void *opaque, hwaddr offset,
@@ -40,9 +52,27 @@ static uint64_t s5l8950x_gpio_read(void *opaque, hwaddr offset,
}
value = s->regs[offset / sizeof(uint32_t)];
if (offset == S5L8950X_GPIO_BOOT_BUTTON_OFFSET) {
/*
* No host button is currently wired up: expose the released level so
* iBEC does not mistake the zero-filled register file for a button
* held continuously and power the device off after its timeout.
*/
value |= S5L8950X_GPIO_INPUT_LEVEL;
}
if (s->force_dfu && offset == S5L8950X_GPIO_DFU_OFFSET) {
value |= S5L8950X_GPIO_INPUT_LEVEL;
}
if ((offset == S5L8950X_GPIO_STRAP_0_OFFSET &&
(s->board_straps & BIT(0))) ||
(offset == S5L8950X_GPIO_STRAP_1_OFFSET &&
(s->board_straps & BIT(1))) ||
(offset == S5L8950X_GPIO_STRAP_2_OFFSET &&
(s->board_straps & BIT(2))) ||
(offset == S5L8950X_GPIO_STRAP_3_OFFSET &&
(s->board_straps & BIT(3)))) {
value |= S5L8950X_GPIO_INPUT_LEVEL;
}
return value;
}
@@ -76,6 +106,7 @@ static const MemoryRegionOps s5l8950x_gpio_ops = {
static const Property s5l8950x_gpio_properties[] = {
DEFINE_PROP_BOOL("force-dfu", S5L8950XGPIOState, force_dfu, false),
DEFINE_PROP_UINT8("board-straps", S5L8950XGPIOState, board_straps, 0),
};
static void s5l8950x_gpio_reset(DeviceState *dev)