[coreboot] [PATCH 8/8] ASUS M2V support: Add m2v mainboard directory and files

Tobias Diedrich ranma+coreboot at tdiedrich.de
Wed Oct 27 13:43:03 CEST 2010


This adds the m2v directory to src/mainboards/asus and adjusts the Kconfig.
Note:

I added pci irq routing setup based on pirq tables:
pci_fixup_irqs() in irq_tables.c

I didn't see any existing functionality that will just take the pirq
information and use that to setup pci interrupts.
For example, in src/southbridge/via/vt8237r/vt8237r_lpc.c there is
some epia specific setup, which may really belong into the
corresponding mainboard directory...

Signed-off-by: Tobias Diedrich <ranma+coreboot at tdiedrich.de>

---

Index: src/mainboard/asus/Kconfig
===================================================================
--- src.orig/mainboard/asus/Kconfig	2010-10-27 12:51:17.000000000 +0200
+++ src/mainboard/asus/Kconfig	2010-10-27 12:51:19.000000000 +0200
@@ -25,6 +25,8 @@
 	bool "A8N-E"
 config BOARD_ASUS_A8V_E_SE
 	bool "A8V-E SE"
+config BOARD_ASUS_M2V
+	bool "M2V"
 config BOARD_ASUS_M2V_MX_SE
 	bool "M2V-MX SE"
 config BOARD_ASUS_M4A785M
@@ -50,6 +52,7 @@
 
 source "src/mainboard/asus/a8n_e/Kconfig"
 source "src/mainboard/asus/a8v-e_se/Kconfig"
+source "src/mainboard/asus/m2v/Kconfig"
 source "src/mainboard/asus/m2v-mx_se/Kconfig"
 source "src/mainboard/asus/m4a785-m/Kconfig"
 source "src/mainboard/asus/mew-am/Kconfig"
