Introduces support for loading a vbootrom image into the dedicated vbootrom
memory region in the AST2700 Full Core machine.

Additionally, it implements a mechanism to extract the content of fmc_cs0
flash data(backend file) and copy it into the memory-mapped region
corresponding to ASPEED_DEV_SPI_BOOT.

Signed-off-by: Jamin Lin <jamin_...@aspeedtech.com>
---
 hw/arm/aspeed_ast27x0-fc.c | 75 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c
index 7087be4288..e2eee6183f 100644
--- a/hw/arm/aspeed_ast27x0-fc.c
+++ b/hw/arm/aspeed_ast27x0-fc.c
@@ -11,6 +11,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/units.h"
+#include "qemu/datadir.h"
 #include "qapi/error.h"
 #include "system/block-backend.h"
 #include "system/system.h"
@@ -35,6 +36,7 @@ struct Ast2700FCState {
 
     MemoryRegion ca35_memory;
     MemoryRegion ca35_dram;
+    MemoryRegion ca35_boot_rom;
     MemoryRegion ssp_memory;
     MemoryRegion tsp_memory;
 
@@ -55,12 +57,65 @@ struct Ast2700FCState {
 #define AST2700FC_HW_STRAP2 0x00000003
 #define AST2700FC_FMC_MODEL "w25q01jvq"
 #define AST2700FC_SPI_MODEL "w25q512jv"
+#define VBOOTROM_FILE_NAME  "ast27x0_bootrom.bin"
+
+static void ast2700fc_ca35_load_vbootrom(AspeedSoCState *soc,
+                                         const char *bios_name, Error **errp)
+{
+    g_autofree char *filename = NULL;
+    int ret;
+
+    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+    if (!filename) {
+        error_setg(errp, "Could not find vbootrom image '%s'", bios_name);
+        return;
+    }
+
+    ret = load_image_mr(filename, &soc->vbootrom);
+    if (ret < 0) {
+        error_setg(errp, "Failed to load vbootrom image '%s'", bios_name);
+        return;
+    }
+}
+
+static void ast2700fc_ca35_write_boot_rom(DriveInfo *dinfo, hwaddr addr,
+                                         size_t rom_size, Error **errp)
+{
+    BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+    g_autofree void *storage = NULL;
+    int64_t size;
+
+    /*
+     * The block backend size should have already been 'validated' by
+     * the creation of the m25p80 object.
+     */
+    size = blk_getlength(blk);
+    if (size <= 0) {
+        error_setg(errp, "failed to get flash size");
+        return;
+    }
+
+    if (rom_size > size) {
+        rom_size = size;
+    }
+
+    storage = g_malloc0(rom_size);
+    if (blk_pread(blk, 0, rom_size, storage, 0) < 0) {
+        error_setg(errp, "failed to read the initial flash content");
+        return;
+    }
+
+    rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
+}
 
 static void ast2700fc_ca35_init(MachineState *machine)
 {
     Ast2700FCState *s = AST2700A1FC(machine);
+    const char *bios_name = NULL;
     AspeedSoCState *soc;
     AspeedSoCClass *sc;
+    uint64_t rom_size;
+    DriveInfo *mtd0;
 
     object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a1");
     soc = ASPEED_SOC(&s->ca35);
@@ -118,6 +173,26 @@ static void ast2700fc_ca35_init(MachineState *machine)
     ast2700fc_board_info.ram_size = machine->ram_size;
     ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
 
+    /* Install first FMC flash content as a boot rom. */
+    if (!s->mmio_exec) {
+        mtd0 = drive_get(IF_MTD, 0, 0);
+
+        if (mtd0) {
+            rom_size = memory_region_size(&soc->spi_boot);
+            memory_region_init_rom(&s->ca35_boot_rom, NULL, "aspeed.boot_rom",
+                                   rom_size, &error_abort);
+            memory_region_add_subregion_overlap(&soc->spi_boot_container, 0,
+                                                &s->ca35_boot_rom, 1);
+            ast2700fc_ca35_write_boot_rom(mtd0,
+                                          sc->memmap[ASPEED_DEV_SPI_BOOT],
+                                          rom_size, &error_abort);
+        }
+    }
+
+    /* VBOOTROM */
+    bios_name = machine->firmware ?: VBOOTROM_FILE_NAME;
+    ast2700fc_ca35_load_vbootrom(soc, bios_name, &error_abort);
+
     arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info);
 }
 
-- 
2.43.0


Reply via email to