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
;
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
)
73 DriveInfo
*drive0
= drive_get(IF_MTD
, 0, 0);
75 object_initialize_child(OBJECT(s
), "bmc", &s
->bmc
, "ast2600-a3");
77 memory_region_init(&s
->bmc_memory
, OBJECT(&s
->bmc
), "bmc-memory",
79 memory_region_init_ram(&s
->bmc_dram
, OBJECT(&s
->bmc
), "bmc-dram",
80 FBY35_BMC_RAM_SIZE
, &error_abort
);
82 object_property_set_int(OBJECT(&s
->bmc
), "ram-size", FBY35_BMC_RAM_SIZE
,
84 object_property_set_link(OBJECT(&s
->bmc
), "memory", OBJECT(&s
->bmc_memory
),
86 object_property_set_link(OBJECT(&s
->bmc
), "dram", OBJECT(&s
->bmc_dram
),
88 object_property_set_int(OBJECT(&s
->bmc
), "hw-strap1", 0x000000C0,
90 object_property_set_int(OBJECT(&s
->bmc
), "hw-strap2", 0x00000003,
92 aspeed_soc_uart_set_chr(&s
->bmc
, ASPEED_DEV_UART5
, serial_hd(0));
93 qdev_realize(DEVICE(&s
->bmc
), NULL
, &error_abort
);
95 aspeed_board_init_flashes(&s
->bmc
.fmc
, "n25q00", 2, 0);
97 /* Install first FMC flash content as a boot rom. */
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
);
104 memory_region_init_alias(boot_rom
, NULL
, "aspeed.boot_rom",
106 memory_region_add_subregion(&s
->bmc_memory
, FBY35_BMC_FIRMWARE_ADDR
,
110 memory_region_init_rom(boot_rom
, NULL
, "aspeed.boot_rom",
112 memory_region_add_subregion(&s
->bmc_memory
, FBY35_BMC_FIRMWARE_ADDR
,
114 fby35_bmc_write_boot_rom(drive0
, boot_rom
, FBY35_BMC_FIRMWARE_ADDR
,
120 static void fby35_bic_init(Fby35State
*s
)
122 s
->bic_sysclk
= clock_new(OBJECT(s
), "SYSCLK");
123 clock_set_hz(s
->bic_sysclk
, 200000000ULL);
125 object_initialize_child(OBJECT(s
), "bic", &s
->bic
, "ast1030-a1");
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(&s
->bic
, ASPEED_DEV_UART5
, serial_hd(1));
134 qdev_realize(DEVICE(&s
->bic
), NULL
, &error_abort
);
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);
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
);