From 0044d53a105bb843767c91984cb56c2f0f30b148 Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Sat, 9 Feb 2008 16:32:59 +0000 Subject: [PATCH] This set of changes creates irq tables for alix1c and adds the functions from v2 to install them. Linux boots fine and all interrupts seem to work correctly -- the network comes up, USB hot plug works, I can mount the USB disk, etc. To enable pirq tables for a given mainboard, simply add the select PIRQ_TABLE (see below) to the Kconfig for that board. Again, this code builds and boots linux on the alix1c. I think, with this change, we are very close to moving ALL LX boards to v3 and deprecating v2. The major remaining fix is to add an empty LAR entry to fill empty space in LAR and speed up the LAR file search process. Signed-off-by: Ronald G. Minnich Acked-by: Stefan Reinauer Index: include/tables.h Add prototype, conditioned on CONFIG_PIRQ_TABLE Index: util/x86emu/vm86.c Comment out 'debug trap' code that scribbles vectors at 0x4000. I don't know why this is here, but I'd like to leave it #if'ed out -- somebody, at some point, thought we needed it. To reenable, we will need to move stage2 code or these magic vectors. Index: arch/x86/Makefile Add support for conditional compilation of pirq support code. Index: arch/x86/pirq_routing.c Add this file from v2. Index: arch/x86/archtables.c Add call to write_pirq_routing_table (controlled by #ifdef CONFIG_PIRQ_TABLE) Index: arch/x86/Kconfig Add new config variable: PIRQ_TABLE Index: device/device.c Fix some trivial bugs. Index: mainboard/pcengines/alix1c/Makefile Add pirq table code for stage2 Index: mainboard/pcengines/alix1c/dts Modify dts to properly set southbridge variables Index: mainboard/pcengines/alix1c/irq_tables.c Add code from v2 for the alix1c. Index: mainboard/pcengines/Kconfig Add 'select PIRQ_TABLE' Index: include/arch/x86/pirq_routing.h Add include file from v2. Remove all the SLOTCOUNT nonsense. This hack was only needed for a very early version of gcc 3.x, where they screwed up the creation of struct members that used the [] syntax for variable-length array at the end of the struct. Index: include/device/pci.h Add prototype git-svn-id: svn://coreboot.org/repository/coreboot-v3@582 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- arch/x86/Kconfig | 7 ++ arch/x86/Makefile | 4 + arch/x86/archtables.c | 9 +- arch/x86/pirq_routing.c | 120 ++++++++++++++++++ device/device.c | 9 +- include/arch/x86/pirq_routing.h | 55 ++++++++ include/device/pci.h | 3 + include/tables.h | 5 + mainboard/pcengines/Kconfig | 1 + mainboard/pcengines/alix1c/Makefile | 4 + mainboard/pcengines/alix1c/dts | 10 ++ mainboard/pcengines/alix1c/irq_tables.c | 160 ++++++++++++++++++++++++ util/x86emu/vm86.c | 12 ++ 13 files changed, 391 insertions(+), 8 deletions(-) create mode 100644 arch/x86/pirq_routing.c create mode 100644 include/arch/x86/pirq_routing.h create mode 100644 mainboard/pcengines/alix1c/irq_tables.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9895b5f79c..65432e6904 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -55,6 +55,13 @@ config OPTION_TABLE a battery backed up real time clock with CMOS NVRAM. It is usually set in mainboard/*/Kconfig. +config PIRQ_TABLE + boolean + help + This option is used to determine whether the mainboard has + a PIRQ table, which is the old way to set up interrupt routing. + It is usually set in mainboard/*/Kconfig. + config SMP boolean help diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 487a8c3de2..872c24c8fe 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -179,6 +179,10 @@ STAGE2_ARCH_X86_OBJ = archtables.o coreboot_table.o udelay_io.o STAGE2_ARCH_X86_OBJ += pci_ops_auto.o pci_ops_conf1.o pci_ops_conf2.o STAGE2_ARCH_X86_OBJ += keyboard.o i8259.o isa-dma.o +ifeq ($(CONFIG_PIRQ_TABLE),y) +STAGE2_ARCH_X86_OBJ += pirq_routing.o +endif + STAGE2_DYNAMIC_OBJ = statictree.o STAGE2_OBJ := $(patsubst %,$(obj)/lib/%,$(STAGE2_LIB_OBJ)) \ diff --git a/arch/x86/archtables.c b/arch/x86/archtables.c index 844fe5c849..aefcbab256 100644 --- a/arch/x86/archtables.c +++ b/arch/x86/archtables.c @@ -79,8 +79,13 @@ struct lb_memory *arch_write_tables(void) post_code(POST_STAGE2_ARCH_WRITE_TABLES_ENTER); /* This table must be betweeen 0xf0000 & 0x100000 */ -// rom_table_end = write_pirq_routing_table(rom_table_end); -// rom_table_end = (rom_table_end + 1023) & ~1023; + /* we need to make a decision: create empty functions + * in .h files if the cpp variable is undefined, or #ifdef? + */ +#ifdef CONFIG_PIRQ_TABLE + rom_table_end = write_pirq_routing_table(rom_table_end); + rom_table_end = (rom_table_end + 1023) & ~1023; +#endif /* Write ACPI tables */ /* write them in the rom area because DSDT can be large (8K on epia-m) which diff --git a/arch/x86/pirq_routing.c b/arch/x86/pirq_routing.c new file mode 100644 index 0000000000..b9c57d8b4d --- /dev/null +++ b/arch/x86/pirq_routing.c @@ -0,0 +1,120 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2000 Ollie Lo, Silicon Integrated Systems + * Copyright (C) 2000 Ron Minnich + * Copyright (C) 2001 Eric Biederman + * Copyright (C) 2002 Andrew Ip + * Copyright (C) 2008 Ron Minnich + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include +#include +#include +#include + +static void check_pirq_routing_table(struct irq_routing_table *rt) +{ + u8 *addr = (u8 *)rt; + u8 sum=0; + int i; + + printk(BIOS_INFO, "Checking IRQ routing table consistency...\n"); + +#if defined(IRQ_SLOT_COUNT) + if (sizeof(struct irq_routing_table) != rt->size) { + printk_warning("Inconsistent IRQ routing table size (0x%x/0x%x)\n", + sizeof(struct irq_routing_table), + rt->size + ); + rt->size=sizeof(struct irq_routing_table); + } +#endif + + for (i = 0; i < rt->size; i++) + sum += addr[i]; + + printk(BIOS_DEBUG, "%s() - irq_routing_table located at: 0x%p\n", + __FUNCTION__, addr); + + + sum = rt->checksum - sum; + + if (sum != rt->checksum) { + printk(BIOS_WARNING, "%s:%6d:%s() - " + "checksum is: 0x%02x but should be: 0x%02x\n", + __FILE__, __LINE__, __FUNCTION__, rt->checksum, sum); + rt->checksum = sum; + } + + if (rt->signature != PIRQ_SIGNATURE || rt->version != PIRQ_VERSION || + rt->size % 16 ) { + printk(BIOS_WARNING, "%s:%6d:%s() - " + "Interrupt Routing Table not valid\n", + __FILE__, __LINE__, __FUNCTION__); + return; + } + + sum = 0; + for (i=0; isize; i++) + sum += addr[i]; + + if (sum) { + printk(BIOS_WARNING, "%s:%6d:%s() - " + "checksum error in irq routing table\n", + __FILE__, __LINE__, __FUNCTION__); + } + + printk(BIOS_INFO, "done.\n"); +} + +static int verify_copy_pirq_routing_table(unsigned long addr) +{ + int i; + u8 *rt_orig, *rt_curr; + + rt_curr = (u8*)addr; + rt_orig = (u8*)&intel_irq_routing_table; + printk(BIOS_INFO, "Verifing copy of IRQ routing tables at 0x%lux...", addr); + for (i = 0; i < intel_irq_routing_table.size; i++) { + if (*(rt_curr + i) != *(rt_orig + i)) { + printk(BIOS_INFO, "failed\n"); + return -1; + } + } + printk(BIOS_INFO, "done\n"); + + check_pirq_routing_table((struct irq_routing_table *)addr); + + return 0; +} +unsigned long copy_pirq_routing_table(unsigned long addr) +{ + /* Align the table to be 16 byte aligned. */ + addr += 15; + addr &= ~15; + + /* This table must be betweeen 0xf0000 & 0x100000 */ + printk(BIOS_INFO, "Copying IRQ routing tables to 0x%lux...", addr); + memcpy((void *)addr, &intel_irq_routing_table, intel_irq_routing_table.size); + printk(BIOS_INFO, "done.\n"); + verify_copy_pirq_routing_table(addr); + return addr + intel_irq_routing_table.size; +} + diff --git a/device/device.c b/device/device.c index 3694276a92..5d45de566f 100644 --- a/device/device.c +++ b/device/device.c @@ -119,16 +119,13 @@ struct constructor *find_constructor(struct device_id *id) extern struct constructor *all_constructors[]; struct constructor *c; int i; - printk(BIOS_SPEW, "%s: find %s\n", __func__, dev_id_string(id)); + for (i = 0; all_constructors[i]; i++) { printk(BIOS_SPEW, "%s: check all_constructors[i] %p\n", __func__, all_constructors[i]); for (c = all_constructors[i]; c->ops; c++) { printk(BIOS_SPEW, "%s: cons %p, cons id %s\n", __func__, c, dev_id_string(&c->id)); - if (!c->ops) { - continue; - } if (id_eq(&c->id, id)) { printk(BIOS_SPEW, "%s: match\n", __func__); return c; @@ -180,6 +177,7 @@ void constructor(struct device *dev, struct device_id *id) struct constructor *c; c = find_constructor(id); + printk(BIOS_SPEW, "%s: constructor is %p\n", __func__, c); if(c && c->ops) { @@ -190,7 +188,7 @@ void constructor(struct device *dev, struct device_id *id) } else printk(BIOS_INFO, "No constructor called for %s.\n", - dev_id_string(&c->id)); + dev_id_string(id)); } /** @@ -211,7 +209,6 @@ struct device *alloc_dev(struct bus *parent, struct device_path *path, { struct device *dev, *child; int link; - spin_lock(&dev_lock); /* Find the last child of our parent. */ diff --git a/include/arch/x86/pirq_routing.h b/include/arch/x86/pirq_routing.h new file mode 100644 index 0000000000..031b610e2c --- /dev/null +++ b/include/arch/x86/pirq_routing.h @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2000 Ollie Lo, Silicon Integrated Systems + * Copyright (C) 2008 Ron Minnich + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef ARCH_PIRQ_ROUTING_H +#define ARCH_PIRQ_ROUTING_H + +#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) +#define PIRQ_VERSION 0x0100 + +struct irq_info { + u8 bus, devfn; /* Bus, device and function */ + struct { + u8 link; /* IRQ line ID, chipset dependent, 0=not routed */ + u16 bitmap; /* Available IRQs */ + } __attribute__((packed)) irq[4]; + u8 slot; /* Slot number, 0=onboard */ + u8 rfu; +} __attribute__((packed)); + +struct irq_routing_table { + u32 signature; /* PIRQ_SIGNATURE should be here */ + u16 version; /* PIRQ_VERSION */ + u16 size; /* Table size in bytes */ + u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */ + u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */ + u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */ + u32 miniport_data; /* Crap */ + u8 rfu[11]; + u8 checksum; /* Modulo 256 checksum must give zero */ + struct irq_info slots[]; +} __attribute__((packed)); + +extern const struct irq_routing_table intel_irq_routing_table; + +unsigned long copy_pirq_routing_table(unsigned long start); +unsigned long write_pirq_routing_table(unsigned long start); + +#endif /* ARCH_PIRQ_ROUTING_H */ diff --git a/include/device/pci.h b/include/device/pci.h index ae56729777..07a24527e3 100644 --- a/include/device/pci.h +++ b/include/device/pci.h @@ -99,6 +99,9 @@ void pci_domain_read_resources(struct device *dev); void ram_resource(struct device *dev, unsigned long index, unsigned long basek, unsigned long sizek); unsigned int pci_domain_scan_bus(struct device *dev, unsigned int max); +void pci_assign_irqs(unsigned int bus, unsigned int slot, + const unsigned char pIntAtoD[4]); + #define PCI_IO_BRIDGE_ALIGN 4096 diff --git a/include/tables.h b/include/tables.h index 6ee51f2d95..f468348e55 100644 --- a/include/tables.h +++ b/include/tables.h @@ -269,4 +269,9 @@ struct lb_memory *get_lb_mem(void); struct cmos_option_table *get_option_table(void); +#ifdef CONFIG_PIRQ_TABLE +unsigned long write_pirq_routing_table(unsigned long addr); +#endif + + #endif /* TABLES_H */ diff --git a/mainboard/pcengines/Kconfig b/mainboard/pcengines/Kconfig index 63d046bc25..a17bde991a 100644 --- a/mainboard/pcengines/Kconfig +++ b/mainboard/pcengines/Kconfig @@ -31,6 +31,7 @@ config BOARD_PCENGINES_ALIX1C select NORTHBRIDGE_AMD_GEODELX select SOUTHBRIDGE_AMD_CS5536 select SUPERIO_WINBOND_W83627HF + select PIRQ_TABLE help PC Engines ALIX1.C. diff --git a/mainboard/pcengines/alix1c/Makefile b/mainboard/pcengines/alix1c/Makefile index da4c25a6c6..bcb216f2c5 100644 --- a/mainboard/pcengines/alix1c/Makefile +++ b/mainboard/pcengines/alix1c/Makefile @@ -27,6 +27,10 @@ INITRAM_OBJ = $(src)/mainboard/$(MAINBOARDDIR)/initram.c \ STAGE2_MAINBOARD_OBJ = +ifeq ($(CONFIG_PIRQ_TABLE),y) +STAGE2_MAINBOARD_OBJ += irq_tables.o +endif + $(obj)/coreboot.vpd: $(Q)printf " BUILD DUMMY VPD\n" $(Q)dd if=/dev/zero of=$(obj)/coreboot.vpd bs=256 count=1 $(SILENT) diff --git a/mainboard/pcengines/alix1c/dts b/mainboard/pcengines/alix1c/dts index b3b2c968af..a615fce28d 100644 --- a/mainboard/pcengines/alix1c/dts +++ b/mainboard/pcengines/alix1c/dts @@ -43,6 +43,16 @@ pcipath = "0xf,0"; enabled; enable_ide = "1"; + /* Interrupt enables for LPC bus. + * Each bit is an IRQ 0-15. */ + lpc_serirq_enable = "0x000010da"; + /* LPC IRQ polarity. Each bit is an IRQ 0-15. */ + lpc_serirq_polarity = "0x0000EF25"; + /* 0:continuous 1:quiet */ + lpc_serirq_mode = "1"; + /* GPIO(0-0x20) for INT D:C:B:A, 0xFF=none. + * See virtual PIC spec. */ + enable_gpio_int_route = "0x0D0C0700"; }; superio { /config/("superio/winbond/w83627hf/dts"); diff --git a/mainboard/pcengines/alix1c/irq_tables.c b/mainboard/pcengines/alix1c/irq_tables.c new file mode 100644 index 0000000000..169d553e67 --- /dev/null +++ b/mainboard/pcengines/alix1c/irq_tables.c @@ -0,0 +1,160 @@ +/* +* This file is part of the coreboot project. +* +* Copyright (C) 2007 Advanced Micro Devices, Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* This program 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../southbridge/amd/cs5536/cs5536.h" + + + +/* Platform IRQs */ +#define PIRQA 11 +#define PIRQB 10 +#define PIRQC 11 +#define PIRQD 9 + +/* Map */ +#define M_PIRQA (1 << PIRQA) /* Bitmap of supported IRQs */ +#define M_PIRQB (1 << PIRQB) /* Bitmap of supported IRQs */ +#define M_PIRQC (1 << PIRQC) /* Bitmap of supported IRQs */ +#define M_PIRQD (1 << PIRQD) /* Bitmap of supported IRQs */ + +/* Link */ +#define L_PIRQA 1 /* Means Slot INTx# Connects To Chipset INTA# */ +#define L_PIRQB 2 /* Means Slot INTx# Connects To Chipset INTB# */ +#define L_PIRQC 3 /* Means Slot INTx# Connects To Chipset INTC# */ +#define L_PIRQD 4 /* Means Slot INTx# Connects To Chipset INTD# */ + +/* + * ALIX1.C interrupt wiring. + * + * Devices are: + * + * 00:01.0 Host bridge: Advanced Micro Devices [AMD] CS5536 [Geode companion] Host Bridge (rev 31) + * 00:01.2 Entertainment encryption device: Advanced Micro Devices [AMD] Geode LX AES Security Block + * 00:0d.0 Ethernet controller: VIA Technologies, Inc. VT6105M [Rhine-III] (rev 96) + * 00:0e.0 Network controller: Intersil Corporation Prism 2.5 Wavelan chipset (rev 01) + * 00:0f.0 ISA bridge: Advanced Micro Devices [AMD] CS5536 [Geode companion] ISA (rev 03) + * 00:0f.2 IDE interface: Advanced Micro Devices [AMD] CS5536 [Geode companion] IDE (rev 01) + * 00:0f.3 Multimedia audio controller: Advanced Micro Devices [AMD] CS5536 [Geode companion] Audio (rev 01) + * 00:0f.4 USB Controller: Advanced Micro Devices [AMD] CS5536 [Geode companion] OHC (rev 02) + * 00:0f.5 USB Controller: Advanced Micro Devices [AMD] CS5536 [Geode companion] EHC (rev 02) + * + * The only devices that interrupt are: + * + * What Device IRQ PIN PIN WIRED TO + * ------------------------------------------------- + * AES 00:01.2 0a 01 A A + * 3VPCI 00:0c.0 0a 01 A A + * eth0 00:0d.0 0b 01 A B + * mpci 00:0e.0 0a 01 A A + * usb 00:0f.3 0b 02 B B + * usb 00:0f.4 0b 04 D D + * usb 00:0f.5 0b 04 D D + * + * The only swizzled interrupt is eth0, where INTA is wired to interrupt controller line B. + */ + +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, + PIRQ_VERSION, + 32 + 16 * 5, /* Max. number of devices on the bus */ + 0x00, /* Where the interrupt router lies (bus) */ + (0x0F << 3) | 0x0, /* Where the interrupt router lies (dev) */ + 0x00, /* IRQs devoted exclusively to PCI usage */ + 0x100B, /* Vendor */ + 0x002B, /* Device */ + 0, /* Crap (miniport) */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* u8 rfu[11] */ + 0x00, /* Checksum */ + { + /* If you change the number of entries, change IRQ_SLOT_COUNT above! */ + + /* bus, dev|fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + + /* CPU */ + {0x00, (0x01 << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, + + /* PCI (slot 1) */ + {0x00, (0x0C << 3) | 0x0, {{L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}}, 0x4, 0x0}, + + /* On-board ethernet */ + {0x00, (0x0D << 3) | 0x0, {{L_PIRQB, M_PIRQB}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, + + /* Mini PCI (slot 2) */ + {0x00, (0x0E << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x1, 0x0}, + + /* Chipset slots -- f.3 wires to B, and f.4 and f.5 wires to D. */ + {0x00, (0x0F << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x0, 0x0}, + } +}; + +unsigned long write_pirq_routing_table(unsigned long addr) +{ + int i, j, k, num_entries; + unsigned char pirq[4]; + u16 chipset_irq_map; + u32 pciAddr, pirtable_end; + struct irq_routing_table *pirq_tbl; + + pirtable_end = copy_pirq_routing_table(addr); + + /* Set up chipset IRQ steering. */ + pciAddr = 0x80000000 | (CHIPSET_DEV_NUM << 11) | 0x5C; + chipset_irq_map = (PIRQD << 12 | PIRQC << 8 | PIRQB << 4 | PIRQA); + printk(BIOS_DEBUG, "%s(%08X, %04X)\n", __FUNCTION__, pciAddr, + chipset_irq_map); + outl(pciAddr & ~3, 0xCF8); + outl(chipset_irq_map, 0xCFC); + + pirq_tbl = (struct irq_routing_table *) (addr); + num_entries = (pirq_tbl->size - 32) / 16; + + /* Set PCI IRQs. */ + for (i = 0; i < num_entries; i++) { + printk(BIOS_DEBUG, "PIR Entry %d Dev/Fn: %X Slot: %d\n", i, + pirq_tbl->slots[i].devfn, pirq_tbl->slots[i].slot); + for (j = 0; j < 4; j++) { + printk(BIOS_DEBUG, "INT: %c bitmap: %x ", 'A' + j, + pirq_tbl->slots[i].irq[j].bitmap); + /* Finds lsb in bitmap to IRQ#. */ + for (k = 0; + (!((pirq_tbl->slots[i].irq[j].bitmap >> k) & 1)) + && (pirq_tbl->slots[i].irq[j].bitmap != 0); + k++); + pirq[j] = k; + printk(BIOS_DEBUG, "PIRQ: %d\n", k); + } + + /* Bus, device, slots IRQs for {A,B,C,D}. */ + pci_assign_irqs(pirq_tbl->slots[i].bus, + pirq_tbl->slots[i].devfn >> 3, pirq); + } + + /* Put the PIR table in memory and checksum. */ + return pirtable_end; +} diff --git a/util/x86emu/vm86.c b/util/x86emu/vm86.c index c9e4b6a280..fe0db7a678 100644 --- a/util/x86emu/vm86.c +++ b/util/x86emu/vm86.c @@ -595,11 +595,23 @@ void setup_realmode_idt(void) intbyte = codeptr + 3; *intbyte = 0x42; /* int42 is the relocated int10 */ + /* The source of the following code is not yet known. + * We feel it may be useful someday, but right now it + * scribbles over code space. We are leaving it here as a + * "Living comment" since it may at some point be needed + * again. It is a very intriguing idea -- one could run + * vm86 code with TF set and set programmable times + * between instructions to slow them down. For those who + * recall the "turbo" switch on old PCs, this is the + * software equivalent. + */ +#if 0 /* debug handler - useful to set a programmable delay between instructions if the TF bit is set upon call to real mode */ idts[1].cs = 0; idts[1].offset = 16384; memcpy((void *)16384, &debughandle, &end_debughandle - &debughandle); +#endif }