Author: rminnich
Date: 2008-02-09 17:32:59 +0100 (Sat, 09 Feb 2008)
New Revision: 582
Added:
coreboot-v3/arch/x86/pirq_routing.c
coreboot-v3/include/arch/x86/pirq_routing.h
coreboot-v3/mainboard/pcengines/alix1c/irq_tables.c
Modified:
coreboot-v3/arch/x86/Kconfig
coreboot-v3/arch/x86/Makefile
coreboot-v3/arch/x86/archtables.c
coreboot-v3/device/device.c
coreboot-v3/include/device/pci.h
coreboot-v3/include/tables.h
coreboot-v3/mainboard/pcengines/Kconfig
coreboot-v3/mainboard/pcengines/alix1c/Makefile
coreboot-v3/mainboard/pcengines/alix1c/dts
coreboot-v3/util/x86emu/vm86.c
Log:
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 <rminnich(a)gmail.com>
Acked-by: Stefan Reinauer <stepan(a)coresystems.de>
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
Modified: coreboot-v3/arch/x86/Kconfig
===================================================================
--- coreboot-v3/arch/x86/Kconfig 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/arch/x86/Kconfig 2008-02-09 16:32:59 UTC (rev 582)
@@ -55,6 +55,13 @@
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
Modified: coreboot-v3/arch/x86/Makefile
===================================================================
--- coreboot-v3/arch/x86/Makefile 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/arch/x86/Makefile 2008-02-09 16:32:59 UTC (rev 582)
@@ -179,6 +179,10 @@
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)) \
Modified: coreboot-v3/arch/x86/archtables.c
===================================================================
--- coreboot-v3/arch/x86/archtables.c 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/arch/x86/archtables.c 2008-02-09 16:32:59 UTC (rev 582)
@@ -79,8 +79,13 @@
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
Added: coreboot-v3/arch/x86/pirq_routing.c
===================================================================
--- coreboot-v3/arch/x86/pirq_routing.c (rev 0)
+++ coreboot-v3/arch/x86/pirq_routing.c 2008-02-09 16:32:59 UTC (rev 582)
@@ -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 <types.h>
+#include <string.h>
+#include <lar.h>
+#include <console.h>
+#include <device/device.h>
+#include <tables.h>
+#include <pirq_routing.h>
+
+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; i<rt->size; 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;
+}
+
Modified: coreboot-v3/device/device.c
===================================================================
--- coreboot-v3/device/device.c 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/device/device.c 2008-02-09 16:32:59 UTC (rev 582)
@@ -119,16 +119,13 @@
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 @@
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 @@
}
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 *dev, *child;
int link;
-
spin_lock(&dev_lock);
/* Find the last child of our parent. */
Added: coreboot-v3/include/arch/x86/pirq_routing.h
===================================================================
--- coreboot-v3/include/arch/x86/pirq_routing.h (rev 0)
+++ coreboot-v3/include/arch/x86/pirq_routing.h 2008-02-09 16:32:59 UTC (rev 582)
@@ -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 */
Modified: coreboot-v3/include/device/pci.h
===================================================================
--- coreboot-v3/include/device/pci.h 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/include/device/pci.h 2008-02-09 16:32:59 UTC (rev 582)
@@ -99,8 +99,11 @@
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
#define PCI_MEM_BRIDGE_ALIGN (1024*1024)
Modified: coreboot-v3/include/tables.h
===================================================================
--- coreboot-v3/include/tables.h 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/include/tables.h 2008-02-09 16:32:59 UTC (rev 582)
@@ -269,4 +269,9 @@
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 */
Modified: coreboot-v3/mainboard/pcengines/Kconfig
===================================================================
--- coreboot-v3/mainboard/pcengines/Kconfig 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/mainboard/pcengines/Kconfig 2008-02-09 16:32:59 UTC (rev 582)
@@ -31,6 +31,7 @@
select NORTHBRIDGE_AMD_GEODELX
select SOUTHBRIDGE_AMD_CS5536
select SUPERIO_WINBOND_W83627HF
+ select PIRQ_TABLE
help
PC Engines ALIX1.C.
Modified: coreboot-v3/mainboard/pcengines/alix1c/Makefile
===================================================================
--- coreboot-v3/mainboard/pcengines/alix1c/Makefile 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/mainboard/pcengines/alix1c/Makefile 2008-02-09 16:32:59 UTC (rev 582)
@@ -27,6 +27,10 @@
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)
Modified: coreboot-v3/mainboard/pcengines/alix1c/dts
===================================================================
--- coreboot-v3/mainboard/pcengines/alix1c/dts 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/mainboard/pcengines/alix1c/dts 2008-02-09 16:32:59 UTC (rev 582)
@@ -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");
Added: coreboot-v3/mainboard/pcengines/alix1c/irq_tables.c
===================================================================
--- coreboot-v3/mainboard/pcengines/alix1c/irq_tables.c (rev 0)
+++ coreboot-v3/mainboard/pcengines/alix1c/irq_tables.c 2008-02-09 16:32:59 UTC (rev 582)
@@ -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 <types.h>
+#include <lib.h>
+#include <console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <string.h>
+#include <msr.h>
+#include <io.h>
+#include <pirq_routing.h>
+#include <amd_geodelx.h>
+#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;
+}
Modified: coreboot-v3/util/x86emu/vm86.c
===================================================================
--- coreboot-v3/util/x86emu/vm86.c 2008-02-08 15:57:02 UTC (rev 581)
+++ coreboot-v3/util/x86emu/vm86.c 2008-02-09 16:32:59 UTC (rev 582)
@@ -595,11 +595,23 @@
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
}