1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <arch/ioapic.h>
5 #include <console/console.h>
7 #include <cpu/x86/lapic_def.h>
8 #include <cpu/x86/mp.h>
9 #include <device/pci_def.h>
10 #include <device/pci_ops.h>
11 #include <device/device.h>
12 #include <device/fw_cfg.h>
13 #include <device/fw_cfg_if.h>
22 static void qemu_reserve_ports(struct device
*dev
, unsigned int idx
,
23 unsigned int base
, unsigned int size
,
26 unsigned int end
= base
+ size
-1;
29 printk(BIOS_DEBUG
, "QEMU: reserve ioports 0x%04x-0x%04x [%s]\n",
31 res
= new_resource(dev
, idx
);
35 res
->flags
= IORESOURCE_IO
| IORESOURCE_FIXED
| IORESOURCE_STORED
|
39 static void cpu_pci_domain_set_resources(struct device
*dev
)
41 assign_resources(dev
->downstream
);
44 static void cpu_pci_domain_read_resources(struct device
*dev
)
46 u16 nbid
= pci_read_config16(pcidev_on_root(0x0, 0), PCI_DEVICE_ID
);
47 int i440fx
= (nbid
== 0x1237);
48 int q35
= (nbid
== 0x29c0);
54 pci_domain_read_resources(dev
);
56 if (!fw_cfg_check_file(&f
, "etc/e820") && f
.size
> 0) {
57 /* supported by qemu 1.7+ */
58 FwCfgE820Entry
*list
= malloc(f
.size
);
60 fw_cfg_get(f
.select
, list
, f
.size
);
61 for (i
= 0; i
< f
.size
/ sizeof(*list
); i
++) {
62 switch (list
[i
].type
) {
64 printk(BIOS_DEBUG
, "QEMU: e820/ram: 0x%08llx + 0x%08llx\n",
65 list
[i
].address
, list
[i
].length
);
66 if (list
[i
].address
== 0) {
67 tomk
= list
[i
].length
/ 1024;
68 ram_from_to(dev
, idx
++, 0, 0xa0000);
69 ram_from_to(dev
, idx
++, 0xc0000, tomk
* KiB
);
71 ram_range(dev
, idx
++, list
[i
].address
, list
[i
].length
);
74 case 2: /* reserved */
75 printk(BIOS_DEBUG
, "QEMU: e820/res: 0x%08llx +0x%08llx\n",
76 list
[i
].address
, list
[i
].length
);
77 res
= new_resource(dev
, idx
++);
78 res
->base
= list
[i
].address
;
79 res
->size
= list
[i
].length
;
80 res
->limit
= 0xffffffff;
81 res
->flags
= IORESOURCE_MEM
| IORESOURCE_FIXED
|
82 IORESOURCE_STORED
| IORESOURCE_ASSIGNED
;
93 /* qemu older than 1.7, or reading etc/e820 failed. Fallback to cmos. */
94 tomk
= qemu_get_memory_size();
95 uint64_t high
= qemu_get_high_memory_size();
96 printk(BIOS_DEBUG
, "QEMU: cmos: %llu MiB RAM below 4G.\n", tomk
/ 1024);
97 printk(BIOS_DEBUG
, "QEMU: cmos: %llu MiB RAM above 4G.\n", high
/ 1024);
99 /* Report the memory regions. */
100 ram_from_to(dev
, idx
++, 0, 0xa0000);
101 ram_from_to(dev
, idx
++, 0xc0000, tomk
* KiB
);
104 upper_ram_end(dev
, idx
++, 4ull * GiB
+ high
* KiB
);
107 /* Reserve I/O ports used by QEMU */
108 qemu_reserve_ports(dev
, idx
++, 0x0510, 0x02, "firmware-config");
109 qemu_reserve_ports(dev
, idx
++, 0x5658, 0x01, "vmware-port");
111 qemu_reserve_ports(dev
, idx
++, 0xae00, 0x10, "pci-hotplug");
112 qemu_reserve_ports(dev
, idx
++, 0xaf00, 0x20, "cpu-hotplug");
113 qemu_reserve_ports(dev
, idx
++, 0xafe0, 0x04, "piix4-gpe0");
115 if (inb(CONFIG_CONSOLE_QEMU_DEBUGCON_PORT
) == 0xe9) {
116 qemu_reserve_ports(dev
, idx
++, CONFIG_CONSOLE_QEMU_DEBUGCON_PORT
, 1,
120 /* A segment is legacy VGA region */
121 mmio_from_to(dev
, idx
++, 0xa0000, 0xc0000);
123 /* C segment to 1MB is reserved RAM (low tables) */
124 reserved_ram_from_to(dev
, idx
++, 0xc0000, 1 * MiB
);
126 if (q35
&& ((tomk
* 1024) < 0xb0000000)) {
128 * Reserve the region between top-of-ram and the
129 * mmconf xbar (ar 0xb0000000), so coreboot doesn't
130 * place pci bars there. The region isn't declared as
131 * pci io window in the ACPI tables (\_SB.PCI0._CRS).
133 res
= new_resource(dev
, idx
++);
134 res
->base
= tomk
* 1024;
135 res
->size
= 0xb0000000 - tomk
* 1024;
136 res
->limit
= 0xffffffff;
137 res
->flags
= IORESOURCE_MEM
| IORESOURCE_FIXED
|
138 IORESOURCE_STORED
| IORESOURCE_ASSIGNED
;
142 /* Reserve space for the IOAPIC. This should be in
143 * the southbridge, but I couldn't tell which device
145 res
= new_resource(dev
, 2);
146 res
->base
= IO_APIC_ADDR
;
147 res
->size
= 0x100000UL
;
148 res
->limit
= 0xffffffffUL
;
149 res
->flags
= IORESOURCE_MEM
| IORESOURCE_FIXED
|
150 IORESOURCE_STORED
| IORESOURCE_ASSIGNED
;
153 /* Reserve space for the LAPIC. There's one in every processor, but
154 * the space only needs to be reserved once, so we do it here. */
155 res
= new_resource(dev
, 3);
156 res
->base
= cpu_get_lapic_addr();
157 res
->size
= 0x10000UL
;
158 res
->limit
= 0xffffffffUL
;
159 res
->flags
= IORESOURCE_MEM
| IORESOURCE_FIXED
| IORESOURCE_STORED
|
163 #if CONFIG(GENERATE_SMBIOS_TABLES)
164 static int qemu_get_smbios_data16(int handle
, unsigned long *current
)
166 struct smbios_type16
*t
= smbios_carve_table(*current
, SMBIOS_PHYS_MEMORY_ARRAY
,
169 t
->location
= MEMORY_ARRAY_LOCATION_SYSTEM_BOARD
;
170 t
->use
= MEMORY_ARRAY_USE_SYSTEM
;
171 t
->memory_error_correction
= MEMORY_ARRAY_ECC_NONE
;
172 t
->maximum_capacity
= qemu_get_memory_size();
174 const int len
= smbios_full_table_len(&t
->header
, t
->eos
);
179 static int qemu_get_smbios_data17(int handle
, int parent_handle
, unsigned long *current
)
181 struct smbios_type17
*t
= smbios_carve_table(*current
, SMBIOS_MEMORY_DEVICE
,
184 t
->phys_memory_array_handle
= parent_handle
;
185 t
->size
= qemu_get_memory_size() / 1024;
188 t
->form_factor
= MEMORY_FORMFACTOR_DIMM
;
189 t
->device_locator
= smbios_add_string(t
->eos
, "Virtual");
190 t
->memory_type
= MEMORY_TYPE_DDR
;
191 t
->type_detail
= MEMORY_TYPE_DETAIL_SYNCHRONOUS
;
193 t
->clock_speed
= 200;
194 t
->manufacturer
= smbios_add_string(t
->eos
, mainboard_vendor
);
196 const int len
= smbios_full_table_len(&t
->header
, t
->eos
);
201 static int qemu_get_smbios_data(struct device
*dev
, int *handle
, unsigned long *current
)
205 len
= fw_cfg_smbios_tables(handle
, current
);
209 len
= qemu_get_smbios_data16(*handle
, current
);
210 len
+= qemu_get_smbios_data17(*handle
+1, *handle
, current
);
216 #if CONFIG(HAVE_ACPI_TABLES)
217 static const char *qemu_acpi_name(const struct device
*dev
)
219 if (dev
->path
.type
== DEVICE_PATH_DOMAIN
)
222 if (!is_pci_dev_on_bus(dev
, 0))
229 static struct device_operations pci_domain_ops
= {
230 .read_resources
= cpu_pci_domain_read_resources
,
231 .set_resources
= cpu_pci_domain_set_resources
,
232 .scan_bus
= pci_host_bridge_scan_bus
,
233 #if CONFIG(GENERATE_SMBIOS_TABLES)
234 .get_smbios_data
= qemu_get_smbios_data
,
236 #if CONFIG(HAVE_ACPI_TABLES)
237 .acpi_name
= qemu_acpi_name
,
241 static const struct mp_ops mp_ops_no_smm
= {
242 .get_cpu_count
= fw_cfg_max_cpus
,
245 extern const struct mp_ops mp_ops_with_smm
;
247 void mp_init_cpus(struct bus
*cpu_bus
)
249 const struct mp_ops
*ops
= CONFIG(NO_SMM
) ? &mp_ops_no_smm
: &mp_ops_with_smm
;
251 /* TODO: Handle mp_init_with_smm failure? */
252 mp_init_with_smm(cpu_bus
, ops
);
255 static void cpu_bus_init(struct device
*dev
)
257 mp_cpu_bus_init(dev
);
260 static struct device_operations cpu_bus_ops
= {
261 .read_resources
= noop_read_resources
,
262 .set_resources
= noop_set_resources
,
263 .init
= cpu_bus_init
,
266 static void northbridge_enable(struct device
*dev
)
268 /* Set the operations if it is a special bus type */
269 if (dev
->path
.type
== DEVICE_PATH_DOMAIN
) {
270 dev
->ops
= &pci_domain_ops
;
272 else if (dev
->path
.type
== DEVICE_PATH_CPU_CLUSTER
) {
273 dev
->ops
= &cpu_bus_ops
;
277 struct chip_operations mainboard_emulation_qemu_i440fx_ops
= {
278 .name
= "QEMU Northbridge i440fx",
279 .enable_dev
= northbridge_enable
,
282 struct chip_operations mainboard_emulation_qemu_q35_ops
= {
283 .name
= "QEMU Northbridge q35",
284 .enable_dev
= northbridge_enable
,