2 * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
4 * This code is licensed under the GPL version 2 or later. See the COPYING
5 * file in the top-level directory.
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"
18 #define TYPE_FBY35 MACHINE_TYPE_NAME("fby35")
19 OBJECT_DECLARE_SIMPLE_TYPE(Fby35State
, FBY35
);
22 MachineState parent_obj
;
24 MemoryRegion bmc_memory
;
25 MemoryRegion bmc_dram
;
26 MemoryRegion bmc_boot_rom
;
27 MemoryRegion bic_memory
;
30 Aspeed2600SoCState bmc
;
31 Aspeed10x0SoCState bic
;
36 #define FBY35_BMC_RAM_SIZE (2 * GiB)
37 #define FBY35_BMC_FIRMWARE_ADDR 0x0
39 static void fby35_bmc_write_boot_rom(DriveInfo
*dinfo
, MemoryRegion
*mr
,
40 hwaddr offset
, size_t rom_size
,
43 BlockBackend
*blk
= blk_by_legacy_dinfo(dinfo
);
44 g_autofree
void *storage
= NULL
;
48 * The block backend size should have already been 'validated' by
49 * the creation of the m25p80 object.
51 size
= blk_getlength(blk
);
53 error_setg(errp
, "failed to get flash size");
57 if (rom_size
> size
) {
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");
67 /* TODO: find a better way to install the ROM */
68 memcpy(memory_region_get_ram_ptr(mr
) + offset
, storage
, rom_size
);
71 static void fby35_bmc_init(Fby35State
*s
)
75 object_initialize_child(OBJECT(s
), "bmc", &s
->bmc
, "ast2600-a3");
76 soc
= ASPEED_SOC(&s
->bmc
);
78 memory_region_init(&s
->bmc_memory
, OBJECT(&s
->bmc
), "bmc-memory",
80 memory_region_init_ram(&s
->bmc_dram
, OBJECT(&s
->bmc
), "bmc-dram",
81 FBY35_BMC_RAM_SIZE
, &error_abort
);
83 object_property_set_int(OBJECT(&s
->bmc
), "ram-size", FBY35_BMC_RAM_SIZE
,
85 object_property_set_link(OBJECT(&s
->bmc
), "memory", OBJECT(&s
->bmc_memory
),
87 object_property_set_link(OBJECT(&s
->bmc
), "dram", OBJECT(&s
->bmc_dram
),
89 object_property_set_int(OBJECT(&s
->bmc
), "hw-strap1", 0x000000C0,
91 object_property_set_int(OBJECT(&s
->bmc
), "hw-strap2", 0x00000003,
93 aspeed_soc_uart_set_chr(soc
, ASPEED_DEV_UART5
, serial_hd(0));
94 qdev_realize(DEVICE(&s
->bmc
), NULL
, &error_abort
);
96 aspeed_board_init_flashes(&soc
->fmc
, "n25q00", 2, 0);
98 /* Install first FMC flash content as a boot rom. */
100 DriveInfo
*mtd0
= drive_get(IF_MTD
, 0, 0);
103 uint64_t rom_size
= memory_region_size(&soc
->spi_boot
);
105 memory_region_init_rom(&s
->bmc_boot_rom
, NULL
, "aspeed.boot_rom",
106 rom_size
, &error_abort
);
107 memory_region_add_subregion_overlap(&soc
->spi_boot_container
, 0,
108 &s
->bmc_boot_rom
, 1);
110 fby35_bmc_write_boot_rom(mtd0
, &s
->bmc_boot_rom
,
111 FBY35_BMC_FIRMWARE_ADDR
,
112 rom_size
, &error_abort
);
117 static void fby35_bic_init(Fby35State
*s
)
121 s
->bic_sysclk
= clock_new(OBJECT(s
), "SYSCLK");
122 clock_set_hz(s
->bic_sysclk
, 200000000ULL);
124 object_initialize_child(OBJECT(s
), "bic", &s
->bic
, "ast1030-a1");
125 soc
= ASPEED_SOC(&s
->bic
);
127 memory_region_init(&s
->bic_memory
, OBJECT(&s
->bic
), "bic-memory",
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
),
133 aspeed_soc_uart_set_chr(soc
, ASPEED_DEV_UART5
, serial_hd(1));
134 qdev_realize(DEVICE(&s
->bic
), NULL
, &error_abort
);
136 aspeed_board_init_flashes(&soc
->fmc
, "sst25vf032b", 2, 2);
137 aspeed_board_init_flashes(&soc
->spi
[0], "sst25vf032b", 2, 4);
138 aspeed_board_init_flashes(&soc
->spi
[1], "sst25vf032b", 2, 6);
141 static void fby35_init(MachineState
*machine
)
143 Fby35State
*s
= FBY35(machine
);
150 static bool fby35_get_mmio_exec(Object
*obj
, Error
**errp
)
152 return FBY35(obj
)->mmio_exec
;
155 static void fby35_set_mmio_exec(Object
*obj
, bool value
, Error
**errp
)
157 FBY35(obj
)->mmio_exec
= value
;
160 static void fby35_instance_init(Object
*obj
)
162 FBY35(obj
)->mmio_exec
= false;
165 static void fby35_class_init(ObjectClass
*oc
, void *data
)
167 MachineClass
*mc
= MACHINE_CLASS(oc
);
169 mc
->desc
= "Meta Platforms fby35";
170 mc
->init
= fby35_init
;
173 mc
->min_cpus
= mc
->max_cpus
= mc
->default_cpus
= 3;
175 object_class_property_add_bool(oc
, "execute-in-place",
177 fby35_set_mmio_exec
);
178 object_class_property_set_description(oc
, "execute-in-place",
179 "boot directly from CE0 flash device");
182 static const TypeInfo fby35_types
[] = {
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
,
192 DEFINE_TYPES(fby35_types
);