Index: src/mainboard/asus/m2v/acpi_tables.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/acpi_tables.c	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,195 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Written by Stefan Reinauer <stepan at openbios.org>.
+ * ACPI FADT, FACS, and DSDT table support added by
+ *
+ * Copyright (C) 2004 Stefan Reinauer <stepan at openbios.org>
+ * Copyright (C) 2005 Nick Barker <nick.barker9 at btinternet.com>
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek at assembler.cz>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <console/console.h>
+#include <string.h>
+#include <arch/acpi.h>
+#include <arch/smp/mpspec.h>
+#include <arch/ioapic.h>
+#include <device/device.h>
+#include <device/pci_ids.h>
+#include "southbridge/via/vt8237r/vt8237r.h"
+#include "southbridge/via/k8t890/k8t890.h"
+#include "northbridge/amd/amdk8/amdk8_acpi.h"
+#include <cpu/amd/model_fxx_powernow.h>
+
+extern const unsigned char AmlCode[];
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+	device_t dev;
+	struct resource *res;
+
+	dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8T890CF_5, 0);
+	if (!dev)
+		return current;
+
+	res = find_resource(dev, K8T890_MMCONFIG_MBAR);
+	if (res) {
+		current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)
+				current, res->base, 0x0, 0x0, 0xff);
+	}
+	return current;
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+	unsigned int gsi_base = 0x18;
+
+	/* Create all subtables for processors. */
+	current = acpi_create_madt_lapics(current);
+
+	/* Write SB IOAPIC. */
+	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+				VT8237R_APIC_ID, IO_APIC_ADDR, 0);
+
+	/* Write NB IOAPIC. */
+	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+				K8T890_APIC_ID, K8T890_APIC_BASE, gsi_base);
+
+	/* IRQ9 ACPI active low. */
+	current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+		current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW);
+
+	/* IRQ0 -> APIC IRQ2. */
+	current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+						current, 0, 0, 2, 0x0);
+
+	/* Create all subtables for processors. */
+	current = acpi_create_madt_lapic_nmis(current,
+			MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 1);
+
+	return current;
+}
+
+unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id)
+{
+	k8acpi_write_vars();
+	amd_model_fxx_generate_powernow(0, 0, 0);
+	return (unsigned long) (acpigen_get_current());
+}
+
+unsigned long write_acpi_tables(unsigned long start)
+{
+	unsigned long current;
+	acpi_rsdp_t *rsdp;
+	acpi_srat_t *srat;
+	acpi_rsdt_t *rsdt;
+	acpi_mcfg_t *mcfg;
+	acpi_hpet_t *hpet;
+	acpi_madt_t *madt;
+	acpi_fadt_t *fadt;
+	acpi_facs_t *facs;
+	acpi_slit_t *slit;
+	acpi_header_t *ssdt;
+	acpi_header_t *dsdt;
+
+	/* Align ACPI tables to 16 byte. */
+	start = (start + 0x0f) & -0x10;
+	current = start;
+
+	printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", start);
+
+	/* We need at least an RSDP and an RSDT table. */
+	rsdp = (acpi_rsdp_t *) current;
+	current += sizeof(acpi_rsdp_t);
+	rsdt = (acpi_rsdt_t *) current;
+	current += sizeof(acpi_rsdt_t);
+
+	/* Clear all table memory. */
+	memset((void *) start, 0, current - start);
+
+	acpi_write_rsdp(rsdp, rsdt, NULL);
+	acpi_write_rsdt(rsdt);
+
+	/* We explicitly add these tables later on: */
+	printk(BIOS_DEBUG, "ACPI:     * FACS\n");
+
+	/* we should align FACS to 64B as per ACPI specs */
+
+	current = ALIGN(current, 64);
+	facs = (acpi_facs_t *) current;
+	current += sizeof(acpi_facs_t);
+	acpi_create_facs(facs);
+
+	dsdt = (acpi_header_t *) current;
+	memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
+	current += dsdt->length;
+	memcpy(dsdt, &AmlCode, dsdt->length);
+	dsdt->checksum = 0;	/* Don't trust iasl to get this right. */
+	dsdt->checksum = acpi_checksum((u8*)dsdt, dsdt->length);
+	printk(BIOS_DEBUG, "ACPI:     * DSDT @ %p Length %x\n", dsdt,
+		     dsdt->length);
+	printk(BIOS_DEBUG, "ACPI:     * FADT\n");
+
+	fadt = (acpi_fadt_t *) current;
+	current += sizeof(acpi_fadt_t);
+
+	acpi_create_fadt(fadt, facs, dsdt);
+	acpi_add_table(rsdp, fadt);
+
+	printk(BIOS_DEBUG, "ACPI:    * HPET\n");
+	hpet = (acpi_hpet_t *) current;
+	current += sizeof(acpi_hpet_t);
+	acpi_create_hpet(hpet);
+	acpi_add_table(rsdp, hpet);
+
+	/* If we want to use HPET timers Linux wants an MADT. */
+	printk(BIOS_DEBUG, "ACPI:    * MADT\n");
+	madt = (acpi_madt_t *) current;
+	acpi_create_madt(madt);
+	current += madt->header.length;
+	acpi_add_table(rsdp, madt);
+
+	printk(BIOS_DEBUG, "ACPI:    * MCFG\n");
+	mcfg = (acpi_mcfg_t *) current;
+	acpi_create_mcfg(mcfg);
+	current += mcfg->header.length;
+	acpi_add_table(rsdp, mcfg);
+
+	printk(BIOS_DEBUG, "ACPI:    * SRAT\n");
+	srat = (acpi_srat_t *) current;
+	acpi_create_srat(srat);
+	current += srat->header.length;
+	acpi_add_table(rsdp, srat);
+
+	/* SLIT */
+        printk(BIOS_DEBUG, "ACPI:    * SLIT\n");
+        slit = (acpi_slit_t *) current;
+        acpi_create_slit(slit);
+        current+=slit->header.length;
+        acpi_add_table(rsdp,slit);
+
+	/* SSDT */
+	printk(BIOS_DEBUG, "ACPI:    * SSDT\n");
+	ssdt = (acpi_header_t *)current;
+
+	acpi_create_ssdt_generator(ssdt, "DYNADATA");
+	current += ssdt->length;
+	acpi_add_table(rsdp, ssdt);
+
+	printk(BIOS_INFO, "ACPI: done.\n");
+
+	return current;
+}
Index: src/mainboard/asus/m2v/chip.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/chip.h	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek at assembler.cz>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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
+ */
+
+extern struct chip_operations mainboard_ops;
+
+struct mainboard_config {};
Index: src/mainboard/asus/m2v/cmos.layout
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/cmos.layout	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,98 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+395          1       e       1        hw_scrubber
+396          1       e       1        interleave_chip_selects
+397          2       e       8        max_mem_clock
+399         1       e       2        multi_core
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432         8       h       0        boot_countdown
+440          4       e       9        slow_cpu
+444          1       e       1        nmi
+445          1       e       1        iommu
+728        256       h       0        user_data
+984         16       h       0        check_sum
+# Reserve the extended AMD configuration registers
+1000        24       r       0        amd_reserved
+
+
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+8     0     DDR400
+8     1     DDR333
+8     2     DDR266
+8     3     DDR200
+9     0     off
+9     1     87.5%
+9     2     75.0%
+9     3     62.5%
+9     4     50.0%
+9     5     37.5%
+9     6     25.0%
+9     7     12.5%
+
+checksums
+
+checksum 392 983 984
+
+
Index: src/mainboard/asus/m2v/devicetree.cb
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/devicetree.cb	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,74 @@
+chip northbridge/amd/amdk8/root_complex		# Root complex
+  device lapic_cluster 0 on			# APIC cluster
+    chip cpu/amd/socket_AM2			# CPU
+      device lapic 0 on end			# APIC
+    end
+  end
+  device pci_domain 0 on			# PCI domain
+    chip northbridge/amd/amdk8			# mc0
+      device pci 18.0 on			# Northbridge
+        # Devices on link 0, link 0 == LDT 0
+        chip southbridge/via/vt8237r		# Southbridge
+          register "ide0_enable" = "1"		# Enable IDE channel 0
+          register "ide1_enable" = "1"		# Enable IDE channel 1
+          register "ide0_80pin_cable" = "1"	# 80pin cable on IDE channel 0
+          register "ide1_80pin_cable" = "1"	# 80pin cable on IDE channel 1
+          register "fn_ctrl_lo" = "0xc0"	# Enable SB functions
+          register "fn_ctrl_hi" = "0x0d"	# Enable SB functions
+          device pci 0.0 on end			# HT
+          device pci f.1 on end			# IDE
+          device pci 11.0 on			# LPC
+            chip drivers/generic/generic	# DIMM 0-0-0
+              device i2c 50 on end
+            end
+            chip drivers/generic/generic	# DIMM 0-0-1
+              device i2c 51 on end
+            end
+            chip drivers/generic/generic	# DIMM 0-1-0
+              device i2c 52 on end
+            end
+            chip drivers/generic/generic	# DIMM 0-1-1
+              device i2c 53 on end
+            end
+            chip superio/ite/it8712f		# Super I/O
+              device pnp 2e.0 on		# Floppy
+                io 0x60 = 0x3f0
+                irq 0x70 = 6
+                drq 0x74 = 2
+              end
+              device pnp 2e.1 on		# Com1
+                io 0x60 = 0x3f8
+                irq 0x70 = 4
+              end
+              device pnp 2e.2 off end		# Com2 (N/A on this board)
+              device pnp 2e.3 on		# Lpt1
+                io 0x60 = 0x378
+                irq 0x70 = 7
+                drq 0x74 = 3
+              end
+              device pnp 2e.4 on		# Environment controller
+                io 0x60 = 0xd00
+                io 0x62 = 0xc00
+                irq 0x70 = 0x00
+              end
+              device pnp 2e.5 off end		# PS/2 keyboard
+              device pnp 2e.6 off end		# PS/2 mouse
+              device pnp 2e.7 off end		# GPIO config
+              device pnp 2e.8 off end		# Midi port
+              device pnp 2e.9 off end		# Game port
+              device pnp 2e.a off end		# IR
+            end
+          end
+          device pci 12.0 off end		# VIA LAN (off, other chip used)
+          device pci 13.0 on end		# br
+          device pci 13.1 on end		# br2, need to have it here to discover it
+        end
+        chip southbridge/via/k8t890		# "Southbridge" K8T890
+        end
+      end
+      device pci 18.1 on end
+      device pci 18.2 on end
+      device pci 18.3 on end
+    end
+  end
+end
Index: src/mainboard/asus/m2v/dsdt.asl
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/dsdt.asl	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,912 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Nick Barker <Nick.Barker9 at btinternet.com>
+ * Copyright (C) 2007 Rudolf Marek <r.marek at assembler.cz>
+ * Copyright (C) 2010 Tobias Diedrich <ranma+coreboot at tdiedrich.de>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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
+ */
+
+/*
+ * ISA portions taken from QEMU acpi-dsdt.dsl.
+ */
+
+DefinitionBlock ("DSDT.aml", "DSDT", 2, "CORE  ", "COREBOOT", 1)
+{
+	/* Data to be patched by the BIOS during POST */
+	/* FIXME the patching is not done yet! */
+	/* Memory related values */
+	Name(LOMH, 0x0)	/* Start of unused memory in C0000-E0000 range */
+	Name(PBAD, 0x0)	/* Address of BIOS area (If TOM2 != 0, Addr >> 16) */
+	Name(PBLN, 0x0)	/* Length of BIOS area */
+
+	Name(PCBA, 0xE0000000)	/* Base address of PCIe config space */
+	Name(HPBA, 0xFED00000)	/* Base address of HPET table */
+
+	/* global variables */
+	Name(APIC, 0)		// 0=>8259, 1=>IOAPIC
+	Name(LINX, 0)
+	Name(OSYS, 0x0000)
+
+	/* very generic stuff */
+
+	/* Port 80 POST */
+
+	OperationRegion (POST, SystemIO, 0x80, 1)
+	Field (POST, ByteAcc, Lock, Preserve)
+	{
+		DBG0, 8
+	}
+
+	Method (DEBG, 1, NotSerialized)
+	{
+		Store (Arg0, DBG0)
+	}
+
+	Method (MIN, 2, NotSerialized)
+	{
+		If (LLess (Arg0, Arg1)) {
+			Return (Arg0)
+		}
+		Return (Arg1)
+	}
+
+	/* generic acpi */
+
+	/* The _PIC method is called by the OS to choose between interrupt
+	 * routing via the i8259 interrupt controller or the APIC.
+	 *
+	 * _PIC is called with a parameter of 0 for i8259 configuration and
+	 * with a parameter of 1 for Local Apic/IOAPIC configuration.
+	 */
+
+	Method(_PIC, 1)
+	{
+		// Remember the OS' IRQ routing choice.
+		Store(Arg0, APIC)
+	}
+
+	Scope(\_SB)
+	{
+		/* This method is placed on the top level, so we can make sure it's the
+		 * first executed _INI method.
+		 */
+		Method(_INI, 0)
+		{
+			/* Determine the Operating System and save the value in OSYS.
+			 * We have to do this in order to be able to work around
+			 * certain windows bugs.
+			 *
+			 *    OSYS value | Operating System
+			 *    -----------+------------------
+			 *       2000    | Windows 2000
+			 *       2001    | Windows XP(+SP1)
+			 *       2002    | Windows XP SP2
+			 *       2006    | Windows Vista
+			 *       ????    | Windows 7
+			 */
+
+			/* Let's assume we're running at least Windows 2000 */
+			Store (2000, OSYS)
+
+			If (CondRefOf(_OSI, Local0)) {
+				/* Linux answers _OSI with "True" for a couple of
+				 * Windows version queries. But unlike Windows it
+				 * needs a Video repost, so let's determine whether
+				 * we're running Linux.
+				 */
+
+				If (_OSI("Linux")) {
+					Store (1, LINX)
+				}
+
+				If (_OSI("Windows 2001")) {
+					Store (2001, OSYS)
+				}
+
+				If (_OSI("Windows 2001 SP1")) {
+					Store (2001, OSYS)
+				}
+
+				If (_OSI("Windows 2001 SP2")) {
+					Store (2002, OSYS)
+				}
+
+				If (_OSI("Windows 2006")) {
+					Store (2006, OSYS)
+				}
+			}
+		}
+	}
+
+	/* _PR CPU0 is dynamically supplied by SSDT */
+
+	/* For now only define 2 power states:
+	 *  - S0 which is fully on
+	 *  - S5 which is soft off
+	 * Any others would involve declaring the wake up methods.
+	 *
+	 * Package contents:
+	 * ofs len desc
+	 * 0   1   Value for PM1a_CNT.SLP_TYP register to enter this system state.
+	 * 1   1   Value for PM1b_CNT.SLP_TYP register to enter this system state. To enter any
+	 *         given state, OSPM must write the PM1a_CNT.SLP_TYP register before the
+	 *         PM1b_CNT.SLP_TYP register.
+	 * 2   2   Reserved
+	 */
+	Name (\_S0, Package () { 0x00, 0x00, 0x00, 0x00 })
+	Name (\_S5, Package () { 0x02, 0x02, 0x00, 0x00 })
+
+	/*
+	 * Prepare to sleep
+	 *
+	 * Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.)
+	 * Return Value: None
+	 */
+	Method (_PTS, 1, NotSerialized)
+	{
+		// FIXME: Not implemented
+	}
+
+	/*
+	 * Transition to state
+	 *
+	 * Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.)
+	 * Return Value: None
+	 */
+	Method (_TTS, 1, NotSerialized)
+	{
+		// FIXME: Not implemented
+	}
+
+	/*
+	 * System wake
+	 *
+	 * Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.)
+	 * Return Value: A Package containing two Integers containing status and the power supply S-state
+	 *
+	 * Element 0 – An Integer containing a bitfield that represents conditions that occurred during sleep.
+	 *    0x00000000 – Wake was signaled and was successful
+	 *    0x00000001 – Wake was signaled but failed due to lack of power
+	 *    0x00000002 – Wake was signaled but failed due to thermal condition
+	 *    Other values – Reserved
+	 * Element 1 – An Integer containing the power supply S-state.
+	 *    If non-zero, this is the effective S-state the power supply that was actually entered. This value is used
+	 *    to detect when the targeted S-state was not entered because of too much current being drawn from the
+	 *    power supply. For example, this might occur when some active device’s current consumption pushes
+	 *    the system’s power requirements over the low power supply mark, thus preventing the lower power
+	 *    mode from being entered as desired.
+	 */
+	Method (_WAK, 1, NotSerialized)
+	{
+		// FIXME: Not implemented
+		Return ( Package () {0x00, 0x00} ) /* successful, S0 */
+	}
+
+/*
+OSPM will invoke _GTS, _PTS, _TTS, _WAK, and _BFS in the following order:
+   1. OSPM decides (through a policy scheme) to place the system into a sleeping state
+   2. _TTS(Sx) is run, where Sx is the desired sleep state to enter
+   3. OSPM notifies all native device drivers of the sleep state transition
+   4. _PTS is run
+   5. OSPM readies system for the sleep state transition
+   6. _GTS is run
+   7. OSPM writes the sleep vector and the system enters the specified Sx sleep state
+   8. System Wakes up
+   9. _BFS is run
+   10. OSPM readies system for the return from the sleep state transition
+   11. _WAK is run
+   12. OSPM notifies all native device drivers of the return from the sleep state transition
+   13. _TTS(0) is run to indicate the return to the S0 state
+*/
+
+	/* Root of the bus hierarchy */
+	Scope (\_SB)
+	{
+		/* Top PCI device */
+		Device (PCI0)
+		{
+			Name (_HID, EisaId ("PNP0A03"))
+			Name (_ADR, 0x00180000)
+			Name (_BBN, 0x00)
+
+			Name (APR0, Package() {
+				/* ?? */
+				Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x10 },
+				Package (0x04) { 0x0001FFFF, 0x01, 0x00, 0x11 },
+				Package (0x04) { 0x0001FFFF, 0x02, 0x00, 0x12 },
+				Package (0x04) { 0x0001FFFF, 0x03, 0x00, 0x13 },
+				/* PCIe graphics bridge */
+				Package (0x04) { 0x0002FFFF, 0x00, 0x00, 0x1B },
+				Package (0x04) { 0x0002FFFF, 0x01, 0x00, 0x1B },
+				Package (0x04) { 0x0002FFFF, 0x02, 0x00, 0x1B },
+				Package (0x04) { 0x0002FFFF, 0x03, 0x00, 0x1B },
+				/* PCIe bridge */
+				Package (0x04) { 0x0003FFFF, 0x00, 0x00, 0x1F },
+				Package (0x04) { 0x0003FFFF, 0x01, 0x00, 0x23 },
+				Package (0x04) { 0x0003FFFF, 0x02, 0x00, 0x27 },
+				Package (0x04) { 0x0003FFFF, 0x03, 0x00, 0x2B },
+				/* SATA */
+				Package (0x04) { 0x000FFFFF, 0x01, 0x00, 0x15 },
+				/* IDE */
+				Package (0x04) { 0x000FFFFF, 0x00, 0x00, 0x15 },
+				/* USB */
+				Package (0x04) { 0x0010FFFF, 0x00, 0x00, 0x14 },
+				Package (0x04) { 0x0010FFFF, 0x01, 0x00, 0x16 },
+				Package (0x04) { 0x0010FFFF, 0x02, 0x00, 0x15 },
+				Package (0x04) { 0x0010FFFF, 0x03, 0x00, 0x17 },
+				/* PCI bridge */
+				Package (0x04) { 0x0013FFFF, 0x00, 0x00, 0x14 },
+				Package (0x04) { 0x0013FFFF, 0x01, 0x00, 0x14 },
+				Package (0x04) { 0x0013FFFF, 0x02, 0x00, 0x14 },
+				Package (0x04) { 0x0013FFFF, 0x03, 0x00, 0x14 },
+			})
+			Name (PPR0, Package() {
+				/* ?? */
+				Package (0x04) { 0x0001FFFF, 0x00, LNKA, 0x00 },
+				Package (0x04) { 0x0001FFFF, 0x01, LNKB, 0x00 },
+				Package (0x04) { 0x0001FFFF, 0x02, LNKC, 0x00 },
+				Package (0x04) { 0x0001FFFF, 0x03, LNKD, 0x00 },
+				/* PCIe graphics bridge */
+				Package (0x04) { 0x0002FFFF, 0x00, LNKH, 0x00 },
+				Package (0x04) { 0x0002FFFF, 0x01, LNKH, 0x00 },
+				Package (0x04) { 0x0002FFFF, 0x02, LNKH, 0x00 },
+				Package (0x04) { 0x0002FFFF, 0x03, LNKH, 0x00 },
+				/* PCIe bridge */
+				Package (0x04) { 0x0003FFFF, 0x00, LNKH, 0x00 },
+				Package (0x04) { 0x0003FFFF, 0x01, LNKH, 0x00 },
+				Package (0x04) { 0x0003FFFF, 0x02, LNKH, 0x00 },
+				Package (0x04) { 0x0003FFFF, 0x03, LNKH, 0x00 },
+				/* SATA */
+				Package (0x04) { 0x000FFFFF, 0x01, LNKB, 0x00 },
+				/* USB */
+				Package (0x04) { 0x0010FFFF, 0x00, LNKA, 0x00 },
+				Package (0x04) { 0x0010FFFF, 0x01, LNKB, 0x00 },
+				Package (0x04) { 0x0010FFFF, 0x02, LNKC, 0x00 },
+				Package (0x04) { 0x0010FFFF, 0x03, LNKD, 0x00 },
+				/* PCI bridge */
+				Package (0x04) { 0x0013FFFF, 0x00, LNKD, 0x00 },
+				Package (0x04) { 0x0013FFFF, 0x01, LNKD, 0x00 },
+				Package (0x04) { 0x0013FFFF, 0x02, LNKD, 0x00 },
+				Package (0x04) { 0x0013FFFF, 0x03, LNKD, 0x00 },
+			})
+
+			/* PCI Routing Table */
+			Method (_PRT, 0, NotSerialized)
+			{
+				If (APIC)
+				{
+					Return (APR0)
+				}
+				Return (PPR0)
+			}
+
+			Device (K8T0) { Name (_ADR, 0x00000000) }
+			Device (K8T1) { Name (_ADR, 0x00000001) }
+			Device (K8T2) { Name (_ADR, 0x00000002) }
+			Device (K8T3) { Name (_ADR, 0x00000003) }
+			Device (K8T4) { Name (_ADR, 0x00000004) }
+			Device (K8T5) { Name (_ADR, 0x00000005) }
+			Device (K8T6) { Name (_ADR, 0x00000006) }
+			Device (K8T7) { Name (_ADR, 0x00000007) }
+
+			Device (PCI1) { Name (_ADR, 0x00010000) }
+
+			Device (PEGG)
+			{
+				Name (_ADR, 0x00020000)
+				Name (_PRT, Package () {
+					Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x18 }, /* PCIE IRQ24-IRQ27 */
+					Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x19 },
+					Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x1A },
+					Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x1B },
+				})
+			}
+
+			Device (PEX0)
+			{
+				Name (_ADR, 0x00030000)
+				Name (_PRT, Package () {
+					Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x1C }, /* PCIE IRQ28-IRQ31 */
+					Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x1D },
+					Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x1E },
+					Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x1F },
+				})
+			}
+
+			Device (PEX1)
+			{
+				Name (_ADR, 0x00030001)
+				Name (_PRT, Package () {
+					Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x20 }, /* PCIE IRQ32-IRQ35 */
+					Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x21 },
+					Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x22 },
+					Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x23 },
+				})
+			}
+
+			Device (PEX2)
+			{
+				Name (_ADR, 0x00030002)
+				Name (_PRT, Package () {
+					Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x24 }, /* PCIE IRQ36-IRQ39 */
+					Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x25 },
+					Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x26 },
+					Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x27 },
+				})
+			}
+
+			Device (PEX3)
+			{
+				Name (_ADR, 0x00030003)
+				Name (_PRT, Package () {
+					Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x28 }, /* PCIE IRQ40-IRQ43 */
+					Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x29 },
+					Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x2A },
+					Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x2B },
+				})
+			}
+
+			Device (SATA) { Name (_ADR, 0x000f0000) }
+			Device (PATA) { Name (_ADR, 0x000f0001) }
+
+			Device (PCI7)
+			{
+				Name (_ADR, 0x00130000)
+				Name (_PRT, Package () {
+					Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x11 }, /* IRQ17 */
+				})
+			}
+
+			Device (PCI8)
+			{
+				Name (_ADR, 0x00130001)
+				Name (APR8, Package () {
+					/* PCI slot 1 */
+					Package (0x04) { 0x0006FFFF, 0x00, 0x00, 0x10 },
+					Package (0x04) { 0x0006FFFF, 0x01, 0x00, 0x11 },
+					Package (0x04) { 0x0006FFFF, 0x02, 0x00, 0x12 },
+					Package (0x04) { 0x0006FFFF, 0x03, 0x00, 0x13 },
+
+					/* PCI slot 2 */
+					Package (0x04) { 0x0007FFFF, 0x00, 0x00, 0x11 },
+					Package (0x04) { 0x0007FFFF, 0x01, 0x00, 0x12 },
+					Package (0x04) { 0x0007FFFF, 0x02, 0x00, 0x13 },
+					Package (0x04) { 0x0007FFFF, 0x03, 0x00, 0x10 },
+
+					/* PCI slot 3 */
+					Package (0x04) { 0x0008FFFF, 0x00, 0x00, 0x12 },
+					Package (0x04) { 0x0008FFFF, 0x01, 0x00, 0x13 },
+					Package (0x04) { 0x0008FFFF, 0x02, 0x00, 0x10 },
+					Package (0x04) { 0x0008FFFF, 0x03, 0x00, 0x11 },
+
+					/* PCI slot 4 */
+					Package (0x04) { 0x0009FFFF, 0x00, 0x00, 0x13 },
+					Package (0x04) { 0x0009FFFF, 0x01, 0x00, 0x10 },
+					Package (0x04) { 0x0009FFFF, 0x02, 0x00, 0x11 },
+					Package (0x04) { 0x0009FFFF, 0x03, 0x00, 0x12 },
+				})
+				Name (PPR8, Package () {
+					/* PCI slot 1 */
+					Package (0x04) { 0x0006FFFF, 0x00, LNKA, 0x00 },
+					Package (0x04) { 0x0006FFFF, 0x01, LNKB, 0x00 },
+					Package (0x04) { 0x0006FFFF, 0x02, LNKC, 0x00 },
+					Package (0x04) { 0x0006FFFF, 0x03, LNKD, 0x00 },
+
+					/* PCI slot 2 */
+					Package (0x04) { 0x0007FFFF, 0x00, LNKB, 0x00 },
+					Package (0x04) { 0x0007FFFF, 0x01, LNKC, 0x00 },
+					Package (0x04) { 0x0007FFFF, 0x02, LNKD, 0x00 },
+					Package (0x04) { 0x0007FFFF, 0x03, LNKA, 0x00 },
+
+					/* PCI slot 3 */
+					Package (0x04) { 0x0008FFFF, 0x00, LNKC, 0x00 },
+					Package (0x04) { 0x0008FFFF, 0x01, LNKD, 0x00 },
+					Package (0x04) { 0x0008FFFF, 0x02, LNKA, 0x00 },
+					Package (0x04) { 0x0008FFFF, 0x03, LNKB, 0x00 },
+
+					/* PCI slot 4 */
+					Package (0x04) { 0x0009FFFF, 0x00, LNKD, 0x00 },
+					Package (0x04) { 0x0009FFFF, 0x01, LNKA, 0x00 },
+					Package (0x04) { 0x0009FFFF, 0x02, LNKB, 0x00 },
+					Package (0x04) { 0x0009FFFF, 0x03, LNKC, 0x00 },
+				})
+
+				Method (_PRT, 0, NotSerialized)
+				{
+					If (APIC)
+					{
+						Return (APR8)
+					}
+					Return (PPR8)
+				}
+			}
+
+			Device (PCIE)
+			{
+				Name (_HID, EisaId ("PNP0C02"))
+				Method (_CRS, 0, NotSerialized)
+				{
+					Name (TMP, ResourceTemplate () {
+						Memory32Fixed(ReadOnly,
+							0xE0000000,
+							0x10000000,
+						)
+					})
+					Return (TMP)
+				}
+			}
+
+			Device (SBRG) { /* southbridge */
+				Name (_ADR, 0x00110000)
+				Device (HPET) {
+					Name (_HID, EisaId ("PNP0103"))
+					Method (_STA, 0, NotSerialized)
+					{
+						Return (0x0F)
+					}
+					Method (_CRS, 0, NotSerialized)
+					{
+						Name (TMP, ResourceTemplate () {
+							Memory32Fixed(ReadOnly,
+								0xFED00000,
+								0x00000400,
+							)
+							IRQNoFlags () {0}
+							IRQNoFlags () {8}
+						})
+						Return (TMP)
+					}
+				}
+
+				/* PS/2 keyboard (seems to be important for WinXP install) */
+				Device (KBD)
+				{
+					Name (_HID, EisaId ("PNP0303"))
+					Method (_STA, 0, NotSerialized)
+					{
+						Return (0x0f)
+					}
+					Method (_CRS, 0, NotSerialized)
+					{
+						Name (TMP, ResourceTemplate () {
+							IO (Decode16, 0x0060, 0x0060, 0x01, 0x01)
+							IO (Decode16, 0x0064, 0x0064, 0x01, 0x01)
+							IRQNoFlags () {1}
+						})
+						Return (TMP)
+					}
+				}
+
+				/* PS/2 mouse */
+				Device (MOU)
+				{
+					Name (_HID, EisaId ("PNP0F13"))
+					Method (_STA, 0, NotSerialized)
+					{
+						Return (0x0f)
+					}
+					Method (_CRS, 0, NotSerialized)
+					{
+						Name (TMP, ResourceTemplate () {
+						     IRQNoFlags () {12}
+						})
+						Return (TMP)
+					}
+				}
+
+				/* Parallel port */
+				Device (LPT0)
+				{
+					Name (_HID, EisaId ("PNP0401"))
+					Method (_STA, 0, NotSerialized)
+					{
+						Return (0x0f)
+					}
+					Method (_CRS, 0, NotSerialized)
+					{
+						Name (TMP, ResourceTemplate () {
+							IO (Decode16, 0x0378, 0x0378, 0x01, 0x08)
+							IO (Decode16, 0x0778, 0x0778, 0x01, 0x08)
+							IRQNoFlags () {7}
+							DMA (Compatibility, NotBusMaster, Transfer8) {3}
+						})
+						Return (TMP)
+					}
+				}
+			}
+
+			Name(CRES, ResourceTemplate() {
+				WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
+					0x0000,             // Granularity
+					0x0000,             // Range Minimum
+					0x00FF,             // Range Maximum
+					0x0000,             // Translation Offset
+					0x0100,             // Length
+					,,
+				)
+				IO(Decode16, 0x0CF8, 0x0CF8, 1,	8)
+
+				WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+					0x0000,			/* address granularity */
+					0x0000,			/* range minimum */
+					0x0CF7,			/* range maximum */
+					0x0000,			/* translation */
+					0x0CF8			/* length */
+				)
+
+				WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+					0x0000,			/* address granularity */
+					0x0D00,			/* range minimum */
+					0xFFFF,			/* range maximum */
+					0x0000,			/* translation */
+					0xF300			/* length */
+				)
+
+				Memory32Fixed(READWRITE, 0, 0xA0000, BSMM)
+				Memory32Fixed(READONLY, 0x000A0000, 0x00020000, VGAM) 	/* VGA memory space */
+				Memory32Fixed(READONLY, 0x000C0000, 0x00020000, EMM1)	/* Assume C0000-E0000 empty */
+				Memory32Fixed(READONLY, 0x000E0000, 0x00020000, RDBS)   /* BIOS ROM area */
+				/* DRAM Memory from 1MB to TopMem */
+				Memory32Fixed(READWRITE, 0x00100000, 0x00000000, DMLO)  /* 1MB to TopMem */
+				Memory32Fixed(ReadOnly, 0xE0000000, 0x10000000, MCFG)   /* MMCONFIG area */
+				Memory32Fixed(READONLY, 0xF0000000, 0x10000000, MMIO)   /* PCI mapping space */
+
+#if 0
+				/* BIOS space just below 4GB */
+				DWORDMemory(
+					ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+					0x00,			/* Granularity */
+					0x00000000,		/* Min */
+					0x00000000,		/* Max */
+					0x00000000,		/* Translation */
+					0x00000001,		/* Max-Min, RLEN */
+					,,
+					PCBM
+				)
+
+				/* BIOS space just below 16EB */
+				QWORDMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+					0x00000000,		/* Granularity */
+					0x00000000,		/* Min */
+					0x00000000,		/* Max */
+					0x00000000,		/* Translation */
+					0x00000001,		/* Max-Min, RLEN */
+					,,
+					PEBM
+				)
+#endif
+
+				/* DRAM memory from 4GB to TopMem2 */
+				QWORDMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+					0x00000000,		/* Granularity */
+					0x00000000,		/* Min */
+					0x00000000,		/* Max */
+					0x00000000,		/* Translation */
+					0x00000001,		/* Max-Min, RLEN */
+					,,
+					DMHI
+				)
+
+			}) /* End Name(_SB.PCI0.CRES) */
+
+			External(TOM1) /* 32bit top of memory from SSDT */
+			External(TOM2) /* 64bit top of memory from SSDT */
+
+			Method(_CRS, 0) {
+				/* DBGO("\\_SB\\PCI0\\_CRS\n") */
+
+				CreateDWordField(CRES, ^EMM1._BAS, EM1B)
+				CreateDWordField(CRES, ^EMM1._LEN, EM1L)
+				CreateDWordField(CRES, ^DMLO._BAS, DMLB)
+				CreateDWordField(CRES, ^DMLO._LEN, DMLL)
+#if 0
+				CreateDWordField(CRES, ^PCBM._MIN, PBMB)
+				CreateDWordField(CRES, ^PCBM._LEN, PBML)
+				CreateQWordField(CRES, ^PEBM._MIN, EBMB)
+				CreateQWordField(CRES, ^PEBM._LEN, EBML)
+#endif
+
+				CreateQWordField(CRES, ^DMHI._MIN, DMHB)
+				CreateQWordField(CRES, ^DMHI._MAX, DMHT)
+				CreateQWordField(CRES, ^DMHI._LEN, DMHL)
+
+//				If(LGreater(LOMH, 0xC0000)){
+//					Store(0xC0000, EM1B)	/* Hole above C0000 and below E0000 */
+//					Subtract(LOMH, 0xC0000, EM1L)	/* subtract start, assumes allocation from C0000 going up */
+//				}
+
+				/* Set size of memory from 1MB to TopMem */
+				Subtract(TOM1, 0x100000, DMLL)
+
+				If(LNotEqual(TOM2, 0x00000000)){
+					Store(0x100000000,DMHB)		/* DRAM from 4GB to TopMem2 */
+					Store(TOM2,DMHT)
+					Subtract(TOM2, 0x100000000, DMHL)
+				}
+
+//				/* If there is no memory above 4GB, put the BIOS just below 4GB */
+//				If(LEqual(TOM2, 0x00000000)){
+//					Store(PBAD,PBMB)			/* Reserve the "BIOS" space */
+//					Store(PBLN,PBML)
+//				}
+//				Else {  /* Otherwise, put the BIOS just below 16EB */
+//					ShiftLeft(PBAD,16,EBMB)		/* Reserve the "BIOS" space */
+//					Store(PBLN,EBML)
+//				}
+
+				Return(CRES) /* note to change the Name buffer */
+			}  /* end of Method(_SB.PCI0._CRS) */
+		}
+	}
+
+	Scope (\_SB)
+	{
+		OperationRegion (PCI0.SBRG.PIX0, PCI_Config, 0x55, 0x04)
+		OperationRegion (PCI0.SBRG.PIX1, PCI_Config, 0x50, 0x02)
+		OperationRegion (PCI0.SBRG.PIX2, PCI_Config, 0x44, 0x02)
+		OperationRegion (PCI0.SBRG.PIX3, PCI_Config, 0x67, 0x03)
+		OperationRegion (PCI0.SBRG.PIX4, PCI_Config, 0x6C, 0x04)
+		OperationRegion (PCI0.SBRG.PIEF, PCI_Config, 0x46, 0x01)
+		Field (PCI0.SBRG.PIX0, ByteAcc, NoLock, Preserve)
+		{
+			    , 4,
+			PIRA, 4,
+			PIRB, 4,
+			PIRC, 4,
+			    , 4,
+			PIRD, 4,
+			    , 4
+		}
+		Field (PCI0.SBRG.PIX1, ByteAcc, NoLock, Preserve)
+		{
+			    , 1,
+			EP3C, 1,
+			EN3C, 1,
+			    , 6,
+			KBFG, 1
+		}
+		Field (PCI0.SBRG.PIX2, ByteAcc, NoLock, Preserve)
+		{
+			PIRE, 4,
+			PIRF, 4,
+			PIRG, 4,
+			PIRH, 4,
+		}
+		Field (PCI0.SBRG.PIX3, ByteAcc, NoLock, Preserve)
+		{
+			ENIR, 1,
+			IRSD, 1,
+			Offset (0x02),
+			IRBA, 8
+		}
+		Field (PCI0.SBRG.PIX4, ByteAcc, NoLock, Preserve)
+		{
+			PS0E, 1,
+			PS1E, 1,
+			ROME, 1,
+			APCE, 1,
+			LPMS, 2,
+			MSEN, 1,
+			IXEN, 1,
+			LPMD, 2,
+			MDEN, 1,
+			GMEN, 1,
+			LPLP, 2,
+			LPEN, 1,
+			FDEN, 1,
+			LPCA, 3,
+			CAEN, 1,
+			LPCB, 3,
+			CBEN, 1,
+			LPSB, 2,
+			SBEN, 1,
+			FDSE, 1,
+			Offset (0x04)
+		}
+		Field (PCI0.SBRG.PIEF, ByteAcc, NoLock, Preserve)
+		{
+			POLE, 1,
+			POLF, 1,
+			POLG, 1,
+			POLH, 1,
+			ENR8, 1
+		}
+		Name (IRQA, 0x00)
+		Name (IRQB, 0x00)
+		Name (IRQC, 0x00)
+		Name (IRQD, 0x00)
+		Name (IRQE, 0x00)
+		Name (IRQF, 0x00)
+		Name (IRQG, 0x00)
+		Name (IRQH, 0x00)
+		Name (ICRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, ) {15} } )
+		Name (IPRS, ResourceTemplate () {
+			IRQ (Level, ActiveLow, Shared, ) {3,4,5,6,7,10,11,12,14,15}
+		})
+
+		Device (LNKA)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x01)
+			Method (_PRS, 0, NotSerialized) { Return (IPRS) }
+			Method (_STA, 0, NotSerialized)
+			{
+				Store (PIRA, IRQA)
+				If (PIRA) {
+					Return (0x0B)
+				} Else {
+					Return (0x09)
+				}
+			}
+			Method (_DIS, 0, NotSerialized)
+			{
+				Store (Zero, PIRA)
+			}
+			Method (_CRS, 0, NotSerialized)
+			{
+				CreateWordField (ICRS, One, IRA0)
+				Store (One, Local1)
+				ShiftLeft (Local1, IRQA, IRA0)
+				Return (ICRS)
+			}
+			Method (_SRS, 1, NotSerialized)
+			{
+				CreateWordField (Arg0, One, IRA)
+				FindSetRightBit (IRA, Local0)
+				Decrement (Local0)
+				Store (Local0, PIRA)
+				Store (PIRA, IRQA)
+			}
+		}
+		Device (LNKB)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x02)
+			Method (_PRS, 0, NotSerialized) { Return (IPRS) }
+			Method (_STA, 0, NotSerialized)
+			{
+				Store (PIRB, IRQB)
+				If (PIRB) {
+					Return (0x0B)
+				} Else {
+					Return (0x09)
+				}
+			}
+			Method (_DIS, 0, NotSerialized)
+			{
+				Store (Zero, PIRB)
+			}
+			Method (_CRS, 0, NotSerialized)
+			{
+				CreateWordField (ICRS, One, IRB0)
+				Store (One, Local1)
+				ShiftLeft (Local1, IRQB, IRB0)
+				Return (ICRS)
+			}
+			Method (_SRS, 1, NotSerialized)
+			{
+				CreateWordField (Arg0, One, IRA)
+				FindSetRightBit (IRA, Local0)
+				Decrement (Local0)
+				Store (Local0, PIRB)
+				Store (PIRB, IRQB)
+			}
+		}
+		Device (LNKC)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x03)
+			Method (_PRS, 0, NotSerialized) { Return (IPRS) }
+			Method (_STA, 0, NotSerialized)
+			{
+				Store (PIRC, IRQC)
+				If (PIRC) {
+					Return (0x0B)
+				} Else {
+					Return (0x09)
+				}
+			}
+			Method (_DIS, 0, NotSerialized)
+			{
+				Store (Zero, PIRC)
+			}
+			Method (_CRS, 0, NotSerialized)
+			{
+				CreateWordField (ICRS, One, IRB0)
+				Store (One, Local1)
+				ShiftLeft (Local1, IRQC, IRB0)
+				Return (ICRS)
+			}
+			Method (_SRS, 1, NotSerialized)
+			{
+				CreateWordField (Arg0, One, IRA)
+				FindSetRightBit (IRA, Local0)
+				Decrement (Local0)
+				Store (Local0, PIRC)
+				Store (PIRC, IRQC)
+			}
+		}
+		Device (LNKD)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x04)
+			Method (_PRS, 0, NotSerialized) { Return (IPRS) }
+			Method (_STA, 0, NotSerialized)
+			{
+				Store (PIRD, IRQD)
+				If (PIRD) {
+					Return (0x0B)
+				} Else {
+					Return (0x09)
+				}
+			}
+			Method (_DIS, 0, NotSerialized)
+			{
+				Store (Zero, PIRD)
+			}
+			Method (_CRS, 0, NotSerialized)
+			{
+				CreateWordField (ICRS, One, IRB0)
+				Store (One, Local1)
+				ShiftLeft (Local1, IRQD, IRB0)
+				Return (ICRS)
+			}
+			Method (_SRS, 1, NotSerialized)
+			{
+				CreateWordField (Arg0, One, IRA)
+				FindSetRightBit (IRA, Local0)
+				Decrement (Local0)
+				Store (Local0, PIRD)
+				Store (PIRD, IRQD)
+			}
+		}
+		Device (LNKH)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x08)
+			Method (_PRS, 0, NotSerialized) { Return (IPRS) }
+			Method (_STA, 0, NotSerialized)
+			{
+				Store (PIRH, IRQH)
+				If (PIRH) {
+					Return (0x0B)
+				} Else {
+					Return (0x09)
+				}
+			}
+			Method (_DIS, 0, NotSerialized)
+			{
+				Store (Zero, PIRH)
+			}
+			Method (_CRS, 0, NotSerialized)
+			{
+				CreateWordField (ICRS, One, IRA0)
+				Store (One, Local1)
+				ShiftLeft (Local1, IRQH, IRA0)
+				Return (ICRS)
+			}
+			Method (_SRS, 1, NotSerialized)
+			{
+				CreateWordField (Arg0, One, IRA)
+				FindSetRightBit (IRA, Local0)
+				Decrement (Local0)
+				Store (Local0, PIRH)
+				Store (PIRH, IRQH)
+				Store (One, ENR8)
+			}
+		}
+	}
+}
Index: src/mainboard/asus/m2v/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/Kconfig	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,84 @@
+if BOARD_ASUS_M2V
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+	select ARCH_X86
+	select CPU_AMD_SOCKET_AM2
+	select DIMM_DDR2
+	select K8_HT_FREQ_1G_SUPPORT
+	select NORTHBRIDGE_AMD_AMDK8
+	select NORTHBRIDGE_AMD_AMDK8_ROOT_COMPLEX
+	select SOUTHBRIDGE_VIA_VT8237R
+	select SOUTHBRIDGE_VIA_K8T890
+	select SUPERIO_ITE_IT8712F
+	select CACHE_AS_RAM
+	select HAVE_OPTION_TABLE
+	select HAVE_ACPI_TABLES
+	select HAVE_MP_TABLE
+	select HAVE_PIRQ_TABLE
+	select HAVE_MAINBOARD_RESOURCES
+	select BOARD_ROMSIZE_KB_512
+	select RAMINIT_SYSINFO
+	select TINY_BOOTBLOCK
+
+config MAINBOARD_DIR
+	string
+	default asus/m2v
+
+config DCACHE_RAM_BASE
+	hex
+	default 0xcc000
+
+config DCACHE_RAM_SIZE
+	hex
+	default 0x4000
+
+config DCACHE_RAM_GLOBAL_VAR_SIZE
+	hex
+	default 0x1000
+
+config APIC_ID_OFFSET
+	hex
+	default 0x10
+
+config SB_HT_CHAIN_ON_BUS0
+	int
+	default 1
+
+config MAINBOARD_PART_NUMBER
+	string
+	default "M2V"
+
+config HW_MEM_HOLE_SIZEK
+	hex
+	default 0
+
+config MAX_CPUS
+	int
+	default 2
+
+config MAX_PHYSICAL_CPUS
+	int
+	default 1
+
+config HEAP_SIZE
+	hex
+	default 0x40000
+
+config HT_CHAIN_END_UNITID_BASE
+	hex
+	default 0x20
+
+config HT_CHAIN_UNITID_BASE
+	hex
+	default 0x0
+
+config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+	hex
+	default 0x1043
+
+config IRQ_SLOT_COUNT
+	int
+	default 17
+
+endif # BOARD_ASUS_M2V
Index: src/mainboard/asus/m2v/mainboard.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/mainboard.c	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Wang Qing Pei <wangqingpei at gmail.com>
+ * Copyright (C) 2010 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 as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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 <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <boot/tables.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/mtrr.h>
+#include <device/pci_def.h>
+#include "southbridge/via/vt8237r/vt8237r.h"
+#include "southbridge/via/k8t890/k8t890.h"
+#include "chip.h"
+
+#define SMBUS_IO_BASE 0x6000
+
+uint64_t uma_memory_base, uma_memory_size;
+
+/*
+ * FIXME do we need to touch GPIOs to derest PEG/PEX slots?
+ ***/
+static void set_pcie_dereset(void)
+{
+}
+
+static void m2v_enable(device_t dev)
+{
+	printk(BIOS_INFO, "Mainboard M2V Enable. dev=0x%p\n", dev);
+
+	set_pcie_dereset();
+	/* get_ide_dma66(); */
+}
+
+int add_mainboard_resources(struct lb_memory *mem)
+{
+	printk(BIOS_INFO, "Adding APIC + BIOS reserved memory resources\n");
+	/*
+	 * Mark APIC memory as reserved to get closer to ASUS E820 map
+	 */
+	lb_add_memory_range(mem, LB_MEM_RESERVED, IO_APIC_ADDR,     0x1000);
+	lb_add_memory_range(mem, LB_MEM_RESERVED, K8T890_APIC_BASE, 0x1000);
+	/*
+	 * Mark BIOS ROM space as reserved
+	 */
+	lb_add_memory_range(mem, LB_MEM_RESERVED, 0xffc00000, 0x400000);
+	return 0;
+}
+
+struct chip_operations mainboard_ops = {
+	CHIP_NAME("ASUS M2V")
+	.enable_dev = m2v_enable,
+};
Index: src/mainboard/asus/m2v/mptable.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/mptable.c	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,169 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek at assembler.cz>
+ * Copyright (C) 2010 Tobias Diedrich <ranma+coreboot at tdiedrich.de>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <string.h>
+#include <stdint.h>
+#include <arch/smp/mpspec.h>
+#include <arch/ioapic.h>
+#include "southbridge/via/vt8237r/vt8237r.h"
+#include "southbridge/via/k8t890/k8t890.h"
+
+static void *smp_write_config_table(void *v)
+{
+	static const char sig[4] = "PCMP";
+	static const char oem[8] = "COREBOOT";
+	static const char productid[12] = "M2V         ";
+	struct mp_config_table *mc;
+	int bus_isa = 42;
+
+	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+	memset(mc, 0, sizeof(*mc));
+
+	memcpy(mc->mpc_signature, sig, sizeof(sig));
+	mc->mpc_length = sizeof(*mc); /* Initially just the header. */
+	mc->mpc_spec = 0x04;
+	mc->mpc_checksum = 0; /* Not yet computed. */
+	memcpy(mc->mpc_oem, oem, sizeof(oem));
+	memcpy(mc->mpc_productid, productid, sizeof(productid));
+	mc->mpc_oemptr = 0;
+	mc->mpc_oemsize = 0;
+	mc->mpc_entry_count = 0; /* No entries yet. */
+	mc->mpc_lapic = LAPIC_ADDR;
+	mc->mpe_length = 0;
+	mc->mpe_checksum = 0;
+	mc->reserved = 0;
+
+	smp_write_processors(mc);
+
+	/* Bus:		Bus ID	Type */
+	smp_write_bus(mc, 0, "PCI   "); /* root bus */
+	smp_write_bus(mc, 1, "PCI   "); /* ??? */
+	smp_write_bus(mc, 2, "PCI   "); /* pcie x16 */
+	smp_write_bus(mc, 3, "PCI   "); /* pcie x1 */
+	smp_write_bus(mc, 4, "PCI   "); /* pcie x1 */
+	smp_write_bus(mc, 5, "PCI   "); /* pcie x1 */
+	smp_write_bus(mc, 6, "PCI   "); /* pcie x1 */
+	smp_write_bus(mc, 7, "PCI   "); /* azalia audio */
+	smp_write_bus(mc, 8, "PCI   "); /* pci */
+	smp_write_bus(mc, bus_isa, "ISA   ");
+
+	/* I/O APICs:	APIC ID	Version	State		Address */
+	smp_write_ioapic(mc, VT8237R_APIC_ID, 0x3, IO_APIC_ADDR);
+	smp_write_ioapic(mc, K8T890_APIC_ID, 0x3, K8T890_APIC_BASE);
+
+	mptable_add_isa_interrupts(mc, bus_isa, VT8237R_APIC_ID, 0);
+
+	/* peg bridge */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x2 << 2) | 0, K8T890_APIC_ID, 0x3);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x2 << 2) | 1, K8T890_APIC_ID, 0x3);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x2 << 2) | 2, K8T890_APIC_ID, 0x3);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x2 << 2) | 3, K8T890_APIC_ID, 0x3);
+
+	/* pex bridge */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x3 << 2) | 0, K8T890_APIC_ID, 0x7);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x3 << 2) | 1, K8T890_APIC_ID, 0xb);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x3 << 2) | 2, K8T890_APIC_ID, 0xf);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x3 << 2) | 3, K8T890_APIC_ID, 0x13);
+
+	/* SATA / IDE */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0xf << 2) | 0, VT8237R_APIC_ID, 0x15);
+
+	/* USB */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x10 << 2) | 0, VT8237R_APIC_ID, 0x14);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x10 << 2) | 1, VT8237R_APIC_ID, 0x16);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x10 << 2) | 2, VT8237R_APIC_ID, 0x15);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0,  (0x10 << 2) | 3, VT8237R_APIC_ID, 0x17);
+
+	/* PCIE graphics */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x2,  (0x00 << 2) | 0, K8T890_APIC_ID, 0x0);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x2,  (0x00 << 2) | 1, K8T890_APIC_ID, 0x1);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x2,  (0x00 << 2) | 2, K8T890_APIC_ID, 0x2);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x2,  (0x00 << 2) | 3, K8T890_APIC_ID, 0x3);
+
+	/* onboard PCIE atl1 ethernet */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x3,  (0x00 << 2) | 0, K8T890_APIC_ID, 0x4);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x3,  (0x00 << 2) | 1, K8T890_APIC_ID, 0x5);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x3,  (0x00 << 2) | 2, K8T890_APIC_ID, 0x6);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x3,  (0x00 << 2) | 3, K8T890_APIC_ID, 0x7);
+
+	/* PCIE slot */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x4,  (0x00 << 2) | 0, K8T890_APIC_ID, 0x8);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x4,  (0x00 << 2) | 1, K8T890_APIC_ID, 0x9);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x4,  (0x00 << 2) | 2, K8T890_APIC_ID, 0xa);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x4,  (0x00 << 2) | 3, K8T890_APIC_ID, 0xb);
+
+	/* onboard marvell sata */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x5,  (0x00 << 2) | 0, K8T890_APIC_ID, 0xc);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x5,  (0x00 << 2) | 1, K8T890_APIC_ID, 0xd);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x5,  (0x00 << 2) | 2, K8T890_APIC_ID, 0xe);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x5,  (0x00 << 2) | 3, K8T890_APIC_ID, 0xf);
+
+	/* n/a */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x6,  (0x00 << 2) | 0, K8T890_APIC_ID, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x6,  (0x00 << 2) | 1, K8T890_APIC_ID, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x6,  (0x00 << 2) | 2, K8T890_APIC_ID, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x6,  (0x00 << 2) | 3, K8T890_APIC_ID, 0x13);
+
+	/* azalia audio */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x7,  (0x01 << 2) | 0, VT8237R_APIC_ID, 0x11);
+
+	/* pci slot 1 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x6 << 2) | 0, VT8237R_APIC_ID, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x6 << 2) | 1, VT8237R_APIC_ID, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x6 << 2) | 2, VT8237R_APIC_ID, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x6 << 2) | 3, VT8237R_APIC_ID, 0x13);
+
+	/* pci slot 2 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x7 << 2) | 0, VT8237R_APIC_ID, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x7 << 2) | 1, VT8237R_APIC_ID, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x7 << 2) | 2, VT8237R_APIC_ID, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x7 << 2) | 3, VT8237R_APIC_ID, 0x10);
+
+	/* pci slot 3 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x8 << 2) | 0, VT8237R_APIC_ID, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x8 << 2) | 1, VT8237R_APIC_ID, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x8 << 2) | 2, VT8237R_APIC_ID, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x8 << 2) | 3, VT8237R_APIC_ID, 0x11);
+
+	/* pci slot 4 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x8 << 2) | 0, VT8237R_APIC_ID, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x8 << 2) | 1, VT8237R_APIC_ID, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x8 << 2) | 2, VT8237R_APIC_ID, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x8,  (0x8 << 2) | 3, VT8237R_APIC_ID, 0x12);
+
+	/* Local Ints:	Type	Polarity    Trigger	Bus ID	 IRQ	APIC ID	PIN# */
+	smp_write_lintsrc(mc, mp_ExtINT,	MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0, 0x0, MP_APIC_ALL, 0x0);
+	smp_write_lintsrc(mc, mp_NMI,	MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0, 0x0, MP_APIC_ALL, 0x1);
+	/* There is no extension information... */
+
+	/* Compute the checksums. */
+	mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc),
+						mc->mpe_length);
+	mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+
+	return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+	void *v;
+	v = smp_write_floating_table(addr);
+	return (unsigned long)smp_write_config_table(v);
+}
Index: src/mainboard/asus/m2v/romstage.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/romstage.c	2010-10-27 12:51:19.000000000 +0200
@@ -0,0 +1,210 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 AMD
+ * (Written by Yinghai Lu <yinghailu at amd.com> for AMD)
+ * Copyright (C) 2006 MSI
+ * (Written by Bingxun Shi <bingxunshi at gmail.com> for MSI)
+ * Copyright (C) 2008 Rudolf Marek <r.marek at assembler.cz>
+ *
+ * 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
+ */
+
+unsigned int get_sbdn(unsigned bus);
+
+/* Used by raminit. */
+#define QRANK_DIMM_SUPPORT 1
+
+/* Used by init_cpus and fidvid */
+#define SET_FIDVID 1
+
+/* If we want to wait for core1 done before DQS training, set it to 0. */
+#define SET_FIDVID_CORE0_ONLY 1
+
+#if CONFIG_K8_REV_F_SUPPORT == 1
+#define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/amd/mtrr.h>
+#include <cpu/x86/lapic.h>
+#include <pc80/mc146818rtc.h>
+#include <console/console.h>
+#include <cpu/amd/model_fxx_rev.h>
+#include "northbridge/amd/amdk8/raminit.h"
+#include "cpu/amd/model_fxx/apic_timer.c"
+#include "lib/delay.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+#include "northbridge/amd/amdk8/debug.c"
+#include "superio/ite/it8712f/it8712f_early_serial.c"
+#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "cpu/x86/bist.h"
+#include "northbridge/amd/amdk8/setup_resource_map.c"
+
+#define SERIAL_DEV PNP_DEV(0x2e, IT8712F_SP1)
+#define WATCHDOG_DEV PNP_DEV(0x2e, IT8712F_GPIO)
+
+static void memreset(int controllers, const struct mem_controller *ctrl)
+{
+}
+
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+static void activate_spd_rom(const struct mem_controller *ctrl)
+{
+}
+
+// defines S3_NVRAM_EARLY:
+#include "southbridge/via/k8t890/k8t890_early_car.c"
+
+#include "northbridge/amd/amdk8/amdk8.h"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
+#include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/raminit_f.c"
+#include "lib/generic_sdram.c"
+
+#include "cpu/amd/dualcore/dualcore.c"
+
+#include "cpu/amd/car/post_cache_as_ram.c"
+#include "cpu/amd/model_fxx/init_cpus.c"
+
+#define SB_VFSMAF 0
+
+/* this function might fail on some K8 CPUs with errata #181 */
+static void ldtstop_sb(void)
+{
+	print_debug("toggle LDTSTP#\n");
+	u8 reg = inb (VT8237R_ACPI_IO_BASE + 0x5c);
+	reg = reg ^ (1 << 0);
+	outb(reg, VT8237R_ACPI_IO_BASE + 0x5c);
+	reg = inb(VT8237R_ACPI_IO_BASE + 0x15);
+	print_debug("done\n");
+}
+
+#include "cpu/amd/model_fxx/fidvid.c"
+#include "northbridge/amd/amdk8/resourcemap.c"
+
+void soft_reset(void)
+{
+	uint8_t tmp;
+
+	set_bios_reset();
+	print_debug("soft reset \n");
+
+	/* PCI reset */
+	tmp = pci_read_config8(PCI_DEV(0, 0x11, 0), 0x4f);
+	tmp |= 0x01;
+	/* FIXME from S3 set bit1 to disable USB reset VT8237A/S */
+	pci_write_config8(PCI_DEV(0, 0x11, 0), 0x4f, tmp);
+
+	while (1) {
+		/* daisy daisy ... */
+		hlt();
+	}
+}
+
+unsigned int get_sbdn(unsigned bus)
+{
+	device_t dev;
+
+	dev = pci_locate_device_on_bus(PCI_ID(PCI_VENDOR_ID_VIA,
+					PCI_DEVICE_ID_VIA_VT8237R_LPC), bus);
+	return (dev >> 15) & 0x1f;
+}
+
+void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+{
+	static const uint16_t spd_addr[] = {
+		// Node 0
+		(0xa << 3) | 0, (0xa << 3) | 2, 0, 0,
+		(0xa << 3) | 1, (0xa << 3) | 3, 0, 0,
+		// Node 1
+		(0xa << 3) | 4, (0xa << 3) | 6, 0, 0,
+		(0xa << 3) | 5, (0xa << 3) | 7, 0, 0,
+	};
+	unsigned bsp_apicid = 0;
+	int needs_reset = 0;
+	struct sys_info *sysinfo =
+	    (struct sys_info *)(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE);
+
+	it8712f_24mhz_clkin();
+	it8712f_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
+	it8712f_kill_watchdog();
+	uart_init();
+	console_init();
+	enable_rom_decode();
+
+	printk(BIOS_INFO, "now booting... \n");
+
+	if (bist == 0)
+		bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
+
+	/* Halt if there was a built in self test failure. */
+	report_bist_failure(bist);
+	setup_default_resource_map();
+	setup_coherent_ht_domain();
+	wait_all_core0_started();
+
+	printk(BIOS_INFO, "now booting... All core 0 started\n");
+
+#if CONFIG_LOGICAL_CPUS==1
+	/* It is said that we should start core1 after all core0 launched. */
+	start_other_cores();
+	wait_all_other_cores_started(bsp_apicid);
+#endif
+	init_timer();
+	ht_setup_chains_x(sysinfo); /* Init sblnk and sbbusn, nodes, sbdn. */
+
+	needs_reset = optimize_link_coherent_ht();
+	print_debug_hex8(needs_reset);
+	needs_reset |= optimize_link_incoherent_ht(sysinfo);
+	print_debug_hex8(needs_reset);
+	needs_reset |= k8t890_early_setup_ht();
+	print_debug_hex8(needs_reset);
+
+	if (needs_reset) {
+		printk(BIOS_DEBUG, "ht reset -\n");
+		soft_reset();
+		printk(BIOS_DEBUG, "FAILED!\n");
+	}
+
+	/* the HT settings needs to be OK, because link freq chnage may cause HT disconnect */
+	/* allow LDT STOP asserts */
+	vt8237_sb_enable_fid_vid();
+
+	enable_fid_change();
+	print_debug("after enable_fid_change\n");
+
+	init_fidvid_bsp(bsp_apicid);
+
+	/* Stop the APs so we can start them later in init. */
+	allow_all_aps_stop(bsp_apicid);
+
+	/* It's the time to set ctrl now. */
+	fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
+	enable_smbus();
+	sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
+	post_cache_as_ram();
+}
+
Index: src/mainboard/asus/m2v/irq_tables.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/mainboard/asus/m2v/irq_tables.c	2010-10-27 12:53:54.000000000 +0200
@@ -0,0 +1,175 @@
+/* This file was generated by getpir.c, do not modify!
+   (but if you do, please run checkpir on it to verify)
+   Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
+
+   Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
+*/
+#include <console/console.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+#include <arch/pirq_routing.h>
+#include <pc80/i8259.h>
+
+const struct irq_routing_table intel_irq_routing_table = {
+        PIRQ_SIGNATURE, /* u32 signature */
+        PIRQ_VERSION,   /* u16 version   */
+        32+16*CONFIG_IRQ_SLOT_COUNT,        /* there can be total CONFIG_IRQ_SLOT_COUNT devices on the bus */
+        0,           /* Where the interrupt router lies (bus) */
+        (0x11<<3)|0,           /* Where the interrupt router lies (dev) */
+        0,         /* IRQs devoted exclusively to PCI usage */
+        0x1106,         /* Vendor */
+        0x3337,         /* Device */
+        0,         /* Miniport data */
+        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+        0xd9,         /*  u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structu
+re (including checksum) */
+        {
+		/* bus,        dev | fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
+		/* ?? bridge */
+		{0x00, (0x01 << 3) | 0x0, {{0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}}, 0x0, 0x0},
+		/* peg bridge */
+		{0x00, (0x02 << 3) | 0x0, {{0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}}, 0x0, 0x0},
+		/* pcie bridge */
+		{0x00, (0x03 << 3) | 0x0, {{0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}}, 0x0, 0x0},
+		/* sata/ide */
+		{0x00, (0x0f << 3) | 0x0, {{0x00, 0x0000}, {0x02, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
+		/* usb */
+		{0x00, (0x10 << 3) | 0x0, {{0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}}, 0x0, 0x0},
+		/* pci bridge */
+		{0x00, (0x13 << 3) | 0x0, {{0x04, 0xdcf8}, {0x04, 0xdcf8}, {0x04, 0xdcf8}, {0x04, 0xdcf8}}, 0x0, 0x0},
+		{0x01, (0x00 << 3) | 0x0, {{0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}}, 0xa, 0x0},
+		{0x02, (0x00 << 3) | 0x0, {{0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}}, 0xb, 0x0},
+		{0x03, (0x00 << 3) | 0x0, {{0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}}, 0xf, 0x0},
+		{0x04, (0x00 << 3) | 0x0, {{0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}}, 0x0, 0x0},
+		{0x05, (0x00 << 3) | 0x0, {{0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}}, 0xd, 0x0},
+		{0x06, (0x00 << 3) | 0x0, {{0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}, {0x09, 0xdcf8}}, 0x0, 0x0},
+		/* Azalia */
+		{0x07, (0x01 << 3) | 0x0, {{0x02, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
+		/* PCI slots */
+		{0x08, (0x06 << 3) | 0x0, {{0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}}, 0x1, 0x0},
+		{0x08, (0x07 << 3) | 0x0, {{0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}, {0x01, 0xdcf8}}, 0x2, 0x0},
+		{0x08, (0x08 << 3) | 0x0, {{0x03, 0xdcf8}, {0x04, 0xdcf8}, {0x01, 0xdcf8}, {0x02, 0xdcf8}}, 0x3, 0x0},
+		{0x08, (0x09 << 3) | 0x0, {{0x04, 0xdcf8}, {0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}}, 0x4, 0x0},
+        }
+};
+
+static void pci_fixup_irqs(void)
+{
+	const struct irq_routing_table *pirq = &intel_irq_routing_table;
+	/* We don't have a secondary serial port or an isa soundcard, so we
+	 * can use irqs 3 and 5 in addition to 10 and 11.
+	 */
+	char route[4] = {
+		3, 5, 10, 11
+	};
+	int i;
+	device_t dev;
+
+	i8259_configure_irq_trigger(10, IRQ_LEVEL_TRIGGERED);
+	i8259_configure_irq_trigger(11, IRQ_LEVEL_TRIGGERED);
+
+	/* set up router */
+	dev = dev_find_slot(0, PCI_DEVFN(0x11, 0));
+	pci_write_config8(dev, 0x55,  route[0] << 4);
+	pci_write_config8(dev, 0x56, (route[2] << 4) | route[1]);
+	pci_write_config8(dev, 0x57,  route[3] << 4);
+
+	/* Test: disable SATA led */
+	i = pci_read_config8(dev, 0xe5);
+	i &= ~1;
+	pci_write_config8(dev, 0xe5, i);
+
+	for (i=0; i<CONFIG_IRQ_SLOT_COUNT; i++) {
+		const struct irq_info *slot = &pirq->slots[i];
+		int intx, irq, link, d, fn;
+
+		for (intx=0; intx<4; intx++) {
+			link = slot->irq[intx].link;
+			if (link != 0)
+				break;
+		}
+		if (link>0 && link<=sizeof(route)) {
+			irq = route[link-1];
+			intx++;
+		} else {
+			irq = -1;
+		}
+
+		d = slot->devfn >> 3;
+		fn = slot->devfn & 7;
+
+		dev = dev_find_slot(slot->bus, slot->devfn);
+		if (!dev) {
+			printk(BIOS_ERR, "Could not find device %02x:%02x.%d from routing table!\n", slot->bus, d, fn);
+			continue;
+		}
+
+		intx = 0;
+		do {
+			int j;
+
+			/* find first INTx that has link info and can be used */
+			for (j=0; j<4; intx++, j++) {
+				intx %= 4;
+				link = slot->irq[intx].link;
+				if (link != 0)
+					break;
+			}
+			if (link == 0)
+				break;
+
+			pci_write_config8(dev, PCI_INTERRUPT_PIN, intx+1);
+			/* read back (may be fixed and unchangable) */
+			intx = pci_read_config8(dev, PCI_INTERRUPT_PIN)-1;
+			if (intx < 1 || intx > 4) {
+				printk(BIOS_INFO, "PCI %02x:%02x.%d (%08x) invalid pin %d!\n",
+						slot->bus, d, fn, pci_read_config32(dev, 0), intx);
+				break;
+			}
+
+			irq = route[link-1];
+			pci_write_config8(dev, PCI_INTERRUPT_LINE, irq);
+			printk(BIOS_INFO, "PCI %02x:%02x.%d (%08x) routed to pin %d irq %d.\n",
+					slot->bus, d, fn, pci_read_config32(dev, 0), intx, irq);
+
+			if (fn == 7)
+				break; /* last subdevice */
+
+			if (!(pci_read_config8(dev, PCI_HEADER_TYPE) & 0x80))
+				break; /* not multifunction device */
+
+			fn++;
+			dev = dev_find_slot(slot->bus, PCI_DEVFN(d, fn));
+		} while (dev);
+	}
+}
+
+unsigned long write_pirq_routing_table(unsigned long addr)
+{
+	struct irq_routing_table *pirq;
+	unsigned long ret;
+	uint8_t *v;
+	uint8_t sum;
+	int i;
+
+	ret = copy_pirq_routing_table(addr);
+	pci_fixup_irqs();
+
+	/* fixup checksum */
+	v = (void*)(addr);
+	pirq = (void*)(addr);
+
+	sum = 0;
+	for (i = 0; i < pirq->size; i++)
+		sum += v[i];
+	sum = pirq->checksum - sum;
+
+	if (sum != pirq->checksum) {
+		printk(BIOS_ERR, "PIRQ checksum is %02x, should be %02x, fixing...!\n",
+			pirq->checksum, sum);
+		pirq->checksum = sum;
+	}
+
+	return ret;
+}




More information about the coreboot mailing list