qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

fby35.c (6086B)


      1 /*
      2  * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
      3  *
      4  * This code is licensed under the GPL version 2 or later. See the COPYING
      5  * file in the top-level directory.
      6  */
      7 
      8 #include "qemu/osdep.h"
      9 #include "qemu/units.h"
     10 #include "qapi/error.h"
     11 #include "sysemu/sysemu.h"
     12 #include "sysemu/block-backend.h"
     13 #include "hw/boards.h"
     14 #include "hw/qdev-clock.h"
     15 #include "hw/arm/aspeed_soc.h"
     16 #include "hw/arm/boot.h"
     17 
     18 #define TYPE_FBY35 MACHINE_TYPE_NAME("fby35")
     19 OBJECT_DECLARE_SIMPLE_TYPE(Fby35State, FBY35);
     20 
     21 struct Fby35State {
     22     MachineState parent_obj;
     23 
     24     MemoryRegion bmc_memory;
     25     MemoryRegion bmc_dram;
     26     MemoryRegion bmc_boot_rom;
     27     MemoryRegion bic_memory;
     28     Clock *bic_sysclk;
     29 
     30     AspeedSoCState bmc;
     31     AspeedSoCState bic;
     32 
     33     bool mmio_exec;
     34 };
     35 
     36 #define FBY35_BMC_RAM_SIZE (2 * GiB)
     37 #define FBY35_BMC_FIRMWARE_ADDR 0x0
     38 
     39 static void fby35_bmc_write_boot_rom(DriveInfo *dinfo, MemoryRegion *mr,
     40                                      hwaddr offset, size_t rom_size,
     41                                      Error **errp)
     42 {
     43     BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
     44     g_autofree void *storage = NULL;
     45     int64_t size;
     46 
     47     /*
     48      * The block backend size should have already been 'validated' by
     49      * the creation of the m25p80 object.
     50      */
     51     size = blk_getlength(blk);
     52     if (size <= 0) {
     53         error_setg(errp, "failed to get flash size");
     54         return;
     55     }
     56 
     57     if (rom_size > size) {
     58         rom_size = size;
     59     }
     60 
     61     storage = g_malloc0(rom_size);
     62     if (blk_pread(blk, 0, rom_size, storage, 0) < 0) {
     63         error_setg(errp, "failed to read the initial flash content");
     64         return;
     65     }
     66 
     67     /* TODO: find a better way to install the ROM */
     68     memcpy(memory_region_get_ram_ptr(mr) + offset, storage, rom_size);
     69 }
     70 
     71 static void fby35_bmc_init(Fby35State *s)
     72 {
     73     DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
     74 
     75     object_initialize_child(OBJECT(s), "bmc", &s->bmc, "ast2600-a3");
     76 
     77     memory_region_init(&s->bmc_memory, OBJECT(&s->bmc), "bmc-memory",
     78                        UINT64_MAX);
     79     memory_region_init_ram(&s->bmc_dram, OBJECT(&s->bmc), "bmc-dram",
     80                            FBY35_BMC_RAM_SIZE, &error_abort);
     81 
     82     object_property_set_int(OBJECT(&s->bmc), "ram-size", FBY35_BMC_RAM_SIZE,
     83                             &error_abort);
     84     object_property_set_link(OBJECT(&s->bmc), "memory", OBJECT(&s->bmc_memory),
     85                              &error_abort);
     86     object_property_set_link(OBJECT(&s->bmc), "dram", OBJECT(&s->bmc_dram),
     87                              &error_abort);
     88     object_property_set_int(OBJECT(&s->bmc), "hw-strap1", 0x000000C0,
     89                             &error_abort);
     90     object_property_set_int(OBJECT(&s->bmc), "hw-strap2", 0x00000003,
     91                             &error_abort);
     92     aspeed_soc_uart_set_chr(&s->bmc, ASPEED_DEV_UART5, serial_hd(0));
     93     qdev_realize(DEVICE(&s->bmc), NULL, &error_abort);
     94 
     95     aspeed_board_init_flashes(&s->bmc.fmc, "n25q00", 2, 0);
     96 
     97     /* Install first FMC flash content as a boot rom. */
     98     if (drive0) {
     99         AspeedSMCFlash *fl = &s->bmc.fmc.flashes[0];
    100         MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
    101         uint64_t size = memory_region_size(&fl->mmio);
    102 
    103         if (s->mmio_exec) {
    104             memory_region_init_alias(boot_rom, NULL, "aspeed.boot_rom",
    105                                      &fl->mmio, 0, size);
    106             memory_region_add_subregion(&s->bmc_memory, FBY35_BMC_FIRMWARE_ADDR,
    107                                         boot_rom);
    108         } else {
    109 
    110             memory_region_init_rom(boot_rom, NULL, "aspeed.boot_rom",
    111                                    size, &error_abort);
    112             memory_region_add_subregion(&s->bmc_memory, FBY35_BMC_FIRMWARE_ADDR,
    113                                         boot_rom);
    114             fby35_bmc_write_boot_rom(drive0, boot_rom, FBY35_BMC_FIRMWARE_ADDR,
    115                                      size, &error_abort);
    116         }
    117     }
    118 }
    119 
    120 static void fby35_bic_init(Fby35State *s)
    121 {
    122     s->bic_sysclk = clock_new(OBJECT(s), "SYSCLK");
    123     clock_set_hz(s->bic_sysclk, 200000000ULL);
    124 
    125     object_initialize_child(OBJECT(s), "bic", &s->bic, "ast1030-a1");
    126 
    127     memory_region_init(&s->bic_memory, OBJECT(&s->bic), "bic-memory",
    128                        UINT64_MAX);
    129 
    130     qdev_connect_clock_in(DEVICE(&s->bic), "sysclk", s->bic_sysclk);
    131     object_property_set_link(OBJECT(&s->bic), "memory", OBJECT(&s->bic_memory),
    132                              &error_abort);
    133     aspeed_soc_uart_set_chr(&s->bic, ASPEED_DEV_UART5, serial_hd(1));
    134     qdev_realize(DEVICE(&s->bic), NULL, &error_abort);
    135 
    136     aspeed_board_init_flashes(&s->bic.fmc, "sst25vf032b", 2, 2);
    137     aspeed_board_init_flashes(&s->bic.spi[0], "sst25vf032b", 2, 4);
    138     aspeed_board_init_flashes(&s->bic.spi[1], "sst25vf032b", 2, 6);
    139 }
    140 
    141 static void fby35_init(MachineState *machine)
    142 {
    143     Fby35State *s = FBY35(machine);
    144 
    145     fby35_bmc_init(s);
    146     fby35_bic_init(s);
    147 }
    148 
    149 
    150 static bool fby35_get_mmio_exec(Object *obj, Error **errp)
    151 {
    152     return FBY35(obj)->mmio_exec;
    153 }
    154 
    155 static void fby35_set_mmio_exec(Object *obj, bool value, Error **errp)
    156 {
    157     FBY35(obj)->mmio_exec = value;
    158 }
    159 
    160 static void fby35_instance_init(Object *obj)
    161 {
    162     FBY35(obj)->mmio_exec = false;
    163 }
    164 
    165 static void fby35_class_init(ObjectClass *oc, void *data)
    166 {
    167     MachineClass *mc = MACHINE_CLASS(oc);
    168 
    169     mc->desc = "Meta Platforms fby35";
    170     mc->init = fby35_init;
    171     mc->no_floppy = 1;
    172     mc->no_cdrom = 1;
    173     mc->min_cpus = mc->max_cpus = mc->default_cpus = 3;
    174 
    175     object_class_property_add_bool(oc, "execute-in-place",
    176                                    fby35_get_mmio_exec,
    177                                    fby35_set_mmio_exec);
    178     object_class_property_set_description(oc, "execute-in-place",
    179                            "boot directly from CE0 flash device");
    180 }
    181 
    182 static const TypeInfo fby35_types[] = {
    183     {
    184         .name = MACHINE_TYPE_NAME("fby35"),
    185         .parent = TYPE_MACHINE,
    186         .class_init = fby35_class_init,
    187         .instance_size = sizeof(Fby35State),
    188         .instance_init = fby35_instance_init,
    189     },
    190 };
    191 
    192 DEFINE_TYPES(fby35_types);