aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-02-21 19:52:58 +0000
committerPeter Maydell <peter.maydell@linaro.org>2021-02-21 19:52:58 +0000
commit00d8ba9e0d62ea1c7459c25aeabf9c8bb7659462 (patch)
tree188c7a650d48c12a9cf244575cdd13700471b584 /hw
parent4115aec9af2a3de5fa89a0b1daa12debcd7741ff (diff)
parentcc2b4550115baf77d556341f17eb464d18953cee (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.c16
-rw-r--r--hw/isa/trace-events2
-rw-r--r--hw/isa/vt82c686.c464
-rw-r--r--hw/mips/bootloader.c200
-rw-r--r--hw/mips/boston.c62
-rw-r--r--hw/mips/fuloong2e.c60
-rw-r--r--hw/mips/loongson3_bootp.h7
-rw-r--r--hw/mips/loongson3_virt.c6
-rw-r--r--hw/mips/meson.build2
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'))