ASpeed的 Alternate Bootblock Recovery 功能, 当primary flash不能正常启动时, 可以支持从backup的flash启动. 这个功能有点复杂, qemu 暂时不支持. 但是现在修改关键的寄存器, 可以设置系统的环境, 来进行启动之后的环境. 虽然不能真的切到secondary 系统, 但是可以模拟在这个情况的环境.
在qemu的源码 hw/ssi/aspeed_smc.c
static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
........
} else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) {
s->regs[addr] = value & FMC_WDT2_CTRL_EN;
} else if (addr == R_INTR_CTRL) {
这段代码修改FMC WDT2 的control寄存器, 但是只能修改 enable bit.
按照SPEC register说明, 修改其操作. 另外这个寄存器部分bit实际上Readonly. 允许修改, 就能根据需要建立测试环境
#define R_FMC_WDT2_CTRL (0x64 / 4)
#define FMC_WDT2_CTRL_ALT_BOOT_MODE BIT(6) /* O: 2 chips 1: 1 chip */
#define FMC_WDT2_CTRL_SINGLE_BOOT_MODE BIT(5)
#define FMC_WDT2_CTRL_BOOT_SOURCE BIT(4) /* O: primary 1: alternate */
#define FMC_WDT2_CTRL_EN BIT(0)
/* FMC_WDT2 Reload/Status Register for Alternate Boot (AST2600) */
#define R_FMC_WDT2_RELOAD (0x68 / 4)
#define FMC_WDT2_RELOAD_ALT_BOOT_MODE BIT(6) /* O: 2 chips 1: 1 chip */
#define FMC_WDT2_RELOAD_SINGLE_BOOT_MODE BIT(5)
#define FMC_WDT2_RELOAD_BOOT_SOURCE BIT(4) /* O: primary 1: alternate */
#define FMC_WDT2_RELOAD_EXPIRE_TIME (0xFFF)
/* FMC_WDT2 Reload/Status Register for Alternate Boot (AST2600) */
#define R_FMC_WDT2_RESTART (0x6C / 4)
......
static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
.........
} else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) {
if (value == 0xea0000)
s->regs[addr] = s->regs[addr] & (~FMC_WDT2_CTRL_BOOT_SOURCE);
else if (value == 0xea000000)
s->regs[addr] = s->regs[addr] & (~0xFF00);
else
s->regs[addr] = value;// & FMC_WDT2_CTRL_EN;
}
这样启动后, 通过devmem修改寄存器, 假装进入了 secondary 系统.
devmem 0x1e620064 32 0x10
这样部分测试, qemu比真机测试还方便, 只要设置register就行, 不需要重新启动.