summaryrefslogtreecommitdiff
path: root/emulators
diff options
context:
space:
mode:
authorthorpej <thorpej@pkgsrc.org>2020-10-04 20:39:25 +0000
committerthorpej <thorpej@pkgsrc.org>2020-10-04 20:39:25 +0000
commit129bfb045f5a33a1b41414871196374ccf35da30 (patch)
treedda04d302bdc13b72577399bb024bacd11095993 /emulators
parent42ae2629f514642fe6d0bc429791fb16bcd8a807 (diff)
downloadpkgsrc-129bfb045f5a33a1b41414871196374ccf35da30.tar.gz
Fix several issues in qemu-system-alpha's system emulation and
PALcode. qemu-system-alpha is now capable of running NetBSD/alpha. Bump package revision to 6.
Diffstat (limited to 'emulators')
-rw-r--r--emulators/qemu/Makefile11
-rw-r--r--emulators/qemu/distinfo21
-rw-r--r--emulators/qemu/patches/patch-hw_alpha_alpha_sys.h15
-rw-r--r--emulators/qemu/patches/patch-hw_alpha_dp264.c39
-rw-r--r--emulators/qemu/patches/patch-hw_alpha_typhoon.c148
-rw-r--r--emulators/qemu/patches/patch-hw_rtc_mc146818rtc.c32
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_hwrpb.h72
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_init.c234
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_memcpy.c15
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_memset.c15
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_pal.S53
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_pci.c78
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_pci.h18
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_printf.c31
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_protos.h66
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_sys-clipper.h38
-rw-r--r--emulators/qemu/patches/patch-roms_qemu-palcode_vgaio.c16
17 files changed, 899 insertions, 3 deletions
diff --git a/emulators/qemu/Makefile b/emulators/qemu/Makefile
index 54122078300..d99de9a276e 100644
--- a/emulators/qemu/Makefile
+++ b/emulators/qemu/Makefile
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.252 2020/09/27 21:29:57 jakllsch Exp $
+# $NetBSD: Makefile,v 1.253 2020/10/04 20:39:25 thorpej Exp $
DISTNAME= qemu-5.1.0
-PKGREVISION= 5
+PKGREVISION= 6
CATEGORIES= emulators
MASTER_SITES= https://download.qemu.org/
EXTRACT_SUFX= .tar.xz
@@ -34,6 +34,10 @@ SUBST_SED.sphinx-build+= -e 's/sphinx-build/sphinx-build-${PYVERSSUFFIX}/g'
.include "../../mk/bsd.prefs.mk"
+DISTFILES= ${DEFAULT_DISTFILES}
+DISTFILES+= palcode-clipper
+SITES.palcode-clipper= http://ftp.netbsd.org/pub/NetBSD/arch/alpha/qemu/
+
CONFIGURE_ARGS+= --prefix=${PREFIX}
CONFIGURE_ARGS+= --interp-prefix=${PREFIX}/share/qemu
CONFIGURE_ARGS+= --sysconfdir=${PKG_SYSCONFDIR}
@@ -138,6 +142,9 @@ PLIST_SRC= PLIST ${WRKDIR}/PLIST.STATIC
TEST_TARGET= check
+post-extract:
+ cp ${WRKDIR}/palcode-clipper ${WRKSRC}/pc-bios/palcode-clipper
+
# Some dependencies aren't correct and this tries to be re-made on install,
# failing due to configure bugs.
post-build:
diff --git a/emulators/qemu/distinfo b/emulators/qemu/distinfo
index 1506e46fb40..22d8fb0d913 100644
--- a/emulators/qemu/distinfo
+++ b/emulators/qemu/distinfo
@@ -1,5 +1,9 @@
-$NetBSD: distinfo,v 1.163 2020/09/27 21:29:57 jakllsch Exp $
+$NetBSD: distinfo,v 1.164 2020/10/04 20:39:25 thorpej Exp $
+SHA1 (palcode-clipper) = e25ae10a10e0801e47b62b9ee2d10c8ccb4ee940
+RMD160 (palcode-clipper) = a637f1cc38dabfdff36e3f02b6dd02d7c63cb8db
+SHA512 (palcode-clipper) = 8d6966e59b59bc17c563bae3648af4ac99108990294edd0398ee91d8e61ec8f890608b9326b175d6a3a5668106b67b019a2c51b79f5b2935d4a516d34490056c
+Size (palcode-clipper) = 156704 bytes
SHA1 (qemu-5.1.0.tar.xz) = 8c70ce2b65349e9b42bd20c9dec2c90f8e7b960a
RMD160 (qemu-5.1.0.tar.xz) = f5e4a20c481d7e2bf822bf6bf41667b810c3cecd
SHA512 (qemu-5.1.0.tar.xz) = e213edb71d93d5167ddce7546220ecb7b52a7778586a4f476f65bd1e510c9cfc6d1876238a7b501d9cc3fd31cc2ae4b7fb9e753bc3f12cc17cd16dfce2a96ba3
@@ -12,10 +16,14 @@ SHA1 (patch-capstone_Makefile) = f59870031de8c4385a591362749ec82f57fd4c27
SHA1 (patch-configure) = 2f5689b83b58066865598a83d53be2de6b42e303
SHA1 (patch-contrib_ivshmem-client_ivshmem-client.c) = 40c8751607cbf66a37e4c4e08f2664b864e2e984
SHA1 (patch-contrib_ivshmem-server_ivshmem-server.c) = d8f53432b5752f4263dc4ef96108a976a05147a3
+SHA1 (patch-hw_alpha_alpha_sys.h) = 5908698208937ff9eb0bf1c504e1144af3d1bcc4
+SHA1 (patch-hw_alpha_dp264.c) = 856304784f098863728ecac3d0a9287aa22190d7
+SHA1 (patch-hw_alpha_typhoon.c) = 1bed5cd6f355c4163585c5331356ebf38c5c3a16
SHA1 (patch-hw_core_uboot__image.h) = 17eef02349343c5fcfb7a4069cb6f8fd11efcb59
SHA1 (patch-hw_display_omap__dss.c) = 6b13242f28e32346bc70548c216c578d98fd3420
SHA1 (patch-hw_net_etraxfs__eth.c) = e5dd1661d60dbcd27b332403e0843500ba9544bc
SHA1 (patch-hw_net_xilinx__axienet.c) = ebcd2676d64ce6f31e4a8c976d4fdf530ad5e8b7
+SHA1 (patch-hw_rtc_mc146818rtc.c) = cc7a3b28010966b65b7a16db756226ac2669f310
SHA1 (patch-hw_scsi_scsi-disk.c) = fdbf2f962a6dcb1a115a7f8a5b8790ff9295fb33
SHA1 (patch-hw_usb_dev-mtp.c) = 0f9034fb3904e5d5e3b98d24b94e054181687d95
SHA1 (patch-include_sysemu_hw__accel.h) = 852bc031a1e065f614c5c913351f3e13183e00b7
@@ -23,6 +31,17 @@ SHA1 (patch-include_sysemu_kvm.h) = 9847abe3be70bd708a521310f5d5515e45a1a5a0
SHA1 (patch-include_sysemu_nvmm.h) = 3bd3da9b42ace0f806fabeb580f90ae19c273869
SHA1 (patch-net_tap-solaris.c) = cc953c9a624dd55ace4e130d0b31bbfb956c17d5
SHA1 (patch-qemu-options.hx) = e2f264117f703aa4ccf56219f370c3b1303e8b07
+SHA1 (patch-roms_qemu-palcode_hwrpb.h) = ae7b4c0680367af6f740d62a54dc86352128d76f
+SHA1 (patch-roms_qemu-palcode_init.c) = 7a0ebcd86f4106318791e7d90273fb55a424f1b8
+SHA1 (patch-roms_qemu-palcode_memcpy.c) = 7761774ae9092d0f494deaf302d663ba479a09cf
+SHA1 (patch-roms_qemu-palcode_memset.c) = 55fa4e52e03a351eb98475e7c4755e5edc409e6c
+SHA1 (patch-roms_qemu-palcode_pal.S) = 4f41194ffaeaddb39fa7bff953bd75c2f070dfa5
+SHA1 (patch-roms_qemu-palcode_pci.c) = 1d5b240fd6c940cbbe8518e4db529adba23d6fec
+SHA1 (patch-roms_qemu-palcode_pci.h) = 081c9d6d9955be24fd19455ae653339cdb133f02
+SHA1 (patch-roms_qemu-palcode_printf.c) = 7fb158f85bd1be9a939850d9d86175013f7a142b
+SHA1 (patch-roms_qemu-palcode_protos.h) = 60cf9db5544cb842207a893a78fa6bbe45af4c71
+SHA1 (patch-roms_qemu-palcode_sys-clipper.h) = 8983d7072b1c1e66bf0a18d2e49e503745692a46
+SHA1 (patch-roms_qemu-palcode_vgaio.c) = c8d7adc053cd6655f005527d16647611040c09d2
SHA1 (patch-roms_u-boot-sam460ex_Makefile) = e43111db0c56625bc8df5e3688c242c341f3fa6a
SHA1 (patch-roms_u-boot_tools_imx8m__image.sh) = e4c452062f40569e33aa93eec4a65bd3af2e74fc
SHA1 (patch-softmmu_cpus.c) = 489b6ef1a37bb617d50b903dfdd6fb41a302508d
diff --git a/emulators/qemu/patches/patch-hw_alpha_alpha_sys.h b/emulators/qemu/patches/patch-hw_alpha_alpha_sys.h
new file mode 100644
index 00000000000..ae19d96f621
--- /dev/null
+++ b/emulators/qemu/patches/patch-hw_alpha_alpha_sys.h
@@ -0,0 +1,15 @@
+$NetBSD: patch-hw_alpha_alpha_sys.h,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Pass 'devfn_min' argument to typhoon_init().
+
+--- hw/alpha/alpha_sys.h.orig 2020-10-01 00:17:37.231192966 +0000
++++ hw/alpha/alpha_sys.h 2020-10-01 00:17:49.188425709 +0000
+@@ -11,7 +11,7 @@
+
+
+ PCIBus *typhoon_init(MemoryRegion *, ISABus **, qemu_irq *, AlphaCPU *[4],
+- pci_map_irq_fn);
++ pci_map_irq_fn, uint8_t devfn_min);
+
+ /* alpha_pci.c. */
+ extern const MemoryRegionOps alpha_pci_ignore_ops;
diff --git a/emulators/qemu/patches/patch-hw_alpha_dp264.c b/emulators/qemu/patches/patch-hw_alpha_dp264.c
new file mode 100644
index 00000000000..1d3d99147a2
--- /dev/null
+++ b/emulators/qemu/patches/patch-hw_alpha_dp264.c
@@ -0,0 +1,39 @@
+$NetBSD: patch-hw_alpha_dp264.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Because we're using CLIPPER IRQ mappings, the minimum PCI device
+IdSel is 1. Pass that to typhoon_init().
+
+Set bit 6 in trap_arg2 to tell the PALcode that the -nographic option
+was specified. This is used by the PALcode to initialize the CTB for
+serial console.
+
+--- hw/alpha/dp264.c.orig 2020-08-11 19:17:14.000000000 +0000
++++ hw/alpha/dp264.c 2020-10-02 15:52:10.654767858 +0000
+@@ -72,13 +72,25 @@ static void clipper_init(MachineState *m
+ cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type));
+ }
+
++ /* arg0 -> memory size
++ arg1 -> kernel entry point
++ arg2 -> config word
++
++ Config word: bits 0-5 -> ncpus
++ bit 6 -> nographics option (for HWRPB CTB)
++
++ See init_hwrpb() in the PALcode. */
++
+ cpus[0]->env.trap_arg0 = ram_size;
+ cpus[0]->env.trap_arg1 = 0;
+ cpus[0]->env.trap_arg2 = smp_cpus;
++ if (!machine->enable_graphics)
++ cpus[0]->env.trap_arg2 |= (1 << 6);
+
+- /* Init the chipset. */
++ /* Init the chipset. Because we're using CLIPPER IRQ mappings,
++ the minimum PCI device IdSel is 1. */
+ pci_bus = typhoon_init(machine->ram, &isa_bus, &rtc_irq, cpus,
+- clipper_pci_map_irq);
++ clipper_pci_map_irq, PCI_DEVFN(1, 0));
+
+ /* Since we have an SRM-compatible PALcode, use the SRM epoch. */
+ mc146818_rtc_init(isa_bus, 1900, rtc_irq);
diff --git a/emulators/qemu/patches/patch-hw_alpha_typhoon.c b/emulators/qemu/patches/patch-hw_alpha_typhoon.c
new file mode 100644
index 00000000000..a11679c5cc6
--- /dev/null
+++ b/emulators/qemu/patches/patch-hw_alpha_typhoon.c
@@ -0,0 +1,148 @@
+$NetBSD: patch-hw_alpha_typhoon.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Allow callers of typhoon_init() to specify a minimum PCI devfn.
+
+Add a minimal i82378 SIO PCI node so that NetBSD/alpha will find
+and probe the ISA bus.
+
+--- hw/alpha/typhoon.c.orig 2020-10-01 00:34:35.392982214 +0000
++++ hw/alpha/typhoon.c 2020-10-01 00:53:13.419539599 +0000
+@@ -817,7 +817,8 @@ static void typhoon_alarm_timer(void *op
+ }
+
+ PCIBus *typhoon_init(MemoryRegion *ram, ISABus **isa_bus, qemu_irq *p_rtc_irq,
+- AlphaCPU *cpus[4], pci_map_irq_fn sys_map_irq)
++ AlphaCPU *cpus[4], pci_map_irq_fn sys_map_irq,
++ uint8_t devfn_min)
+ {
+ MemoryRegion *addr_space = get_system_memory();
+ DeviceState *dev;
+@@ -887,7 +888,7 @@ PCIBus *typhoon_init(MemoryRegion *ram,
+ b = pci_register_root_bus(dev, "pci",
+ typhoon_set_irq, sys_map_irq, s,
+ &s->pchip.reg_mem, &s->pchip.reg_io,
+- 0, 64, TYPE_PCI_BUS);
++ devfn_min, 64, TYPE_PCI_BUS);
+ phb->bus = b;
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+@@ -921,10 +922,21 @@ PCIBus *typhoon_init(MemoryRegion *ram,
+ /* Pchip1 PCI configuration, 0x802.FE00.0000, 16MB. */
+
+ /* Init the ISA bus. */
+- /* ??? Technically there should be a cy82c693ub pci-isa bridge. */
++ /* Init the PCI-ISA bridge. Technically, this would have been
++ a cy82c693ub, but a i82378 SIO was also used on many Alpha
++ systems and is close enough.
++
++ ??? We are using a private, stripped down implementation of i82378
++ so that we can handle the way the ISA interrupts are wired up on
++ Tsunami-type systems. We're leaving that (and the rest of the board
++ peripheral setup) untoucned; we merely need to instantiate the PCI
++ device node for the bridge, so that operating systems that expect
++ it to be there will see it. */
+ {
+ qemu_irq *isa_irqs;
+
++ pci_create_simple(b, PCI_DEVFN(7, 0), "i82378-typhoon");
++
+ *isa_bus = isa_bus_new(NULL, get_system_memory(), &s->pchip.reg_io,
+ &error_abort);
+ isa_irqs = i8259_init(*isa_bus,
+@@ -955,10 +967,96 @@ static const TypeInfo typhoon_iommu_memo
+ .class_init = typhoon_iommu_memory_region_class_init,
+ };
+
++/* The following was copied from hw/isa/i82378.c and modified to provide
++ only the minimal PCI device node. */
++
++/*
++ * QEMU Intel i82378 emulation (PCI to ISA bridge)
++ *
++ * Copyright (c) 2010-2011 Herv\xc3\xa9 Poussineau
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "migration/vmstate.h"
++
++#define TYPE_I82378 "i82378-typhoon"
++#define I82378(obj) \
++ OBJECT_CHECK(I82378State, (obj), TYPE_I82378)
++
++typedef struct I82378State {
++ PCIDevice parent_obj;
++} I82378State;
++
++static const VMStateDescription vmstate_i82378 = {
++ .name = "pci-i82378-typhoon",
++ .version_id = 0,
++ .minimum_version_id = 0,
++ .fields = (VMStateField[]) {
++ VMSTATE_PCI_DEVICE(parent_obj, I82378State),
++ VMSTATE_END_OF_LIST()
++ },
++};
++
++static void i82378_realize(PCIDevice *pci, Error **errp)
++{
++ uint8_t *pci_conf;
++
++ pci_conf = pci->config;
++ pci_set_word(pci_conf + PCI_COMMAND,
++ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
++ pci_set_word(pci_conf + PCI_STATUS,
++ PCI_STATUS_DEVSEL_MEDIUM);
++
++ pci_config_set_interrupt_pin(pci_conf, 1); /* interrupt pin 0 */
++}
++
++static void i82378_init(Object *obj)
++{
++}
++
++static void i82378_class_init(ObjectClass *klass, void *data)
++{
++ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
++ DeviceClass *dc = DEVICE_CLASS(klass);
++
++ k->realize = i82378_realize;
++ k->vendor_id = PCI_VENDOR_ID_INTEL;
++ k->device_id = PCI_DEVICE_ID_INTEL_82378;
++ k->revision = 0x03;
++ k->class_id = PCI_CLASS_BRIDGE_ISA;
++ dc->vmsd = &vmstate_i82378;
++ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
++}
++
++static const TypeInfo i82378_typhoon_type_info = {
++ .name = TYPE_I82378,
++ .parent = TYPE_PCI_DEVICE,
++ .instance_size = sizeof(I82378State),
++ .instance_init = i82378_init,
++ .class_init = i82378_class_init,
++ .interfaces = (InterfaceInfo[]) {
++ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++ { },
++ },
++};
++
+ static void typhoon_register_types(void)
+ {
+ type_register_static(&typhoon_pcihost_info);
+ type_register_static(&typhoon_iommu_memory_region_info);
++ type_register_static(&i82378_typhoon_type_info);
+ }
+
+ type_init(typhoon_register_types)
diff --git a/emulators/qemu/patches/patch-hw_rtc_mc146818rtc.c b/emulators/qemu/patches/patch-hw_rtc_mc146818rtc.c
new file mode 100644
index 00000000000..72465142ae0
--- /dev/null
+++ b/emulators/qemu/patches/patch-hw_rtc_mc146818rtc.c
@@ -0,0 +1,32 @@
+$NetBSD: patch-hw_rtc_mc146818rtc.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Ensure the periodic timer is started as soon as the device is realized,
+and follow the real hardware's lead of updating the PF bit in REG_C even
+if it's not going to result in raising an interrupt.
+
+--- hw/rtc/mc146818rtc.c.orig 2020-10-01 00:56:55.574093880 +0000
++++ hw/rtc/mc146818rtc.c 2020-10-01 00:58:40.326479896 +0000
+@@ -155,9 +155,15 @@ static uint32_t rtc_periodic_clock_ticks
+ {
+ int period_code;
+
++#if 0
++ /*
++ * Real hardware sets the PF bit rergardless if it actually
++ * raises an interrupt.
++ */
+ if (!(s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
+ return 0;
+ }
++#endif
+
+ period_code = s->cmos_data[RTC_REG_A] & 0x0f;
+
+@@ -944,6 +950,7 @@ static void rtc_realizefn(DeviceState *d
+ }
+
+ s->periodic_timer = timer_new_ns(rtc_clock, rtc_periodic_timer, s);
++ periodic_timer_update(s, qemu_clock_get_ns(rtc_clock), 0, true);
+ s->update_timer = timer_new_ns(rtc_clock, rtc_update_timer, s);
+ check_update_timer(s);
+
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_hwrpb.h b/emulators/qemu/patches/patch-roms_qemu-palcode_hwrpb.h
new file mode 100644
index 00000000000..58bf04b8cb6
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_hwrpb.h
@@ -0,0 +1,72 @@
+$NetBSD: patch-roms_qemu-palcode_hwrpb.h,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Add definitions for the Console Terminal Block portion of the HWRPB.
+
+--- roms/qemu-palcode/hwrpb.h.orig 2020-10-03 23:04:51.494017689 +0000
++++ roms/qemu-palcode/hwrpb.h 2020-10-03 23:06:34.713833960 +0000
+@@ -146,6 +146,65 @@ struct crb_struct {
+ struct vf_map_struct map[1];
+ };
+
++struct ctb_struct {
++ unsigned long type;
++ unsigned long unit;
++ unsigned long res0;
++ unsigned long len;
++ unsigned long ipl;
++ unsigned long tintr_vec;
++ unsigned long rintr_vec;
++ unsigned long term_type;
++ unsigned long keybd_type;
++ unsigned long keybd_trans;
++ unsigned long keybd_map;
++ unsigned long keybd_state;
++ unsigned long keybd_last;
++ unsigned long font_us;
++ unsigned long font_mcs;
++ unsigned long font_width;
++ unsigned long font_height;
++ unsigned long mon_width;
++ unsigned long mon_height;
++ unsigned long dpi;
++ unsigned long planes;
++ unsigned long cur_width;
++ unsigned long cur_height;
++ unsigned long head_cnt;
++ unsigned long opwindow;
++ unsigned long head_offset;
++ unsigned long putchar;
++ unsigned long io_state;
++ unsigned long listen_state;
++ unsigned long xaddr;
++ unsigned long turboslot;
++ unsigned long server_off;
++ unsigned long line_off;
++ unsigned char csd;
++};
++
++#define CTB_NONE 0x00
++#define CTB_PRINTERPORT 0x02
++#define CTB_GRAPHICS 0x03
++#define CTB_TYPE4 0x04
++
++/*
++ * Format of the Console Terminal Block Type 4 `turboslot' field:
++ *
++ * 63 40 39 32 31 24 23 16 15 8 7 0
++ * | reserved | channel | hose | bus type | bus | slot|
++ */
++#define CTB_TURBOSLOT_CHANNEL(x) (((x) >> 32) & 0xff)
++#define CTB_TURBOSLOT_HOSE(x) (((x) >> 24) & 0xff)
++#define CTB_TURBOSLOT_TYPE(x) (((x) >> 16) & 0xff)
++#define CTB_TURBOSLOT_BUS(x) (((x) >> 8) & 0xff)
++#define CTB_TURBOSLOT_SLOT(x) ((x) & 0xff)
++
++#define CTB_TURBOSLOT_TYPE_TC 0 /* TURBOchannel */
++#define CTB_TURBOSLOT_TYPE_ISA 1 /* ISA */
++#define CTB_TURBOSLOT_TYPE_EISA 2 /* EISA */
++#define CTB_TURBOSLOT_TYPE_PCI 3 /* PCI */
++
+ struct memclust_struct {
+ unsigned long start_pfn;
+ unsigned long numpages;
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_init.c b/emulators/qemu/patches/patch-roms_qemu-palcode_init.c
new file mode 100644
index 00000000000..5e39958a7b2
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_init.c
@@ -0,0 +1,234 @@
+$NetBSD: patch-roms_qemu-palcode_init.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+- Don't include cross-host header files.
+- Initialize the HWRPB CPU ID field with the WHAMI of the primary
+ CPU (and not the CPU type) as per the architecture specification.
+- Don't set the "PALcode memory valid" bit in the PCS flags; that field
+ in the HWRPB is not initialized by this PALcode.
+- Provide a Console Terminal Block (CTB) in the HWRPB - NetBSD requires
+ it to find the console device.
+- Define entry point register $a2 as a config word, rather than just a
+ CPU count, and extract the "-nographic" option passed by Qemu, so that
+ the CTB can be initialized properly.
+- Call the SWPPAL with a private argument in $a4, to specify the value of
+ $pv is to be after the SWPPAL has completed.
+- When a secondary CPU starts up, extract a new value for $pv from the
+ HWRPB "CPU restart data" field, and pass that to the SWPPAL operation
+ used to trampiline to into the kernel entry point.
+
+--- roms/qemu-palcode/init.c.orig 2020-10-03 23:12:30.442663290 +0000
++++ roms/qemu-palcode/init.c 2020-10-03 23:12:34.687159989 +0000
+@@ -18,8 +18,6 @@
+ along with this program; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>. */
+
+-#include <string.h>
+-#include <stddef.h>
+ #include "hwrpb.h"
+ #include "osf.h"
+ #include "ioport.h"
+@@ -38,11 +36,21 @@
+
+ #define HZ 1024
+
++/*
++ * Register a2 contains configuration information from the VM:
++ *
++ * bits 0-5 -- ncpus
++ * bit 6 -- "nographics" option
++ */
++#define CONFIG_NCPUS(x) ((x) & 63)
++#define CONFIG_NOGRAPHICS(x) ((x) & (1ull << 6))
++
+ struct hwrpb_combine {
+ struct hwrpb_struct hwrpb;
+ struct percpu_struct processor[4];
+ struct memdesc_struct md;
+ struct memclust_struct mc[2];
++ struct ctb_struct ctb;
+ struct crb_struct crb;
+ struct procdesc_struct proc_dispatch;
+ struct procdesc_struct proc_fixup;
+@@ -61,6 +69,8 @@ struct hwrpb_combine hwrpb __attribute__
+
+ void *last_alloc;
+ bool have_vga;
++unsigned int pci_vga_bus;
++unsigned int pci_vga_dev;
+
+ static void *
+ alloc (unsigned long size, unsigned long align)
+@@ -138,11 +148,13 @@ init_page_table(void)
+ }
+
+ static void
+-init_hwrpb (unsigned long memsize, unsigned long cpus)
++init_hwrpb (unsigned long memsize, unsigned long config)
+ {
+ unsigned long pal_pages;
+ unsigned long amask;
+ unsigned long i;
++ unsigned long proc_type = EV4_CPU;
++ unsigned long cpus = CONFIG_NCPUS(config);
+
+ hwrpb.hwrpb.phys_addr = PA(&hwrpb);
+
+@@ -164,12 +176,12 @@ init_hwrpb (unsigned long memsize, unsig
+ switch (__builtin_alpha_implver())
+ {
+ case 0: /* EV4 */
+- hwrpb.hwrpb.cpuid = EV4_CPU;
++ proc_type = EV4_CPU;
+ hwrpb.hwrpb.max_asn = 63;
+ break;
+
+ case 1: /* EV5 */
+- hwrpb.hwrpb.cpuid
++ proc_type
+ = ((amask & 0x101) == 0x101 ? PCA56_CPU /* MAX+BWX */
+ : amask & 1 ? EV56_CPU /* BWX */
+ : EV5_CPU);
+@@ -177,11 +189,12 @@ init_hwrpb (unsigned long memsize, unsig
+ break;
+
+ case 2: /* EV6 */
+- hwrpb.hwrpb.cpuid = (amask & 4 ? EV67_CPU : EV6_CPU); /* CIX */
++ proc_type = (amask & 4 ? EV67_CPU : EV6_CPU); /* CIX */
+ hwrpb.hwrpb.max_asn = 255;
+ break;
+ }
+
++ hwrpb.hwrpb.cpuid = 0; /* CPU #0 is the primary */
+ hwrpb.hwrpb.pagesize = PAGE_SIZE;
+ hwrpb.hwrpb.pa_bits = 40;
+ hwrpb.hwrpb.sys_type = SYS_TYPE;
+@@ -189,9 +202,20 @@ init_hwrpb (unsigned long memsize, unsig
+ hwrpb.hwrpb.sys_revision = SYS_REVISION;
+ for (i = 0; i < cpus; ++i)
+ {
+- /* ??? Look up these bits. Snagging the value examined by the kernel. */
+- hwrpb.processor[i].flags = 0x1cc;
+- hwrpb.processor[i].type = hwrpb.hwrpb.cpuid;
++ /*
++ * original value was 0x1cc ==
++ * PALcode loaded (0x100)
++ * PALcode memory valid (0x080)
++ * PALcode valid (0x040)
++ * processor present (0x008)
++ * processor available (0x004)
++ *
++ * Don't set PALcode memory valid -- we don't initialize those PCS
++ * fields!
++ */
++ hwrpb.processor[i].flags = 0x14c;
++ hwrpb.processor[i].type = proc_type;
++ /* XXX hwrpb.processor[i].pal_revision */
+ }
+
+ hwrpb.hwrpb.intr_freq = HZ * 4096;
+@@ -213,6 +237,21 @@ init_hwrpb (unsigned long memsize, unsig
+ hwrpb.mc[1].start_pfn = pal_pages;
+ hwrpb.mc[1].numpages = (memsize >> PAGE_SHIFT) - pal_pages;
+
++ hwrpb.hwrpb.ctbt_offset = offsetof(struct hwrpb_combine, ctb);
++ hwrpb.hwrpb.ctb_size = sizeof(hwrpb.ctb);
++ if (have_vga && !CONFIG_NOGRAPHICS(config))
++ {
++ printf("CTB: GRAPHICS PCI BUS %d DEV %d\r\n", pci_vga_bus, pci_vga_dev);
++ hwrpb.ctb.term_type = CTB_GRAPHICS;
++ hwrpb.ctb.turboslot = (CTB_TURBOSLOT_TYPE_PCI << 16) |
++ (pci_vga_bus << 8) | pci_vga_dev;
++ }
++ else
++ {
++ printf("CTB: PRINTERPORT\r\n");
++ hwrpb.ctb.term_type = CTB_PRINTERPORT;
++ }
++
+ hwrpb.hwrpb.crb_offset = offsetof(struct hwrpb_combine, crb);
+ hwrpb.crb.dispatch_va = &hwrpb.proc_dispatch;
+ hwrpb.crb.dispatch_pa = PA(&hwrpb.proc_dispatch);
+@@ -260,7 +299,7 @@ init_i8259 (void)
+ outb(0x01, PORT_PIC1_DATA); /* ICW4 */
+
+ /* Initialize level triggers. The CY82C693UB that's on real alpha
+- hardware doesn't have this; this is a PIIX extension. However,
++ hardware controls these differently; we assume a PIIX here. However,
+ QEMU doesn't implement regular level triggers. */
+ outb(0xff, PORT_PIC2_ELCR);
+ outb(0xff, PORT_PIC1_ELCR);
+@@ -275,32 +314,37 @@ init_i8259 (void)
+ }
+
+ static void __attribute__((noreturn))
+-swppal(void *entry, void *pcb)
++swppal(void *entry, void *pcb, unsigned long vptptr, unsigned long pv)
+ {
+ register int variant __asm__("$16") = 2; /* OSF/1 PALcode */
+ register void *pc __asm__("$17") = entry;
+ register unsigned long pa_pcb __asm__("$18") = PA(pcb);
+- register unsigned long vptptr __asm__("$19") = VPTPTR;
++ register unsigned long newvptptr __asm__("$19") = vptptr;
++ register unsigned long newpv __asm__("$20") = pv;
+
+- asm("call_pal 0x0a" : : "r"(variant), "r"(pc), "r"(pa_pcb), "r"(vptptr));
++ asm("call_pal 0x0a" : :
++ "r"(variant), "r"(pc), "r"(pa_pcb), "r"(newvptptr), "r"(newpv));
+ __builtin_unreachable ();
+ }
+
+ void
+-do_start(unsigned long memsize, void (*kernel_entry)(void), unsigned long cpus)
++do_start(unsigned long memsize, void (*kernel_entry)(void),
++ unsigned long config)
+ {
+ last_alloc = _end;
+
+ init_page_table();
+- init_hwrpb(memsize, cpus);
+ init_pcb();
+ init_i8259();
+ uart_init();
+ ps2port_setup();
+ pci_setup();
+ vgahw_init();
++ init_hwrpb(memsize, config);
+
+- swppal(kernel_entry ? kernel_entry : do_console, &pcb);
++ void *new_pc = kernel_entry ? kernel_entry : do_console;
++
++ swppal(new_pc, &pcb, VPTPTR, (unsigned long)new_pc);
+ }
+
+ void
+@@ -315,14 +359,16 @@ do_start_wait(unsigned long cpuid)
+ {
+ /* ??? The only message I know of is "START\r\n".
+ I can't be bothered to verify more than 4 characters. */
+- /* ??? The Linux kernel fills in, but does not require,
+- CPU_restart_data. It just sets that to the same address
+- as CPU_restart itself. Our swppal *does* put the PC into
+- $26 and $27, the latter of which the kernel does rely upon. */
++
++ /* Use use a private extension to SWPPAL to get the
++ CPU_restart_data into $27. Linux fills it in, but does
++ not require it. Other operating system, however,s do use
++ CPU_restart_data as part of secondary CPU start-up. */
+
+ unsigned int len = hwrpb.processor[cpuid].ipc_buffer[0];
+ unsigned int msg = hwrpb.processor[cpuid].ipc_buffer[1];
+ void *CPU_restart = hwrpb.hwrpb.CPU_restart;
++ unsigned long CPU_restart_data = hwrpb.hwrpb.CPU_restart_data;
+ __sync_synchronize();
+ hwrpb.hwrpb.rxrdy = 0;
+
+@@ -330,7 +376,8 @@ do_start_wait(unsigned long cpuid)
+ {
+ /* Set bootstrap in progress */
+ hwrpb.processor[cpuid].flags |= 1;
+- swppal(CPU_restart, hwrpb.processor[cpuid].hwpcb);
++ swppal(CPU_restart, hwrpb.processor[cpuid].hwpcb,
++ hwrpb.hwrpb.vptb, CPU_restart_data);
+ }
+ }
+ }
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_memcpy.c b/emulators/qemu/patches/patch-roms_qemu-palcode_memcpy.c
new file mode 100644
index 00000000000..f381ca52bc4
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_memcpy.c
@@ -0,0 +1,15 @@
+$NetBSD: patch-roms_qemu-palcode_memcpy.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Include local header file for prototypes.
+
+--- roms/qemu-palcode/memcpy.c.orig 2020-10-04 16:22:55.342263484 +0000
++++ roms/qemu-palcode/memcpy.c 2020-10-04 16:23:41.685256308 +0000
+@@ -8,7 +8,7 @@
+ * This is a reasonably optimized memcpy() routine.
+ */
+
+-#include <string.h>
++#include "protos.h"
+
+ /*
+ * Note that the C code is written to be optimized into good assembly. However,
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_memset.c b/emulators/qemu/patches/patch-roms_qemu-palcode_memset.c
new file mode 100644
index 00000000000..b7ed0b6054a
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_memset.c
@@ -0,0 +1,15 @@
+$NetBSD: patch-roms_qemu-palcode_memset.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Include local header file for prototypes.
+
+--- roms/qemu-palcode/memset.c.orig 2020-10-04 16:26:11.159949099 +0000
++++ roms/qemu-palcode/memset.c 2020-10-04 16:29:02.795766148 +0000
+@@ -19,7 +19,7 @@
+ <http://www.gnu.org/licenses/>. */
+
+
+-#include <string.h>
++#include "protos.h"
+
+ void *memset(void *optr, int ival, unsigned long size)
+ {
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_pal.S b/emulators/qemu/patches/patch-roms_qemu-palcode_pal.S
new file mode 100644
index 00000000000..52b55e091fa
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_pal.S
@@ -0,0 +1,53 @@
+$NetBSD: patch-roms_qemu-palcode_pal.S,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+In SWPPAL, allow an additional, non-architected argument for the
+switch to OSF/1 PALcode. This extra argument specifies the desired
+value of $pv after SWPPAL has completed, and is for internal PALcode
+use only and is needed for secondary CPU spin-up. This is allowed
+because per the architecure specification, all registers other than
+$sp and $v0 are UNPREDICTABLE after SWPPAL, and this PALcode's use
+of SWPPAL for secondary CPU spin-up is an implementation detail.
+This PALcode was already relying on this UNPREDICTABLE behavior for
+its own purposes; this change merely gives control of this behavior
+to internal SWPPAL callers.
+
+--- roms/qemu-palcode/pal.S.orig 2020-10-04 16:32:44.901663159 +0000
++++ roms/qemu-palcode/pal.S 2020-10-04 16:31:30.356343608 +0000
+@@ -566,6 +566,8 @@ ENDFN CallPal_Cserve_Cont
+ * r17 (a1) = New PC
+ * r18 (a2) = New PCB
+ * r19 (a3) = New VptPtr
++ * r20 (a4) = New Procedure Value (to place into $27)
++ * (Non-standard; See note below.)
+ *
+ * OUTPUT PARAMETERS:
+ *
+@@ -574,11 +576,15 @@ ENDFN CallPal_Cserve_Cont
+ * 1 - Unknown PALcode variant
+ * 2 - Known PALcode variant, but PALcode not loaded
+ *
+- * r26 (ra) = r27 (pv) = New PC
+- * Note that this is non-architected, but is relied on by
++ * r26 (ra) = New PC
++ * r27 (pv) = From $20
++ * Note that this is non-architected, but is relied upon by
+ * the usage of SwpPal within our own console code in order
+- * to simplify its use within C code.
+- *
++ * to simplify its use within C code. We can get away with
++ * the extra non-standard argument (in $20) because as
++ * architected, all registers except SP and R0 are
++ * UNPREDICTABLE; therefore private internal usage is
++ * fine.
+ */
+ ORG_CALL_PAL_PRIV(0x0A)
+ CallPal_SwpPal:
+@@ -624,7 +630,7 @@ CallPal_SwpPal_Cont:
+ mtpr $31, qemu_tbia // Flush TLB for new PTBR
+
+ mov a1, $26
+- mov a1, $27
++ mov a4, $27
+ hw_ret (a1)
+ ENDFN CallPal_SwpPal_Cont
+ .previous
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_pci.c b/emulators/qemu/patches/patch-roms_qemu-palcode_pci.c
new file mode 100644
index 00000000000..651cb2db953
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_pci.c
@@ -0,0 +1,78 @@
+$NetBSD: patch-roms_qemu-palcode_pci.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+- Move PCI_DEVFN(), PCI_BUS(), PCI_SLOT(), and PCI_FUNC() to pci.h.
+- Improve debug/info messages.
+- Only program a BAR as a 64-bit MEM BAR if it really is a 64-bit MEM BAR.
+ Fixes an issue with the CMD646 IDE controller under NetBSD.
+- Use system-specific information to program the interrupt line register
+ with the interrupt mappings, which is what the SRM console does on real
+ hardware; some operating systems (e.g. NetBSD) use this information
+ rather than having interrupt mapping tables for every possible system
+ variation.
+
+--- roms/qemu-palcode/pci.c.orig 2020-10-04 16:41:22.923562768 +0000
++++ roms/qemu-palcode/pci.c 2020-10-04 16:41:58.183954279 +0000
+@@ -29,12 +29,9 @@
+ #include "protos.h"
+ #include "pci.h"
+ #include "pci_regs.h"
++#include SYSTEM_H
+
+
+-#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+-#define PCI_BUS(devfn) ((devfn) >> 8)
+-#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
+-#define PCI_FUNC(devfn) ((devfn) & 0x07)
+ #define PCI_SLOT_MAX 32
+ #define PCI_FUNC_MAX 8
+ #define PCI_REGION_ROM 6
+@@ -88,7 +85,7 @@ pci_setup_device(int bdf, uint32_t *p_io
+ device_id = pci_config_readw(bdf, PCI_DEVICE_ID);
+ class_id = pci_config_readw(bdf, PCI_CLASS_DEVICE);
+
+- printf("PCI: %02x:%02x:%x class %04x id %04x:%04x\r\n",
++ printf("PCI: %d:%d:%d class %04x id %04x:%04x\r\n",
+ PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
+ class_id, vendor_id, device_id);
+
+@@ -122,9 +119,11 @@ pci_setup_device(int bdf, uint32_t *p_io
+ *p_base = addr + size;
+ pci_config_writel(bdf, ofs, addr);
+
+- printf("PCI: region %d: %08x\r\n", region, addr);
++ printf("PCI: region %d (BAR %02x): %08x\r\n",
++ region, ofs, addr);
+
+- if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
++ if ((old & PCI_BASE_ADDRESS_SPACE_IO) == 0 &&
++ (old & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
+ == PCI_BASE_ADDRESS_MEM_TYPE_64)
+ {
+ pci_config_writel(bdf, ofs + 4, 0);
+@@ -135,7 +134,25 @@ pci_setup_device(int bdf, uint32_t *p_io
+
+ pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+- /* Map the interrupt. */
++ /* Map the interrupt and program the IRQ into the line register.
++ Some operating systems rely on the Console providing this information
++ in order to avoid having mapping tables for every possible system
++ variation. */
++
++ const uint8_t pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
++ const uint8_t slot = PCI_SLOT(bdf);
++ const int irq = MAP_PCI_INTERRUPT(slot, pin, class_id);
++
++ if (irq == -1)
++ {
++ /* No interrupt mapping. */
++ pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 0xff);
++ }
++ else
++ {
++ printf("PCI: intr pin %d -> irq %d\r\n", pin, irq);
++ pci_config_writeb(bdf, PCI_INTERRUPT_LINE, irq);
++ }
+ }
+
+ void
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_pci.h b/emulators/qemu/patches/patch-roms_qemu-palcode_pci.h
new file mode 100644
index 00000000000..a3510126bf0
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_pci.h
@@ -0,0 +1,18 @@
+$NetBSD: patch-roms_qemu-palcode_pci.h,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Move PCI_DEVFN(), PCI_BUS(), PCI_SLOT(), and PCI_FUNC() to pci.h.
+
+--- roms/qemu-palcode/pci.h.orig 2020-10-04 16:48:50.267686138 +0000
++++ roms/qemu-palcode/pci.h 2020-10-04 16:49:11.064722703 +0000
+@@ -60,6 +60,11 @@ extern void pci_config_maskw(int bdf, in
+
+ extern int pci_next(int bdf, int *pmax);
+
++#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
++#define PCI_BUS(devfn) ((devfn) >> 8)
++#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
++#define PCI_FUNC(devfn) ((devfn) & 0x07)
++
+ #define foreachpci(BDF, MAX) \
+ for (MAX = 0x0100, BDF = pci_next(0, &MAX); \
+ BDF >= 0; \
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_printf.c b/emulators/qemu/patches/patch-roms_qemu-palcode_printf.c
new file mode 100644
index 00000000000..f0a08c73c51
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_printf.c
@@ -0,0 +1,31 @@
+$NetBSD: patch-roms_qemu-palcode_printf.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+- Include local header file for prototypes.
+- Add puts(), which the compiler may emit a call to if the string passed
+ to printf has no format specifiers.
+
+--- roms/qemu-palcode/printf.c.orig 2020-10-04 17:01:51.396706889 +0000
++++ roms/qemu-palcode/printf.c 2020-10-04 17:02:27.588036847 +0000
+@@ -18,10 +18,8 @@
+ along with this program; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>. */
+
+-#include <stdarg.h>
+-#include <stdbool.h>
+-#include <string.h>
+ #include "console.h"
++#include "protos.h"
+
+ static int print_buf_pad(char *buf, int buflen, char *p, int width, int pad)
+ {
+@@ -201,3 +199,10 @@ int printf(const char *fmt, ...)
+ va_end(args);
+ return r;
+ }
++
++int puts(const char *s)
++{
++ int len = strlen(s);
++ crb_puts(0, s, len);
++ return len;
++}
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_protos.h b/emulators/qemu/patches/patch-roms_qemu-palcode_protos.h
new file mode 100644
index 00000000000..cb16ba3fce4
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_protos.h
@@ -0,0 +1,66 @@
+$NetBSD: patch-roms_qemu-palcode_protos.h,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+- Don't include system headers. Instead, provide standalone definitions
+ and declarations of types needed and functions used by the PALcode that
+ are compatible with the standard Alpha / GCC ABI.
+- Add pci_vga_bus and pci_vga_dev globals so that the HWRPB CTB can
+ correctly reflect the location of the a graphics console.
+
+--- roms/qemu-palcode/protos.h.orig 2020-10-04 17:05:39.239008051 +0000
++++ roms/qemu-palcode/protos.h 2020-10-04 17:06:01.772319919 +0000
+@@ -21,11 +21,33 @@
+ #ifndef PROTOS_H
+ #define PROTOS_H 1
+
+-#include <stdint.h>
+-#include <stdbool.h>
+-#include <stddef.h>
+-#include <string.h>
+-
++/*
++ * Stand-alone definitions for various types, compatible with
++ * the Alpha Linux ABI and GCC. This eliminates dependencies
++ * on external headers.
++ */
++typedef unsigned char uint8_t;
++typedef unsigned short uint16_t;
++typedef unsigned int uint32_t;
++typedef unsigned long uint64_t;
++typedef unsigned long size_t;
++
++#define bool _Bool
++#define true 1
++#define false 0
++
++#define offsetof(type, member) __builtin_offsetof(type, member)
++
++typedef __builtin_va_list va_list;
++#define va_start(ap, last) __builtin_va_start((ap), (last))
++#define va_arg __builtin_va_arg
++#define va_end(ap) __builtin_va_end(ap)
++
++#define NULL ((void *)0)
++
++extern void *memset(void *, int, size_t);
++extern void *memcpy(void *, const void *, size_t);
++extern size_t strlen(const char *);
+
+ /*
+ * Call_Pal functions.
+@@ -202,6 +224,8 @@ extern unsigned long crb_fixup(unsigned
+ */
+
+ extern bool have_vga;
++extern unsigned int pci_vga_bus;
++extern unsigned int pci_vga_dev;
+
+ extern void do_console(void);
+ extern void entInt(void);
+@@ -211,6 +235,7 @@ extern void entInt(void);
+ */
+
+ extern int printf(const char *, ...);
++extern int puts(const char *);
+ extern void ndelay(unsigned long nsec);
+
+ static inline void udelay(unsigned long msec)
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_sys-clipper.h b/emulators/qemu/patches/patch-roms_qemu-palcode_sys-clipper.h
new file mode 100644
index 00000000000..c16ad0c3ee0
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_sys-clipper.h
@@ -0,0 +1,38 @@
+$NetBSD: patch-roms_qemu-palcode_sys-clipper.h,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Povide PCI device interrupt mapping information.
+
+--- roms/qemu-palcode/sys-clipper.h.orig 2020-10-04 17:10:06.597880613 +0000
++++ roms/qemu-palcode/sys-clipper.h 2020-10-04 17:10:33.149119398 +0000
+@@ -27,4 +27,31 @@
+ #define SYS_VARIATION (5 << 10)
+ #define SYS_REVISION 0
+
++#ifndef __ASSEMBLER__
++
++#define MAP_PCI_INTERRUPT(SLOT, PIN, CLASS_ID) \
++({ \
++ int IRQ; \
++ \
++ if (CLASS_ID == 0x0601) \
++ { \
++ /* PCI-ISA bridge is hard-wired to IRQ 55 on real hardware, \
++ and comes in at a different SCB vector; force the line \
++ register to -1. */ \
++ IRQ = -1; \
++ } \
++ else if (PIN >= 1 && PIN <= 4) \
++ { \
++ /* See hw/alpha/dp264.c:clipper_pci_map_irq() */ \
++ IRQ = (SLOT + 1) * 4 + (PIN - 1); \
++ } \
++ else \
++ { \
++ IRQ = -1; \
++ } \
++ IRQ; \
++})
++
++#endif /* ! __ASSEMBLER__ */
++
+ #endif
diff --git a/emulators/qemu/patches/patch-roms_qemu-palcode_vgaio.c b/emulators/qemu/patches/patch-roms_qemu-palcode_vgaio.c
new file mode 100644
index 00000000000..066d212d846
--- /dev/null
+++ b/emulators/qemu/patches/patch-roms_qemu-palcode_vgaio.c
@@ -0,0 +1,16 @@
+$NetBSD: patch-roms_qemu-palcode_vgaio.c,v 1.1 2020/10/04 20:39:25 thorpej Exp $
+
+Add pci_vga_bus and pci_vga_dev globals so that the HWRPB CTB can
+correctly reflect the location of the a graphics console.
+
+--- roms/qemu-palcode/vgaio.c.orig 2020-10-04 17:12:53.089367837 +0000
++++ roms/qemu-palcode/vgaio.c 2020-10-04 17:13:21.240322169 +0000
+@@ -570,6 +570,8 @@ vgahw_init(void)
+
+ found:
+ have_vga = 1;
++ pci_vga_bus = PCI_BUS(bdf);
++ pci_vga_dev = PCI_SLOT(bdf);
+
+ vmode_g = find_vga_entry(3);
+