diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/arm/virt.c | 4 | ||||
-rw-r--r-- | hw/char/spapr_vty.c | 11 | ||||
-rw-r--r-- | hw/core/qdev-properties-system.c | 8 | ||||
-rw-r--r-- | hw/core/qdev-properties.c | 14 | ||||
-rw-r--r-- | hw/i386/pc.c | 26 | ||||
-rw-r--r-- | hw/ide/atapi.c | 51 | ||||
-rw-r--r-- | hw/net/virtio-net.c | 4 | ||||
-rw-r--r-- | hw/nvram/fw_cfg.c | 1 | ||||
-rw-r--r-- | hw/ppc/mac_newworld.c | 1 | ||||
-rw-r--r-- | hw/ppc/mac_oldworld.c | 1 | ||||
-rw-r--r-- | hw/ppc/pnv.c | 16 | ||||
-rw-r--r-- | hw/ppc/pnv_core.c | 1 | ||||
-rw-r--r-- | hw/ppc/pnv_lpc.c | 3 | ||||
-rw-r--r-- | hw/ppc/pnv_xscom.c | 10 | ||||
-rw-r--r-- | hw/ppc/spapr_pci.c | 18 | ||||
-rw-r--r-- | hw/sparc/sun4m.c | 1 | ||||
-rw-r--r-- | hw/sparc64/sun4u.c | 1 |
17 files changed, 114 insertions, 57 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 54a8b28a58..d04e4acbd9 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -929,9 +929,11 @@ static void create_fw_cfg(const VirtBoardInfo *vbi, AddressSpace *as) { hwaddr base = vbi->memmap[VIRT_FW_CFG].base; hwaddr size = vbi->memmap[VIRT_FW_CFG].size; + FWCfgState *fw_cfg; char *nodename; - fw_cfg_init_mem_wide(base + 8, base, 8, base + 16, as); + fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16, as); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base); qemu_fdt_add_subnode(vbi->fdt, nodename); diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 31822fed9a..06b9b3917f 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -1,4 +1,5 @@ #include "qemu/osdep.h" +#include "qemu/error-report.h" #include "qapi/error.h" #include "qemu-common.h" #include "cpu.h" @@ -37,7 +38,15 @@ static void vty_receive(void *opaque, const uint8_t *buf, int size) qemu_irq_pulse(spapr_vio_qirq(&dev->sdev)); } for (i = 0; i < size; i++) { - assert((dev->in - dev->out) < VTERM_BUFSIZE); + if (dev->in - dev->out >= VTERM_BUFSIZE) { + static bool reported; + if (!reported) { + error_report("VTY input buffer exhausted - characters dropped." + " (input size = %i)", size); + reported = true; + } + break; + } dev->buf[dev->in++ % VTERM_BUFSIZE] = buf[i]; } } diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index c35f0f59d6..1b7ea50e9f 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -200,18 +200,14 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque, } s = qemu_chr_find(str); - g_free(str); if (s == NULL) { error_setg(errp, "Property '%s.%s' can't find value '%s'", object_get_typename(obj), prop->name, str); - return; - } - - if (!qemu_chr_fe_init(be, s, errp)) { + } else if (!qemu_chr_fe_init(be, s, errp)) { error_prepend(errp, "Property '%s.%s' can't take value '%s': ", object_get_typename(obj), prop->name, str); - return; } + g_free(str); } static void release_chr(Object *obj, const char *name, void *opaque) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 311af6da76..2a82768067 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -705,13 +705,19 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name, DeviceState *dev = DEVICE(obj); Property *prop = opaque; PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); - char buffer[] = "xxxx:xx:xx.x"; + char buffer[] = "ffff:ff:ff.f"; char *p = buffer; int rc = 0; - rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d", - addr->domain, addr->bus, addr->slot, addr->function); - assert(rc == sizeof(buffer) - 1); + /* + * Catch "invalid" device reference from vfio-pci and allow the + * default buffer representing the non-existant device to be used. + */ + if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) { + rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d", + addr->domain, addr->bus, addr->slot, addr->function); + assert(rc == sizeof(buffer) - 1); + } visit_type_str(v, name, &p, errp); } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index a9b19507f1..a9e64a88e5 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -744,6 +744,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms) int i, j; fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86: * @@ -1226,7 +1227,7 @@ static void rtc_set_cpus_count(ISADevice *rtc, uint16_t cpus_count) { if (cpus_count > 0xff) { /* If the number of CPUs can't be represented in 8 bits, the - * BIOS must use "etc/boot-cpus". Set RTC field to 0 just + * BIOS must use "FW_CFG_NB_CPUS". Set RTC field to 0 just * to make old BIOSes fail more predictably. */ rtc_set_memory(rtc, 0x5f, 0); @@ -1243,7 +1244,7 @@ void pc_machine_done(Notifier *notifier, void *data) PCIBus *bus = pcms->bus; /* set the number of CPUs */ - rtc_set_cpus_count(pcms->rtc, le16_to_cpu(pcms->boot_cpus_le)); + rtc_set_cpus_count(pcms->rtc, pcms->boot_cpus); if (bus) { int extra_hosts = 0; @@ -1264,15 +1265,10 @@ void pc_machine_done(Notifier *notifier, void *data) acpi_setup(); if (pcms->fw_cfg) { - MachineClass *mc = MACHINE_GET_CLASS(pcms); - pc_build_smbios(pcms->fw_cfg); pc_build_feature_control_file(pcms); - - if (mc->max_cpus > 255) { - fw_cfg_add_file(pcms->fw_cfg, "etc/boot-cpus", &pcms->boot_cpus_le, - sizeof(pcms->boot_cpus_le)); - } + /* update FW_CFG_NB_CPUS to account for -device added CPUs */ + fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); } if (pcms->apic_id_limit > 255) { @@ -1350,6 +1346,7 @@ void xen_load_linux(PCMachineState *pcms) assert(MACHINE(pcms)->kernel_filename != NULL); fw_cfg = fw_cfg_init_io(FW_CFG_IO_BASE); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); rom_set_fw(fw_cfg); load_linux(pcms, fw_cfg); @@ -1820,10 +1817,10 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev, } /* increment the number of CPUs */ - pcms->boot_cpus_le = cpu_to_le16(le16_to_cpu(pcms->boot_cpus_le) + 1); + pcms->boot_cpus++; if (dev->hotplugged) { - /* Update the number of CPUs in CMOS */ - rtc_set_cpus_count(pcms->rtc, le16_to_cpu(pcms->boot_cpus_le)); + rtc_set_cpus_count(pcms->rtc, pcms->boot_cpus); + fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); } found_cpu = pc_find_cpu_slot(pcms, CPU(dev), NULL); @@ -1878,9 +1875,10 @@ static void pc_cpu_unplug_cb(HotplugHandler *hotplug_dev, object_unparent(OBJECT(dev)); /* decrement the number of CPUs */ - pcms->boot_cpus_le = cpu_to_le16(le16_to_cpu(pcms->boot_cpus_le) - 1); + pcms->boot_cpus--; /* Update the number of CPUs in CMOS */ - rtc_set_cpus_count(pcms->rtc, le16_to_cpu(pcms->boot_cpus_le)); + rtc_set_cpus_count(pcms->rtc, pcms->boot_cpus); + fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); out: error_propagate(errp, local_err); } diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 6189675036..fc1d19c6d4 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -637,6 +637,23 @@ static unsigned int event_status_media(IDEState *s, return 8; /* We wrote to 4 extra bytes from the header */ } +/* + * Before transferring data or otherwise signalling acceptance of a command + * marked CONDDATA, we must check the validity of the byte_count_limit. + */ +static bool validate_bcl(IDEState *s) +{ + /* TODO: Check IDENTIFY data word 125 for defacult BCL (currently 0) */ + if (s->atapi_dma || atapi_byte_count_limit(s)) { + return true; + } + + /* TODO: Move abort back into core.c and introduce proper error flow between + * ATAPI layer and IDE core layer */ + ide_abort_command(s); + return false; +} + static void cmd_get_event_status_notification(IDEState *s, uint8_t *buf) { @@ -1028,12 +1045,19 @@ static void cmd_read_cd(IDEState *s, uint8_t* buf) return; } - transfer_request = buf[9]; - switch(transfer_request & 0xf8) { - case 0x00: + transfer_request = buf[9] & 0xf8; + if (transfer_request == 0x00) { /* nothing */ ide_atapi_cmd_ok(s); - break; + return; + } + + /* Check validity of BCL before transferring data */ + if (!validate_bcl(s)) { + return; + } + + switch (transfer_request) { case 0x10: /* normal read */ ide_atapi_cmd_read(s, lba, nb_sectors, 2048); @@ -1266,6 +1290,14 @@ enum { * See ATA8-ACS3 "7.21.5 Byte Count Limit" */ NONDATA = 0x04, + + /* + * CONDDATA implies a command that transfers data only conditionally based + * on the presence of suboptions. It should be exempt from the BCL check at + * command validation time, but it needs to be checked at the command + * handler level instead. + */ + CONDDATA = 0x08, }; static const struct AtapiCmd { @@ -1289,7 +1321,7 @@ static const struct AtapiCmd { [ 0xad ] = { cmd_read_dvd_structure, CHECK_READY }, [ 0xbb ] = { cmd_set_speed, NONDATA }, [ 0xbd ] = { cmd_mechanism_status, 0 }, - [ 0xbe ] = { cmd_read_cd, CHECK_READY }, + [ 0xbe ] = { cmd_read_cd, CHECK_READY | CONDDATA }, /* [1] handler detects and reports not ready condition itself */ }; @@ -1348,15 +1380,12 @@ void ide_atapi_cmd(IDEState *s) return; } - /* Nondata commands permit the byte_count_limit to be 0. + /* Commands that don't transfer DATA permit the byte_count_limit to be 0. * If this is a data-transferring PIO command and BCL is 0, * we abort at the /ATA/ level, not the ATAPI level. * See ATA8 ACS3 section 7.17.6.49 and 7.21.5 */ - if (cmd->handler && !(cmd->flags & NONDATA)) { - /* TODO: Check IDENTIFY data word 125 for default BCL (currently 0) */ - if (!(atapi_byte_count_limit(s) || s->atapi_dma)) { - /* TODO: Move abort back into core.c and make static inline again */ - ide_abort_command(s); + if (cmd->handler && !(cmd->flags & (NONDATA | CONDDATA))) { + if (!validate_bcl(s)) { return; } } diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index b68c69d8f6..5009533cfa 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -508,6 +508,10 @@ static void virtio_net_set_queues(VirtIONet *n) int i; int r; + if (n->nic->peer_deleted) { + return; + } + for (i = 0; i < n->max_queues; i++) { if (i < n->curr_queues) { r = peer_attach(n, i); diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 1f0c3e9910..3ebecb2260 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -884,7 +884,6 @@ static void fw_cfg_init1(DeviceState *dev) fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4); fw_cfg_add_bytes(s, FW_CFG_UUID, &qemu_uuid, 16); fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)!machine->enable_graphics); - fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu); fw_cfg_bootsplash(s); fw_cfg_reboot(s); diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 7d2510658d..2bfdb643df 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -466,6 +466,7 @@ static void ppc_core99_init(MachineState *machine) /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 447948746b..56282c5bc6 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -319,6 +319,7 @@ static void ppc_heathrow_init(MachineState *machine) /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW); diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 82276e0857..9df7b25315 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -110,7 +110,7 @@ static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt) CPUState *cs = CPU(DEVICE(pc->threads)); DeviceClass *dc = DEVICE_GET_CLASS(cs); PowerPCCPU *cpu = POWERPC_CPU(cs); - int smt_threads = ppc_get_compat_smt_threads(cpu); + int smt_threads = CPU_CORE(pc)->nr_threads; CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); uint32_t servers_prop[smt_threads]; @@ -206,10 +206,6 @@ static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt) _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, sizeof(pa_features)))); - if (cpu->cpu_version) { - _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", cpu->cpu_version))); - } - /* Build interrupt servers properties */ for (i = 0; i < smt_threads; i++) { servers_prop[i] = cpu_to_be32(pc->pir + i); @@ -525,6 +521,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8E_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->xscom_base = 0x003fc0000000000ull; + k->xscom_core_base = 0x10000000ull; dc->desc = "PowerNV Chip POWER8E"; } @@ -546,6 +543,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->xscom_base = 0x003fc0000000000ull; + k->xscom_core_base = 0x10000000ull; dc->desc = "PowerNV Chip POWER8"; } @@ -567,6 +565,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->xscom_base = 0x003fc0000000000ull; + k->xscom_core_base = 0x10000000ull; dc->desc = "PowerNV Chip POWER8NVL"; } @@ -588,6 +587,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER9_CORE_MASK; k->core_pir = pnv_chip_core_pir_p9; k->xscom_base = 0x00603fc00000000ull; + k->xscom_core_base = 0x0ull; dc->desc = "PowerNV Chip POWER9"; } @@ -620,7 +620,7 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp) chip->cores_mask &= pcc->cores_mask; /* now that we have a sane layout, let check the number of cores */ - cores_max = hweight_long(chip->cores_mask); + cores_max = ctpop64(chip->cores_mask); if (chip->nr_cores > cores_max) { error_setg(errp, "warning: too many cores for chip ! Limit is %d", cores_max); @@ -695,7 +695,9 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp) object_unref(OBJECT(pnv_core)); /* Each core has an XSCOM MMIO region */ - pnv_xscom_add_subregion(chip, PNV_XSCOM_EX_CORE_BASE(core_hwid), + pnv_xscom_add_subregion(chip, + PNV_XSCOM_EX_CORE_BASE(pcc->xscom_core_base, + core_hwid), &PNV_CORE(pnv_core)->xscom_regs); i++; } diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 2acda9637d..76ce854b0c 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -24,6 +24,7 @@ #include "hw/ppc/ppc.h" #include "hw/ppc/pnv.h" #include "hw/ppc/pnv_core.h" +#include "hw/ppc/pnv_xscom.h" static void powernv_cpu_reset(void *opaque) { diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index 00dbd8b07b..0e2117f0f5 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -23,8 +23,9 @@ #include "qapi/error.h" #include "qemu/log.h" -#include "hw/ppc/pnv_lpc.h" #include "hw/ppc/pnv.h" +#include "hw/ppc/pnv_lpc.h" +#include "hw/ppc/pnv_xscom.h" #include "hw/ppc/fdt.h" #include <libfdt.h> diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c index 5aaa264bd7..8da271872f 100644 --- a/hw/ppc/pnv_xscom.c +++ b/hw/ppc/pnv_xscom.c @@ -25,8 +25,8 @@ #include "hw/sysbus.h" #include "hw/ppc/fdt.h" -#include "hw/ppc/pnv_xscom.h" #include "hw/ppc/pnv.h" +#include "hw/ppc/pnv_xscom.h" #include <libfdt.h> @@ -124,8 +124,8 @@ static uint64_t xscom_read(void *opaque, hwaddr addr, unsigned width) goto complete; } - val = address_space_ldq(&chip->xscom_as, pcba << 3, MEMTXATTRS_UNSPECIFIED, - &result); + val = address_space_ldq(&chip->xscom_as, (uint64_t) pcba << 3, + MEMTXATTRS_UNSPECIFIED, &result); if (result != MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "XSCOM read failed at @0x%" HWADDR_PRIx " pcba=0x%08x\n", addr, pcba); @@ -150,8 +150,8 @@ static void xscom_write(void *opaque, hwaddr addr, uint64_t val, goto complete; } - address_space_stq(&chip->xscom_as, pcba << 3, val, MEMTXATTRS_UNSPECIFIED, - &result); + address_space_stq(&chip->xscom_as, (uint64_t) pcba << 3, val, + MEMTXATTRS_UNSPECIFIED, &result); if (result != MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "XSCOM write failed at @0x%" HWADDR_PRIx " pcba=0x%08x data=0x%" PRIx64 "\n", diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 7cde30ee09..f9661b7d1a 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1658,19 +1658,25 @@ static int spapr_pci_post_load(void *opaque, int version_id) return 0; } +static bool version_before_3(void *opaque, int version_id) +{ + return version_id < 3; +} + static const VMStateDescription vmstate_spapr_pci = { .name = "spapr_pci", - .version_id = 2, + .version_id = 3, .minimum_version_id = 2, .pre_save = spapr_pci_pre_save, .post_load = spapr_pci_post_load, .fields = (VMStateField[]) { VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState), - VMSTATE_UINT32_EQUAL(dma_liobn[0], sPAPRPHBState), - VMSTATE_UINT64_EQUAL(mem_win_addr, sPAPRPHBState), - VMSTATE_UINT64_EQUAL(mem_win_size, sPAPRPHBState), - VMSTATE_UINT64_EQUAL(io_win_addr, sPAPRPHBState), - VMSTATE_UINT64_EQUAL(io_win_size, sPAPRPHBState), + VMSTATE_UNUSED_TEST(version_before_3, + sizeof(uint32_t) /* dma_liobn[0] */ + + sizeof(uint64_t) /* mem_win_addr */ + + sizeof(uint64_t) /* mem_win_size */ + + sizeof(uint64_t) /* io_win_addr */ + + sizeof(uint64_t) /* io_win_size */), VMSTATE_STRUCT_ARRAY(lsi_table, sPAPRPHBState, PCI_NUM_PINS, 0, vmstate_spapr_pci_lsi, struct spapr_pci_lsi), VMSTATE_INT32(msi_devs_num, sPAPRPHBState), diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 6224288ac3..f5b6efddf8 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -1033,6 +1033,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, hwdef->ecc_version); fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 271d8bc592..466331535b 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -855,6 +855,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, (uint8_t *)&nd_table[0].macaddr); fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); |