• R/O
  • HTTP
  • SSH
  • HTTPS

qemu: Commit


Commit MetaInfo

Revisionbdea5e44788c570ecd641802a52c718caf78d6f0 (tree)
Time2020-07-09 20:28:10
AuthorBALATON Zoltan <balaton@eik....>
CommiterBALATON Zoltan

Log Message

WIP pegasos2 emulation

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>

Change Summary

Incremental Difference

--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -14,5 +14,7 @@ CONFIG_SAM460EX=y
1414 CONFIG_MAC_OLDWORLD=y
1515 CONFIG_MAC_NEWWORLD=y
1616
17+CONFIG_PEGASOS2=y
18+
1719 # For PReP
1820 CONFIG_PREP=y
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -149,3 +149,9 @@ config FW_CFG_PPC
149149
150150 config FDT_PPC
151151 bool
152+
153+config PEGASOS2
154+ bool
155+ select VT82C686
156+ select IDE_VIA
157+ select SMBUS_EEPROM
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -33,3 +33,5 @@ obj-$(CONFIG_E500) += e500.o mpc8544ds.o e500plat.o
3333 obj-$(CONFIG_E500) += mpc8544_guts.o ppce500_spin.o
3434 # PowerPC 440 Xilinx ML507 reference board.
3535 obj-$(CONFIG_VIRTEX) += virtex_ml507.o
36+# Pegasos2
37+obj-$(CONFIG_PEGASOS2) += pegasos2.o
--- /dev/null
+++ b/hw/ppc/pegasos2.c
@@ -0,0 +1,1458 @@
1+/*
2+ * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
3+ *
4+ * Copyright (c) 2018-2020 BALATON Zoltan
5+ *
6+ * This work is licensed under the GNU GPL license version 2 or later.
7+ *
8+ */
9+
10+#include "qemu/osdep.h"
11+#include "qemu-common.h"
12+#include "qemu/units.h"
13+#include "qapi/error.h"
14+#include "hw/hw.h"
15+#include "hw/ppc/ppc.h"
16+#include "hw/sysbus.h"
17+#include "hw/pci/pci_host.h"
18+#include "hw/irq.h"
19+#include "hw/isa/vt82c686.h"
20+#include "hw/isa/superio.h"
21+#include "hw/ide/pci.h"
22+#include "hw/i2c/pm_smbus.h"
23+#include "hw/i2c/smbus_eeprom.h"
24+#include "hw/dma/i8257.h"
25+#include "hw/timer/i8254.h"
26+#include "hw/rtc/mc146818rtc.h"
27+#include "net/net.h"
28+#include "sysemu/reset.h"
29+#include "hw/boards.h"
30+#include "hw/loader.h"
31+#include "hw/fw-path-provider.h"
32+#include "elf.h"
33+#include "qemu/log.h"
34+#include "qemu/error-report.h"
35+#include "sysemu/kvm.h"
36+#include "kvm_ppc.h"
37+#include "hw/intc/i8259.h"
38+#include "exec/address-spaces.h"
39+#include "trace.h"
40+
41+/* ------------------------------------------------------------------------- */
42+/* Marvell Discovery II MV64361 System Controller */
43+
44+/* mv64361.h */
45+
46+#include "mv643xx.h"
47+
48+static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data)
49+{
50+ DeviceClass *dc = DEVICE_CLASS(klass);
51+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
52+
53+ k->vendor_id = PCI_VENDOR_ID_MARVELL;
54+ k->device_id = 0x6460;
55+ k->class_id = PCI_CLASS_BRIDGE_HOST;
56+ /*
57+ * PCI-facing part of the host bridge,
58+ * not usable without the host-facing part
59+ */
60+ dc->user_creatable = false;
61+}
62+
63+static const TypeInfo mv64361_pcibridge_info = {
64+ .name = "mv64361-pcibridge",
65+ .parent = TYPE_PCI_DEVICE,
66+ .instance_size = sizeof(PCIDevice),
67+ .class_init = mv64361_pcibridge_class_init,
68+ .interfaces = (InterfaceInfo[]) {
69+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
70+ { },
71+ },
72+};
73+
74+#define TYPE_MV64361_PCI "mv64361-pcihost"
75+#define MV64361_PCI(obj) OBJECT_CHECK(MV64361PCIState, (obj), TYPE_MV64361_PCI)
76+
77+typedef struct MV64361PCIState {
78+ PCIHostState parent_obj;
79+
80+ uint8_t index;
81+ MemoryRegion io;
82+ MemoryRegion mem;
83+ qemu_irq irq[4];
84+
85+ uint32_t io_base;
86+ uint32_t io_size;
87+ uint32_t mem_base[4];
88+ uint32_t mem_size[4];
89+ uint64_t remap[5];
90+} MV64361PCIState;
91+
92+static int mv64361_pcihost_map_irq(PCIDevice *pci_dev, int n)
93+{
94+ return (n + PCI_SLOT(pci_dev->devfn) - 1) % 4;
95+}
96+
97+static void mv64361_pcihost_set_irq(void *opaque, int n, int level)
98+{
99+ MV64361PCIState *s = opaque;
100+
101+ qemu_set_irq(s->irq[n], level);
102+}
103+
104+static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
105+{
106+ MV64361PCIState *s = MV64361_PCI(dev);
107+ PCIHostState *h = PCI_HOST_BRIDGE(dev);
108+ char *name;
109+
110+ name = g_strdup_printf("pci%d-io", s->index);
111+ memory_region_init(&s->io, OBJECT(dev), name, 0x10000);
112+ g_free(name);
113+ name = g_strdup_printf("pci%d-mem", s->index);
114+ memory_region_init(&s->mem, OBJECT(dev), name, 1ULL << 32);
115+ g_free(name);
116+ name = g_strdup_printf("pci.%d", s->index);
117+ h->bus = pci_register_root_bus(dev, name, mv64361_pcihost_set_irq,
118+ mv64361_pcihost_map_irq, dev,
119+ &s->mem, &s->io, 0, 4, TYPE_PCI_BUS);
120+ g_free(name);
121+ pci_create_simple(h->bus, 0, "mv64361-pcibridge");
122+}
123+
124+static Property mv64361_pcihost_props[] = {
125+ DEFINE_PROP_UINT8("index", MV64361PCIState, index, 0),
126+ DEFINE_PROP_END_OF_LIST()
127+};
128+
129+static void mv64361_pcihost_class_init(ObjectClass *klass, void *data)
130+{
131+ DeviceClass *dc = DEVICE_CLASS(klass);
132+
133+ dc->realize = mv64361_pcihost_realize;
134+ device_class_set_props(dc, mv64361_pcihost_props);
135+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
136+}
137+
138+static const TypeInfo mv64361_pcihost_info = {
139+ .name = TYPE_MV64361_PCI,
140+ .parent = TYPE_PCI_HOST_BRIDGE,
141+ .instance_size = sizeof(MV64361PCIState),
142+ .class_init = mv64361_pcihost_class_init,
143+};
144+
145+static void mv64361_pci_register_types(void)
146+{
147+ type_register_static(&mv64361_pcihost_info);
148+ type_register_static(&mv64361_pcibridge_info);
149+}
150+
151+type_init(mv64361_pci_register_types)
152+
153+#define TYPE_MV64361 "mv64361"
154+#define MV64361(obj) OBJECT_CHECK(MV64361State, (obj), TYPE_MV64361)
155+
156+typedef struct MV64361State {
157+ SysBusDevice parent_obj;
158+
159+ MemoryRegion regs;
160+ MV64361PCIState pci[2];
161+ MemoryRegion cpu_win[19];
162+ qemu_irq cpu_irq;
163+
164+ /* registers state */
165+ uint32_t cpu_conf;
166+ uint32_t regs_base;
167+ uint32_t base_addr_enable;
168+ uint64_t main_int_cr;
169+ uint64_t cpu0_int_mask;
170+ uint32_t gpp_io;
171+ uint32_t gpp_level;
172+ uint32_t gpp_value;
173+ uint32_t gpp_int_cr;
174+ uint32_t gpp_int_mask;
175+ bool gpp_int_level;
176+} MV64361State;
177+
178+/* mv64361.c */
179+
180+enum mv64361_irq_cause {
181+ MV64361_IRQ_DEVERR = 1,
182+ MV64361_IRQ_DMAERR,
183+ MV64361_IRQ_CPUERR,
184+ MV64361_IRQ_IDMA0,
185+ MV64361_IRQ_IDMA1,
186+ MV64361_IRQ_IDMA2,
187+ MV64361_IRQ_IDMA3,
188+ MV64361_IRQ_TIMER0,
189+ MV64361_IRQ_TIMER1,
190+ MV64361_IRQ_TIMER2,
191+ MV64361_IRQ_TIMER3,
192+ MV64361_IRQ_PCI0,
193+ MV64361_IRQ_SRAMERR,
194+ MV64361_IRQ_GBEERR,
195+ MV64361_IRQ_CERR,
196+ MV64361_IRQ_PCI1,
197+ MV64361_IRQ_DRAMERR,
198+ MV64361_IRQ_WDNMI,
199+ MV64361_IRQ_WDE,
200+ MV64361_IRQ_PCI0IN,
201+ MV64361_IRQ_PCI0OUT,
202+ MV64361_IRQ_PCI1IN,
203+ MV64361_IRQ_PCI1OUT,
204+ MV64361_IRQ_P1_GPP0_7,
205+ MV64361_IRQ_P1_GPP8_15,
206+ MV64361_IRQ_P1_GPP16_23,
207+ MV64361_IRQ_P1_GPP24_31,
208+ MV64361_IRQ_P1_CPU_DB,
209+ /* 29-31: reserved */
210+ MV64361_IRQ_GBE0 = 32,
211+ MV64361_IRQ_GBE1,
212+ MV64361_IRQ_GBE2,
213+ /* 35: reserved */
214+ MV64361_IRQ_SDMA0 = 36,
215+ MV64361_IRQ_TWSI,
216+ MV64361_IRQ_SDMA1,
217+ MV64361_IRQ_BRG,
218+ MV64361_IRQ_MPSC0,
219+ MV64361_IRQ_MPSC1,
220+ MV64361_IRQ_G0RX,
221+ MV64361_IRQ_G0TX,
222+ MV64361_IRQ_G0MISC,
223+ MV64361_IRQ_G1RX,
224+ MV64361_IRQ_G1TX,
225+ MV64361_IRQ_G1MISC,
226+ MV64361_IRQ_G2RX,
227+ MV64361_IRQ_G2TX,
228+ MV64361_IRQ_G2MISC,
229+ /* 51-55: reserved */
230+ MV64361_IRQ_P0_GPP0_7 = 56,
231+ MV64361_IRQ_P0_GPP8_15,
232+ MV64361_IRQ_P0_GPP16_23,
233+ MV64361_IRQ_P0_GPP24_31,
234+ MV64361_IRQ_P0_CPU_DB,
235+ /* 61-63: reserved */
236+};
237+
238+static void unmap_region(MemoryRegion *mr)
239+{
240+ if (memory_region_is_mapped(mr)) {
241+ memory_region_del_subregion(get_system_memory(), mr);
242+ object_unparent(OBJECT(mr));
243+ }
244+}
245+
246+static void map_pci_region(MemoryRegion *mr, MemoryRegion *parent,
247+ struct Object *owner, const char *name,
248+ hwaddr poffs, uint64_t size, hwaddr moffs)
249+{
250+ memory_region_init_alias(mr, owner, name, parent, poffs, size);
251+ memory_region_add_subregion(get_system_memory(), moffs, mr);
252+ printf("Mapping %s 0x%"HWADDR_PRIx"+0x%"PRIx64" @ 0x%"HWADDR_PRIx"\n", name, poffs, size, moffs);
253+}
254+
255+static void setup_mem_windows(MV64361State *s, uint32_t val)
256+{
257+ MV64361PCIState *p;
258+ MemoryRegion *mr;
259+ uint32_t mask;
260+ int i;
261+
262+ val &= 0x1fffff;
263+ for (mask = 1, i = 0; i < 21; i++, mask <<= 1) {
264+ if ((val & mask) != (s->base_addr_enable & mask)) {
265+ printf("%s: Should %s region %d\n", __func__, (!(val & mask) ? "enable" : "disable"), i);
266+ switch (i) {
267+ /*
268+ * 0-3 are SDRAM chip selects but we map all RAM directly
269+ * 4-7 are device chip selects (not sure what those are)
270+ * 8 is Boot device (ROM) chip select but we map that directly too
271+ */
272+ case 9:
273+ p = &s->pci[0];
274+ mr = &s->cpu_win[i];
275+ unmap_region(mr);
276+ if (!(val & mask)) {
277+ map_pci_region(mr, &p->io, OBJECT(s), "pci0-io-win",
278+ p->remap[4], (p->io_size + 1) << 16,
279+ (p->io_base & 0xfffff) << 16);
280+ }
281+ break;
282+ case 10:
283+ p = &s->pci[0];
284+ mr = &s->cpu_win[i];
285+ unmap_region(mr);
286+ if (!(val & mask)) {
287+ map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem0-win",
288+ p->remap[0], (p->mem_size[0] + 1) << 16,
289+ (p->mem_base[0] & 0xfffff) << 16);
290+ }
291+ break;
292+ case 11:
293+ p = &s->pci[0];
294+ mr = &s->cpu_win[i];
295+ unmap_region(mr);
296+ if (!(val & mask)) {
297+ map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem1-win",
298+ p->remap[1], (p->mem_size[1] + 1) << 16,
299+ (p->mem_base[1] & 0xfffff) << 16);
300+ }
301+ break;
302+ case 12:
303+ p = &s->pci[0];
304+ mr = &s->cpu_win[i];
305+ unmap_region(mr);
306+ if (!(val & mask)) {
307+ map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem2-win",
308+ p->remap[2], (p->mem_size[2] + 1) << 16,
309+ (p->mem_base[2] & 0xfffff) << 16);
310+ }
311+ break;
312+ case 13:
313+ p = &s->pci[0];
314+ mr = &s->cpu_win[i];
315+ unmap_region(mr);
316+ if (!(val & mask)) {
317+ map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem3-win",
318+ p->remap[3], (p->mem_size[3] + 1) << 16,
319+ (p->mem_base[3] & 0xfffff) << 16);
320+ }
321+ break;
322+ case 14:
323+ p = &s->pci[1];
324+ mr = &s->cpu_win[i];
325+ unmap_region(mr);
326+ if (!(val & mask)) {
327+ map_pci_region(mr, &p->io, OBJECT(s), "pci1-io-win",
328+ p->remap[4], (p->io_size + 1) << 16,
329+ (p->io_base & 0xfffff) << 16);
330+ }
331+ break;
332+ case 15:
333+ p = &s->pci[1];
334+ mr = &s->cpu_win[i];
335+ unmap_region(mr);
336+ if (!(val & mask)) {
337+ map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem0-win",
338+ p->remap[0], (p->mem_size[0] + 1) << 16,
339+ (p->mem_base[0] & 0xfffff) << 16);
340+ }
341+ break;
342+ case 16:
343+ p = &s->pci[1];
344+ mr = &s->cpu_win[i];
345+ unmap_region(mr);
346+ if (!(val & mask)) {
347+ map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem1-win",
348+ p->remap[1], (p->mem_size[1] + 1) << 16,
349+ (p->mem_base[1] & 0xfffff) << 16);
350+ }
351+ break;
352+ case 17:
353+ p = &s->pci[1];
354+ mr = &s->cpu_win[i];
355+ unmap_region(mr);
356+ if (!(val & mask)) {
357+ map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem2-win",
358+ p->remap[2], (p->mem_size[2] + 1) << 16,
359+ (p->mem_base[2] & 0xfffff) << 16);
360+ }
361+ break;
362+ case 18:
363+ p = &s->pci[1];
364+ mr = &s->cpu_win[i];
365+ unmap_region(mr);
366+ if (!(val & mask)) {
367+ map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem3-win",
368+ p->remap[3], (p->mem_size[3] + 1) << 16,
369+ (p->mem_base[3] & 0xfffff) << 16);
370+ }
371+ break;
372+ /* 19 is integrated SRAM */
373+ case 20:
374+ mr = &s->regs;
375+ unmap_region(mr);
376+ if (!(val & mask)) {
377+ memory_region_add_subregion(get_system_memory(),
378+ (s->regs_base & 0xfffff) << 16, mr);
379+ }
380+ break;
381+ }
382+ }
383+ }
384+}
385+
386+static void mv64361_update_irq(void *opaque, int n, int level)
387+{
388+ MV64361State *s = opaque;
389+ uint64_t val = s->main_int_cr;
390+
391+ if (level) {
392+ val |= BIT_ULL(n);
393+ } else {
394+ val &= ~BIT_ULL(n);
395+ }
396+ if ((s->main_int_cr & s->cpu0_int_mask) != (val & s->cpu0_int_mask)) {
397+ qemu_set_irq(s->cpu_irq, level);
398+ }
399+ s->main_int_cr = val;
400+}
401+
402+static uint64_t mv64361_read(void *opaque, hwaddr addr, unsigned int size)
403+{
404+ MV64361State *s = MV64361(opaque);
405+ uint32_t ret = 0;
406+
407+ switch (addr) {
408+ case MV64340_CPU_CONFIG:
409+ ret = s->cpu_conf;
410+ break;
411+ case MV64340_PCI_0_IO_BASE_ADDR:
412+ ret = s->pci[0].io_base;
413+ break;
414+ case MV64340_PCI_0_IO_SIZE:
415+ ret = s->pci[0].io_size;
416+ break;
417+ case MV64340_PCI_0_IO_ADDR_REMAP:
418+ ret = s->pci[0].remap[4] >> 16;
419+ break;
420+ case MV64340_PCI_0_MEMORY0_BASE_ADDR:
421+ ret = s->pci[0].mem_base[0];
422+ break;
423+ case MV64340_PCI_0_MEMORY0_SIZE:
424+ ret = s->pci[0].mem_size[0];
425+ break;
426+ case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP:
427+ ret = (s->pci[0].remap[0] & 0xffff0000) >> 16;
428+ break;
429+ case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP:
430+ ret = s->pci[0].remap[0] >> 32;
431+ break;
432+ case MV64340_PCI_0_MEMORY1_BASE_ADDR:
433+ ret = s->pci[0].mem_base[1];
434+ break;
435+ case MV64340_PCI_0_MEMORY1_SIZE:
436+ ret = s->pci[0].mem_size[1];
437+ break;
438+ case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP:
439+ ret = (s->pci[0].remap[1] & 0xffff0000) >> 16;
440+ break;
441+ case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP:
442+ ret = s->pci[0].remap[1] >> 32;
443+ break;
444+ case MV64340_PCI_0_MEMORY2_BASE_ADDR:
445+ ret = s->pci[0].mem_base[2];
446+ break;
447+ case MV64340_PCI_0_MEMORY2_SIZE:
448+ ret = s->pci[0].mem_size[2];
449+ break;
450+ case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP:
451+ ret = (s->pci[0].remap[2] & 0xffff0000) >> 16;
452+ break;
453+ case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP:
454+ ret = s->pci[0].remap[2] >> 32;
455+ break;
456+ case MV64340_PCI_0_MEMORY3_BASE_ADDR:
457+ ret = s->pci[0].mem_base[3];
458+ break;
459+ case MV64340_PCI_0_MEMORY3_SIZE:
460+ ret = s->pci[0].mem_size[3];
461+ break;
462+ case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP:
463+ ret = (s->pci[0].remap[3] & 0xffff0000) >> 16;
464+ break;
465+ case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP:
466+ ret = s->pci[0].remap[3] >> 32;
467+ break;
468+ case MV64340_PCI_1_IO_BASE_ADDR:
469+ ret = s->pci[1].io_base;
470+ break;
471+ case MV64340_PCI_1_IO_SIZE:
472+ ret = s->pci[1].io_size;
473+ break;
474+ case MV64340_PCI_1_IO_ADDR_REMAP:
475+ ret = s->pci[1].remap[4] >> 16;
476+ break;
477+ case MV64340_PCI_1_MEMORY0_BASE_ADDR:
478+ ret = s->pci[1].mem_base[0];
479+ break;
480+ case MV64340_PCI_1_MEMORY0_SIZE:
481+ ret = s->pci[1].mem_size[0];
482+ break;
483+ case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP:
484+ ret = (s->pci[1].remap[0] & 0xffff0000) >> 16;
485+ break;
486+ case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP:
487+ ret = s->pci[1].remap[0] >> 32;
488+ break;
489+ case MV64340_PCI_1_MEMORY1_BASE_ADDR:
490+ ret = s->pci[1].mem_base[1];
491+ break;
492+ case MV64340_PCI_1_MEMORY1_SIZE:
493+ ret = s->pci[1].mem_size[1];
494+ break;
495+ case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP:
496+ ret = (s->pci[1].remap[1] & 0xffff0000) >> 16;
497+ break;
498+ case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP:
499+ ret = s->pci[1].remap[1] >> 32;
500+ break;
501+ case MV64340_PCI_1_MEMORY2_BASE_ADDR:
502+ ret = s->pci[1].mem_base[2];
503+ break;
504+ case MV64340_PCI_1_MEMORY2_SIZE:
505+ ret = s->pci[1].mem_size[2];
506+ break;
507+ case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP:
508+ ret = (s->pci[1].remap[2] & 0xffff0000) >> 16;
509+ break;
510+ case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP:
511+ ret = s->pci[1].remap[2] >> 32;
512+ break;
513+ case MV64340_PCI_1_MEMORY3_BASE_ADDR:
514+ ret = s->pci[1].mem_base[3];
515+ break;
516+ case MV64340_PCI_1_MEMORY3_SIZE:
517+ ret = s->pci[1].mem_size[3];
518+ break;
519+ case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP:
520+ ret = (s->pci[1].remap[3] & 0xffff0000) >> 16;
521+ break;
522+ case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP:
523+ ret = s->pci[1].remap[3] >> 32;
524+ break;
525+ case MV64340_INTERNAL_SPACE_BASE_ADDR:
526+ ret = s->regs_base;
527+ break;
528+ case MV64340_BASE_ADDR_ENABLE:
529+ ret = s->base_addr_enable;
530+ break;
531+ case MV64340_PCI_0_CONFIG_ADDR:
532+ ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(&s->pci[0]), 0, size);
533+ break;
534+ case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ...
535+ MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3:
536+ ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(&s->pci[0]),
537+ addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, size);
538+ break;
539+ case MV64340_PCI_1_CONFIG_ADDR:
540+ ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(&s->pci[1]), 0, size);
541+ break;
542+ case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ...
543+ MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3:
544+ ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(&s->pci[1]),
545+ addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, size);
546+ break;
547+ case MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG:
548+ /* FIXME: This should be sent via the PCI bus? */
549+ if (s->gpp_int_level && (s->gpp_value & BIT(31))) {
550+ ret = pic_read_irq(isa_pic);
551+ }
552+ break;
553+ case MV64340_MAIN_INTERRUPT_CAUSE_LOW:
554+ ret = s->main_int_cr;
555+ break;
556+ case MV64340_MAIN_INTERRUPT_CAUSE_HIGH:
557+ ret = s->main_int_cr >> 32;
558+ break;
559+ case MV64340_CPU_INTERRUPT0_MASK_LOW:
560+ ret = s->cpu0_int_mask;
561+ break;
562+ case MV64340_CPU_INTERRUPT0_MASK_HIGH:
563+ ret = s->cpu0_int_mask >> 32;
564+ break;
565+ case MV64340_CPU_INTERRUPT0_SELECT_CAUSE:
566+ ret = s->main_int_cr;
567+ if (s->main_int_cr & s->cpu0_int_mask) {
568+ if (!(s->main_int_cr & s->cpu0_int_mask & 0xffffffff)) {
569+ ret = s->main_int_cr >> 32 | BIT(30);
570+ } else if ((s->main_int_cr & s->cpu0_int_mask) >> 32) {
571+ ret |= BIT(31);
572+ }
573+ }
574+ break;
575+ case MV64340_CUNIT_ARBITER_CONTROL_REG:
576+ ret = 0x11ff0000 | (s->gpp_int_level << 10);
577+ break;
578+ case MV64340_GPP_IO_CONTROL:
579+ ret = s->gpp_io;
580+ break;
581+ case MV64340_GPP_LEVEL_CONTROL:
582+ ret = s->gpp_level;
583+ break;
584+ case MV64340_GPP_VALUE:
585+ ret = s->gpp_value;
586+ break;
587+ case MV64340_GPP_VALUE_SET:
588+ case MV64340_GPP_VALUE_CLEAR:
589+ ret = 0;
590+ break;
591+ case MV64340_GPP_INTERRUPT_CAUSE:
592+ ret = s->gpp_int_cr;
593+ break;
594+ case MV64340_GPP_INTERRUPT_MASK0:
595+ case MV64340_GPP_INTERRUPT_MASK1:
596+ ret = s->gpp_int_mask;
597+ break;
598+ default:
599+ qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register read 0x%"
600+ HWADDR_PRIx "\n", __func__, addr);
601+ break;
602+ }
603+ if (addr != MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG) {
604+ printf("%s: %"PRIx64" -> %x\n", __func__, addr, ret);
605+ }
606+ return ret;
607+}
608+
609+static void warn_swap_bit(uint64_t val)
610+{
611+ if ((val & 0x3000000ULL) >> 24 != 1) {
612+ qemu_log_mask(LOG_UNIMP, "%s: Data swap not implemented", __func__);
613+ }
614+}
615+
616+static void mv64361_set_pci_mem_remap(MV64361State *s, int bus, int idx,
617+ uint64_t val, bool high)
618+{
619+ if (high) {
620+ s->pci[bus].remap[idx] = val;
621+ } else {
622+ s->pci[bus].remap[idx] &= 0xffffffff00000000ULL;
623+ s->pci[bus].remap[idx] |= (val & 0xffffULL) << 16;
624+ }
625+}
626+
627+static void mv64361_write(void *opaque, hwaddr addr, uint64_t val,
628+ unsigned int size)
629+{
630+ MV64361State *s = MV64361(opaque);
631+
632+ printf("%s: %"PRIx64" <- %"PRIx64"\n", __func__, addr, val);
633+ switch (addr) {
634+ case MV64340_CPU_CONFIG:
635+ s->cpu_conf = val & 0xe4e3bffULL;
636+ s->cpu_conf |= BIT(23);
637+ break;
638+ case MV64340_PCI_0_IO_BASE_ADDR:
639+ s->pci[0].io_base = val & 0x30fffffULL;
640+ warn_swap_bit(val);
641+ if (!(s->cpu_conf & BIT(27))) {
642+ s->pci[0].remap[4] = (val & 0xffffULL) << 16;
643+ }
644+ break;
645+ case MV64340_PCI_0_IO_SIZE:
646+ s->pci[0].io_size = val & 0xffffULL;
647+ break;
648+ case MV64340_PCI_0_IO_ADDR_REMAP:
649+ s->pci[0].remap[4] = (val & 0xffffULL) << 16;
650+ break;
651+ case MV64340_PCI_0_MEMORY0_BASE_ADDR:
652+ s->pci[0].mem_base[0] = val & 0x70fffffULL;
653+ warn_swap_bit(val);
654+ if (!(s->cpu_conf & BIT(27))) {
655+ mv64361_set_pci_mem_remap(s, 0, 0, val, false);
656+ }
657+ break;
658+ case MV64340_PCI_0_MEMORY0_SIZE:
659+ s->pci[0].mem_size[0] = val & 0xffffULL;
660+ break;
661+ case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP:
662+ case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP:
663+ mv64361_set_pci_mem_remap(s, 0, 0, val,
664+ (addr == MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP));
665+ break;
666+ case MV64340_PCI_0_MEMORY1_BASE_ADDR:
667+ s->pci[0].mem_base[1] = val & 0x70fffffULL;
668+ warn_swap_bit(val);
669+ if (!(s->cpu_conf & BIT(27))) {
670+ mv64361_set_pci_mem_remap(s, 0, 1, val, false);
671+ }
672+ break;
673+ case MV64340_PCI_0_MEMORY1_SIZE:
674+ s->pci[0].mem_size[1] = val & 0xffffULL;
675+ break;
676+ case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP:
677+ case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP:
678+ mv64361_set_pci_mem_remap(s, 0, 1, val,
679+ (addr == MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP));
680+ break;
681+ case MV64340_PCI_0_MEMORY2_BASE_ADDR:
682+ s->pci[0].mem_base[2] = val & 0x70fffffULL;
683+ warn_swap_bit(val);
684+ if (!(s->cpu_conf & BIT(27))) {
685+ mv64361_set_pci_mem_remap(s, 0, 2, val, false);
686+ }
687+ break;
688+ case MV64340_PCI_0_MEMORY2_SIZE:
689+ s->pci[0].mem_size[2] = val & 0xffffULL;
690+ break;
691+ case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP:
692+ case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP:
693+ mv64361_set_pci_mem_remap(s, 0, 2, val,
694+ (addr == MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP));
695+ break;
696+ case MV64340_PCI_0_MEMORY3_BASE_ADDR:
697+ s->pci[0].mem_base[3] = val & 0x70fffffULL;
698+ warn_swap_bit(val);
699+ if (!(s->cpu_conf & BIT(27))) {
700+ mv64361_set_pci_mem_remap(s, 0, 3, val, false);
701+ }
702+ break;
703+ case MV64340_PCI_0_MEMORY3_SIZE:
704+ s->pci[0].mem_size[3] = val & 0xffffULL;
705+ break;
706+ case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP:
707+ case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP:
708+ mv64361_set_pci_mem_remap(s, 0, 3, val,
709+ (addr == MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP));
710+ break;
711+ case MV64340_PCI_1_IO_BASE_ADDR:
712+ s->pci[1].io_base = val & 0x30fffffULL;
713+ warn_swap_bit(val);
714+ break;
715+ if (!(s->cpu_conf & BIT(27))) {
716+ s->pci[1].remap[4] = (val & 0xffffULL) << 16;
717+ }
718+ break;
719+ case MV64340_PCI_1_IO_SIZE:
720+ s->pci[1].io_size = val & 0xffffULL;
721+ break;
722+ case MV64340_PCI_1_MEMORY0_BASE_ADDR:
723+ s->pci[1].mem_base[0] = val & 0x70fffffULL;
724+ warn_swap_bit(val);
725+ if (!(s->cpu_conf & BIT(27))) {
726+ mv64361_set_pci_mem_remap(s, 1, 0, val, false);
727+ }
728+ break;
729+ case MV64340_PCI_1_MEMORY0_SIZE:
730+ s->pci[1].mem_size[0] = val & 0xffffULL;
731+ break;
732+ case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP:
733+ case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP:
734+ mv64361_set_pci_mem_remap(s, 1, 0, val,
735+ (addr == MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP));
736+ break;
737+ case MV64340_PCI_1_MEMORY1_BASE_ADDR:
738+ s->pci[1].mem_base[1] = val & 0x70fffffULL;
739+ warn_swap_bit(val);
740+ if (!(s->cpu_conf & BIT(27))) {
741+ mv64361_set_pci_mem_remap(s, 1, 1, val, false);
742+ }
743+ break;
744+ case MV64340_PCI_1_MEMORY1_SIZE:
745+ s->pci[1].mem_size[1] = val & 0xffffULL;
746+ break;
747+ case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP:
748+ case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP:
749+ mv64361_set_pci_mem_remap(s, 1, 1, val,
750+ (addr == MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP));
751+ break;
752+ case MV64340_PCI_1_MEMORY2_BASE_ADDR:
753+ s->pci[1].mem_base[2] = val & 0x70fffffULL;
754+ warn_swap_bit(val);
755+ if (!(s->cpu_conf & BIT(27))) {
756+ mv64361_set_pci_mem_remap(s, 1, 2, val, false);
757+ }
758+ break;
759+ case MV64340_PCI_1_MEMORY2_SIZE:
760+ s->pci[1].mem_size[2] = val & 0xffffULL;
761+ break;
762+ case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP:
763+ case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP:
764+ mv64361_set_pci_mem_remap(s, 1, 2, val,
765+ (addr == MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP));
766+ break;
767+ case MV64340_PCI_1_MEMORY3_BASE_ADDR:
768+ s->pci[1].mem_base[3] = val & 0x70fffffULL;
769+ warn_swap_bit(val);
770+ if (!(s->cpu_conf & BIT(27))) {
771+ mv64361_set_pci_mem_remap(s, 1, 3, val, false);
772+ }
773+ break;
774+ case MV64340_PCI_1_MEMORY3_SIZE:
775+ s->pci[1].mem_size[3] = val & 0xffffULL;
776+ break;
777+ case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP:
778+ case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP:
779+ mv64361_set_pci_mem_remap(s, 1, 3, val,
780+ (addr == MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP));
781+ break;
782+ case MV64340_INTERNAL_SPACE_BASE_ADDR:
783+ s->regs_base = val & 0xfffffULL;
784+ break;
785+ case MV64340_BASE_ADDR_ENABLE:
786+ setup_mem_windows(s, val);
787+ s->base_addr_enable = val & 0x1fffffULL;
788+ break;
789+ case MV64340_PCI_0_CONFIG_ADDR:
790+ pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]), 0, val, size);
791+ break;
792+ case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ...
793+ MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3:
794+ pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]),
795+ addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, val, size);
796+ break;
797+ case MV64340_PCI_1_CONFIG_ADDR:
798+ pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]), 0, val, size);
799+ break;
800+ case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ...
801+ MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3:
802+ pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]),
803+ addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, val, size);
804+ break;
805+ case MV64340_CPU_INTERRUPT0_MASK_LOW:
806+ s->cpu0_int_mask &= 0xffffffff00000000ULL;
807+ s->cpu0_int_mask |= val & 0xffffffffULL;
808+ break;
809+ case MV64340_CPU_INTERRUPT0_MASK_HIGH:
810+ s->cpu0_int_mask &= 0xffffffffULL;
811+ s->cpu0_int_mask |= val << 32;
812+ break;
813+ case MV64340_CUNIT_ARBITER_CONTROL_REG:
814+ s->gpp_int_level = !!(val & BIT(10));
815+ break;
816+ case MV64340_GPP_IO_CONTROL:
817+ s->gpp_io = val;
818+ break;
819+ case MV64340_GPP_LEVEL_CONTROL:
820+ s->gpp_level = val;
821+ break;
822+ case MV64340_GPP_VALUE:
823+ s->gpp_value &= ~s->gpp_io;
824+ s->gpp_value |= val & s->gpp_io;
825+ break;
826+ case MV64340_GPP_VALUE_SET:
827+ s->gpp_value |= val & s->gpp_io;
828+ break;
829+ case MV64340_GPP_VALUE_CLEAR:
830+ s->gpp_value &= ~(val & s->gpp_io);
831+ break;
832+ case MV64340_GPP_INTERRUPT_CAUSE:
833+ if (!s->gpp_int_level && val != s->gpp_int_cr) {
834+ int i;
835+ uint32_t ch = s->gpp_int_cr ^ val;
836+ s->gpp_int_cr = val;
837+ for (i = 0; i < 4; i++) {
838+ if ((ch & 0xff << i) && !(val & 0xff << i)) {
839+ mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + i, 0);
840+ }
841+ }
842+ } else {
843+ s->gpp_int_cr = val;
844+ }
845+ break;
846+ case MV64340_GPP_INTERRUPT_MASK0:
847+ case MV64340_GPP_INTERRUPT_MASK1:
848+ s->gpp_int_mask = val;
849+ break;
850+ default:
851+ qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register write 0x%"
852+ HWADDR_PRIx " = %"PRIx64"\n", __func__, addr, val);
853+ break;
854+ }
855+}
856+
857+static const MemoryRegionOps mv64361_ops = {
858+ .read = mv64361_read,
859+ .write = mv64361_write,
860+ .valid.min_access_size = 1,
861+ .valid.max_access_size = 4,
862+ .endianness = DEVICE_LITTLE_ENDIAN,
863+};
864+
865+static void mv64361_gpp_irq(void *opaque, int n, int level)
866+{
867+ MV64361State *s = opaque;
868+ uint32_t mask = BIT(n);
869+ uint32_t val = s->gpp_value & ~mask;
870+
871+ if (s->gpp_level & mask) {
872+ level = !level;
873+ }
874+ val |= level << n;
875+ if (val > s->gpp_value) {
876+ s->gpp_value = val;
877+ s->gpp_int_cr |= mask;
878+ if (s->gpp_int_mask & mask) {
879+ mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + n / 8, 1);
880+ }
881+ } else if (val < s->gpp_value) {
882+ int b = n / 8;
883+ s->gpp_value = val;
884+ if (s->gpp_int_level && !(val & 0xff << b)) {
885+ mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + b, 0);
886+ }
887+ }
888+}
889+
890+static void mv64361_realize(DeviceState *dev, Error **errp)
891+{
892+ MV64361State *s = MV64361(dev);
893+ int i;
894+
895+ s->base_addr_enable = 0x1fffff;
896+ memory_region_init_io(&s->regs, OBJECT(s), &mv64361_ops, s,
897+ TYPE_MV64361, 0x10000);
898+ for (i = 0; i < 2; i++) {
899+ char *name = g_strdup_printf("pcihost%d", i);
900+ object_initialize_child(OBJECT(dev), name, &s->pci[i],
901+ TYPE_MV64361_PCI);
902+ g_free(name);
903+ DeviceState *pci = DEVICE(&s->pci[i]);
904+ qdev_prop_set_uint8(pci, "index", i);
905+ sysbus_realize_and_unref(SYS_BUS_DEVICE(pci), &error_fatal);
906+ }
907+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
908+ qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
909+ /* FIXME: PCI IRQ connections may be board specific */
910+ for (i = 0; i < 4; i++) {
911+ s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
912+ }
913+}
914+
915+static void mv64361_reset(DeviceState *dev)
916+{
917+ MV64361State *s = MV64361(dev);
918+ int i, j;
919+
920+ /*
921+ * These values may be board specific
922+ * Real chip supports init from an eprom but that's not modelled
923+ */
924+ setup_mem_windows(s, 0x1fffff);
925+ s->base_addr_enable = 0x1fffff;
926+ s->cpu_conf = 0x28000ff;
927+ s->regs_base = 0x100f100;
928+ s->pci[0].io_base = 0x100f800;
929+ s->pci[0].io_size = 0xff;
930+ s->pci[0].mem_base[0] = 0x100c000;
931+ s->pci[0].mem_size[0] = 0x1fff;
932+ s->pci[0].mem_base[1] = 0x100f900;
933+ s->pci[0].mem_size[1] = 0xff;
934+ s->pci[0].mem_base[2] = 0x100f400;
935+ s->pci[0].mem_size[2] = 0x1ff;
936+ s->pci[0].mem_base[3] = 0x100f600;
937+ s->pci[0].mem_size[3] = 0x1ff;
938+ s->pci[1].io_base = 0x100fe00;
939+ s->pci[1].io_size = 0xff;
940+ s->pci[1].mem_base[0] = 0x1008000;
941+ s->pci[1].mem_size[0] = 0x3fff;
942+ s->pci[1].mem_base[1] = 0x100fd00;
943+ s->pci[1].mem_size[1] = 0xff;
944+ s->pci[1].mem_base[2] = 0x1002600;
945+ s->pci[1].mem_size[2] = 0x1ff;
946+ s->pci[1].mem_base[3] = 0x100ff80;
947+ s->pci[1].mem_size[3] = 0x7f;
948+ for (i = 0; i < 2; i++) {
949+ for (j = 0; j < 4; j++) {
950+ s->pci[i].remap[j] = s->pci[i].mem_base[j] << 16;
951+ }
952+ }
953+ s->pci[0].remap[1] = 0;
954+ s->pci[1].remap[1] = 0;
955+ setup_mem_windows(s, 0xfbfff);
956+ s->base_addr_enable = 0xfbfff;
957+}
958+
959+static void mv64361_class_init(ObjectClass *klass, void *data)
960+{
961+ DeviceClass *dc = DEVICE_CLASS(klass);
962+
963+ dc->realize = mv64361_realize;
964+ dc->reset = mv64361_reset;
965+}
966+
967+static const TypeInfo mv64361_type_info = {
968+ .name = TYPE_MV64361,
969+ .parent = TYPE_SYS_BUS_DEVICE,
970+ .instance_size = sizeof(MV64361State),
971+ .class_init = mv64361_class_init,
972+};
973+
974+static void mv64361_register_types(void)
975+{
976+ type_register_static(&mv64361_type_info);
977+}
978+
979+type_init(mv64361_register_types)
980+
981+/* ------------------------------------------------------------------------- */
982+/* VIA VT8231 South Bridge, very similar to VT82C686B */
983+
984+/* vt8231.c */
985+
986+typedef struct SuperIOConfig {
987+ uint8_t config[0x100];
988+ uint8_t index;
989+ uint8_t data;
990+} SuperIOConfig;
991+
992+typedef struct VT8231ISAState {
993+ PCIDevice dev;
994+ MemoryRegion superio;
995+ SuperIOConfig superio_conf;
996+} VT8231ISAState;
997+
998+#define TYPE_VT8231_ISA "vt8231-isa"
999+#define VT8231_ISA(obj) OBJECT_CHECK(VT8231ISAState, (obj), TYPE_VT8231_ISA)
1000+
1001+static uint64_t superio_ioport_readb(void *opaque, hwaddr addr, unsigned size)
1002+{
1003+ SuperIOConfig *sc = opaque;
1004+
1005+ printf("%s: address 0x%lx -> %x\n", __func__, addr, sc->config[sc->index]);
1006+ return (sc->config[sc->index]);
1007+}
1008+
1009+static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data,
1010+ unsigned size)
1011+{
1012+ SuperIOConfig *sc = opaque;
1013+
1014+ printf("%s: address 0x%lx val 0x%"PRIx64"\n", __func__, addr, data);
1015+ if (addr == 0x3f0) { /* config index */
1016+ sc->index = data & 0xff;
1017+ } else {
1018+ bool can_write = true;
1019+ /* 0x3f1 - config data */
1020+ switch (sc->index) {
1021+ case 0x00 ... 0xdf:
1022+ case 0xe4:
1023+ case 0xe5:
1024+ case 0xe7 ... 0xed:
1025+ case 0xf3:
1026+ case 0xf5:
1027+ case 0xf7:
1028+ case 0xf9 ... 0xfb:
1029+ case 0xfd ... 0xff:
1030+ can_write = false;
1031+ break;
1032+ default:
1033+ break;
1034+ }
1035+ if (can_write) {
1036+ sc->config[sc->index] = data & 0xff;
1037+ }
1038+ }
1039+}
1040+
1041+static const MemoryRegionOps superio_ops = {
1042+ .read = superio_ioport_readb,
1043+ .write = superio_ioport_writeb,
1044+ .endianness = DEVICE_NATIVE_ENDIAN,
1045+ .impl = {
1046+ .min_access_size = 1,
1047+ .max_access_size = 1,
1048+ },
1049+};
1050+
1051+static void vt8231_isa_reset(void *opaque)
1052+{
1053+ PCIDevice *d = opaque;
1054+ VT8231ISAState *s = VT8231_ISA(d);
1055+ uint8_t *pci_conf = d->config;
1056+
1057+ pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
1058+ pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
1059+ PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
1060+ pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
1061+
1062+ pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
1063+ pci_conf[0x67] = 0x08; /* Fast IR Config */
1064+ pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
1065+
1066+ s->superio_conf.config[0xf0] = 0x3c; /* Super-I/O Device-ID */
1067+ s->superio_conf.config[0xf1] = 0x01; /* Super-I/O Device Revision */
1068+ s->superio_conf.config[0xf2] = 0x03; /* Function Select */
1069+ s->superio_conf.config[0xf4] = 0xfe; /* Serial Port Base Addr */
1070+ s->superio_conf.config[0xf6] = 0xde; /* Parallel Port Base Addr */
1071+ s->superio_conf.config[0xf7] = 0xfc; /* Floppy Ctrlr Base Addr */
1072+}
1073+
1074+static void vt8231_isa_write_config(PCIDevice *d, uint32_t address,
1075+ uint32_t val, int len)
1076+{
1077+ VT8231ISAState *s = VT8231_ISA(d);
1078+
1079+ printf("%s: address 0x%x val 0x%x len 0x%x\n", __func__,
1080+ address, val, len);
1081+
1082+ pci_default_write_config(d, address, val, len);
1083+ if (address == 0x50) { /* enable or disable super IO configure */
1084+ memory_region_set_enabled(&s->superio, val & 4);
1085+ }
1086+}
1087+
1088+static void vt8231_isa_realize(PCIDevice *d, Error **errp)
1089+{
1090+ VT8231ISAState *s = VT8231_ISA(d);
1091+ ISABus *isa_bus;
1092+
1093+ isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
1094+ pci_address_space_io(d), errp);
1095+ if (!isa_bus) {
1096+ return;
1097+ }
1098+
1099+ memory_region_init_io(&s->superio, OBJECT(d), &superio_ops,
1100+ &s->superio_conf, "superio", 2);
1101+ memory_region_set_enabled(&s->superio, false);
1102+ /* The floppy also uses 0x3f0 and 0x3f1.
1103+ * But we do not emulate a floppy, so just set it here. */
1104+ memory_region_add_subregion(isa_bus->address_space_io, 0x3f0,
1105+ &s->superio);
1106+
1107+ qemu_register_reset(vt8231_isa_reset, d);
1108+}
1109+
1110+static void vt8231_isa_class_init(ObjectClass *klass, void *data)
1111+{
1112+ DeviceClass *dc = DEVICE_CLASS(klass);
1113+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1114+
1115+ k->realize = vt8231_isa_realize;
1116+ k->config_write = vt8231_isa_write_config;
1117+ k->vendor_id = PCI_VENDOR_ID_VIA;
1118+ k->device_id = 0x8231;
1119+ k->class_id = PCI_CLASS_BRIDGE_ISA;
1120+ dc->desc = "PCI-to-ISA bridge";
1121+ /* Reason: part of VIA VT8231 southbridge */
1122+ dc->user_creatable = false;
1123+}
1124+
1125+static const TypeInfo vt8231_isa_info = {
1126+ .name = TYPE_VT8231_ISA,
1127+ .parent = TYPE_PCI_DEVICE,
1128+ .instance_size = sizeof(VT8231ISAState),
1129+ .class_init = vt8231_isa_class_init,
1130+ .interfaces = (InterfaceInfo[]) {
1131+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
1132+ { },
1133+ },
1134+};
1135+
1136+static uint16_t vt8231_superio_get_iobase(ISASuperIODevice *sio, uint8_t index)
1137+{
1138+ return 0x2f8; /* FIXME: This should be settable via a register */
1139+}
1140+
1141+static bool vt8231_superio_floppy_is_enabled(ISASuperIODevice *sio, uint8_t index)
1142+{
1143+ return false; /* FIXME: Disabled due to clash with SuperIO Ctrl */
1144+}
1145+
1146+static void vt8231_superio_class_init(ObjectClass *klass, void *data)
1147+{
1148+ ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass);
1149+
1150+ sc->serial.count = 1;
1151+ sc->serial.get_iobase = vt8231_superio_get_iobase;
1152+ sc->parallel.count = 1;
1153+ sc->ide.count = 0;
1154+ sc->floppy.is_enabled = vt8231_superio_floppy_is_enabled;
1155+}
1156+
1157+#define TYPE_VT8231_SUPERIO "vt8231-superio"
1158+
1159+static const TypeInfo vt8231_superio_info = {
1160+ .name = TYPE_VT8231_SUPERIO,
1161+ .parent = TYPE_ISA_SUPERIO,
1162+ .instance_size = sizeof(ISASuperIODevice),
1163+ .class_size = sizeof(ISASuperIOClass),
1164+ .class_init = vt8231_superio_class_init,
1165+};
1166+
1167+#define TYPE_VT8231_PM "vt8231-pm"
1168+#define VT8231_PM(obj) OBJECT_CHECK(VT8231PMState, (obj), TYPE_VT8231_PM)
1169+
1170+typedef struct VT8231PMState {
1171+ PCIDevice dev;
1172+ PMSMBus smb;
1173+} VT8231PMState;
1174+
1175+static void vt8231_pm_write_config(PCIDevice *d, uint32_t addr,
1176+ uint32_t val, int len)
1177+{
1178+ VT8231PMState *s = VT8231_PM(d);
1179+
1180+ printf("%s: address 0x%x val 0x%x len 0x%x\n", __func__,
1181+ addr, val, len);
1182+
1183+ pci_default_write_config(d, addr, val, len);
1184+ if (addr == 0xd2) { /* enable or disable smbus IO range */
1185+ uint16_t iobase = pci_get_word(d->config + 0x90);
1186+ printf("%s: %s SMBus @ 0x%x\n", __func__, (val & 1 ? "enabling" : "disabling"), iobase);
1187+ memory_region_set_address(&s->smb.io, iobase);
1188+ memory_region_set_enabled(&s->smb.io, val & 1);
1189+ }
1190+}
1191+
1192+static void vt8231_pm_realize(PCIDevice *d, Error **errp)
1193+{
1194+ VT8231PMState *s = VT8231_PM(d);
1195+
1196+ pci_set_word(d->config + PCI_STATUS, PCI_STATUS_FAST_BACK |
1197+ PCI_STATUS_DEVSEL_MEDIUM);
1198+
1199+ /* 0x48-0x4B is Power Management I/O Base */
1200+ pci_set_long(d->config + 0x48, 0x00000001);
1201+
1202+ /* 0x90-0x93 is SMBus I/O Base */
1203+ pci_set_long(d->config + 0x90, 0x00000001);
1204+ pm_smbus_init(&s->dev.qdev, &s->smb, false);
1205+ memory_region_add_subregion(pci_address_space_io(d), 0, &s->smb.io);
1206+ memory_region_set_enabled(&s->smb.io, false);
1207+}
1208+
1209+static void vt8231_pm_class_init(ObjectClass *klass, void *data)
1210+{
1211+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1212+
1213+ k->realize = vt8231_pm_realize;
1214+ k->config_write = vt8231_pm_write_config;
1215+ k->vendor_id = PCI_VENDOR_ID_VIA;
1216+ k->device_id = 0x8235;
1217+}
1218+
1219+static const TypeInfo vt8231_pm_info = {
1220+ .name = TYPE_VT8231_PM,
1221+ .parent = TYPE_PCI_DEVICE,
1222+ .instance_size = sizeof(VT8231PMState),
1223+ .class_init = vt8231_pm_class_init,
1224+ .interfaces = (InterfaceInfo[]) {
1225+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
1226+ { },
1227+ },
1228+};
1229+
1230+static void vt8231_isa_register_types(void)
1231+{
1232+ type_register_static(&vt8231_isa_info);
1233+ type_register_static(&vt8231_superio_info);
1234+ type_register_static(&vt8231_pm_info);
1235+}
1236+
1237+type_init(vt8231_isa_register_types)
1238+
1239+/* ------------------------------------------------------------------------- */
1240+/* board code starts here (pegasos2.c) */
1241+
1242+#include "sysemu/device_tree.h"
1243+
1244+#include <libfdt.h>
1245+
1246+#define PROM_FILENAME "pegrom.bin"
1247+#define PROM_ADDR 0xfff00000
1248+#define PROM_SIZE 0x80000
1249+
1250+#define BUS_FREQ 133333333
1251+
1252+#define FDT_ADDR (2 * MiB)
1253+#define FDT_MAX_SIZE (1 * MiB)
1254+
1255+static void *build_fdt(MachineState *machine, PowerPCCPU *cpu, int *fdt_size);
1256+
1257+static void pegasos2_reset(void *opaque)
1258+{
1259+ PowerPCCPU *cpu = opaque;
1260+
1261+ cpu_reset(CPU(cpu));
1262+ cpu->env.spr[SPR_HID1] = 7ULL << 28;
1263+}
1264+
1265+static void pegasos2_init(MachineState *machine)
1266+{
1267+ PowerPCCPU *cpu = NULL;
1268+ MemoryRegion *rom = g_new(MemoryRegion, 1);
1269+ MV64361State *mv;
1270+ PCIBus *pci_bus;
1271+ PCIDevice *dev;
1272+ ISABus *isa_bus;
1273+ I2CBus *i2c_bus;
1274+ qemu_irq *i8259;
1275+ char *filename;
1276+ int sz;
1277+ void *fdt;
1278+ uint8_t *spd_data;
1279+
1280+ /* init CPU */
1281+ cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
1282+ if (PPC_INPUT(&cpu->env) != PPC_FLAGS_INPUT_6xx) {
1283+ error_report("Incompatible CPU, only 6xx bus supported");
1284+ exit(1);
1285+ }
1286+
1287+ /* Set time-base frequency */
1288+ cpu_ppc_tb_init(&cpu->env, BUS_FREQ / 4);
1289+ qemu_register_reset(pegasos2_reset, cpu);
1290+
1291+ /* RAM */
1292+ memory_region_add_subregion(get_system_memory(), 0, machine->ram);
1293+
1294+ /* allocate and load firmware */
1295+ if (!bios_name) {
1296+ bios_name = PROM_FILENAME;
1297+ }
1298+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
1299+ if (!filename) {
1300+ error_report("Could not find firmware '%s'", bios_name);
1301+ exit(1);
1302+ }
1303+ memory_region_init_rom(rom, NULL, "pegasos2.rom", PROM_SIZE, &error_fatal);
1304+ memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom);
1305+ sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1,
1306+ PPC_ELF_MACHINE, 0, 0);
1307+ if (sz <= 0) {
1308+ sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE);
1309+ }
1310+ if (sz <= 0 || sz > PROM_SIZE) {
1311+ error_report("Could not load firmware '%s'", filename);
1312+ exit(1);
1313+ }
1314+ g_free(filename);
1315+
1316+ /* Marvell Discovery II system controller */
1317+ mv = MV64361(sysbus_create_simple(TYPE_MV64361, -1,
1318+ ((qemu_irq *)cpu->env.irq_inputs)[PPC6xx_INPUT_INT]));
1319+ pci_bus = PCI_HOST_BRIDGE(&mv->pci[1])->bus;
1320+
1321+ /* VIA VT8231 South Bridge (multifunction PCI device) */
1322+ /* VT8231 function 0: PCI-to-ISA Bridge */
1323+ dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
1324+ "vt8231-isa");
1325+ isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(dev), "isa.0"));
1326+ i8259 = i8259_init(isa_bus, qdev_get_gpio_in_named(DEVICE(mv), "gpp", 31));
1327+ isa_bus_irqs(isa_bus, i8259);
1328+ i8254_pit_init(isa_bus, 0x40, 0, NULL);
1329+ i8257_dma_init(isa_bus, 0);
1330+ isa_create_simple(isa_bus, TYPE_VT8231_SUPERIO);
1331+ mc146818_rtc_init(isa_bus, 2000, NULL);
1332+
1333+ /* VT8231 function 1: IDE Controller */
1334+ dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide");
1335+ pci_ide_create_devs(dev);
1336+
1337+ /* VT8231 function 2-3: USB Ports */
1338+ pci_create_simple(pci_bus, PCI_DEVFN(12, 2), "vt82c686b-usb-uhci");
1339+ pci_create_simple(pci_bus, PCI_DEVFN(12, 3), "vt82c686b-usb-uhci");
1340+
1341+ /* VT8231 function 4: Power Management Controller */
1342+ dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), "vt8231-pm");
1343+ i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
1344+ spd_data = spd_data_generate(DDR, machine->ram_size);
1345+ smbus_eeprom_init_one(i2c_bus, 0x57, spd_data);
1346+
1347+ /* VT8231 function 5-6: AC97 Audio & Modem */
1348+ vt82c686b_ac97_init(pci_bus, PCI_DEVFN(12, 5));
1349+ vt82c686b_mc97_init(pci_bus, PCI_DEVFN(12, 6));
1350+
1351+ /* other PC hardware */
1352+ pci_vga_init(pci_bus);
1353+
1354+ fdt = build_fdt(machine, cpu, &sz);
1355+ /* fdt_pack should only fail if we've built a corrupted tree */
1356+ if (fdt_pack(fdt) || fdt_totalsize(fdt) > FDT_MAX_SIZE) {
1357+ g_free(fdt);
1358+ error_report("Error creating FDT (0x%x bytes, max is 0x%lx)",
1359+ fdt_totalsize(fdt), FDT_MAX_SIZE);
1360+ exit(1);
1361+ }
1362+ /* Place DTB in client memory for firmware */
1363+ qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
1364+ cpu_physical_memory_write(FDT_ADDR, fdt, fdt_totalsize(fdt));
1365+ g_free(fdt);
1366+}
1367+
1368+static void pegasos2_machine_class_init(ObjectClass *oc, void *data)
1369+{
1370+ MachineClass *mc = MACHINE_CLASS(oc);
1371+
1372+ mc->desc = "Genesi/bPlan Pegasos II";
1373+ mc->init = pegasos2_init;
1374+ mc->block_default_type = IF_IDE;
1375+ mc->default_boot_order = "cd";
1376+ mc->default_display = "std";
1377+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("750cxe_v3.1b");
1378+ mc->default_ram_id = "pegasos2.ram";
1379+ mc->default_ram_size = 512 * MiB;
1380+}
1381+
1382+static const TypeInfo pegasos2_machine_info = {
1383+ .name = MACHINE_TYPE_NAME("pegasos2"),
1384+ .parent = TYPE_MACHINE,
1385+ .class_init = pegasos2_machine_class_init,
1386+ .instance_size = sizeof(MachineState),
1387+};
1388+
1389+static void pegasos2_machine_register_types(void)
1390+{
1391+ type_register_static(&pegasos2_machine_info);
1392+}
1393+
1394+type_init(pegasos2_machine_register_types)
1395+
1396+/* FDT creation for passing to firmware */
1397+static void *build_fdt(MachineState *machine, PowerPCCPU *cpu, int *fdt_size)
1398+{
1399+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(CPU(cpu));
1400+ uint32_t mem_reg[] = { 0, cpu_to_be32(machine->ram_size) };
1401+ void *fdt = create_device_tree(fdt_size);
1402+
1403+ /* root node */
1404+ qemu_fdt_setprop_string(fdt, "/", "name", "bplan,Pegasos2");
1405+ qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 1);
1406+ qemu_fdt_setprop_string(fdt, "/", "device_type", "chrp");
1407+ qemu_fdt_setprop_string(fdt, "/", "model", "Pegasos2");
1408+ qemu_fdt_setprop_string(fdt, "/", "revision", "2B");
1409+ qemu_fdt_setprop_string(fdt, "/", "CODEGEN,vendor", "bplan GmbH");
1410+ qemu_fdt_setprop_string(fdt, "/", "CODEGEN,board", "Pegasos2");
1411+ qemu_fdt_setprop_string(fdt, "/", "CODEGEN,description",
1412+ "Pegasos CHRP PowerPC System");
1413+ /* extra props for OpenFirmware */
1414+ qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 1);
1415+ qemu_fdt_setprop_cell(fdt, "/", "clock-frequency", BUS_FREQ);
1416+
1417+ /* memory */
1418+ qemu_fdt_add_subnode(fdt, "/memory");
1419+ qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
1420+ qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg, sizeof(mem_reg));
1421+
1422+ /* cpus */
1423+ qemu_fdt_add_subnode(fdt, "/cpus");
1424+ qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0);
1425+ qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 1);
1426+ qemu_fdt_setprop_cell(fdt, "/cpus", "#cpus", 1);
1427+
1428+ /* FIXME Get CPU name from CPU object */
1429+ const char *cp = "/cpus/PowerPC,750CXE";
1430+ qemu_fdt_add_subnode(fdt, cp);
1431+ qemu_fdt_setprop_string(fdt, cp, "device_type", "cpu");
1432+ qemu_fdt_setprop_cell(fdt, cp, "reg", 0);
1433+ qemu_fdt_setprop_cell(fdt, cp, "cpu-version", cpu->env.spr[SPR_PVR]);
1434+ qemu_fdt_setprop_cell(fdt, cp, "clock-frequency", BUS_FREQ * 4.5);
1435+ qemu_fdt_setprop_cell(fdt, cp, "bus-frequency", BUS_FREQ);
1436+ qemu_fdt_setprop_cell(fdt, cp, "timebase-frequency",
1437+ cpu->env.tb_env->tb_freq);
1438+ qemu_fdt_setprop_string(fdt, cp, "state", "running");
1439+ qemu_fdt_setprop_cell(fdt, cp, "tlb-size", cpu->env.nb_tlb);
1440+ qemu_fdt_setprop_cell(fdt, cp, "tlb-sets", cpu->env.nb_ways);
1441+ if (cpu->env.id_tlbs) {
1442+ qemu_fdt_setprop_cell(fdt, cp, "d-tlb-size", cpu->env.tlb_per_way);
1443+ qemu_fdt_setprop_cell(fdt, cp, "d-tlb-sets", cpu->env.nb_ways);
1444+ qemu_fdt_setprop_cell(fdt, cp, "i-tlb-size", cpu->env.tlb_per_way);
1445+ qemu_fdt_setprop_cell(fdt, cp, "i-tlb-sets", cpu->env.nb_ways);
1446+ }
1447+ qemu_fdt_setprop_cell(fdt, cp, "i-cache-line-size",
1448+ cpu->env.icache_line_size);
1449+ qemu_fdt_setprop_cell(fdt, cp, "i-cache-block-size",
1450+ cpu->env.icache_line_size);
1451+ qemu_fdt_setprop_cell(fdt, cp, "i-cache-size", pcc->l1_icache_size);
1452+ qemu_fdt_setprop_cell(fdt, cp, "d-cache-line-size",
1453+ cpu->env.dcache_line_size);
1454+ qemu_fdt_setprop_cell(fdt, cp, "d-cache-block-size",
1455+ cpu->env.dcache_line_size);
1456+ qemu_fdt_setprop_cell(fdt, cp, "d-cache-size", pcc->l1_dcache_size);
1457+ return fdt;
1458+}
Show on old repository browser