diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-02-21 19:52:58 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-02-21 19:52:58 +0000 |
commit | 00d8ba9e0d62ea1c7459c25aeabf9c8bb7659462 (patch) | |
tree | 188c7a650d48c12a9cf244575cdd13700471b584 /hw | |
parent | 4115aec9af2a3de5fa89a0b1daa12debcd7741ff (diff) | |
parent | cc2b4550115baf77d556341f17eb464d18953cee (diff) |
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/mips-20210221' into staging
MIPS patches queue
- Drop redundant struct MemmapEntry (Bin)
- Fix for Coverity CID 1438965 and 1438967 (Jiaxun)
- Add MIPS bootloader API (Jiaxun)
- Use MIPS bootloader API on fuloong2e and boston machines (Jiaxun)
- Add PMON test for Loongson-3A1000 CPU (Jiaxun)
- Convert to translator API (Philippe)
- MMU cleanups (Philippe)
- Promote 128-bit multimedia registers as global ones (Philippe)
- Various cleanups/fixes on the VT82C686B southbridge (Zoltan)
# gpg: Signature made Sun 21 Feb 2021 18:43:57 GMT
# gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE
* remotes/philmd-gitlab/tags/mips-20210221: (43 commits)
vt82c686: Fix superio_cfg_{read,write}() functions
vt82c686: Log superio_cfg unimplemented accesses
vt82c686: Simplify by returning earlier
vt82c686: Reduce indentation by returning early
vt82c686: Remove index field of SuperIOConfig
vt82c686: Move creation of ISA devices to the ISA bridge
vt82c686: Simplify vt82c686b_realize()
vt82c686: Make vt82c686b-pm an abstract base class and add vt8231-pm based on it
vt82c686: Set user_creatable=false for VT82C686B_PM
vt82c686: Fix up power management io base and config
vt82c686: Correctly reset all registers to default values on reset
vt82c686: Correct vt82c686-pm I/O size
vt82c686: Make vt82c686-pm an I/O tracing region
vt82c686: Fix SMBus IO base and configuration registers
vt82c686: Reorganise code
vt82c686: Move superio memory region to SuperIOConfig struct
target/mips: Use GPR move functions in gen_HILO1_tx79()
target/mips: Introduce gen_load_gpr_hi() / gen_store_gpr_hi() helpers
target/mips: Rename 128-bit upper halve GPR registers
target/mips: Promote 128-bit multimedia registers as global ones
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/intc/loongson_liointc.c | 16 | ||||
-rw-r--r-- | hw/isa/trace-events | 2 | ||||
-rw-r--r-- | hw/isa/vt82c686.c | 464 | ||||
-rw-r--r-- | hw/mips/bootloader.c | 200 | ||||
-rw-r--r-- | hw/mips/boston.c | 62 | ||||
-rw-r--r-- | hw/mips/fuloong2e.c | 60 | ||||
-rw-r--r-- | hw/mips/loongson3_bootp.h | 7 | ||||
-rw-r--r-- | hw/mips/loongson3_virt.c | 6 | ||||
-rw-r--r-- | hw/mips/meson.build | 2 |
9 files changed, 522 insertions, 297 deletions
diff --git a/hw/intc/loongson_liointc.c b/hw/intc/loongson_liointc.c index f823d484e0..cc11b544cb 100644 --- a/hw/intc/loongson_liointc.c +++ b/hw/intc/loongson_liointc.c @@ -41,7 +41,7 @@ #define R_IEN_CLR 0x2c #define R_ISR_SIZE 0x8 #define R_START 0x40 -#define R_END 0x64 +#define R_END (R_START + R_ISR_SIZE * NUM_CORES) struct loongson_liointc { SysBusDevice parent_obj; @@ -125,7 +125,12 @@ liointc_read(void *opaque, hwaddr addr, unsigned int size) } if (addr >= R_START && addr < R_END) { - int core = (addr - R_START) / R_ISR_SIZE; + hwaddr offset = addr - R_START; + int core = offset / R_ISR_SIZE; + + if (offset % R_ISR_SIZE) { + goto out; + } r = p->per_core_isr[core]; goto out; } @@ -169,7 +174,12 @@ liointc_write(void *opaque, hwaddr addr, } if (addr >= R_START && addr < R_END) { - int core = (addr - R_START) / R_ISR_SIZE; + hwaddr offset = addr - R_START; + int core = offset / R_ISR_SIZE; + + if (offset % R_ISR_SIZE) { + goto out; + } p->per_core_isr[core] = value; goto out; } diff --git a/hw/isa/trace-events b/hw/isa/trace-events index d267d3e652..641d69eedf 100644 --- a/hw/isa/trace-events +++ b/hw/isa/trace-events @@ -17,5 +17,7 @@ apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x" # vt82c686.c via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_io_read(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_io_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" via_superio_read(uint8_t addr, uint8_t val) "addr 0x%x val 0x%x" via_superio_write(uint8_t addr, uint32_t val) "addr 0x%x val 0x%x" diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index a6f5a0843d..5db9b1706c 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -16,135 +16,125 @@ #include "hw/qdev-properties.h" #include "hw/isa/isa.h" #include "hw/isa/superio.h" +#include "hw/intc/i8259.h" +#include "hw/irq.h" +#include "hw/dma/i8257.h" +#include "hw/timer/i8254.h" +#include "hw/rtc/mc146818rtc.h" #include "migration/vmstate.h" #include "hw/isa/apm.h" #include "hw/acpi/acpi.h" #include "hw/i2c/pm_smbus.h" #include "qapi/error.h" +#include "qemu/log.h" #include "qemu/module.h" +#include "qemu/range.h" #include "qemu/timer.h" #include "exec/address-spaces.h" #include "trace.h" -typedef struct SuperIOConfig { - uint8_t regs[0x100]; - uint8_t index; - uint8_t data; -} SuperIOConfig; +#define TYPE_VIA_PM "via-pm" +OBJECT_DECLARE_SIMPLE_TYPE(ViaPMState, VIA_PM) -struct VT82C686BISAState { +struct ViaPMState { PCIDevice dev; - MemoryRegion superio; - SuperIOConfig superio_cfg; + MemoryRegion io; + ACPIREGS ar; + APMState apm; + PMSMBus smb; }; -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) - -static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, - unsigned size) +static void pm_io_space_update(ViaPMState *s) { - SuperIOConfig *sc = opaque; + uint32_t pmbase = pci_get_long(s->dev.config + 0x48) & 0xff80UL; - if (addr == 0x3f0) { /* config index register */ - sc->index = data & 0xff; - } else { - bool can_write = true; - /* 0x3f1, config data register */ - trace_via_superio_write(sc->index, data & 0xff); - switch (sc->index) { - case 0x00 ... 0xdf: - case 0xe4: - case 0xe5: - case 0xe9 ... 0xed: - case 0xf3: - case 0xf5: - case 0xf7: - case 0xf9 ... 0xfb: - case 0xfd ... 0xff: - can_write = false; - break; - /* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ - default: - break; + memory_region_transaction_begin(); + memory_region_set_address(&s->io, pmbase); + memory_region_set_enabled(&s->io, s->dev.config[0x41] & BIT(7)); + memory_region_transaction_commit(); +} - } - if (can_write) { - sc->regs[sc->index] = data & 0xff; - } - } +static void smb_io_space_update(ViaPMState *s) +{ + uint32_t smbase = pci_get_long(s->dev.config + 0x90) & 0xfff0UL; + + memory_region_transaction_begin(); + memory_region_set_address(&s->smb.io, smbase); + memory_region_set_enabled(&s->smb.io, s->dev.config[0xd2] & BIT(0)); + memory_region_transaction_commit(); } -static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) +static int vmstate_acpi_post_load(void *opaque, int version_id) { - SuperIOConfig *sc = opaque; - uint8_t val = sc->regs[sc->index]; + ViaPMState *s = opaque; - trace_via_superio_read(sc->index, val); - return val; + pm_io_space_update(s); + smb_io_space_update(s); + return 0; } -static const MemoryRegionOps superio_cfg_ops = { - .read = superio_cfg_read, - .write = superio_cfg_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .impl = { - .min_access_size = 1, - .max_access_size = 1, - }, +static const VMStateDescription vmstate_acpi = { + .name = "vt82c686b_pm", + .version_id = 1, + .minimum_version_id = 1, + .post_load = vmstate_acpi_post_load, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(dev, ViaPMState), + VMSTATE_UINT16(ar.pm1.evt.sts, ViaPMState), + VMSTATE_UINT16(ar.pm1.evt.en, ViaPMState), + VMSTATE_UINT16(ar.pm1.cnt.cnt, ViaPMState), + VMSTATE_STRUCT(apm, ViaPMState, 0, vmstate_apm, APMState), + VMSTATE_TIMER_PTR(ar.tmr.timer, ViaPMState), + VMSTATE_INT64(ar.tmr.overflow_time, ViaPMState), + VMSTATE_END_OF_LIST() + } }; -static void vt82c686b_isa_reset(DeviceState *dev) +static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { - VT82C686BISAState *s = VT82C686B_ISA(dev); - uint8_t *pci_conf = s->dev.config; - - pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); - pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL); - pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); + ViaPMState *s = VIA_PM(d); - pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */ - pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */ - pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */ - pci_conf[0x50] = 0x2d; /* PnP DMA Request Control */ - pci_conf[0x59] = 0x04; - pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/ - pci_conf[0x5f] = 0x04; - pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ - - s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ - s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ - s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ - s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ - s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ - s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ + trace_via_pm_write(addr, val, len); + pci_default_write_config(d, addr, val, len); + if (ranges_overlap(addr, len, 0x48, 4)) { + uint32_t v = pci_get_long(s->dev.config + 0x48); + pci_set_long(s->dev.config + 0x48, (v & 0xff80UL) | 1); + } + if (range_covers_byte(addr, len, 0x41)) { + pm_io_space_update(s); + } + if (ranges_overlap(addr, len, 0x90, 4)) { + uint32_t v = pci_get_long(s->dev.config + 0x90); + pci_set_long(s->dev.config + 0x90, (v & 0xfff0UL) | 1); + } + if (range_covers_byte(addr, len, 0xd2)) { + s->dev.config[0xd2] &= 0xf; + smb_io_space_update(s); + } } -/* write config pci function0 registers. PCI-ISA bridge */ -static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, - uint32_t val, int len) +static void pm_io_write(void *op, hwaddr addr, uint64_t data, unsigned size) { - VT82C686BISAState *s = VT82C686B_ISA(d); + trace_via_pm_io_write(addr, data, size); +} - trace_via_isa_write(addr, val, len); - pci_default_write_config(d, addr, val, len); - if (addr == 0x85) { /* enable or disable super IO configure */ - memory_region_set_enabled(&s->superio, val & 0x2); - } +static uint64_t pm_io_read(void *op, hwaddr addr, unsigned size) +{ + trace_via_pm_io_read(addr, 0, size); + return 0; } -struct VT686PMState { - PCIDevice dev; - MemoryRegion io; - ACPIREGS ar; - APMState apm; - PMSMBus smb; - uint32_t smb_io_base; +static const MemoryRegionOps pm_io_ops = { + .read = pm_io_read, + .write = pm_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; -OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) - -static void pm_update_sci(VT686PMState *s) +static void pm_update_sci(ViaPMState *s) { int sci_level, pmsts; @@ -162,120 +152,196 @@ static void pm_update_sci(VT686PMState *s) static void pm_tmr_timer(ACPIREGS *ar) { - VT686PMState *s = container_of(ar, VT686PMState, ar); + ViaPMState *s = container_of(ar, ViaPMState, ar); pm_update_sci(s); } -static void pm_io_space_update(VT686PMState *s) -{ - uint32_t pm_io_base; - - pm_io_base = pci_get_long(s->dev.config + 0x40); - pm_io_base &= 0xffc0; - - memory_region_transaction_begin(); - memory_region_set_enabled(&s->io, s->dev.config[0x80] & 1); - memory_region_set_address(&s->io, pm_io_base); - memory_region_transaction_commit(); -} - -static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) +static void via_pm_reset(DeviceState *d) { - trace_via_pm_write(addr, val, len); - pci_default_write_config(d, addr, val, len); -} + ViaPMState *s = VIA_PM(d); -static int vmstate_acpi_post_load(void *opaque, int version_id) -{ - VT686PMState *s = opaque; + memset(s->dev.config + PCI_CONFIG_HEADER_SIZE, 0, + PCI_CONFIG_SPACE_SIZE - PCI_CONFIG_HEADER_SIZE); + /* Power Management IO base */ + pci_set_long(s->dev.config + 0x48, 1); + /* SMBus IO base */ + pci_set_long(s->dev.config + 0x90, 1); pm_io_space_update(s); - return 0; + smb_io_space_update(s); } -static const VMStateDescription vmstate_acpi = { - .name = "vt82c686b_pm", - .version_id = 1, - .minimum_version_id = 1, - .post_load = vmstate_acpi_post_load, - .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE(dev, VT686PMState), - VMSTATE_UINT16(ar.pm1.evt.sts, VT686PMState), - VMSTATE_UINT16(ar.pm1.evt.en, VT686PMState), - VMSTATE_UINT16(ar.pm1.cnt.cnt, VT686PMState), - VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState), - VMSTATE_TIMER_PTR(ar.tmr.timer, VT686PMState), - VMSTATE_INT64(ar.tmr.overflow_time, VT686PMState), - VMSTATE_END_OF_LIST() - } -}; - -/* vt82c686 pm init */ -static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) +static void via_pm_realize(PCIDevice *dev, Error **errp) { - VT686PMState *s = VT82C686B_PM(dev); - uint8_t *pci_conf; + ViaPMState *s = VIA_PM(dev); - pci_conf = s->dev.config; - pci_set_word(pci_conf + PCI_COMMAND, 0); - pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK | + pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); - /* 0x48-0x4B is Power Management I/O Base */ - pci_set_long(pci_conf + 0x48, 0x00000001); - - /* SMB ports:0xeee0~0xeeef */ - s->smb_io_base = ((s->smb_io_base & 0xfff0) + 0x0); - pci_conf[0x90] = s->smb_io_base | 1; - pci_conf[0x91] = s->smb_io_base >> 8; - pci_conf[0xd2] = 0x90; pm_smbus_init(DEVICE(s), &s->smb, false); - memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io); + memory_region_add_subregion(pci_address_space_io(dev), 0, &s->smb.io); + memory_region_set_enabled(&s->smb.io, false); apm_init(dev, &s->apm, NULL, s); - memory_region_init(&s->io, OBJECT(dev), "vt82c686-pm", 64); + memory_region_init_io(&s->io, OBJECT(dev), &pm_io_ops, s, "via-pm", 128); + memory_region_add_subregion(pci_address_space_io(dev), 0, &s->io); memory_region_set_enabled(&s->io, false); - memory_region_add_subregion(get_system_io(), 0, &s->io); acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_cnt_init(&s->ar, &s->io, false, false, 2); } -static Property via_pm_properties[] = { - DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0), - DEFINE_PROP_END_OF_LIST(), -}; +typedef struct via_pm_init_info { + uint16_t device_id; +} ViaPMInitInfo; static void via_pm_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + ViaPMInitInfo *info = data; - k->realize = vt82c686b_pm_realize; + k->realize = via_pm_realize; k->config_write = pm_write_config; k->vendor_id = PCI_VENDOR_ID_VIA; - k->device_id = PCI_DEVICE_ID_VIA_ACPI; + k->device_id = info->device_id; k->class_id = PCI_CLASS_BRIDGE_OTHER; k->revision = 0x40; - dc->desc = "PM"; + dc->reset = via_pm_reset; + /* Reason: part of VIA south bridge, does not exist stand alone */ + dc->user_creatable = false; dc->vmsd = &vmstate_acpi; - set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); - device_class_set_props(dc, via_pm_properties); } static const TypeInfo via_pm_info = { - .name = TYPE_VT82C686B_PM, + .name = TYPE_VIA_PM, .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(VT686PMState), - .class_init = via_pm_class_init, + .instance_size = sizeof(ViaPMState), + .abstract = true, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; +static const ViaPMInitInfo vt82c686b_pm_init_info = { + .device_id = PCI_DEVICE_ID_VIA_82C686B_PM, +}; + +static const TypeInfo vt82c686b_pm_info = { + .name = TYPE_VT82C686B_PM, + .parent = TYPE_VIA_PM, + .class_init = via_pm_class_init, + .class_data = (void *)&vt82c686b_pm_init_info, +}; + +static const ViaPMInitInfo vt8231_pm_init_info = { + .device_id = PCI_DEVICE_ID_VIA_8231_PM, +}; + +static const TypeInfo vt8231_pm_info = { + .name = TYPE_VT8231_PM, + .parent = TYPE_VIA_PM, + .class_init = via_pm_class_init, + .class_data = (void *)&vt8231_pm_init_info, +}; + + +typedef struct SuperIOConfig { + uint8_t regs[0x100]; + MemoryRegion io; +} SuperIOConfig; + +static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) +{ + SuperIOConfig *sc = opaque; + uint8_t idx = sc->regs[0]; + + if (addr == 0) { /* config index register */ + sc->regs[0] = data; + return; + } + + /* config data register */ + trace_via_superio_write(idx, data); + switch (idx) { + case 0x00 ... 0xdf: + case 0xe4: + case 0xe5: + case 0xe9 ... 0xed: + case 0xf3: + case 0xf5: + case 0xf7: + case 0xf9 ... 0xfb: + case 0xfd ... 0xff: + /* ignore write to read only registers */ + return; + /* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ + default: + qemu_log_mask(LOG_UNIMP, + "via_superio_cfg: unimplemented register 0x%x\n", idx); + break; + } + sc->regs[idx] = data; +} + +static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) +{ + SuperIOConfig *sc = opaque; + uint8_t idx = sc->regs[0]; + uint8_t val = sc->regs[idx]; + + if (addr == 0) { + return idx; + } + if (addr == 1 && idx == 0) { + val = 0; /* reading reg 0 where we store index value */ + } + trace_via_superio_read(idx, val); + return val; +} + +static const MemoryRegionOps superio_cfg_ops = { + .read = superio_cfg_read, + .write = superio_cfg_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + + +OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) + +struct VT82C686BISAState { + PCIDevice dev; + qemu_irq cpu_intr; + SuperIOConfig superio_cfg; +}; + +static void via_isa_request_i8259_irq(void *opaque, int irq, int level) +{ + VT82C686BISAState *s = opaque; + qemu_set_irq(s->cpu_intr, level); +} + +static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, + uint32_t val, int len) +{ + VT82C686BISAState *s = VT82C686B_ISA(d); + + trace_via_isa_write(addr, val, len); + pci_default_write_config(d, addr, val, len); + if (addr == 0x85) { + /* BIT(1): enable or disable superio config io ports */ + memory_region_set_enabled(&s->superio_cfg.io, val & BIT(1)); + } +} + static const VMStateDescription vmstate_via = { .name = "vt82c686b", .version_id = 1, @@ -286,40 +352,66 @@ static const VMStateDescription vmstate_via = { } }; -/* init the PCI-to-ISA bridge */ +static void vt82c686b_isa_reset(DeviceState *dev) +{ + VT82C686BISAState *s = VT82C686B_ISA(dev); + uint8_t *pci_conf = s->dev.config; + + pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); + pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL); + pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); + + pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */ + pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */ + pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */ + pci_conf[0x50] = 0x2d; /* PnP DMA Request Control */ + pci_conf[0x59] = 0x04; + pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/ + pci_conf[0x5f] = 0x04; + pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ + + s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ + s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ + s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ + s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ + s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ + s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ +} + static void vt82c686b_realize(PCIDevice *d, Error **errp) { VT82C686BISAState *s = VT82C686B_ISA(d); - uint8_t *pci_conf; + DeviceState *dev = DEVICE(d); ISABus *isa_bus; - uint8_t *wmask; + qemu_irq *isa_irq; int i; - isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), - pci_address_space_io(d), errp); - if (!isa_bus) { - return; - } - - pci_conf = d->config; - pci_config_set_prog_interface(pci_conf, 0x0); - - wmask = d->wmask; - for (i = 0x00; i < 0xff; i++) { - if (i <= 0x03 || (i >= 0x08 && i <= 0x3f)) { - wmask[i] = 0x00; + qdev_init_gpio_out(dev, &s->cpu_intr, 1); + isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1); + isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d), + &error_fatal); + isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq)); + i8254_pit_init(isa_bus, 0x40, 0, NULL); + i8257_dma_init(isa_bus, 0); + isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); + mc146818_rtc_init(isa_bus, 2000, NULL); + + for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { + if (i < PCI_COMMAND || i >= PCI_REVISION_ID) { + d->wmask[i] = 0; } } - memory_region_init_io(&s->superio, OBJECT(d), &superio_cfg_ops, - &s->superio_cfg, "superio", 2); - memory_region_set_enabled(&s->superio, false); + memory_region_init_io(&s->superio_cfg.io, OBJECT(d), &superio_cfg_ops, + &s->superio_cfg, "superio_cfg", 2); + memory_region_set_enabled(&s->superio_cfg.io, false); /* * The floppy also uses 0x3f0 and 0x3f1. * But we do not emulate a floppy, so just set it here. */ memory_region_add_subregion(isa_bus->address_space_io, 0x3f0, - &s->superio); + &s->superio_cfg.io); } static void via_class_init(ObjectClass *klass, void *data) @@ -354,6 +446,7 @@ static const TypeInfo via_info = { }, }; + static void vt82c686b_superio_class_init(ObjectClass *klass, void *data) { ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); @@ -372,11 +465,14 @@ static const TypeInfo via_superio_info = { .class_init = vt82c686b_superio_class_init, }; + static void vt82c686b_register_types(void) { type_register_static(&via_pm_info); - type_register_static(&via_superio_info); + type_register_static(&vt82c686b_pm_info); + type_register_static(&vt8231_pm_info); type_register_static(&via_info); + type_register_static(&via_superio_info); } type_init(vt82c686b_register_types) diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c new file mode 100644 index 0000000000..6ec8314490 --- /dev/null +++ b/hw/mips/bootloader.c @@ -0,0 +1,200 @@ +/* + * Utility for QEMU MIPS to generate it's simple bootloader + * + * Instructions used here are carefully selected to keep compatibility with + * MIPS Release 6. + * + * Copyright (C) 2020 Jiaxun Yang <jiaxun.yang@flygoat.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/bitops.h" +#include "cpu.h" +#include "hw/mips/bootloader.h" + +typedef enum bl_reg { + BL_REG_ZERO = 0, + BL_REG_AT = 1, + BL_REG_V0 = 2, + BL_REG_V1 = 3, + BL_REG_A0 = 4, + BL_REG_A1 = 5, + BL_REG_A2 = 6, + BL_REG_A3 = 7, + BL_REG_T0 = 8, + BL_REG_T1 = 9, + BL_REG_T2 = 10, + BL_REG_T3 = 11, + BL_REG_T4 = 12, + BL_REG_T5 = 13, + BL_REG_T6 = 14, + BL_REG_T7 = 15, + BL_REG_S0 = 16, + BL_REG_S1 = 17, + BL_REG_S2 = 18, + BL_REG_S3 = 19, + BL_REG_S4 = 20, + BL_REG_S5 = 21, + BL_REG_S6 = 22, + BL_REG_S7 = 23, + BL_REG_T8 = 24, + BL_REG_T9 = 25, + BL_REG_K0 = 26, + BL_REG_K1 = 27, + BL_REG_GP = 28, + BL_REG_SP = 29, + BL_REG_FP = 30, + BL_REG_RA = 31, +} bl_reg; + +static bool bootcpu_supports_isa(uint64_t isa_mask) +{ + return cpu_supports_isa(&MIPS_CPU(first_cpu)->env, isa_mask); +} + +/* Base types */ +static void bl_gen_nop(uint32_t **p) +{ + stl_p(*p, 0); + *p = *p + 1; +} + +static void bl_gen_r_type(uint32_t **p, uint8_t opcode, + bl_reg rs, bl_reg rt, bl_reg rd, + uint8_t shift, uint8_t funct) +{ + uint32_t insn = 0; + + insn = deposit32(insn, 26, 6, opcode); + insn = deposit32(insn, 21, 5, rs); + insn = deposit32(insn, 16, 5, rt); + insn = deposit32(insn, 11, 5, rd); + insn = deposit32(insn, 6, 5, shift); + insn = deposit32(insn, 0, 6, funct); + + stl_p(*p, insn); + *p = *p + 1; +} + +static void bl_gen_i_type(uint32_t **p, uint8_t opcode, + bl_reg rs, bl_reg rt, uint16_t imm) +{ + uint32_t insn = 0; + + insn = deposit32(insn, 26, 6, opcode); + insn = deposit32(insn, 21, 5, rs); + insn = deposit32(insn, 16, 5, rt); + insn = deposit32(insn, 0, 16, imm); + + stl_p(*p, insn); + *p = *p + 1; +} + +/* Single instructions */ +static void bl_gen_dsll(uint32_t **p, bl_reg rd, bl_reg rt, uint8_t sa) +{ + if (bootcpu_supports_isa(ISA_MIPS3)) { + bl_gen_r_type(p, 0, 0, rt, rd, sa, 0x38); + } else { + g_assert_not_reached(); /* unsupported */ + } +} + +static void bl_gen_jalr(uint32_t **p, bl_reg rs) +{ + bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x09); +} + +static void bl_gen_lui(uint32_t **p, bl_reg rt, uint16_t imm) +{ + /* R6: It's a alias of AUI with RS = 0 */ + bl_gen_i_type(p, 0x0f, 0, rt, imm); +} + +static void bl_gen_ori(uint32_t **p, bl_reg rt, bl_reg rs, uint16_t imm) +{ + bl_gen_i_type(p, 0x0d, rs, rt, imm); +} + +static void bl_gen_sw(uint32_t **p, bl_reg rt, uint8_t base, uint16_t offset) +{ + bl_gen_i_type(p, 0x2b, base, rt, offset); +} + +static void bl_gen_sd(uint32_t **p, bl_reg rt, uint8_t base, uint16_t offset) +{ + if (bootcpu_supports_isa(ISA_MIPS3)) { + bl_gen_i_type(p, 0x3f, base, rt, offset); + } else { + g_assert_not_reached(); /* unsupported */ + } +} + +/* Pseudo instructions */ +static void bl_gen_li(uint32_t **p, bl_reg rt, uint32_t imm) +{ + bl_gen_lui(p, rt, extract32(imm, 16, 16)); + bl_gen_ori(p, rt, rt, extract32(imm, 0, 16)); +} + +static void bl_gen_dli(uint32_t **p, bl_reg rt, uint64_t imm) +{ + bl_gen_li(p, rt, extract64(imm, 32, 32)); + bl_gen_dsll(p, rt, rt, 16); + bl_gen_ori(p, rt, rt, extract64(imm, 16, 16)); + bl_gen_dsll(p, rt, rt, 16); + bl_gen_ori(p, rt, rt, extract64(imm, 0, 16)); +} + +static void bl_gen_load_ulong(uint32_t **p, bl_reg rt, target_ulong imm) +{ + if (bootcpu_supports_isa(ISA_MIPS3)) { + bl_gen_dli(p, rt, imm); /* 64bit */ + } else { + bl_gen_li(p, rt, imm); /* 32bit */ + } +} + +/* Helpers */ +void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr) +{ + bl_gen_load_ulong(p, BL_REG_T9, jump_addr); + bl_gen_jalr(p, BL_REG_T9); + bl_gen_nop(p); /* delay slot */ +} + +void bl_gen_jump_kernel(uint32_t **p, target_ulong sp, target_ulong a0, + target_ulong a1, target_ulong a2, target_ulong a3, + target_ulong kernel_addr) +{ + bl_gen_load_ulong(p, BL_REG_SP, sp); + bl_gen_load_ulong(p, BL_REG_A0, a0); + bl_gen_load_ulong(p, BL_REG_A1, a1); + bl_gen_load_ulong(p, BL_REG_A2, a2); + bl_gen_load_ulong(p, BL_REG_A3, a3); + + bl_gen_jump_to(p, kernel_addr); +} + +void bl_gen_write_ulong(uint32_t **p, target_ulong addr, target_ulong val) +{ + bl_gen_load_ulong(p, BL_REG_K0, val); + bl_gen_load_ulong(p, BL_REG_K1, addr); + bl_gen_sd(p, BL_REG_K0, BL_REG_K1, 0x0); +} + +void bl_gen_write_u32(uint32_t **p, target_ulong addr, uint32_t val) +{ + bl_gen_li(p, BL_REG_K0, val); + bl_gen_load_ulong(p, BL_REG_K1, addr); + bl_gen_sw(p, BL_REG_K0, BL_REG_K1, 0x0); +} + +void bl_gen_write_u64(uint32_t **p, target_ulong addr, uint64_t val) +{ + bl_gen_dli(p, BL_REG_K0, val); + bl_gen_load_ulong(p, BL_REG_K1, addr); + bl_gen_sd(p, BL_REG_K0, BL_REG_K1, 0x0); +} diff --git a/hw/mips/boston.c b/hw/mips/boston.c index 467fbc1c8b..ac2e93a05a 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -27,6 +27,7 @@ #include "hw/ide/ahci.h" #include "hw/loader.h" #include "hw/loader-fit.h" +#include "hw/mips/bootloader.h" #include "hw/mips/cps.h" #include "hw/pci-host/xilinx-pcie.h" #include "hw/qdev-clock.h" @@ -273,48 +274,26 @@ static void boston_register_types(void) } type_init(boston_register_types) -static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr, - bool is_64b) +static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr) { const uint32_t cm_base = 0x16100000; const uint32_t gic_base = 0x16120000; const uint32_t cpc_base = 0x16200000; /* Move CM GCRs */ - if (is_64b) { - stl_p(p++, 0x40287803); /* dmfc0 $8, CMGCRBase */ - stl_p(p++, 0x00084138); /* dsll $8, $8, 4 */ - } else { - stl_p(p++, 0x40087803); /* mfc0 $8, CMGCRBase */ - stl_p(p++, 0x00084100); /* sll $8, $8, 4 */ - } - stl_p(p++, 0x3c09a000); /* lui $9, 0xa000 */ - stl_p(p++, 0x01094025); /* or $8, $9 */ - stl_p(p++, 0x3c0a0000 | (cm_base >> 16)); /* lui $10, cm_base >> 16 */ - if (is_64b) { - stl_p(p++, 0xfd0a0008); /* sd $10, 0x8($8) */ - } else { - stl_p(p++, 0xad0a0008); /* sw $10, 0x8($8) */ - } - stl_p(p++, 0x012a4025); /* or $8, $10 */ + bl_gen_write_ulong(&p, + cpu_mips_phys_to_kseg1(NULL, GCR_BASE_ADDR + GCR_BASE_OFS), + cm_base); /* Move & enable GIC GCRs */ - stl_p(p++, 0x3c090000 | (gic_base >> 16)); /* lui $9, gic_base >> 16 */ - stl_p(p++, 0x35290001); /* ori $9, 0x1 */ - if (is_64b) { - stl_p(p++, 0xfd090080); /* sd $9, 0x80($8) */ - } else { - stl_p(p++, 0xad090080); /* sw $9, 0x80($8) */ - } + bl_gen_write_ulong(&p, + cpu_mips_phys_to_kseg1(NULL, cm_base + GCR_GIC_BASE_OFS), + gic_base | GCR_GIC_BASE_GICEN_MSK); /* Move & enable CPC GCRs */ - stl_p(p++, 0x3c090000 | (cpc_base >> 16)); /* lui $9, cpc_base >> 16 */ - stl_p(p++, 0x35290001); /* ori $9, 0x1 */ - if (is_64b) { - stl_p(p++, 0xfd090088); /* sd $9, 0x88($8) */ - } else { - stl_p(p++, 0xad090088); /* sw $9, 0x88($8) */ - } + bl_gen_write_ulong(&p, + cpu_mips_phys_to_kseg1(NULL, cm_base + GCR_CPC_BASE_OFS), + cpc_base | GCR_CPC_BASE_CPCEN_MSK); /* * Setup argument registers to follow the UHI boot protocol: @@ -324,21 +303,7 @@ static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr, * a2/$6 = 0 * a3/$7 = 0 */ - stl_p(p++, 0x2404fffe); /* li $4, -2 */ - /* lui $5, hi(fdt_addr) */ - stl_p(p++, 0x3c050000 | ((fdt_addr >> 16) & 0xffff)); - if (fdt_addr & 0xffff) { /* ori $5, lo(fdt_addr) */ - stl_p(p++, 0x34a50000 | (fdt_addr & 0xffff)); - } - stl_p(p++, 0x34060000); /* li $6, 0 */ - stl_p(p++, 0x34070000); /* li $7, 0 */ - - /* Load kernel entry address & jump to it */ - /* lui $25, hi(kernel_entry) */ - stl_p(p++, 0x3c190000 | ((kernel_entry >> 16) & 0xffff)); - /* ori $25, lo(kernel_entry) */ - stl_p(p++, 0x37390000 | (kernel_entry & 0xffff)); - stl_p(p++, 0x03200009); /* jr $25 */ + bl_gen_jump_kernel(&p, 0, (int32_t)-2, fdt_addr, 0, 0, kernel_entry); } static const void *boston_fdt_filter(void *opaque, const void *fdt_orig, @@ -542,8 +507,7 @@ static void boston_mach_init(MachineState *machine) } gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c00000, - s->kernel_entry, s->fdt_base, - cpu_type_is_64bit(machine->cpu_type)); + s->kernel_entry, s->fdt_base); } else if (!qtest_enabled()) { error_report("Please provide either a -kernel or -bios argument"); exit(1); diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index bac2adbd5a..4f61f2c873 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -25,26 +25,24 @@ #include "qapi/error.h" #include "cpu.h" #include "hw/clock.h" -#include "hw/intc/i8259.h" -#include "hw/dma/i8257.h" -#include "hw/isa/superio.h" #include "net/net.h" #include "hw/boards.h" #include "hw/i2c/smbus_eeprom.h" #include "hw/block/flash.h" #include "hw/mips/mips.h" +#include "hw/mips/bootloader.h" #include "hw/mips/cpudevs.h" #include "hw/pci/pci.h" #include "qemu/log.h" #include "hw/loader.h" #include "hw/ide/pci.h" +#include "hw/qdev-properties.h" #include "elf.h" #include "hw/isa/vt82c686.h" -#include "hw/rtc/mc146818rtc.h" -#include "hw/timer/i8254.h" #include "exec/address-spaces.h" #include "sysemu/qtest.h" #include "sysemu/reset.h" +#include "sysemu/sysemu.h" #include "qemu/error-report.h" #define ENVP_PADDR 0x2000 @@ -185,30 +183,8 @@ static void write_bootloader(CPUMIPSState *env, uint8_t *base, /* Second part of the bootloader */ p = (uint32_t *)(base + 0x040); - /* lui a0, 0 */ - stl_p(p++, 0x3c040000); - /* ori a0, a0, 2 */ - stl_p(p++, 0x34840002); - /* lui a1, high(ENVP_VADDR) */ - stl_p(p++, 0x3c050000 | ((ENVP_VADDR >> 16) & 0xffff)); - /* ori a1, a0, low(ENVP_VADDR) */ - stl_p(p++, 0x34a50000 | (ENVP_VADDR & 0xffff)); - /* lui a2, high(ENVP_VADDR + 8) */ - stl_p(p++, 0x3c060000 | (((ENVP_VADDR + 8) >> 16) & 0xffff)); - /* ori a2, a2, low(ENVP_VADDR + 8) */ - stl_p(p++, 0x34c60000 | ((ENVP_VADDR + 8) & 0xffff)); - /* lui a3, high(env->ram_size) */ - stl_p(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); - /* ori a3, a3, low(env->ram_size) */ - stl_p(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); - /* lui ra, high(kernel_addr) */ - stl_p(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff)); - /* ori ra, ra, low(kernel_addr) */ - stl_p(p++, 0x37ff0000 | (kernel_addr & 0xffff)); - /* jr ra */ - stl_p(p++, 0x03e00008); - /* nop */ - stl_p(p++, 0x00000000); + bl_gen_jump_kernel(&p, ENVP_VADDR - 64, 2, ENVP_VADDR, ENVP_VADDR + 8, + loaderparams.ram_size, kernel_addr); } static void main_cpu_reset(void *opaque) @@ -224,26 +200,13 @@ static void main_cpu_reset(void *opaque) } static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, - I2CBus **i2c_bus, ISABus **p_isa_bus) + I2CBus **i2c_bus) { - qemu_irq *i8259; - ISABus *isa_bus; PCIDevice *dev; dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true, TYPE_VT82C686B_ISA); - isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(dev), "isa.0")); - assert(isa_bus); - *p_isa_bus = isa_bus; - /* Interrupt controller */ - /* The 8259 -> IP5 */ - i8259 = i8259_init(isa_bus, intc); - isa_bus_irqs(isa_bus, i8259); - /* init other devices */ - i8254_pit_init(isa_bus, 0x40, 0, NULL); - i8257_dma_init(isa_bus, 0); - /* Super I/O */ - isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); + qdev_connect_gpio_out(DEVICE(dev), 0, intc); dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide"); pci_ide_create_devs(dev); @@ -251,9 +214,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); - dev = pci_new(PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); - qdev_prop_set_uint32(DEVICE(dev), "smb_io_base", 0xeee1); - pci_realize_and_unref(dev, pci_bus, &error_fatal); + dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); /* Audio support */ @@ -292,7 +253,6 @@ static void mips_fuloong2e_init(MachineState *machine) uint64_t kernel_entry; PCIDevice *pci_dev; PCIBus *pci_bus; - ISABus *isa_bus; I2CBus *smbus; Clock *cpuclk; MIPSCPU *cpu; @@ -359,7 +319,7 @@ static void mips_fuloong2e_init(MachineState *machine) /* South bridge -> IP5 */ vt82c686b_southbridge_init(pci_bus, FULOONG2E_VIA_SLOT, env->irq[5], - &smbus, &isa_bus); + &smbus); /* GPU */ if (vga_interface_type != VGA_NONE) { @@ -374,8 +334,6 @@ static void mips_fuloong2e_init(MachineState *machine) spd_data = spd_data_generate(DDR, machine->ram_size); smbus_eeprom_init_one(smbus, 0x50, spd_data); - mc146818_rtc_init(isa_bus, 2000, NULL); - /* Network card: RTL8139D */ network_init(pci_bus); } diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h index 09f8480abf..d525ab745a 100644 --- a/hw/mips/loongson3_bootp.h +++ b/hw/mips/loongson3_bootp.h @@ -228,12 +228,7 @@ enum { LOADER_PARAM, }; -struct MemmapEntry { - hwaddr base; - hwaddr size; -}; - -extern const struct MemmapEntry virt_memmap[]; +extern const MemMapEntry virt_memmap[]; void init_loongson_params(struct loongson_params *lp, void *p, uint64_t cpu_freq, uint64_t ram_size); void init_reset_system(struct efi_reset_system_t *reset); diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c index d4a82fa536..b15071defc 100644 --- a/hw/mips/loongson3_virt.c +++ b/hw/mips/loongson3_virt.c @@ -72,7 +72,7 @@ #define RTC_IRQ 1 #define PCIE_IRQ_BASE 2 -const struct MemmapEntry virt_memmap[] = { +const MemMapEntry virt_memmap[] = { [VIRT_LOWMEM] = { 0x00000000, 0x10000000 }, [VIRT_PM] = { 0x10080000, 0x100 }, [VIRT_FW_CFG] = { 0x10080100, 0x100 }, @@ -86,13 +86,13 @@ const struct MemmapEntry virt_memmap[] = { [VIRT_HIGHMEM] = { 0x80000000, 0x0 }, /* Variable */ }; -static const struct MemmapEntry loader_memmap[] = { +static const MemMapEntry loader_memmap[] = { [LOADER_KERNEL] = { 0x00000000, 0x4000000 }, [LOADER_INITRD] = { 0x04000000, 0x0 }, /* Variable */ [LOADER_CMDLINE] = { 0x0ff00000, 0x100000 }, }; -static const struct MemmapEntry loader_rommap[] = { +static const MemMapEntry loader_rommap[] = { [LOADER_BOOTROM] = { 0x1fc00000, 0x1000 }, [LOADER_PARAM] = { 0x1fc01000, 0x10000 }, }; diff --git a/hw/mips/meson.build b/hw/mips/meson.build index ee19cc204d..1195716dc7 100644 --- a/hw/mips/meson.build +++ b/hw/mips/meson.build @@ -1,5 +1,5 @@ mips_ss = ss.source_set() -mips_ss.add(files('mips_int.c')) +mips_ss.add(files('bootloader.c', 'mips_int.c')) mips_ss.add(when: 'CONFIG_FW_CFG_MIPS', if_true: files('fw_cfg.c')) mips_ss.add(when: 'CONFIG_FULOONG', if_true: files('fuloong2e.c')) mips_ss.add(when: 'CONFIG_LOONGSON3V', if_true: files('loongson3_bootp.c', 'loongson3_virt.c')) |