aboutsummaryrefslogtreecommitdiff
path: root/hw/mips
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-01-16 11:24:11 +0000
committerPeter Maydell <peter.maydell@linaro.org>2023-01-16 11:24:11 +0000
commita8d6abe1292e1db1ad9be5b2b124b9c01bcda094 (patch)
tree208272db9d6d6d64436a2a254f1468b4e25234bf /hw/mips
parent886fb67020e32ce6a2cf7049c6f017acf1f0d69a (diff)
parent4828656f65324249273ad2f2db80844ba90eeb9b (diff)
downloadqemu-a8d6abe1292e1db1ad9be5b2b124b9c01bcda094.zip
qemu-a8d6abe1292e1db1ad9be5b2b124b9c01bcda094.tar.gz
qemu-a8d6abe1292e1db1ad9be5b2b124b9c01bcda094.tar.bz2
Merge tag 'mips-20230113' of https://github.com/philmd/qemu into staging
MIPS patches queue A bunch of cleanups from various people. - Improved GT64120 on big-endian hosts - GT64120 north bridge and MC146818 RTC devices are now target independent - Bonito64 north bridge converted to 3-phase reset API - PCI refactors around PIIX devices - Support for nanoMIPS in bootloader generator API - New YAMON Malta Avocado test - Removal of 'trap and emulate' KVM support - System-specific QMP commands restricted to system emulation # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmPBekAACgkQ4+MsLN6t # wN4wjxAAtYxyt6WUBpiYfV/LnbQFpAsacues1Vhy9MPYEg5a/iuXWKvWtgRYvGww # qR0GVQH8rH7tgnCZK+ioq9jX+hvfBskP6CnKhxmb5zDGm7vP7jhhu8UFWY/EtBgq # 0zpNeLMXtnRJ6PBqo/nWFCVtcpDRZ6IkSbpGWkVkciRFc5n/2VCnlIj8k2I1oMvL # 11cp2xFQnaPReFXIpMjJHuHv1NObykdlvVg6wQo/A/4qIb8EvJQEPmePjG9Sf0i0 # v2dhnnxG9mze7+uq0dIC16x8Azko3N7dmtNlBU/aGb9OELwx35aux2M4dNDVogwn # DqL/Wsk54TFewECOfS48t/a/TqV8j/ISW1d/JvovBrN2KovmIAbtqHuMUqKVk5l0 # 23ZOIIPIYwmScZwIlkCIGUuIzFig1zhEmQcoEQaFe/B0oLB2eN/x0Bk9Yklo+i2A # WNiyiAj7k5492qEdndOySEEDVt6886F/+CdQ6QYF5Z1L/ELck7XHBH3mGDznWpPn # 6IURyVquPJx7ul62jSGI+Gc+qakNoahIhPo5O7hklOM9GwWNOWXHveyb7xjs7j+O # eWyVcet+o7hoHkCzmfbyTPySI4qCpF9fA42jqPhATwQPwmGXpbr+4BxUq3KtE43y # w9tEigwd4voN3dWLItVh6QE4in70osz3XHp93byvo8bHlS0huVY= # =oXX+ # -----END PGP SIGNATURE----- # gpg: Signature made Fri 13 Jan 2023 15:35:28 GMT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'mips-20230113' of https://github.com/philmd/qemu: (46 commits) scripts/git.orderfile: Display MAINTAINERS changes first target/mips: Restrict 'qapi-commands-machine.h' to system emulation hw/mips/boston: Rename MachineState 'mc' pointer to 'ms' hw/pci-host/bonito: Declare TYPE_BONITO_PCI_HOST_BRIDGE in header hw/pci-host/bonito: Use 'bonito_pci' for PCI function #0 code hw/pci-host/bonito: Use 'bonito_host' for PCI host bridge code hw/pci-host/bonito: Convert to 3-phase reset softmmu/rtc: Emit warning when using driftfix=slew on systems without mc146818 hw/rtc/mc146818rtc: Make the mc146818 RTC device target independent hw/core/qdev-properties-system: Allow the 'slew' policy only on x86 hw/intc: Extract the IRQ counting functions into a separate file hw/intc/i8259: Make using the isa_pic singleton more type-safe hw/usb/hcd-uhci: Introduce TYPE_ defines for device models hw/mips/Kconfig: Track Malta's PIIX dependencies via Kconfig hw/isa/piix4: Decouple INTx-to-LNKx routing which is board-specific hw/isa/piix3: Decouple INTx-to-LNKx routing which is board-specific hw/pci/pci: Factor out pci_bus_map_irqs() from pci_bus_irqs() hw/pci/pci_host: Trace config accesses on unexisting functions mips: Always include nanomips disassembler mips: Remove support for trap and emulate KVM ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/mips')
-rw-r--r--hw/mips/Kconfig2
-rw-r--r--hw/mips/bootloader.c139
-rw-r--r--hw/mips/boston.c6
-rw-r--r--hw/mips/fuloong2e.c2
-rw-r--r--hw/mips/gt64xxx_pci.c1234
-rw-r--r--hw/mips/malta.c403
-rw-r--r--hw/mips/meson.build2
-rw-r--r--hw/mips/trace-events9
8 files changed, 250 insertions, 1547 deletions
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 7255253..da3a37e 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -1,6 +1,8 @@
config MALTA
bool
+ select GT64120
select ISA_SUPERIO
+ select PIIX4
config MIPSSIM
bool
diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c
index f5f42f2..1dd6ef2 100644
--- a/hw/mips/bootloader.c
+++ b/hw/mips/bootloader.c
@@ -54,17 +54,37 @@ static bool bootcpu_supports_isa(uint64_t isa_mask)
return cpu_supports_isa(&MIPS_CPU(first_cpu)->env, isa_mask);
}
+static void st_nm32_p(void **ptr, uint32_t insn)
+{
+ uint16_t *p = *ptr;
+
+ stw_p(p, insn >> 16);
+ p++;
+ stw_p(p, insn >> 0);
+ p++;
+
+ *ptr = p;
+}
+
/* Base types */
-static void bl_gen_nop(uint32_t **p)
+static void bl_gen_nop(void **ptr)
{
- stl_p(*p, 0);
- *p = *p + 1;
+ if (bootcpu_supports_isa(ISA_NANOMIPS32)) {
+ st_nm32_p(ptr, 0x8000c000);
+ } else {
+ uint32_t *p = *ptr;
+
+ stl_p(p, 0);
+ p++;
+ *ptr = p;
+ }
}
-static void bl_gen_r_type(uint32_t **p, uint8_t opcode,
+static void bl_gen_r_type(void **ptr, uint8_t opcode,
bl_reg rs, bl_reg rt, bl_reg rd,
uint8_t shift, uint8_t funct)
{
+ uint32_t *p = *ptr;
uint32_t insn = 0;
insn = deposit32(insn, 26, 6, opcode);
@@ -74,13 +94,16 @@ static void bl_gen_r_type(uint32_t **p, uint8_t opcode,
insn = deposit32(insn, 6, 5, shift);
insn = deposit32(insn, 0, 6, funct);
- stl_p(*p, insn);
- *p = *p + 1;
+ stl_p(p, insn);
+ p++;
+
+ *ptr = p;
}
-static void bl_gen_i_type(uint32_t **p, uint8_t opcode,
+static void bl_gen_i_type(void **ptr, uint8_t opcode,
bl_reg rs, bl_reg rt, uint16_t imm)
{
+ uint32_t *p = *ptr;
uint32_t insn = 0;
insn = deposit32(insn, 26, 6, opcode);
@@ -88,12 +111,14 @@ static void bl_gen_i_type(uint32_t **p, uint8_t opcode,
insn = deposit32(insn, 16, 5, rt);
insn = deposit32(insn, 0, 16, imm);
- stl_p(*p, insn);
- *p = *p + 1;
+ stl_p(p, insn);
+ p++;
+
+ *ptr = p;
}
/* Single instructions */
-static void bl_gen_dsll(uint32_t **p, bl_reg rd, bl_reg rt, uint8_t sa)
+static void bl_gen_dsll(void **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);
@@ -102,28 +127,83 @@ static void bl_gen_dsll(uint32_t **p, bl_reg rd, bl_reg rt, uint8_t sa)
}
}
-static void bl_gen_jalr(uint32_t **p, bl_reg rs)
+static void bl_gen_jalr(void **p, bl_reg rs)
{
- bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x09);
+ if (bootcpu_supports_isa(ISA_NANOMIPS32)) {
+ uint32_t insn = 0;
+
+ insn = deposit32(insn, 26, 6, 0b010010); /* JALRC */
+ insn = deposit32(insn, 21, 5, BL_REG_RA);
+ insn = deposit32(insn, 16, 5, rs);
+
+ st_nm32_p(p, insn);
+ } else {
+ bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x09);
+ }
+}
+
+static void bl_gen_lui_nm(void **ptr, bl_reg rt, uint32_t imm20)
+{
+ uint32_t insn = 0;
+
+ assert(extract32(imm20, 0, 20) == imm20);
+ insn = deposit32(insn, 26, 6, 0b111000);
+ insn = deposit32(insn, 21, 5, rt);
+ insn = deposit32(insn, 12, 9, extract32(imm20, 0, 9));
+ insn = deposit32(insn, 2, 10, extract32(imm20, 9, 10));
+ insn = deposit32(insn, 0, 1, sextract32(imm20, 19, 1));
+
+ st_nm32_p(ptr, insn);
}
-static void bl_gen_lui(uint32_t **p, bl_reg rt, uint16_t imm)
+static void bl_gen_lui(void **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)
+static void bl_gen_ori_nm(void **ptr, bl_reg rt, bl_reg rs, uint16_t imm12)
+{
+ uint32_t insn = 0;
+
+ assert(extract32(imm12, 0, 12) == imm12);
+ insn = deposit32(insn, 26, 6, 0b100000);
+ insn = deposit32(insn, 21, 5, rt);
+ insn = deposit32(insn, 16, 5, rs);
+ insn = deposit32(insn, 0, 12, imm12);
+
+ st_nm32_p(ptr, insn);
+}
+
+static void bl_gen_ori(void **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)
+static void bl_gen_sw_nm(void **ptr, bl_reg rt, uint8_t rs, uint16_t ofs12)
+{
+ uint32_t insn = 0;
+
+ assert(extract32(ofs12, 0, 12) == ofs12);
+ insn = deposit32(insn, 26, 6, 0b100001);
+ insn = deposit32(insn, 21, 5, rt);
+ insn = deposit32(insn, 16, 5, rs);
+ insn = deposit32(insn, 12, 4, 0b1001);
+ insn = deposit32(insn, 0, 12, ofs12);
+
+ st_nm32_p(ptr, insn);
+}
+
+static void bl_gen_sw(void **p, bl_reg rt, uint8_t base, uint16_t offset)
{
- bl_gen_i_type(p, 0x2b, base, rt, offset);
+ if (bootcpu_supports_isa(ISA_NANOMIPS32)) {
+ bl_gen_sw_nm(p, rt, base, offset);
+ } else {
+ 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)
+static void bl_gen_sd(void **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);
@@ -133,13 +213,18 @@ static void bl_gen_sd(uint32_t **p, bl_reg rt, uint8_t base, uint16_t offset)
}
/* Pseudo instructions */
-static void bl_gen_li(uint32_t **p, bl_reg rt, uint32_t imm)
+static void bl_gen_li(void **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));
+ if (bootcpu_supports_isa(ISA_NANOMIPS32)) {
+ bl_gen_lui_nm(p, rt, extract32(imm, 12, 20));
+ bl_gen_ori_nm(p, rt, rt, extract32(imm, 0, 12));
+ } else {
+ 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)
+static void bl_gen_dli(void **p, bl_reg rt, uint64_t imm)
{
bl_gen_li(p, rt, extract64(imm, 32, 32));
bl_gen_dsll(p, rt, rt, 16);
@@ -148,7 +233,7 @@ static void bl_gen_dli(uint32_t **p, bl_reg rt, uint64_t imm)
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)
+static void bl_gen_load_ulong(void **p, bl_reg rt, target_ulong imm)
{
if (bootcpu_supports_isa(ISA_MIPS3)) {
bl_gen_dli(p, rt, imm); /* 64bit */
@@ -158,14 +243,14 @@ static void bl_gen_load_ulong(uint32_t **p, bl_reg rt, target_ulong imm)
}
/* Helpers */
-void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr)
+void bl_gen_jump_to(void **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,
+void bl_gen_jump_kernel(void **p,
bool set_sp, target_ulong sp,
bool set_a0, target_ulong a0,
bool set_a1, target_ulong a1,
@@ -192,7 +277,7 @@ void bl_gen_jump_kernel(uint32_t **p,
bl_gen_jump_to(p, kernel_addr);
}
-void bl_gen_write_ulong(uint32_t **p, target_ulong addr, target_ulong val)
+void bl_gen_write_ulong(void **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);
@@ -203,14 +288,14 @@ void bl_gen_write_ulong(uint32_t **p, target_ulong addr, target_ulong val)
}
}
-void bl_gen_write_u32(uint32_t **p, target_ulong addr, uint32_t val)
+void bl_gen_write_u32(void **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)
+void bl_gen_write_u64(void **p, target_ulong addr, uint64_t val)
{
bl_gen_dli(p, BL_REG_K0, val);
bl_gen_load_ulong(p, BL_REG_K1, addr);
diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index edda87e..a9d87f3 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -323,7 +323,7 @@ static void boston_register_types(void)
}
type_init(boston_register_types)
-static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr)
+static void gen_firmware(void *p, hwaddr kernel_entry, hwaddr fdt_addr)
{
uint64_t regaddr;
@@ -515,7 +515,7 @@ static const void *create_fdt(BostonState *s,
{
void *fdt;
int cpu;
- MachineState *mc = s->mach;
+ MachineState *ms = s->mach;
uint32_t platreg_ph, gic_ph, clk_ph;
char *name, *gic_name, *platreg_name, *stdout_name;
static const char * const syscon_compat[2] = {
@@ -542,7 +542,7 @@ static const void *create_fdt(BostonState *s,
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
- for (cpu = 0; cpu < mc->smp.cpus; cpu++) {
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
name = g_strdup_printf("/cpus/cpu@%d", cpu);
qemu_fdt_add_subnode(fdt, name);
qemu_fdt_setprop_string(fdt, name, "compatible", "img,mips");
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 34befa5..cfc8ca6 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -179,7 +179,7 @@ static void write_bootloader(CPUMIPSState *env, uint8_t *base,
/* Second part of the bootloader */
p = (uint32_t *)(base + 0x040);
- bl_gen_jump_kernel(&p,
+ bl_gen_jump_kernel((void **)&p,
true, ENVP_VADDR - 64,
true, 2, true, ENVP_VADDR,
true, ENVP_VADDR + 8,
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
deleted file mode 100644
index 164866c..0000000
--- a/hw/mips/gt64xxx_pci.c
+++ /dev/null
@@ -1,1234 +0,0 @@
-/*
- * QEMU GT64120 PCI host
- *
- * Copyright (c) 2006,2007 Aurelien Jarno
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu/units.h"
-#include "qemu/log.h"
-#include "hw/pci/pci_device.h"
-#include "hw/pci/pci_host.h"
-#include "migration/vmstate.h"
-#include "hw/intc/i8259.h"
-#include "hw/irq.h"
-#include "trace.h"
-#include "qom/object.h"
-
-#define GT_REGS (0x1000 >> 2)
-
-/* CPU Configuration */
-#define GT_CPU (0x000 >> 2)
-#define GT_MULTI (0x120 >> 2)
-
-/* CPU Address Decode */
-#define GT_SCS10LD (0x008 >> 2)
-#define GT_SCS10HD (0x010 >> 2)
-#define GT_SCS32LD (0x018 >> 2)
-#define GT_SCS32HD (0x020 >> 2)
-#define GT_CS20LD (0x028 >> 2)
-#define GT_CS20HD (0x030 >> 2)
-#define GT_CS3BOOTLD (0x038 >> 2)
-#define GT_CS3BOOTHD (0x040 >> 2)
-#define GT_PCI0IOLD (0x048 >> 2)
-#define GT_PCI0IOHD (0x050 >> 2)
-#define GT_PCI0M0LD (0x058 >> 2)
-#define GT_PCI0M0HD (0x060 >> 2)
-#define GT_PCI0M1LD (0x080 >> 2)
-#define GT_PCI0M1HD (0x088 >> 2)
-#define GT_PCI1IOLD (0x090 >> 2)
-#define GT_PCI1IOHD (0x098 >> 2)
-#define GT_PCI1M0LD (0x0a0 >> 2)
-#define GT_PCI1M0HD (0x0a8 >> 2)
-#define GT_PCI1M1LD (0x0b0 >> 2)
-#define GT_PCI1M1HD (0x0b8 >> 2)
-#define GT_ISD (0x068 >> 2)
-
-#define GT_SCS10AR (0x0d0 >> 2)
-#define GT_SCS32AR (0x0d8 >> 2)
-#define GT_CS20R (0x0e0 >> 2)
-#define GT_CS3BOOTR (0x0e8 >> 2)
-
-#define GT_PCI0IOREMAP (0x0f0 >> 2)
-#define GT_PCI0M0REMAP (0x0f8 >> 2)
-#define GT_PCI0M1REMAP (0x100 >> 2)
-#define GT_PCI1IOREMAP (0x108 >> 2)
-#define GT_PCI1M0REMAP (0x110 >> 2)
-#define GT_PCI1M1REMAP (0x118 >> 2)
-
-/* CPU Error Report */
-#define GT_CPUERR_ADDRLO (0x070 >> 2)
-#define GT_CPUERR_ADDRHI (0x078 >> 2)
-#define GT_CPUERR_DATALO (0x128 >> 2) /* GT-64120A only */
-#define GT_CPUERR_DATAHI (0x130 >> 2) /* GT-64120A only */
-#define GT_CPUERR_PARITY (0x138 >> 2) /* GT-64120A only */
-
-/* CPU Sync Barrier */
-#define GT_PCI0SYNC (0x0c0 >> 2)
-#define GT_PCI1SYNC (0x0c8 >> 2)
-
-/* SDRAM and Device Address Decode */
-#define GT_SCS0LD (0x400 >> 2)
-#define GT_SCS0HD (0x404 >> 2)
-#define GT_SCS1LD (0x408 >> 2)
-#define GT_SCS1HD (0x40c >> 2)
-#define GT_SCS2LD (0x410 >> 2)
-#define GT_SCS2HD (0x414 >> 2)
-#define GT_SCS3LD (0x418 >> 2)
-#define GT_SCS3HD (0x41c >> 2)
-#define GT_CS0LD (0x420 >> 2)
-#define GT_CS0HD (0x424 >> 2)
-#define GT_CS1LD (0x428 >> 2)
-#define GT_CS1HD (0x42c >> 2)
-#define GT_CS2LD (0x430 >> 2)
-#define GT_CS2HD (0x434 >> 2)
-#define GT_CS3LD (0x438 >> 2)
-#define GT_CS3HD (0x43c >> 2)
-#define GT_BOOTLD (0x440 >> 2)
-#define GT_BOOTHD (0x444 >> 2)
-#define GT_ADERR (0x470 >> 2)
-
-/* SDRAM Configuration */
-#define GT_SDRAM_CFG (0x448 >> 2)
-#define GT_SDRAM_OPMODE (0x474 >> 2)
-#define GT_SDRAM_BM (0x478 >> 2)
-#define GT_SDRAM_ADDRDECODE (0x47c >> 2)
-
-/* SDRAM Parameters */
-#define GT_SDRAM_B0 (0x44c >> 2)
-#define GT_SDRAM_B1 (0x450 >> 2)
-#define GT_SDRAM_B2 (0x454 >> 2)
-#define GT_SDRAM_B3 (0x458 >> 2)
-
-/* Device Parameters */
-#define GT_DEV_B0 (0x45c >> 2)
-#define GT_DEV_B1 (0x460 >> 2)
-#define GT_DEV_B2 (0x464 >> 2)
-#define GT_DEV_B3 (0x468 >> 2)
-#define GT_DEV_BOOT (0x46c >> 2)
-
-/* ECC */
-#define GT_ECC_ERRDATALO (0x480 >> 2) /* GT-64120A only */
-#define GT_ECC_ERRDATAHI (0x484 >> 2) /* GT-64120A only */
-#define GT_ECC_MEM (0x488 >> 2) /* GT-64120A only */
-#define GT_ECC_CALC (0x48c >> 2) /* GT-64120A only */
-#define GT_ECC_ERRADDR (0x490 >> 2) /* GT-64120A only */
-
-/* DMA Record */
-#define GT_DMA0_CNT (0x800 >> 2)
-#define GT_DMA1_CNT (0x804 >> 2)
-#define GT_DMA2_CNT (0x808 >> 2)
-#define GT_DMA3_CNT (0x80c >> 2)
-#define GT_DMA0_SA (0x810 >> 2)
-#define GT_DMA1_SA (0x814 >> 2)
-#define GT_DMA2_SA (0x818 >> 2)
-#define GT_DMA3_SA (0x81c >> 2)
-#define GT_DMA0_DA (0x820 >> 2)
-#define GT_DMA1_DA (0x824 >> 2)
-#define GT_DMA2_DA (0x828 >> 2)
-#define GT_DMA3_DA (0x82c >> 2)
-#define GT_DMA0_NEXT (0x830 >> 2)
-#define GT_DMA1_NEXT (0x834 >> 2)
-#define GT_DMA2_NEXT (0x838 >> 2)
-#define GT_DMA3_NEXT (0x83c >> 2)
-#define GT_DMA0_CUR (0x870 >> 2)
-#define GT_DMA1_CUR (0x874 >> 2)
-#define GT_DMA2_CUR (0x878 >> 2)
-#define GT_DMA3_CUR (0x87c >> 2)
-
-/* DMA Channel Control */
-#define GT_DMA0_CTRL (0x840 >> 2)
-#define GT_DMA1_CTRL (0x844 >> 2)
-#define GT_DMA2_CTRL (0x848 >> 2)
-#define GT_DMA3_CTRL (0x84c >> 2)
-
-/* DMA Arbiter */
-#define GT_DMA_ARB (0x860 >> 2)
-
-/* Timer/Counter */
-#define GT_TC0 (0x850 >> 2)
-#define GT_TC1 (0x854 >> 2)
-#define GT_TC2 (0x858 >> 2)
-#define GT_TC3 (0x85c >> 2)
-#define GT_TC_CONTROL (0x864 >> 2)
-
-/* PCI Internal */
-#define GT_PCI0_CMD (0xc00 >> 2)
-#define GT_PCI0_TOR (0xc04 >> 2)
-#define GT_PCI0_BS_SCS10 (0xc08 >> 2)
-#define GT_PCI0_BS_SCS32 (0xc0c >> 2)
-#define GT_PCI0_BS_CS20 (0xc10 >> 2)
-#define GT_PCI0_BS_CS3BT (0xc14 >> 2)
-#define GT_PCI1_IACK (0xc30 >> 2)
-#define GT_PCI0_IACK (0xc34 >> 2)
-#define GT_PCI0_BARE (0xc3c >> 2)
-#define GT_PCI0_PREFMBR (0xc40 >> 2)
-#define GT_PCI0_SCS10_BAR (0xc48 >> 2)
-#define GT_PCI0_SCS32_BAR (0xc4c >> 2)
-#define GT_PCI0_CS20_BAR (0xc50 >> 2)
-#define GT_PCI0_CS3BT_BAR (0xc54 >> 2)
-#define GT_PCI0_SSCS10_BAR (0xc58 >> 2)
-#define GT_PCI0_SSCS32_BAR (0xc5c >> 2)
-#define GT_PCI0_SCS3BT_BAR (0xc64 >> 2)
-#define GT_PCI1_CMD (0xc80 >> 2)
-#define GT_PCI1_TOR (0xc84 >> 2)
-#define GT_PCI1_BS_SCS10 (0xc88 >> 2)
-#define GT_PCI1_BS_SCS32 (0xc8c >> 2)
-#define GT_PCI1_BS_CS20 (0xc90 >> 2)
-#define GT_PCI1_BS_CS3BT (0xc94 >> 2)
-#define GT_PCI1_BARE (0xcbc >> 2)
-#define GT_PCI1_PREFMBR (0xcc0 >> 2)
-#define GT_PCI1_SCS10_BAR (0xcc8 >> 2)
-#define GT_PCI1_SCS32_BAR (0xccc >> 2)
-#define GT_PCI1_CS20_BAR (0xcd0 >> 2)
-#define GT_PCI1_CS3BT_BAR (0xcd4 >> 2)
-#define GT_PCI1_SSCS10_BAR (0xcd8 >> 2)
-#define GT_PCI1_SSCS32_BAR (0xcdc >> 2)
-#define GT_PCI1_SCS3BT_BAR (0xce4 >> 2)
-#define GT_PCI1_CFGADDR (0xcf0 >> 2)
-#define GT_PCI1_CFGDATA (0xcf4 >> 2)
-#define GT_PCI0_CFGADDR (0xcf8 >> 2)
-#define GT_PCI0_CFGDATA (0xcfc >> 2)
-
-/* Interrupts */
-#define GT_INTRCAUSE (0xc18 >> 2)
-#define GT_INTRMASK (0xc1c >> 2)
-#define GT_PCI0_ICMASK (0xc24 >> 2)
-#define GT_PCI0_SERR0MASK (0xc28 >> 2)
-#define GT_CPU_INTSEL (0xc70 >> 2)
-#define GT_PCI0_INTSEL (0xc74 >> 2)
-#define GT_HINTRCAUSE (0xc98 >> 2)
-#define GT_HINTRMASK (0xc9c >> 2)
-#define GT_PCI0_HICMASK (0xca4 >> 2)
-#define GT_PCI1_SERR1MASK (0xca8 >> 2)
-
-#define PCI_MAPPING_ENTRY(regname) \
- hwaddr regname ##_start; \
- hwaddr regname ##_length; \
- MemoryRegion regname ##_mem
-
-#define TYPE_GT64120_PCI_HOST_BRIDGE "gt64120"
-
-OBJECT_DECLARE_SIMPLE_TYPE(GT64120State, GT64120_PCI_HOST_BRIDGE)
-
-struct GT64120State {
- PCIHostState parent_obj;
-
- uint32_t regs[GT_REGS];
- PCI_MAPPING_ENTRY(PCI0IO);
- PCI_MAPPING_ENTRY(PCI0M0);
- PCI_MAPPING_ENTRY(PCI0M1);
- PCI_MAPPING_ENTRY(ISD);
- MemoryRegion pci0_mem;
- AddressSpace pci0_mem_as;
-};
-
-/* Adjust range to avoid touching space which isn't mappable via PCI */
-/*
- * XXX: Hardcoded values for Malta: 0x1e000000 - 0x1f100000
- * 0x1fc00000 - 0x1fd00000
- */
-static void check_reserved_space(hwaddr *start, hwaddr *length)
-{
- hwaddr begin = *start;
- hwaddr end = *start + *length;
-
- if (end >= 0x1e000000LL && end < 0x1f100000LL) {
- end = 0x1e000000LL;
- }
- if (begin >= 0x1e000000LL && begin < 0x1f100000LL) {
- begin = 0x1f100000LL;
- }
- if (end >= 0x1fc00000LL && end < 0x1fd00000LL) {
- end = 0x1fc00000LL;
- }
- if (begin >= 0x1fc00000LL && begin < 0x1fd00000LL) {
- begin = 0x1fd00000LL;
- }
- /* XXX: This is broken when a reserved range splits the requested range */
- if (end >= 0x1f100000LL && begin < 0x1e000000LL) {
- end = 0x1e000000LL;
- }
- if (end >= 0x1fd00000LL && begin < 0x1fc00000LL) {
- end = 0x1fc00000LL;
- }
-
- *start = begin;
- *length = end - begin;
-}
-
-static void gt64120_isd_mapping(GT64120State *s)
-{
- /* Bits 14:0 of ISD map to bits 35:21 of the start address. */
- hwaddr start = ((hwaddr)s->regs[GT_ISD] << 21) & 0xFFFE00000ull;
- hwaddr length = 0x1000;
-
- if (s->ISD_length) {
- memory_region_del_subregion(get_system_memory(), &s->ISD_mem);
- }
- check_reserved_space(&start, &length);
- length = 0x1000;
- /* Map new address */
- trace_gt64120_isd_remap(s->ISD_length, s->ISD_start, length, start);
- s->ISD_start = start;
- s->ISD_length = length;
- memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem);
-}
-
-static void gt64120_pci_mapping(GT64120State *s)
-{
- /* Update PCI0IO mapping */
- if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD]) {
- /* Unmap old IO address */
- if (s->PCI0IO_length) {
- memory_region_del_subregion(get_system_memory(), &s->PCI0IO_mem);
- object_unparent(OBJECT(&s->PCI0IO_mem));
- }
- /* Map new IO address */
- s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21;
- s->PCI0IO_length = ((s->regs[GT_PCI0IOHD] + 1) -
- (s->regs[GT_PCI0IOLD] & 0x7f)) << 21;
- if (s->PCI0IO_length) {
- memory_region_init_alias(&s->PCI0IO_mem, OBJECT(s), "pci0-io",
- get_system_io(), 0, s->PCI0IO_length);
- memory_region_add_subregion(get_system_memory(), s->PCI0IO_start,
- &s->PCI0IO_mem);
- }
- }
-
- /* Update PCI0M0 mapping */
- if ((s->regs[GT_PCI0M0LD] & 0x7f) <= s->regs[GT_PCI0M0HD]) {
- /* Unmap old MEM address */
- if (s->PCI0M0_length) {
- memory_region_del_subregion(get_system_memory(), &s->PCI0M0_mem);
- object_unparent(OBJECT(&s->PCI0M0_mem));
- }
- /* Map new mem address */
- s->PCI0M0_start = s->regs[GT_PCI0M0LD] << 21;
- s->PCI0M0_length = ((s->regs[GT_PCI0M0HD] + 1) -
- (s->regs[GT_PCI0M0LD] & 0x7f)) << 21;
- if (s->PCI0M0_length) {
- memory_region_init_alias(&s->PCI0M0_mem, OBJECT(s), "pci0-mem0",
- &s->pci0_mem, s->PCI0M0_start,
- s->PCI0M0_length);
- memory_region_add_subregion(get_system_memory(), s->PCI0M0_start,
- &s->PCI0M0_mem);
- }
- }
-
- /* Update PCI0M1 mapping */
- if ((s->regs[GT_PCI0M1LD] & 0x7f) <= s->regs[GT_PCI0M1HD]) {
- /* Unmap old MEM address */
- if (s->PCI0M1_length) {
- memory_region_del_subregion(get_system_memory(), &s->PCI0M1_mem);
- object_unparent(OBJECT(&s->PCI0M1_mem));
- }
- /* Map new mem address */
- s->PCI0M1_start = s->regs[GT_PCI0M1LD] << 21;
- s->PCI0M1_length = ((s->regs[GT_PCI0M1HD] + 1) -
- (s->regs[GT_PCI0M1LD] & 0x7f)) << 21;
- if (s->PCI0M1_length) {
- memory_region_init_alias(&s->PCI0M1_mem, OBJECT(s), "pci0-mem1",
- &s->pci0_mem, s->PCI0M1_start,
- s->PCI0M1_length);
- memory_region_add_subregion(get_system_memory(), s->PCI0M1_start,
- &s->PCI0M1_mem);
- }
- }
-}
-
-static int gt64120_post_load(void *opaque, int version_id)
-{
- GT64120State *s = opaque;
-
- gt64120_isd_mapping(s);
- gt64120_pci_mapping(s);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_gt64120 = {
- .name = "gt64120",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = gt64120_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, GT64120State, GT_REGS),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void gt64120_writel(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- GT64120State *s = opaque;
- PCIHostState *phb = PCI_HOST_BRIDGE(s);
- uint32_t saddr = addr >> 2;
-
- trace_gt64120_write(addr, val);
- if (!(s->regs[GT_CPU] & 0x00001000)) {
- val = bswap32(val);
- }
-
- switch (saddr) {
-
- /* CPU Configuration */
- case GT_CPU:
- s->regs[GT_CPU] = val;
- break;
- case GT_MULTI:
- /* Read-only register as only one GT64xxx is present on the CPU bus */
- break;
-
- /* CPU Address Decode */
- case GT_PCI0IOLD:
- s->regs[GT_PCI0IOLD] = val & 0x00007fff;
- s->regs[GT_PCI0IOREMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI0M0LD:
- s->regs[GT_PCI0M0LD] = val & 0x00007fff;
- s->regs[GT_PCI0M0REMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI0M1LD:
- s->regs[GT_PCI0M1LD] = val & 0x00007fff;
- s->regs[GT_PCI0M1REMAP] = val & 0x000007ff;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI1IOLD:
- s->regs[GT_PCI1IOLD] = val & 0x00007fff;
- s->regs[GT_PCI1IOREMAP] = val & 0x000007ff;
- break;
- case GT_PCI1M0LD:
- s->regs[GT_PCI1M0LD] = val & 0x00007fff;
- s->regs[GT_PCI1M0REMAP] = val & 0x000007ff;
- break;
- case GT_PCI1M1LD:
- s->regs[GT_PCI1M1LD] = val & 0x00007fff;
- s->regs[GT_PCI1M1REMAP] = val & 0x000007ff;
- break;
- case GT_PCI0M0HD:
- case GT_PCI0M1HD:
- case GT_PCI0IOHD:
- s->regs[saddr] = val & 0x0000007f;
- gt64120_pci_mapping(s);
- break;
- case GT_PCI1IOHD:
- case GT_PCI1M0HD:
- case GT_PCI1M1HD:
- s->regs[saddr] = val & 0x0000007f;
- break;
- case GT_ISD:
- s->regs[saddr] = val & 0x00007fff;
- gt64120_isd_mapping(s);
- break;
-
- case GT_PCI0IOREMAP:
- case GT_PCI0M0REMAP:
- case GT_PCI0M1REMAP:
- case GT_PCI1IOREMAP:
- case GT_PCI1M0REMAP:
- case GT_PCI1M1REMAP:
- s->regs[saddr] = val & 0x000007ff;
- break;
-
- /* CPU Error Report */
- case GT_CPUERR_ADDRLO:
- case GT_CPUERR_ADDRHI:
- case GT_CPUERR_DATALO:
- case GT_CPUERR_DATAHI:
- case GT_CPUERR_PARITY:
- /* Read-only registers, do nothing */
- qemu_log_mask(LOG_GUEST_ERROR,
- "gt64120: Read-only register write "
- "reg:0x%03x size:%u value:0x%0*" PRIx64 "\n",
- saddr << 2, size, size << 1, val);
- break;
-
- /* CPU Sync Barrier */
- case GT_PCI0SYNC:
- case GT_PCI1SYNC:
- /* Read-only registers, do nothing */
- qemu_log_mask(LOG_GUEST_ERROR,
- "gt64120: Read-only register write "
- "reg:0x%03x size:%u value:0x%0*" PRIx64 "\n",
- saddr << 2, size, size << 1, val);
- break;
-
- /* SDRAM and Device Address Decode */
- case GT_SCS0LD:
- case GT_SCS0HD:
- case GT_SCS1LD:
- case GT_SCS1HD:
- case GT_SCS2LD:
- case GT_SCS2HD:
- case GT_SCS3LD:
- case GT_SCS3HD:
- case GT_CS0LD:
- case GT_CS0HD:
- case GT_CS1LD:
- case GT_CS1HD:
- case GT_CS2LD:
- case GT_CS2HD:
- case GT_CS3LD:
- case GT_CS3HD:
- case GT_BOOTLD:
- case GT_BOOTHD:
- case GT_ADERR:
- /* SDRAM Configuration */
- case GT_SDRAM_CFG:
- case GT_SDRAM_OPMODE:
- case GT_SDRAM_BM:
- case GT_SDRAM_ADDRDECODE:
- /* Accept and ignore SDRAM interleave configuration */
- s->regs[saddr] = val;
- break;
-
- /* Device Parameters */
- case GT_DEV_B0:
- case GT_DEV_B1:
- case GT_DEV_B2:
- case GT_DEV_B3:
- case GT_DEV_BOOT:
- /* Not implemented */
- qemu_log_mask(LOG_UNIMP,
- "gt64120: Unimplemented device register write "
- "reg:0x%03x size:%u value:0x%0*" PRIx64 "\n",
- saddr << 2, size, size << 1, val);
- break;
-
- /* ECC */
- case GT_ECC_ERRDATALO:
- case GT_ECC_ERRDATAHI:
- case GT_ECC_MEM:
- case GT_ECC_CALC:
- case GT_ECC_ERRADDR:
- /* Read-only registers, do nothing */
- qemu_log_mask(LOG_GUEST_ERROR,
- "gt64120: Read-only register write "
- "reg:0x%03x size:%u value:0x%0*" PRIx64 "\n",
- saddr << 2, size, size << 1, val);
- break;
-
- /* DMA Record */
- case GT_DMA0_CNT:
- case GT_DMA1_CNT:
- case GT_DMA2_CNT:
- case GT_DMA3_CNT:
- case GT_DMA0_SA:
- case GT_DMA1_SA:
- case GT_DMA2_SA:
- case GT_DMA3_SA:
- case GT_DMA0_DA:
- case GT_DMA1_DA:
- case GT_DMA2_DA:
- case GT_DMA3_DA:
- case GT_DMA0_NEXT:
- case GT_DMA1_NEXT:
- case GT_DMA2_NEXT:
- case GT_DMA3_NEXT:
- case GT_DMA0_CUR:
- case GT_DMA1_CUR:
- case GT_DMA2_CUR:
- case GT_DMA3_CUR:
-
- /* DMA Channel Control */
- case GT_DMA0_CTRL:
- case GT_DMA1_CTRL:
- case GT_DMA2_CTRL:
- case GT_DMA3_CTRL:
-
- /* DMA Arbiter */
- case GT_DMA_ARB:
- /* Not implemented */
- qemu_log_mask(LOG_UNIMP,
- "gt64120: Unimplemented DMA register write "
- "reg:0x%03x size:%u value:0x%0*" PRIx64 "\n",
- saddr << 2, size, size << 1, val);
- break;
-
- /* Timer/Counter */
- case GT_TC0:
- case GT_TC1:
- case GT_TC2:
- case GT_TC3:
- case GT_TC_CONTROL:
- /* Not implemented */
- qemu_log_mask(LOG_UNIMP,
- "gt64120: Unimplemented timer register write "
- "reg:0x%03x size:%u value:0x%0*" PRIx64 "\n",
- saddr << 2, size, size << 1, val);
- break;
-
- /* PCI Internal */
- case GT_PCI0_CMD:
- case GT_PCI1_CMD:
- s->regs[saddr] = val & 0x0401fc0f;
- break;
- case GT_PCI0_TOR:
- case GT_PCI0_BS_SCS10:
- case GT_PCI0_BS_SCS32:
- case GT_PCI0_BS_CS20:
- case GT_PCI0_BS_CS3BT:
- case GT_PCI1_IACK:
- case GT_PCI0_IACK:
- case GT_PCI0_BARE:
- case GT_PCI0_PREFMBR:
- case GT_PCI0_SCS10_BAR:
- case GT_PCI0_SCS32_BAR:
- case GT_PCI0_CS20_BAR:
- case GT_PCI0_CS3BT_BAR:
- case GT_PCI0_SSCS10_BAR:
- case GT_PCI0_SSCS32_BAR:
- case GT_PCI0_SCS3BT_BAR:
- case GT_PCI1_TOR:
- case GT_PCI1_BS_SCS10:
- case GT_PCI1_BS_SCS32:
- case GT_PCI1_BS_CS20:
- case GT_PCI1_BS_CS3BT:
- case GT_PCI1_BARE:
- case GT_PCI1_PREFMBR:
- case GT_PCI1_SCS10_BAR:
- case GT_PCI1_SCS32_BAR:
- case GT_PCI1_CS20_BAR:
- case GT_PCI1_CS3BT_BAR:
- case GT_PCI1_SSCS10_BAR:
- case GT_PCI1_SSCS32_BAR:
- case GT_PCI1_SCS3BT_BAR:
- case GT_PCI1_CFGADDR:
- case GT_PCI1_CFGDATA:
- /* not implemented */
- qemu_log_mask(LOG_UNIMP,
- "gt64120: Unimplemented PCI register write "
- "reg:0x%03x size:%u value:0x%0*" PRIx64 "\n",
- saddr << 2, size, size << 1, val);
- break;
- case GT_PCI0_CFGADDR:
- phb->config_reg = val & 0x80fffffc;
- break;
- case GT_PCI0_CFGDATA:
- if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
- val = bswap32(val);
- }
- if (phb->config_reg & (1u << 31)) {
- pci_data_write(phb->bus, phb->config_reg, val, 4);
- }
- break;
-
- /* Interrupts */
- case GT_INTRCAUSE:
- /* not really implemented */
- s->regs[saddr] = ~(~(s->regs[saddr]) | ~(val & 0xfffffffe));
- s->regs[saddr] |= !!(s->regs[saddr] & 0xfffffffe);
- trace_gt64120_write_intreg("INTRCAUSE", size, val);
- break;
- case GT_INTRMASK:
- s->regs[saddr] = val & 0x3c3ffffe;
- trace_gt64120_write_intreg("INTRMASK", size, val);
- break;
- case GT_PCI0_ICMASK:
- s->regs[saddr] = val & 0x03fffffe;
- trace_gt64120_write_intreg("ICMASK", size, val);
- break;
- case GT_PCI0_SERR0MASK:
- s->regs[saddr] = val & 0x0000003f;
- trace_gt64120_write_intreg("SERR0MASK", size, val);
- break;
-
- /* Reserved when only PCI_0 is configured. */
- case GT_HINTRCAUSE:
- case GT_CPU_INTSEL:
- case GT_PCI0_INTSEL:
- case GT_HINTRMASK:
- case GT_PCI0_HICMASK:
- case GT_PCI1_SERR1MASK:
- /* not implemented */
- break;
-
- /* SDRAM Parameters */
- case GT_SDRAM_B0:
- case GT_SDRAM_B1:
- case GT_SDRAM_B2:
- case GT_SDRAM_B3:
- /*
- * We don't simulate electrical parameters of the SDRAM.
- * Accept, but ignore the values.
- */
- s->regs[saddr] = val;
- break;
-
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "gt64120: Illegal register write "
- "reg:0x%03x size:%u value:0x%0*" PRIx64 "\n",
- saddr << 2, size, size << 1, val);
- break;
- }
-}
-
-static uint64_t gt64120_readl(void *opaque,
- hwaddr addr, unsigned size)
-{
- GT64120State *s = opaque;
- PCIHostState *phb = PCI_HOST_BRIDGE(s);
- uint32_t val;
- uint32_t saddr = addr >> 2;
-
- switch (saddr) {
-
- /* CPU Configuration */
- case GT_MULTI:
- /*
- * Only one GT64xxx is present on the CPU bus, return
- * the initial value.
- */
- val = s->regs[saddr];
- break;
-
- /* CPU Error Report */
- case GT_CPUERR_ADDRLO:
- case GT_CPUERR_ADDRHI:
- case GT_CPUERR_DATALO:
- case GT_CPUERR_DATAHI:
- case GT_CPUERR_PARITY:
- /* Emulated memory has no error, always return the initial values. */
- val = s->regs[saddr];
- break;
-
- /* CPU Sync Barrier */
- case GT_PCI0SYNC:
- case GT_PCI1SYNC:
- /*
- * Reading those register should empty all FIFO on the PCI
- * bus, which are not emulated. The return value should be
- * a random value that should be ignored.
- */
- val = 0xc000ffee;
- break;
-
- /* ECC */
- case GT_ECC_ERRDATALO:
- case GT_ECC_ERRDATAHI:
- case GT_ECC_MEM:
- case GT_ECC_CALC:
- case GT_ECC_ERRADDR:
- /* Emulated memory has no error, always return the initial values. */
- val = s->regs[saddr];
- break;
-
- case GT_CPU:
- case GT_SCS10LD:
- case GT_SCS10HD:
- case GT_SCS32LD:
- case GT_SCS32HD:
- case GT_CS20LD:
- case GT_CS20HD:
- case GT_CS3BOOTLD:
- case GT_CS3BOOTHD:
- case GT_SCS10AR:
- case GT_SCS32AR:
- case GT_CS20R:
- case GT_CS3BOOTR:
- case GT_PCI0IOLD:
- case GT_PCI0M0LD:
- case GT_PCI0M1LD:
- case GT_PCI1IOLD:
- case GT_PCI1M0LD:
- case GT_PCI1M1LD:
- case GT_PCI0IOHD:
- case GT_PCI0M0HD:
- case GT_PCI0M1HD:
- case GT_PCI1IOHD:
- case GT_PCI1M0HD:
- case GT_PCI1M1HD:
- case GT_PCI0IOREMAP:
- case GT_PCI0M0REMAP:
- case GT_PCI0M1REMAP:
- case GT_PCI1IOREMAP:
- case GT_PCI1M0REMAP:
- case GT_PCI1M1REMAP:
- case GT_ISD:
- val = s->regs[saddr];
- break;
- case GT_PCI0_IACK:
- /* Read the IRQ number */
- val = pic_read_irq(isa_pic);
- break;
-
- /* SDRAM and Device Address Decode */
- case GT_SCS0LD:
- case GT_SCS0HD:
- case GT_SCS1LD:
- case GT_SCS1HD:
- case GT_SCS2LD:
- case GT_SCS2HD:
- case GT_SCS3LD:
- case GT_SCS3HD:
- case GT_CS0LD:
- case GT_CS0HD:
- case GT_CS1LD:
- case GT_CS1HD:
- case GT_CS2LD:
- case GT_CS2HD:
- case GT_CS3LD:
- case GT_CS3HD:
- case GT_BOOTLD:
- case GT_BOOTHD:
- case GT_ADERR:
- val = s->regs[saddr];
- break;
-
- /* SDRAM Configuration */
- case GT_SDRAM_CFG:
- case GT_SDRAM_OPMODE:
- case GT_SDRAM_BM:
- case GT_SDRAM_ADDRDECODE:
- val = s->regs[saddr];
- break;
-
- /* SDRAM Parameters */
- case GT_SDRAM_B0:
- case GT_SDRAM_B1:
- case GT_SDRAM_B2:
- case GT_SDRAM_B3:
- /*
- * We don't simulate electrical parameters of the SDRAM.
- * Just return the last written value.
- */
- val = s->regs[saddr];
- break;
-
- /* Device Parameters */
- case GT_DEV_B0:
- case GT_DEV_B1:
- case GT_DEV_B2:
- case GT_DEV_B3:
- case GT_DEV_BOOT:
- val = s->regs[saddr];
- break;
-
- /* DMA Record */
- case GT_DMA0_CNT:
- case GT_DMA1_CNT:
- case GT_DMA2_CNT:
- case GT_DMA3_CNT:
- case GT_DMA0_SA:
- case GT_DMA1_SA:
- case GT_DMA2_SA:
- case GT_DMA3_SA:
- case GT_DMA0_DA:
- case GT_DMA1_DA:
- case GT_DMA2_DA:
- case GT_DMA3_DA:
- case GT_DMA0_NEXT:
- case GT_DMA1_NEXT:
- case GT_DMA2_NEXT:
- case GT_DMA3_NEXT:
- case GT_DMA0_CUR:
- case GT_DMA1_CUR:
- case GT_DMA2_CUR:
- case GT_DMA3_CUR:
- val = s->regs[saddr];
- break;
-
- /* DMA Channel Control */
- case GT_DMA0_CTRL:
- case GT_DMA1_CTRL:
- case GT_DMA2_CTRL:
- case GT_DMA3_CTRL:
- val = s->regs[saddr];
- break;
-
- /* DMA Arbiter */
- case GT_DMA_ARB:
- val = s->regs[saddr];
- break;
-
- /* Timer/Counter */
- case GT_TC0:
- case GT_TC1:
- case GT_TC2:
- case GT_TC3:
- case GT_TC_CONTROL:
- val = s->regs[saddr];
- break;
-
- /* PCI Internal */
- case GT_PCI0_CFGADDR:
- val = phb->config_reg;
- break;
- case GT_PCI0_CFGDATA:
- if (!(phb->config_reg & (1 << 31))) {
- val = 0xffffffff;
- } else {
- val = pci_data_read(phb->bus, phb->config_reg, 4);
- }
- if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
- val = bswap32(val);
- }
- break;
-
- case GT_PCI0_CMD:
- case GT_PCI0_TOR:
- case GT_PCI0_BS_SCS10:
- case GT_PCI0_BS_SCS32:
- case GT_PCI0_BS_CS20:
- case GT_PCI0_BS_CS3BT:
- case GT_PCI1_IACK:
- case GT_PCI0_BARE:
- case GT_PCI0_PREFMBR:
- case GT_PCI0_SCS10_BAR:
- case GT_PCI0_SCS32_BAR:
- case GT_PCI0_CS20_BAR:
- case GT_PCI0_CS3BT_BAR:
- case GT_PCI0_SSCS10_BAR:
- case GT_PCI0_SSCS32_BAR:
- case GT_PCI0_SCS3BT_BAR:
- case GT_PCI1_CMD:
- case GT_PCI1_TOR:
- case GT_PCI1_BS_SCS10:
- case GT_PCI1_BS_SCS32:
- case GT_PCI1_BS_CS20:
- case GT_PCI1_BS_CS3BT:
- case GT_PCI1_BARE:
- case GT_PCI1_PREFMBR:
- case GT_PCI1_SCS10_BAR:
- case GT_PCI1_SCS32_BAR:
- case GT_PCI1_CS20_BAR:
- case GT_PCI1_CS3BT_BAR:
- case GT_PCI1_SSCS10_BAR:
- case GT_PCI1_SSCS32_BAR:
- case GT_PCI1_SCS3BT_BAR:
- case GT_PCI1_CFGADDR:
- case GT_PCI1_CFGDATA:
- val = s->regs[saddr];
- break;
-
- /* Interrupts */
- case GT_INTRCAUSE:
- val = s->regs[saddr];
- trace_gt64120_read_intreg("INTRCAUSE", size, val);
- break;
- case GT_INTRMASK:
- val = s->regs[saddr];
- trace_gt64120_read_intreg("INTRMASK", size, val);
- break;
- case GT_PCI0_ICMASK:
- val = s->regs[saddr];
- trace_gt64120_read_intreg("ICMASK", size, val);
- break;
- case GT_PCI0_SERR0MASK:
- val = s->regs[saddr];
- trace_gt64120_read_intreg("SERR0MASK", size, val);
- break;
-
- /* Reserved when only PCI_0 is configured. */
- case GT_HINTRCAUSE:
- case GT_CPU_INTSEL:
- case GT_PCI0_INTSEL:
- case GT_HINTRMASK:
- case GT_PCI0_HICMASK:
- case GT_PCI1_SERR1MASK:
- val = s->regs[saddr];
- break;
-
- default:
- val = s->regs[saddr];
- qemu_log_mask(LOG_GUEST_ERROR,
- "gt64120: Illegal register read "
- "reg:0x%03x size:%u value:0x%0*x\n",
- saddr << 2, size, size << 1, val);
- break;
- }
-
- if (!(s->regs[GT_CPU] & 0x00001000)) {
- val = bswap32(val);
- }
- trace_gt64120_read(addr, val);
-
- return val;
-}
-
-static const MemoryRegionOps isd_mem_ops = {
- .read = gt64120_readl,
- .write = gt64120_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static void gt64120_reset(DeviceState *dev)
-{
- GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
-
- /* FIXME: Malta specific hw assumptions ahead */
-
- /* CPU Configuration */
-#if TARGET_BIG_ENDIAN
- s->regs[GT_CPU] = 0x00000000;
-#else
- s->regs[GT_CPU] = 0x00001000;
-#endif
- s->regs[GT_MULTI] = 0x00000003;
-
- /* CPU Address decode */
- s->regs[GT_SCS10LD] = 0x00000000;
- s->regs[GT_SCS10HD] = 0x00000007;
- s->regs[GT_SCS32LD] = 0x00000008;
- s->regs[GT_SCS32HD] = 0x0000000f;
- s->regs[GT_CS20LD] = 0x000000e0;
- s->regs[GT_CS20HD] = 0x00000070;
- s->regs[GT_CS3BOOTLD] = 0x000000f8;
- s->regs[GT_CS3BOOTHD] = 0x0000007f;
-
- s->regs[GT_PCI0IOLD] = 0x00000080;
- s->regs[GT_PCI0IOHD] = 0x0000000f;
- s->regs[GT_PCI0M0LD] = 0x00000090;
- s->regs[GT_PCI0M0HD] = 0x0000001f;
- s->regs[GT_ISD] = 0x000000a0;
- s->regs[GT_PCI0M1LD] = 0x00000790;
- s->regs[GT_PCI0M1HD] = 0x0000001f;
- s->regs[GT_PCI1IOLD] = 0x00000100;
- s->regs[GT_PCI1IOHD] = 0x0000000f;
- s->regs[GT_PCI1M0LD] = 0x00000110;
- s->regs[GT_PCI1M0HD] = 0x0000001f;
- s->regs[GT_PCI1M1LD] = 0x00000120;
- s->regs[GT_PCI1M1HD] = 0x0000002f;
-
- s->regs[GT_SCS10AR] = 0x00000000;
- s->regs[GT_SCS32AR] = 0x00000008;
- s->regs[GT_CS20R] = 0x000000e0;
- s->regs[GT_CS3BOOTR] = 0x000000f8;
-
- s->regs[GT_PCI0IOREMAP] = 0x00000080;
- s->regs[GT_PCI0M0REMAP] = 0x00000090;
- s->regs[GT_PCI0M1REMAP] = 0x00000790;
- s->regs[GT_PCI1IOREMAP] = 0x00000100;
- s->regs[GT_PCI1M0REMAP] = 0x00000110;
- s->regs[GT_PCI1M1REMAP] = 0x00000120;
-
- /* CPU Error Report */
- s->regs[GT_CPUERR_ADDRLO] = 0x00000000;
- s->regs[GT_CPUERR_ADDRHI] = 0x00000000;
- s->regs[GT_CPUERR_DATALO] = 0xffffffff;
- s->regs[GT_CPUERR_DATAHI] = 0xffffffff;
- s->regs[GT_CPUERR_PARITY] = 0x000000ff;
-
- /* CPU Sync Barrier */
- s->regs[GT_PCI0SYNC] = 0x00000000;
- s->regs[GT_PCI1SYNC] = 0x00000000;
-
- /* SDRAM and Device Address Decode */
- s->regs[GT_SCS0LD] = 0x00000000;
- s->regs[GT_SCS0HD] = 0x00000007;
- s->regs[GT_SCS1LD] = 0x00000008;
- s->regs[GT_SCS1HD] = 0x0000000f;
- s->regs[GT_SCS2LD] = 0x00000010;
- s->regs[GT_SCS2HD] = 0x00000017;
- s->regs[GT_SCS3LD] = 0x00000018;
- s->regs[GT_SCS3HD] = 0x0000001f;
- s->regs[GT_CS0LD] = 0x000000c0;
- s->regs[GT_CS0HD] = 0x000000c7;
- s->regs[GT_CS1LD] = 0x000000c8;
- s->regs[GT_CS1HD] = 0x000000cf;
- s->regs[GT_CS2LD] = 0x000000d0;
- s->regs[GT_CS2HD] = 0x000000df;
- s->regs[GT_CS3LD] = 0x000000f0;
- s->regs[GT_CS3HD] = 0x000000fb;
- s->regs[GT_BOOTLD] = 0x000000fc;
- s->regs[GT_BOOTHD] = 0x000000ff;
- s->regs[GT_ADERR] = 0xffffffff;
-
- /* SDRAM Configuration */
- s->regs[GT_SDRAM_CFG] = 0x00000200;
- s->regs[GT_SDRAM_OPMODE] = 0x00000000;
- s->regs[GT_SDRAM_BM] = 0x00000007;
- s->regs[GT_SDRAM_ADDRDECODE] = 0x00000002;
-
- /* SDRAM Parameters */
- s->regs[GT_SDRAM_B0] = 0x00000005;
- s->regs[GT_SDRAM_B1] = 0x00000005;
- s->regs[GT_SDRAM_B2] = 0x00000005;
- s->regs[GT_SDRAM_B3] = 0x00000005;
-
- /* ECC */
- s->regs[GT_ECC_ERRDATALO] = 0x00000000;
- s->regs[GT_ECC_ERRDATAHI] = 0x00000000;
- s->regs[GT_ECC_MEM] = 0x00000000;
- s->regs[GT_ECC_CALC] = 0x00000000;
- s->regs[GT_ECC_ERRADDR] = 0x00000000;
-
- /* Device Parameters */
- s->regs[GT_DEV_B0] = 0x386fffff;
- s->regs[GT_DEV_B1] = 0x386fffff;
- s->regs[GT_DEV_B2] = 0x386fffff;
- s->regs[GT_DEV_B3] = 0x386fffff;
- s->regs[GT_DEV_BOOT] = 0x146fffff;
-
- /* DMA registers are all zeroed at reset */
-
- /* Timer/Counter */
- s->regs[GT_TC0] = 0xffffffff;
- s->regs[GT_TC1] = 0x00ffffff;
- s->regs[GT_TC2] = 0x00ffffff;
- s->regs[GT_TC3] = 0x00ffffff;
- s->regs[GT_TC_CONTROL] = 0x00000000;
-
- /* PCI Internal */
-#if TARGET_BIG_ENDIAN
- s->regs[GT_PCI0_CMD] = 0x00000000;
-#else
- s->regs[GT_PCI0_CMD] = 0x00010001;
-#endif
- s->regs[GT_PCI0_TOR] = 0x0000070f;
- s->regs[GT_PCI0_BS_SCS10] = 0x00fff000;
- s->regs[GT_PCI0_BS_SCS32] = 0x00fff000;
- s->regs[GT_PCI0_BS_CS20] = 0x01fff000;
- s->regs[GT_PCI0_BS_CS3BT] = 0x00fff000;
- s->regs[GT_PCI1_IACK] = 0x00000000;
- s->regs[GT_PCI0_IACK] = 0x00000000;
- s->regs[GT_PCI0_BARE] = 0x0000000f;
- s->regs[GT_PCI0_PREFMBR] = 0x00000040;
- s->regs[GT_PCI0_SCS10_BAR] = 0x00000000;
- s->regs[GT_PCI0_SCS32_BAR] = 0x01000000;
- s->regs[GT_PCI0_CS20_BAR] = 0x1c000000;
- s->regs[GT_PCI0_CS3BT_BAR] = 0x1f000000;
- s->regs[GT_PCI0_SSCS10_BAR] = 0x00000000;
- s->regs[GT_PCI0_SSCS32_BAR] = 0x01000000;
- s->regs[GT_PCI0_SCS3BT_BAR] = 0x1f000000;
-#if TARGET_BIG_ENDIAN
- s->regs[GT_PCI1_CMD] = 0x00000000;
-#else
- s->regs[GT_PCI1_CMD] = 0x00010001;
-#endif
- s->regs[GT_PCI1_TOR] = 0x0000070f;
- s->regs[GT_PCI1_BS_SCS10] = 0x00fff000;
- s->regs[GT_PCI1_BS_SCS32] = 0x00fff000;
- s->regs[GT_PCI1_BS_CS20] = 0x01fff000;
- s->regs[GT_PCI1_BS_CS3BT] = 0x00fff000;
- s->regs[GT_PCI1_BARE] = 0x0000000f;
- s->regs[GT_PCI1_PREFMBR] = 0x00000040;
- s->regs[GT_PCI1_SCS10_BAR] = 0x00000000;
- s->regs[GT_PCI1_SCS32_BAR] = 0x01000000;
- s->regs[GT_PCI1_CS20_BAR] = 0x1c000000;
- s->regs[GT_PCI1_CS3BT_BAR] = 0x1f000000;
- s->regs[GT_PCI1_SSCS10_BAR] = 0x00000000;
- s->regs[GT_PCI1_SSCS32_BAR] = 0x01000000;
- s->regs[GT_PCI1_SCS3BT_BAR] = 0x1f000000;
- s->regs[GT_PCI1_CFGADDR] = 0x00000000;
- s->regs[GT_PCI1_CFGDATA] = 0x00000000;
- s->regs[GT_PCI0_CFGADDR] = 0x00000000;
-
- /* Interrupt registers are all zeroed at reset */
-
- gt64120_isd_mapping(s);
- gt64120_pci_mapping(s);
-}
-
-static void gt64120_realize(DeviceState *dev, Error **errp)
-{
- GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
- PCIHostState *phb = PCI_HOST_BRIDGE(dev);
-
- memory_region_init_io(&s->ISD_mem, OBJECT(dev), &isd_mem_ops, s,
- "gt64120-isd", 0x1000);
- memory_region_init(&s->pci0_mem, OBJECT(dev), "pci0-mem", 4 * GiB);
- address_space_init(&s->pci0_mem_as, &s->pci0_mem, "pci0-mem");
- phb->bus = pci_root_bus_new(dev, "pci",
- &s->pci0_mem,
- get_system_io(),
- PCI_DEVFN(18, 0), TYPE_PCI_BUS);
-
- pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
-}
-
-static void gt64120_pci_realize(PCIDevice *d, Error **errp)
-{
- /* FIXME: Malta specific hw assumptions ahead */
- pci_set_word(d->config + PCI_COMMAND, 0);
- pci_set_word(d->config + PCI_STATUS,
- PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
- pci_config_set_prog_interface(d->config, 0);
- pci_set_long(d->config + PCI_BASE_ADDRESS_0, 0x00000008);
- pci_set_long(d->config + PCI_BASE_ADDRESS_1, 0x01000008);
- pci_set_long(d->config + PCI_BASE_ADDRESS_2, 0x1c000000);
- pci_set_long(d->config + PCI_BASE_ADDRESS_3, 0x1f000000);
- pci_set_long(d->config + PCI_BASE_ADDRESS_4, 0x14000000);
- pci_set_long(d->config + PCI_BASE_ADDRESS_5, 0x14000001);
- pci_set_byte(d->config + 0x3d, 0x01);
-}
-
-static void gt64120_pci_class_init(ObjectClass *klass, void *data)
-{
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- k->realize = gt64120_pci_realize;
- k->vendor_id = PCI_VENDOR_ID_MARVELL;
- k->device_id = PCI_DEVICE_ID_MARVELL_GT6412X;
- k->revision = 0x10;
- k->class_id = PCI_CLASS_BRIDGE_HOST;
- /*
- * PCI-facing part of the host bridge, not usable without the
- * host-facing part, which can't be device_add'ed, yet.
- */
- dc->user_creatable = false;
-}
-
-static const TypeInfo gt64120_pci_info = {
- .name = "gt64120_pci",
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(PCIDevice),
- .class_init = gt64120_pci_class_init,
- .interfaces = (InterfaceInfo[]) {
- { INTERFACE_CONVENTIONAL_PCI_DEVICE },
- { },
- },
-};
-
-static void gt64120_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
- dc->realize = gt64120_realize;
- dc->reset = gt64120_reset;
- dc->vmsd = &vmstate_gt64120;
-}
-
-static const TypeInfo gt64120_info = {
- .name = TYPE_GT64120_PCI_HOST_BRIDGE,
- .parent = TYPE_PCI_HOST_BRIDGE,
- .instance_size = sizeof(GT64120State),
- .class_init = gt64120_class_init,
-};
-
-static void gt64120_pci_register_types(void)
-{
- type_register_static(&gt64120_info);
- type_register_static(&gt64120_pci_info);
-}
-
-type_init(gt64120_pci_register_types)
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index c0a2e0a..ec172b1 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -39,6 +39,7 @@
#include "hw/mips/bootloader.h"
#include "hw/mips/cpudevs.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "qemu/log.h"
#include "hw/mips/bios.h"
#include "hw/ide/pci.h"
@@ -53,11 +54,12 @@
#include "sysemu/runstate.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "hw/misc/empty_slot.h"
#include "sysemu/kvm.h"
#include "semihosting/semihost.h"
#include "hw/mips/cps.h"
#include "hw/qdev-clock.h"
+#include "target/mips/internal.h"
+#include "trace.h"
#define ENVP_PADDR 0x2000
#define ENVP_VADDR cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR)
@@ -71,6 +73,8 @@
#define FLASH_SIZE 0x400000
+#define PIIX4_PCI_DEVFN PCI_DEVFN(10, 0)
+
typedef struct {
MemoryRegion iomem;
MemoryRegion iomem_lo; /* 0 - 0x900 */
@@ -106,11 +110,10 @@ static struct _loaderparams {
} loaderparams;
/* Malta FPGA */
-static void malta_fpga_update_display(void *opaque)
+static void malta_fpga_update_display_leds(MaltaFPGAState *s)
{
char leds_text[9];
int i;
- MaltaFPGAState *s = opaque;
for (i = 7 ; i >= 0 ; i--) {
if (s->leds & (1 << i)) {
@@ -121,8 +124,14 @@ static void malta_fpga_update_display(void *opaque)
}
leds_text[8] = '\0';
+ trace_malta_fpga_leds(leds_text);
qemu_chr_fe_printf(&s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n",
leds_text);
+}
+
+static void malta_fpga_update_display_ascii(MaltaFPGAState *s)
+{
+ trace_malta_fpga_display(s->display_text);
qemu_chr_fe_printf(&s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|",
s->display_text);
}
@@ -457,13 +466,13 @@ static void malta_fpga_write(void *opaque, hwaddr addr,
/* LEDBAR Register */
case 0x00408:
s->leds = val & 0xff;
- malta_fpga_update_display(s);
+ malta_fpga_update_display_leds(s);
break;
/* ASCIIWORD Register */
case 0x00410:
snprintf(s->display_text, 9, "%08X", (uint32_t)val);
- malta_fpga_update_display(s);
+ malta_fpga_update_display_ascii(s);
break;
/* ASCIIPOS0 to ASCIIPOS7 Registers */
@@ -476,7 +485,7 @@ static void malta_fpga_write(void *opaque, hwaddr addr,
case 0x00448:
case 0x00450:
s->display_text[(saddr - 0x00418) >> 3] = (char) val;
- malta_fpga_update_display(s);
+ malta_fpga_update_display_ascii(s);
break;
/* SOFTRES Register */
@@ -611,6 +620,78 @@ static void network_init(PCIBus *pci_bus)
}
}
+static void bl_setup_gt64120_jump_kernel(void **p, uint64_t run_addr,
+ uint64_t kernel_entry)
+{
+ static const char pci_pins_cfg[PCI_NUM_PINS] = {
+ 10, 10, 11, 11 /* PIIX IRQRC[A:D] */
+ };
+
+ /* Bus endianess is always reversed */
+#if TARGET_BIG_ENDIAN
+#define cpu_to_gt32 cpu_to_le32
+#else
+#define cpu_to_gt32 cpu_to_be32
+#endif
+
+ /* setup MEM-to-PCI0 mapping as done by YAMON */
+
+ /* move GT64120 registers from 0x14000000 to 0x1be00000 */
+ bl_gen_write_u32(p, /* GT_ISD */
+ cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68),
+ cpu_to_gt32(0x1be00000 << 3));
+
+ /* setup PCI0 io window to 0x18000000-0x181fffff */
+ bl_gen_write_u32(p, /* GT_PCI0IOLD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48),
+ cpu_to_gt32(0x18000000 << 3));
+ bl_gen_write_u32(p, /* GT_PCI0IOHD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50),
+ cpu_to_gt32(0x08000000 << 3));
+
+ /* setup PCI0 mem windows */
+ bl_gen_write_u32(p, /* GT_PCI0M0LD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58),
+ cpu_to_gt32(0x10000000 << 3));
+ bl_gen_write_u32(p, /* GT_PCI0M0HD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60),
+ cpu_to_gt32(0x07e00000 << 3));
+ bl_gen_write_u32(p, /* GT_PCI0M1LD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80),
+ cpu_to_gt32(0x18200000 << 3));
+ bl_gen_write_u32(p, /* GT_PCI0M1HD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88),
+ cpu_to_gt32(0x0bc00000 << 3));
+
+#undef cpu_to_gt32
+
+ /*
+ * The PIIX ISA bridge is on PCI bus 0 dev 10 func 0.
+ * Load the PIIX IRQC[A:D] routing config address, then
+ * write routing configuration to the config data register.
+ */
+ bl_gen_write_u32(p, /* GT_PCI0_CFGADDR */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0xcf8),
+ tswap32((1 << 31) /* ConfigEn */
+ | PCI_BUILD_BDF(0, PIIX4_PCI_DEVFN) << 8
+ | PIIX_PIRQCA));
+ bl_gen_write_u32(p, /* GT_PCI0_CFGDATA */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0xcfc),
+ tswap32(ldl_be_p(pci_pins_cfg)));
+
+ bl_gen_jump_kernel(p,
+ true, ENVP_VADDR - 64,
+ /*
+ * If semihosting is used, arguments have already
+ * been passed, so we preserve $a0.
+ */
+ !semihosting_get_argc(), 2,
+ true, ENVP_VADDR,
+ true, ENVP_VADDR + 8,
+ true, loaderparams.ram_low_size,
+ kernel_entry);
+}
+
static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr,
uint64_t kernel_entry)
{
@@ -619,11 +700,6 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr,
/* Small bootloader */
p = (uint16_t *)base;
-#define NM_HI1(VAL) (((VAL) >> 16) & 0x1f)
-#define NM_HI2(VAL) \
- (((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1))
-#define NM_LO(VAL) ((VAL) & 0xfff)
-
stw_p(p++, 0x2800); stw_p(p++, 0x001c);
/* bc to_here */
stw_p(p++, 0x8000); stw_p(p++, 0xc000);
@@ -642,175 +718,8 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr,
/* nop */
/* to_here: */
- if (semihosting_get_argc()) {
- /* Preserve a0 content as arguments have been passed */
- stw_p(p++, 0x8000); stw_p(p++, 0xc000);
- /* nop */
- } else {
- stw_p(p++, 0x0080); stw_p(p++, 0x0002);
- /* li a0,2 */
- }
-
- stw_p(p++, 0xe3a0 | NM_HI1(ENVP_VADDR - 64));
-
- stw_p(p++, NM_HI2(ENVP_VADDR - 64));
- /* lui sp,%hi(ENVP_VADDR - 64) */
-
- stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_VADDR - 64));
- /* ori sp,sp,%lo(ENVP_VADDR - 64) */
-
- stw_p(p++, 0xe0a0 | NM_HI1(ENVP_VADDR));
-
- stw_p(p++, NM_HI2(ENVP_VADDR));
- /* lui a1,%hi(ENVP_VADDR) */
-
- stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_VADDR));
- /* ori a1,a1,%lo(ENVP_VADDR) */
-
- stw_p(p++, 0xe0c0 | NM_HI1(ENVP_VADDR + 8));
-
- stw_p(p++, NM_HI2(ENVP_VADDR + 8));
- /* lui a2,%hi(ENVP_VADDR + 8) */
-
- stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_VADDR + 8));
- /* ori a2,a2,%lo(ENVP_VADDR + 8) */
-
- stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size));
-
- stw_p(p++, NM_HI2(loaderparams.ram_low_size));
- /* lui a3,%hi(loaderparams.ram_low_size) */
-
- stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size));
- /* ori a3,a3,%lo(loaderparams.ram_low_size) */
-
- /*
- * Load BAR registers as done by YAMON:
- *
- * - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff
- * - set up PCI0 MEM0 at 0x10000000, size 0x8000000
- * - set up PCI0 MEM1 at 0x18200000, size 0xbe00000
- *
- */
- stw_p(p++, 0xe040); stw_p(p++, 0x0681);
- /* lui t1, %hi(0xb4000000) */
-
-#if TARGET_BIG_ENDIAN
-
- stw_p(p++, 0xe020); stw_p(p++, 0x0be1);
- /* lui t0, %hi(0xdf000000) */
-
- /* 0x68 corresponds to GT_ISD (from hw/mips/gt64xxx_pci.c) */
- stw_p(p++, 0x8422); stw_p(p++, 0x9068);
- /* sw t0, 0x68(t1) */
-
- stw_p(p++, 0xe040); stw_p(p++, 0x077d);
- /* lui t1, %hi(0xbbe00000) */
-
- stw_p(p++, 0xe020); stw_p(p++, 0x0801);
- /* lui t0, %hi(0xc0000000) */
-
- /* 0x48 corresponds to GT_PCI0IOLD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9048);
- /* sw t0, 0x48(t1) */
-
- stw_p(p++, 0xe020); stw_p(p++, 0x0800);
- /* lui t0, %hi(0x40000000) */
-
- /* 0x50 corresponds to GT_PCI0IOHD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9050);
- /* sw t0, 0x50(t1) */
-
- stw_p(p++, 0xe020); stw_p(p++, 0x0001);
- /* lui t0, %hi(0x80000000) */
-
- /* 0x58 corresponds to GT_PCI0M0LD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9058);
- /* sw t0, 0x58(t1) */
-
- stw_p(p++, 0xe020); stw_p(p++, 0x07e0);
- /* lui t0, %hi(0x3f000000) */
-
- /* 0x60 corresponds to GT_PCI0M0HD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9060);
- /* sw t0, 0x60(t1) */
- stw_p(p++, 0xe020); stw_p(p++, 0x0821);
- /* lui t0, %hi(0xc1000000) */
-
- /* 0x80 corresponds to GT_PCI0M1LD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9080);
- /* sw t0, 0x80(t1) */
-
- stw_p(p++, 0xe020); stw_p(p++, 0x0bc0);
- /* lui t0, %hi(0x5e000000) */
-
-#else
-
- stw_p(p++, 0x0020); stw_p(p++, 0x00df);
- /* addiu[32] t0, $0, 0xdf */
-
- /* 0x68 corresponds to GT_ISD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9068);
- /* sw t0, 0x68(t1) */
-
- /* Use kseg2 remapped address 0x1be00000 */
- stw_p(p++, 0xe040); stw_p(p++, 0x077d);
- /* lui t1, %hi(0xbbe00000) */
-
- stw_p(p++, 0x0020); stw_p(p++, 0x00c0);
- /* addiu[32] t0, $0, 0xc0 */
-
- /* 0x48 corresponds to GT_PCI0IOLD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9048);
- /* sw t0, 0x48(t1) */
-
- stw_p(p++, 0x0020); stw_p(p++, 0x0040);
- /* addiu[32] t0, $0, 0x40 */
-
- /* 0x50 corresponds to GT_PCI0IOHD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9050);
- /* sw t0, 0x50(t1) */
-
- stw_p(p++, 0x0020); stw_p(p++, 0x0080);
- /* addiu[32] t0, $0, 0x80 */
-
- /* 0x58 corresponds to GT_PCI0M0LD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9058);
- /* sw t0, 0x58(t1) */
-
- stw_p(p++, 0x0020); stw_p(p++, 0x003f);
- /* addiu[32] t0, $0, 0x3f */
-
- /* 0x60 corresponds to GT_PCI0M0HD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9060);
- /* sw t0, 0x60(t1) */
-
- stw_p(p++, 0x0020); stw_p(p++, 0x00c1);
- /* addiu[32] t0, $0, 0xc1 */
-
- /* 0x80 corresponds to GT_PCI0M1LD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9080);
- /* sw t0, 0x80(t1) */
-
- stw_p(p++, 0x0020); stw_p(p++, 0x005e);
- /* addiu[32] t0, $0, 0x5e */
-
-#endif
-
- /* 0x88 corresponds to GT_PCI0M1HD */
- stw_p(p++, 0x8422); stw_p(p++, 0x9088);
- /* sw t0, 0x88(t1) */
-
- stw_p(p++, 0xe320 | NM_HI1(kernel_entry));
-
- stw_p(p++, NM_HI2(kernel_entry));
- /* lui t9,%hi(kernel_entry) */
-
- stw_p(p++, 0x8339); stw_p(p++, NM_LO(kernel_entry));
- /* ori t9,t9,%lo(kernel_entry) */
-
- stw_p(p++, 0x4bf9); stw_p(p++, 0x0000);
- /* jalrc t8 */
+ bl_setup_gt64120_jump_kernel((void **)&p, run_addr, kernel_entry);
}
/*
@@ -839,6 +748,7 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr,
uint64_t kernel_entry)
{
uint32_t *p;
+ void *v;
/* Small bootloader */
p = (uint32_t *)base;
@@ -875,54 +785,9 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr,
*
*/
- /* Bus endianess is always reversed */
-#if TARGET_BIG_ENDIAN
-#define cpu_to_gt32 cpu_to_le32
-#else
-#define cpu_to_gt32 cpu_to_be32
-#endif
-
- /* move GT64120 registers from 0x14000000 to 0x1be00000 */
- bl_gen_write_u32(&p, /* GT_ISD */
- cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68),
- cpu_to_gt32(0x1be00000 << 3));
-
- /* setup MEM-to-PCI0 mapping */
- /* setup PCI0 io window to 0x18000000-0x181fffff */
- bl_gen_write_u32(&p, /* GT_PCI0IOLD */
- cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48),
- cpu_to_gt32(0x18000000 << 3));
- bl_gen_write_u32(&p, /* GT_PCI0IOHD */
- cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50),
- cpu_to_gt32(0x08000000 << 3));
- /* setup PCI0 mem windows */
- bl_gen_write_u32(&p, /* GT_PCI0M0LD */
- cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58),
- cpu_to_gt32(0x10000000 << 3));
- bl_gen_write_u32(&p, /* GT_PCI0M0HD */
- cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60),
- cpu_to_gt32(0x07e00000 << 3));
-
- bl_gen_write_u32(&p, /* GT_PCI0M1LD */
- cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80),
- cpu_to_gt32(0x18200000 << 3));
- bl_gen_write_u32(&p, /* GT_PCI0M1HD */
- cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88),
- cpu_to_gt32(0x0bc00000 << 3));
-
-#undef cpu_to_gt32
-
- bl_gen_jump_kernel(&p,
- true, ENVP_VADDR - 64,
- /*
- * If semihosting is used, arguments have already been
- * passed, so we preserve $a0.
- */
- !semihosting_get_argc(), 2,
- true, ENVP_VADDR,
- true, ENVP_VADDR + 8,
- true, loaderparams.ram_low_size,
- kernel_entry);
+ v = p;
+ bl_setup_gt64120_jump_kernel(&v, run_addr, kernel_entry);
+ p = v;
/* YAMON subroutines */
p = (uint32_t *) (base + 0x800);
@@ -966,7 +831,6 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr,
stl_p(p++, 0x00000000); /* nop */
stl_p(p++, 0x03e00009); /* jalr ra */
stl_p(p++, 0xa1040000); /* sb a0,0(t0) */
-
}
static void G_GNUC_PRINTF(3, 4) prom_set(uint32_t *prom_buf, int index,
@@ -1013,7 +877,6 @@ static uint64_t load_kernel(void)
uint32_t *prom_buf;
long prom_size;
int prom_index = 0;
- uint64_t (*xlate_to_kseg0) (void *opaque, uint64_t addr);
uint8_t rng_seed[32];
char rng_seed_hex[sizeof(rng_seed) * 2 + 1];
size_t rng_seed_prom_offset;
@@ -1037,19 +900,10 @@ static uint64_t load_kernel(void)
}
/* Check where the kernel has been linked */
- if (kernel_entry & 0x80000000ll) {
- if (kvm_enabled()) {
- error_report("KVM guest kernels must be linked in useg. "
- "Did you forget to enable CONFIG_KVM_GUEST?");
- exit(1);
- }
-
- xlate_to_kseg0 = cpu_mips_phys_to_kseg0;
- } else {
- /* if kernel entry is in useg it is probably a KVM T&E kernel */
- mips_um_ksegs_enable();
-
- xlate_to_kseg0 = cpu_mips_kvm_um_phys_to_kseg0;
+ if (kernel_entry <= USEG_LIMIT) {
+ error_report("Trap-and-Emul kernels (Linux CONFIG_KVM_GUEST)"
+ " are not supported");
+ exit(1);
}
/* load initrd */
@@ -1090,7 +944,7 @@ static uint64_t load_kernel(void)
if (initrd_size > 0) {
prom_set(prom_buf, prom_index++,
"rd_start=0x%" PRIx64 " rd_size=%" PRId64 " %s",
- xlate_to_kseg0(NULL, initrd_offset),
+ cpu_mips_phys_to_kseg0(NULL, initrd_offset),
initrd_size, loaderparams.kernel_cmdline);
} else {
prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
@@ -1140,6 +994,31 @@ static void malta_mips_config(MIPSCPU *cpu)
}
}
+static int malta_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+ int slot;
+
+ slot = PCI_SLOT(pci_dev->devfn);
+
+ switch (slot) {
+ /* PIIX4 USB */
+ case 10:
+ return 3;
+ /* AMD 79C973 Ethernet */
+ case 11:
+ return 1;
+ /* Crystal 4281 Sound */
+ case 12:
+ return 2;
+ /* PCI slot 1 to 4 */
+ case 18 ... 21:
+ return ((slot - 18) + irq_num) & 0x03;
+ /* Unknown device, don't do any translation */
+ default:
+ return irq_num;
+ }
+}
+
static void main_cpu_reset(void *opaque)
{
MIPSCPU *cpu = opaque;
@@ -1157,11 +1036,6 @@ static void main_cpu_reset(void *opaque)
}
malta_mips_config(cpu);
-
- if (kvm_enabled()) {
- /* Start running from the bootloader we wrote to end of RAM */
- env->active_tc.PC = 0x40000000 + loaderparams.ram_low_size;
- }
}
static void create_cpu_without_cps(MachineState *ms, MaltaState *s,
@@ -1295,13 +1169,7 @@ void mips_malta_init(MachineState *machine)
fl_idx++;
if (kernel_filename) {
ram_low_size = MIN(ram_size, 256 * MiB);
- /* For KVM we reserve 1MB of RAM for running bootloader */
- if (kvm_enabled()) {
- ram_low_size -= 0x100000;
- bootloader_run_addr = cpu_mips_kvm_um_phys_to_kseg0(NULL, ram_low_size);
- } else {
- bootloader_run_addr = cpu_mips_phys_to_kseg0(NULL, RESET_ADDRESS);
- }
+ bootloader_run_addr = cpu_mips_phys_to_kseg0(NULL, RESET_ADDRESS);
/* Write a small bootloader to the flash location. */
loaderparams.ram_size = ram_size;
@@ -1318,20 +1186,8 @@ void mips_malta_init(MachineState *machine)
write_bootloader_nanomips(memory_region_get_ram_ptr(bios),
bootloader_run_addr, kernel_entry);
}
- if (kvm_enabled()) {
- /* Write the bootloader code @ the end of RAM, 1MB reserved */
- write_bootloader(memory_region_get_ram_ptr(ram_low_preio) +
- ram_low_size,
- bootloader_run_addr, kernel_entry);
- }
} else {
target_long bios_size = FLASH_SIZE;
- /* The flash region isn't executable from a KVM guest */
- if (kvm_enabled()) {
- error_report("KVM enabled but no -kernel argument was specified. "
- "Booting from flash is not supported with KVM.");
- exit(1);
- }
/* Load firmware from flash. */
if (!dinfo) {
/* Load a BIOS image. */
@@ -1391,17 +1247,14 @@ void mips_malta_init(MachineState *machine)
stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);
/* Northbridge */
- dev = sysbus_create_simple("gt64120", -1, NULL);
+ dev = qdev_new("gt64120");
+ qdev_prop_set_bit(dev, "cpu-little-endian", !be);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci"));
- /*
- * The whole address space decoded by the GT-64120A doesn't generate
- * exception when accessing invalid memory. Create an empty slot to
- * emulate this feature.
- */
- empty_slot_init("GT64120", 0, 0x20000000);
+ pci_bus_map_irqs(pci_bus, malta_pci_slot_get_pirq);
/* Southbridge */
- piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true,
+ piix4 = pci_create_simple_multifunction(pci_bus, PIIX4_PCI_DEVFN, true,
TYPE_PIIX4_PCI_DEVICE);
isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0"));
diff --git a/hw/mips/meson.build b/hw/mips/meson.build
index dd0101a..900613f 100644
--- a/hw/mips/meson.build
+++ b/hw/mips/meson.build
@@ -2,7 +2,7 @@ mips_ss = ss.source_set()
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_LOONGSON3V', if_true: files('loongson3_bootp.c', 'loongson3_virt.c'))
-mips_ss.add(when: 'CONFIG_MALTA', if_true: files('gt64xxx_pci.c', 'malta.c'))
+mips_ss.add(when: 'CONFIG_MALTA', if_true: files('malta.c'))
mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c'))
if 'CONFIG_TCG' in config_all
diff --git a/hw/mips/trace-events b/hw/mips/trace-events
index 13ee731..4a4e5fe 100644
--- a/hw/mips/trace-events
+++ b/hw/mips/trace-events
@@ -1,6 +1,3 @@
-# gt64xxx_pci.c
-gt64120_read(uint64_t addr, uint64_t value) "gt64120 read 0x%03"PRIx64" value:0x%08" PRIx64
-gt64120_write(uint64_t addr, uint64_t value) "gt64120 write 0x%03"PRIx64" value:0x%08" PRIx64
-gt64120_read_intreg(const char *regname, unsigned size, uint64_t value) "gt64120 read %s size:%u value:0x%08" PRIx64
-gt64120_write_intreg(const char *regname, unsigned size, uint64_t value) "gt64120 write %s size:%u value:0x%08" PRIx64
-gt64120_isd_remap(uint64_t from_length, uint64_t from_addr, uint64_t to_length, uint64_t to_addr) "ISD: 0x%08" PRIx64 "@0x%08" PRIx64 " -> 0x%08" PRIx64 "@0x%08" PRIx64
+# malta.c
+malta_fpga_leds(const char *text) "LEDs %s"
+malta_fpga_display(const char *text) "ASCII '%s'"