Support Intel SCH (Poulsbo) and add iwave/iWRainbowG6 board

which uses it.

Compiles, but not boot tested lately.
Many things missing (eg. SMM support, proper ACPI, ...)

Signed-off-by: Patrick Georgi <patrick.georgi@coresystems.de>
Acked-by: Peter Stuge <peter@stuge.se>


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6198 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Patrick Georgi
2010-12-18 07:48:43 +00:00
parent 312fc96874
commit be61a17351
81 changed files with 8781 additions and 1 deletions

View File

@ -30,6 +30,8 @@
#include "../../../southbridge/intel/i82801gx/i82801gx.h"
#elif defined(CONFIG_SOUTHBRIDGE_INTEL_I82801DX)
#include "../../../southbridge/intel/i82801dx/i82801dx.h"
#elif defined(CONFIG_SOUTHBRIDGE_INTEL_SCH)
#include "../../../southbridge/intel/sch/sch.h"
#else
#error "Southbridge needs SMM handler support."
#endif

View File

@ -58,6 +58,8 @@ config VENDOR_IEI
bool "IEI"
config VENDOR_INTEL
bool "Intel"
config VENDOR_IWAVE
bool "iWave"
config VENDOR_IWILL
bool "IWILL"
config VENDOR_JETWAY
@ -140,6 +142,7 @@ source "src/mainboard/ibase/Kconfig"
source "src/mainboard/ibm/Kconfig"
source "src/mainboard/iei/Kconfig"
source "src/mainboard/intel/Kconfig"
source "src/mainboard/iwave/Kconfig"
source "src/mainboard/iwill/Kconfig"
source "src/mainboard/jetway/Kconfig"
source "src/mainboard/kontron/Kconfig"

View File

@ -0,0 +1,18 @@
if VENDOR_IWAVE
choice
prompt "Mainboard model"
depends on VENDOR_IWAVE
config BOARD_IWAVE_RAINBOW_G6
bool "iWRainbowG6"
endchoice
source "src/mainboard/iwave/iWRainbowG6/Kconfig"
config MAINBOARD_VENDOR
string
default "iWave"
endif # VENDOR_IWAVE

View File

@ -0,0 +1,46 @@
if BOARD_IWAVE_RAINBOW_G6
# TODO: move options to chipset components as appropriate
config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
select ARCH_X86
select CPU_INTEL_CORE # FIXME
select CPU_INTEL_SOCKET_441
select NORTHBRIDGE_INTEL_SCH
select SOUTHBRIDGE_INTEL_SCH
select BOARD_HAS_FADT
select HAVE_PIRQ_TABLE
# select HAVE_MP_TABLE
select MMCONF_SUPPORT
select USE_PRINTK_IN_CAR
select AP_IN_SIPI_WAIT
select UDELAY_LAPIC
select HAVE_ACPI_TABLES
select HAVE_SMI_HANDLER
select BOARD_ROMSIZE_KB_1024
select USE_DCACHE_RAM
select GFXUMA
select HAVE_HARD_RESET
config MAINBOARD_DIR
string
default iwave/iWRainbowG6
config MAINBOARD_PART_NUMBER
string
default "iWRainbowG6"
config MMCONF_BASE_ADDRESS
hex
default 0xf0000000
config IRQ_SLOT_COUNT
int
default 10
# WTF, is this 19200?
config TTYS0_DIV
int
default 6
endif

View File

@ -0,0 +1,21 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2008 coresystems GmbH
##
## 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
##
smm-$(CONFIG_HAVE_SMI_HANDLER) += mainboard_smi.c

View File

@ -0,0 +1,51 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* Intel Core (2) Duo CPU node support
*
* Note: The ACPI P_BLK on the ICH7 (and probably others) lives at
* PMBASE + 0x10, and it's 0x06 bytes long. On ICH8 it's 8 bytes.
*
* The second CPU core does not need its own P_BLK.
*/
Scope(\_PR)
{
Processor(
CPU1, // name of cpu/core 0
1, // numeric id of cpu/core
0x510, // ACPI P_BLK base address
6 // ACPI P_BLK size
)
{
// TODO: _PDT
}
Processor(
CPU2, // name of cpu/core 1
2, // numeric id of cpu/core 1
0, // ACPI P_BLK base address
0) // ACPI P_BLK size
{
// TODO: _PDT
}
} // End _PR

View File

@ -0,0 +1,51 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
Device(EC0)
{
Name (_HID, EISAID("PNP0C09"))
Name (_UID, 1)
Method (_CRS, 0)
{
Name (ECMD, ResourceTemplate()
{
IO (Decode16, 0x62, 0x62, 0, 1)
IO (Decode16, 0x66, 0x66, 0, 1)
})
Return (ECMD)
}
Method (_REG, 2)
{
// This method is needed by Windows XP/2000
// for EC initialization before a driver
// is loaded
}
Name (_GPE, 23) // GPI07 / GPE23 -> Runtime SCI
// TODO EC Query methods
// TODO Scope _SB devices for AC power, LID, Power button
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* Global Variables */
Name(\PICM,0) // IOAPIC/8259
/* Global ACPI memory region. This region is used for passing information
* between coreboot (aka "the system bios"), ACPI, and the SMI handler.
* Since we don't know where this will end up in memory at ACPI compile time,
* we have to fix it up in coreboot's ACPI creation phase.
*/
OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0xFF)
Field (GNVS, ByteAcc, NoLock, Preserve)
{
Offset (0x00),
OSYS, 16, // 0x00 Operating System
SMIF, 8, // 0x02 SMI function
Offset (0x10),
MPEN, 8, // 0x10 Multi Processor Enable
}

View File

@ -0,0 +1,86 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* This is board specific information: IRQ routing for the
* i945
*/
// PCI Interrupt Routing
Method(_PRT)
{
If (PICM) {
Return (Package() {
// PCIe Graphics 0:1.0
Package() { 0x0001ffff, 0, 0, 16 },
Package() { 0x0001ffff, 1, 0, 17 },
Package() { 0x0001ffff, 2, 0, 18 },
Package() { 0x0001ffff, 3, 0, 19 },
// Onboard graphics (IGD) 0:2.0
Package() { 0x0002ffff, 0, 0, 16 },
// High Definition Audio 0:1b.0
Package() { 0x001bffff, 0, 0, 16 },
// PCIe Root Ports 0:1c.x
Package() { 0x001cffff, 0, 0, 16 },
Package() { 0x001cffff, 1, 0, 17 },
Package() { 0x001cffff, 2, 0, 18 },
Package() { 0x001cffff, 3, 0, 19 },
// USB and EHCI 0:1d.x
Package() { 0x001dffff, 0, 0, 23 },
Package() { 0x001dffff, 1, 0, 19 },
Package() { 0x001dffff, 2, 0, 18 },
Package() { 0x001dffff, 3, 0, 16 },
// AC97/IDE 0:1e.2, 0:1e.3
Package() { 0x001effff, 0, 0, 17 },
Package() { 0x001effff, 1, 0, 20 },
// LPC device 0:1f.0
Package() { 0x001fffff, 0, 0, 18 },
Package() { 0x001fffff, 1, 0, 19},
})
} Else {
Return (Package() {
// PCIe Graphics 0:1.0
Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 },
// Onboard graphics (IGD) 0:2.0
Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
// High Definition Audio 0:1b.0
Package() { 0x001bffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
// PCIe Root Ports 0:1c.x
Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x001cffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x001cffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x001cffff, 3, \_SB.PCI0.LPCB.LNKD, 0 },
// USB and EHCI 0:1d.x
Package() { 0x001dffff, 0, \_SB.PCI0.LPCB.LNKH, 0 },
Package() { 0x001dffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x001dffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x001dffff, 3, \_SB.PCI0.LPCB.LNKA, 0 },
// AC97/IDE 0:1e.2, 0:1e.3
Package() { 0x001effff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x001effff, 1, \_SB.PCI0.LPCB.LNKE, 0 },
// LPC device 0:1f.0
Package() { 0x001fffff, 0, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x001fffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
})
}
}

View File

@ -0,0 +1,93 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* The APM port can be used for generating software SMIs */
OperationRegion (APMP, SystemIO, 0xb2, 2)
Field (APMP, ByteAcc, NoLock, Preserve)
{
APMC, 8, // APM command
APMS, 8 // APM status
}
/* Port 80 POST */
OperationRegion (POST, SystemIO, 0x80, 1)
Field (POST, ByteAcc, Lock, Preserve)
{
DBG0, 8
}
/* SMI I/O Trap */
Method(TRAP, 1, Serialized)
{
Store (Arg0, SMIF) // SMI Function
//Store (0, TRP0) // Generate trap
Return (SMIF) // Return value of SMI handler
}
/* 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, PICM)
}
/* The _PTS method (Prepare To Sleep) is called before the OS is
* entering a sleep state. The sleep state number is passed in Arg0
*/
Method(_PTS,1)
{
// Call a trap so SMI can prepare for Sleep as well.
// TRAP(0x55)
}
/* The _WAK method is called on system wakeup */
Method(_WAK,1)
{
// CPU specific part
// Notify PCI Express slots in case a card
// was inserted while a sleep state was active.
// Are we going to S3?
If (LEqual(Arg0, 3)) {
// ..
}
// Are we going to S4?
If (LEqual(Arg0, 4)) {
// ..
}
// TODO: Windows XP SP2 P-State restore
Return(Package(){0,0})
}

View File

@ -0,0 +1,27 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
Name(\_S0, Package(4){0x0,0x0,0,0})
Name(\_S1, Package(4){0x1,0x0,0,0})
Name(\_S3, Package(4){0x5,0x0,0,0})
Name(\_S4, Package(4){0x6,0x0,0,0})
Name(\_S5, Package(4){0x7,0x0,0,0})

View File

@ -0,0 +1,103 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* This is board specific information: IRQ routing for the
* 0:1e.0 PCI bridge of the ICH7
*/
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 16},
Package() { 0x0001ffff, 0, 0, 20},
Package() { 0x0001ffff, 1, 0, 21},
Package() { 0x0001ffff, 2, 0, 22},
Package() { 0x0001ffff, 3, 0, 23},
Package() { 0x0002ffff, 0, 0, 21},
Package() { 0x0002ffff, 1, 0, 22},
Package() { 0x0002ffff, 2, 0, 23},
Package() { 0x0002ffff, 3, 0, 20},
Package() { 0x0003ffff, 0, 0, 22},
Package() { 0x0003ffff, 1, 0, 23},
Package() { 0x0003ffff, 2, 0, 20},
Package() { 0x0003ffff, 3, 0, 21},
Package() { 0x0004ffff, 0, 0, 23},
Package() { 0x0004ffff, 1, 0, 20},
Package() { 0x0004ffff, 2, 0, 21},
Package() { 0x0004ffff, 3, 0, 22},
Package() { 0x0005ffff, 0, 0, 19},
Package() { 0x0005ffff, 1, 0, 18},
Package() { 0x0005ffff, 2, 0, 17},
Package() { 0x0005ffff, 3, 0, 16},
Package() { 0x0006ffff, 0, 0, 18},
Package() { 0x0006ffff, 1, 0, 17},
Package() { 0x0006ffff, 2, 0, 16},
Package() { 0x0006ffff, 3, 0, 19},
Package() { 0x0009ffff, 0, 0, 21},
Package() { 0x0009ffff, 1, 0, 22},
Package() { 0x0009ffff, 2, 0, 23},
Package() { 0x0009ffff, 3, 0, 20},
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0},
Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKE, 0},
Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKF, 0},
Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKG, 0},
Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKH, 0},
Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKF, 0},
Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKG, 0},
Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKH, 0},
Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKE, 0},
Package() { 0x0003ffff, 0, \_SB.PCI0.LPCB.LNKG, 0},
Package() { 0x0003ffff, 1, \_SB.PCI0.LPCB.LNKH, 0},
Package() { 0x0003ffff, 2, \_SB.PCI0.LPCB.LNKE, 0},
Package() { 0x0003ffff, 3, \_SB.PCI0.LPCB.LNKF, 0},
Package() { 0x0004ffff, 0, \_SB.PCI0.LPCB.LNKH, 0},
Package() { 0x0004ffff, 1, \_SB.PCI0.LPCB.LNKE, 0},
Package() { 0x0004ffff, 2, \_SB.PCI0.LPCB.LNKF, 0},
Package() { 0x0004ffff, 3, \_SB.PCI0.LPCB.LNKG, 0},
Package() { 0x0005ffff, 0, \_SB.PCI0.LPCB.LNKD, 0},
Package() { 0x0005ffff, 1, \_SB.PCI0.LPCB.LNKC, 0},
Package() { 0x0005ffff, 2, \_SB.PCI0.LPCB.LNKB, 0},
Package() { 0x0005ffff, 3, \_SB.PCI0.LPCB.LNKA, 0},
Package() { 0x0006ffff, 0, \_SB.PCI0.LPCB.LNKC, 0},
Package() { 0x0006ffff, 1, \_SB.PCI0.LPCB.LNKB, 0},
Package() { 0x0006ffff, 2, \_SB.PCI0.LPCB.LNKA, 0},
Package() { 0x0006ffff, 3, \_SB.PCI0.LPCB.LNKD, 0},
Package() { 0x0009ffff, 0, \_SB.PCI0.LPCB.LNKF, 0},
Package() { 0x0009ffff, 1, \_SB.PCI0.LPCB.LNKG, 0},
Package() { 0x0009ffff, 2, \_SB.PCI0.LPCB.LNKH, 0},
Package() { 0x0009ffff, 3, \_SB.PCI0.LPCB.LNKE, 0},
})
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
Device (SIO1)
{
Name (_HID, EISAID("PNP0A05"))
Name (_UID, 1)
Device (UAR1)
{
Name(_HID, EISAID("PNP0501"))
Name(_UID, 1)
// Some methods need an implementation here:
// missing: _STA, _DIS, _CRS, _PRS,
// missing: _SRS, _PS0, _PS3
}
Device (UAR2)
{
Name(_HID, EISAID("PNP0501"))
Name(_UID, 2)
// Some methods need an implementation here:
// missing: _STA, _DIS, _CRS, _PRS,
// missing: _SRS, _PS0, _PS3
}
}

View File

@ -0,0 +1,96 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
// Thermal Zone
Scope (\_TZ)
{
ThermalZone (THRM)
{
// FIXME these could/should be read from the
// GNVS area, so they can be controlled by
// coreboot
Name(TC1V, 0x04)
Name(TC2V, 0x03)
Name(TSPV, 0x64)
// At which temperature should the OS start
// active cooling?
Method (_AC0, 0, Serialized)
{
Return (0xf5c) // Value for Rocky
}
// Method (_AC1, 0, Serialized)
// {
// Return (0xf5c)
// }
// Critical shutdown temperature
Method (_CRT, 0, Serialized)
{
Return (Add (0x0aac, 0x50)) // FIXME
}
// CPU throttling start temperature
Method (_PSV, 0, Serialized)
{
Return (0xaaf) // FIXME
}
// Get DTS Temperature
Method (_TMP, 0, Serialized)
{
Return (0xaac) // FIXME
}
// Processors used for active cooling
Method (_PSL, 0, Serialized)
{
If (MPEN) {
Return (Package() {\_PR.CPU1, \_PR.CPU2})
}
Return (Package() {\_PR.CPU1})
}
// TC1 value for passive cooling
Method (_TC1, 0, Serialized)
{
Return (TC1V)
}
// TC2 value for passive cooling
Method (_TC2, 0, Serialized)
{
Return (TC2V)
}
// Sampling period for passive cooling
Method (_TSP, 0, Serialized)
{
Return (TSPV)
}
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
// Brightness write
Method (BRTW, 1, Serialized)
{
// TODO
}
// Hot Key Display Switch
Method (HKDS, 1, Serialized)
{
// TODO
}
// Lid Switch Display Switch
Method (LSDS, 1, Serialized)
{
// TODO
}
// Brightness Notification
Method(BRTN,1,Serialized)
{
// TODO (no displays defined yet)
}

View File

@ -0,0 +1,272 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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 <types.h>
#include <string.h>
#include <console/console.h>
#include <arch/acpi.h>
#include <arch/ioapic.h>
#include <arch/acpigen.h>
#include <arch/smp/mpspec.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <cpu/x86/msr.h>
#include "dmi.h"
extern const unsigned char AmlCode[];
#if CONFIG_HAVE_ACPI_SLIC
unsigned long acpi_create_slic(unsigned long current);
#endif
#include "southbridge/intel/i82801gx/nvs.h" // FIXME: our own copy of nvs would be nice
static void acpi_create_gnvs(global_nvs_t *gnvs)
{
memset((void *)gnvs, 0, sizeof(*gnvs));
gnvs->apic = 1;
gnvs->mpen = 1; /* Enable Multi Processing */
/* Enable both COM ports */
gnvs->cmap = 0x01;
gnvs->cmbp = 0x01;
/* IGD Displays */
gnvs->ndid = 3;
gnvs->did[0] = 0x80000100;
gnvs->did[1] = 0x80000240;
gnvs->did[2] = 0x80000410;
gnvs->did[3] = 0x80000410;
gnvs->did[4] = 0x00000005;
}
static void acpi_create_intel_hpet(acpi_hpet_t * hpet)
{
#define HPET_ADDR 0xfed00000ULL
acpi_header_t *header = &(hpet->header);
acpi_addr_t *addr = &(hpet->addr);
memset((void *) hpet, 0, sizeof(acpi_hpet_t));
/* fill out header fields */
memcpy(header->signature, "HPET", 4);
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, "COREBOOT", 8);
memcpy(header->asl_compiler_id, ASLC, 4);
header->length = sizeof(acpi_hpet_t);
header->revision = 1;
/* fill out HPET address */
addr->space_id = 0; /* Memory */
addr->bit_width = 64;
addr->bit_offset = 0;
addr->addrl = HPET_ADDR & 0xffffffff;
addr->addrh = HPET_ADDR >> 32;
hpet->id = 0x8086a201; /* Intel */
hpet->number = 0x00;
hpet->min_tick = 0x0080;
header->checksum =
acpi_checksum((void *) hpet, sizeof(acpi_hpet_t));
}
unsigned long acpi_fill_madt(unsigned long current)
{
/* Local APICs */
current = acpi_create_madt_lapics(current);
/* IOAPIC */
current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
2, IO_APIC_ADDR, 0);
/* INT_SRC_OVR */
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
current, 0, 0, 2, 0);
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH);
return current;
}
unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id)
{
generate_cpu_entries();
return (unsigned long) (acpigen_get_current());
}
unsigned long acpi_fill_slit(unsigned long current)
{
// Not implemented
return current;
}
unsigned long acpi_fill_srat(unsigned long current)
{
/* No NUMA, no SRAT */
return current;
}
void smm_setup_structures(void *gnvs, void *tcg, void *smi1);
#define ALIGN_CURRENT current = ((current + 0x0f) & -0x10)
unsigned long write_acpi_tables(unsigned long start)
{
unsigned long current;
int i;
acpi_rsdp_t *rsdp;
acpi_rsdt_t *rsdt;
acpi_xsdt_t *xsdt;
acpi_hpet_t *hpet;
acpi_madt_t *madt;
acpi_mcfg_t *mcfg;
acpi_fadt_t *fadt;
acpi_facs_t *facs;
#if CONFIG_HAVE_ACPI_SLIC
acpi_header_t *slic;
#endif
acpi_header_t *ssdt;
acpi_header_t *dsdt;
current = start;
/* Align ACPI tables to 16byte */
ALIGN_CURRENT;
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);
ALIGN_CURRENT;
rsdt = (acpi_rsdt_t *) current;
current += sizeof(acpi_rsdt_t);
ALIGN_CURRENT;
xsdt = (acpi_xsdt_t *) current;
current += sizeof(acpi_xsdt_t);
ALIGN_CURRENT;
/* clear all table memory */
memset((void *) start, 0, current - start);
acpi_write_rsdp(rsdp, rsdt, xsdt);
acpi_write_rsdt(rsdt);
acpi_write_xsdt(xsdt);
/*
* We explicitly add these tables later on:
*/
printk(BIOS_DEBUG, "ACPI: * HPET\n");
hpet = (acpi_hpet_t *) current;
current += sizeof(acpi_hpet_t);
ALIGN_CURRENT;
acpi_create_intel_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;
ALIGN_CURRENT;
acpi_add_table(rsdp, madt);
printk(BIOS_DEBUG, "ACPI: * MCFG\n");
mcfg = (acpi_mcfg_t *) current;
acpi_create_mcfg(mcfg);
current += mcfg->header.length;
ALIGN_CURRENT;
acpi_add_table(rsdp, mcfg);
printk(BIOS_DEBUG, "ACPI: * FACS\n");
facs = (acpi_facs_t *) current;
current += sizeof(acpi_facs_t);
ALIGN_CURRENT;
acpi_create_facs(facs);
dsdt = (acpi_header_t *) current;
memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
current += dsdt->length;
memcpy(dsdt, &AmlCode, dsdt->length);
ALIGN_CURRENT;
/* Pack GNVS into the ACPI table area */
for (i=0; i < dsdt->length; i++) {
if (*(u32*)(((u32)dsdt) + i) == 0xC0DEBABE) {
printk(BIOS_DEBUG, "ACPI: Patching up global NVS in DSDT at offset 0x%04x -> 0x%08lx\n", i, current);
*(u32*)(((u32)dsdt) + i) = current; // 0x92 bytes
break;
}
}
/* And fill it */
acpi_create_gnvs((global_nvs_t *)current);
current += 0x100;
ALIGN_CURRENT;
/* And tell SMI about it */
smm_setup_structures((void *)current, NULL, NULL);
/* We patched up the DSDT, so we need to recalculate the checksum */
dsdt->checksum = 0;
dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length);
printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt,
dsdt->length);
#if CONFIG_HAVE_ACPI_SLIC
printk(BIOS_DEBUG, "ACPI: * SLIC\n");
slic = (acpi_header_t *)current;
current += acpi_create_slic(current);
ALIGN_CURRENT;
acpi_add_table(rsdp, slic);
#endif
printk(BIOS_DEBUG, "ACPI: * FADT\n");
fadt = (acpi_fadt_t *) current;
current += sizeof(acpi_fadt_t);
ALIGN_CURRENT;
acpi_create_fadt(fadt, facs, dsdt);
acpi_add_table(rsdp, fadt);
printk(BIOS_DEBUG, "ACPI: * SSDT\n");
ssdt = (acpi_header_t *)current;
acpi_create_ssdt_generator(ssdt, "COREBOOT");
current += ssdt->length;
acpi_add_table(rsdp, ssdt);
ALIGN_CURRENT;
printk(BIOS_DEBUG, "current = %lx\n", current);
printk(BIOS_DEBUG, "ACPI: * DMI (Linux workaround)\n");
memcpy((void *)0xfff80, dmi_table, DMI_TABLE_SIZE);
#if CONFIG_WRITE_HIGH_TABLES == 1
memcpy((void *)current, dmi_table, DMI_TABLE_SIZE);
current += DMI_TABLE_SIZE;
ALIGN_CURRENT;
#endif
printk(BIOS_INFO, "ACPI: done.\n");
return current;
}

View File

@ -0,0 +1,21 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2008 coresystems GmbH
*
* 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 {};

View File

@ -0,0 +1,149 @@
#
# This file is part of the coreboot project.
#
# Copyright (C) 2007-2009 coresystems GmbH
#
# 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
#
# -----------------------------------------------------------------
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
# -----------------------------------------------------------------
# Status Register A
#80 4 r 0 rate_select
#84 3 r 0 REF_Clock
#87 1 r 0 UIP
# -----------------------------------------------------------------
# Status Register B
#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
# -----------------------------------------------------------------
# Status Register C
#96 4 r 0 status_c_rsvd
#100 1 r 0 uf_flag
#101 1 r 0 af_flag
#102 1 r 0 pf_flag
#103 1 r 0 irqf_flag
# -----------------------------------------------------------------
# Status Register D
#104 7 r 0 status_d_rsvd
#111 1 r 0 valid_cmos_ram
# -----------------------------------------------------------------
# Diagnostic Status Register
#112 8 r 0 diag_rsvd1
# -----------------------------------------------------------------
0 120 r 0 reserved_memory
#120 264 r 0 unused
# -----------------------------------------------------------------
# RTC_BOOT_BYTE (coreboot hardcoded)
384 1 e 4 boot_option
385 1 e 4 last_boot
388 4 r 0 reboot_bits
#390 2 r 0 unused?
# -----------------------------------------------------------------
# coreboot config options: console
392 3 e 5 baud_rate
395 4 e 6 debug_level
#399 1 r 0 unused
# coreboot config options: cpu
400 1 e 2 hyper_threading
#401 7 r 0 unused
# coreboot config options: southbridge
408 1 e 1 nmi
409 2 e 7 power_on_after_fail
#411 5 r 0 unused
# coreboot config options: bootloader
416 512 s 0 boot_devices
#928 40 r 0 unused
968 1 e 2 ethernet1
969 1 e 2 ethernet2
970 1 e 2 ethernet3
#971 13 r 0 unused
# coreboot config options: check sums
984 16 h 0 check_sum
#1000 24 r 0 amd_reserved
# ram initialization internal data
1024 8 r 0 C0WL0REOST
1032 8 r 0 C1WL0REOST
1040 8 r 0 RCVENMT
1048 4 r 0 C0DRT1
1052 4 r 0 C1DRT1
# -----------------------------------------------------------------
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 1 Emergency
6 2 Alert
6 3 Critical
6 4 Error
6 5 Warning
6 6 Notice
6 7 Info
6 8 Debug
6 9 Spew
7 0 Disable
7 1 Enable
7 2 Keep
# -----------------------------------------------------------------
checksums
checksum 392 983 984

View File

@ -0,0 +1,39 @@
chip northbridge/intel/sch
device lapic_cluster 0 on
chip cpu/intel/socket_441
device lapic 0 on end
end
end
device pci_domain 0 on
device pci 00.0 on end # host bridge
device pci 02.0 on end # Integrated Graphics and Video Device
chip southbridge/intel/sch
register "pirqa_routing" = "0xa"
register "pirqb_routing" = "0xb"
register "pirqc_routing" = "0x5"
register "pirqd_routing" = "0xf"
register "pirqe_routing" = "0x80"
register "pirqf_routing" = "0x80"
register "pirqg_routing" = "0x80"
register "pirqh_routing" = "0x80"
device pci 1a.0 on end # 26 0 USB Client
device pci 1b.0 on end # 27 0 HD Audio Controller
device pci 1c.0 on end # 28 0 PCI Express Port 1
device pci 1c.1 on end # 28 1 PCI Express Port 2
device pci 1d.0 on end # USB Classic UHCI Controller 1
device pci 1d.1 on end # USB Classic UHCI Controller 2
device pci 1d.2 on end # USB Classic UHCI Controller 3
device pci 1d.7 on end # USB2 EHCI Controller
device pci 1e.0 on end # SDIO/MMC Port 0
device pci 1e.1 on end # SDIO/MMC Port 1
device pci 1e.2 on end # SDIO/MMC Port 2
device pci 1f.0 on end # LPC bridge
device pci 1f.1 on end # PATA Controller
end
end
end

View File

@ -0,0 +1,29 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
#define DMI_TABLE_SIZE 0x55
static u8 dmi_table[DMI_TABLE_SIZE] = {
0x5f, 0x53, 0x4d, 0x5f, 0x2d, 0x1f, 0x02, 0x03, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5f, 0x44, 0x4d, 0x49, 0x5f, 0xeb, 0xa8, 0x03, 0xa0, 0xff, 0x0f, 0x00, 0x01, 0x00, 0x23, 0x00,
0x00, 0x14, 0x00, 0x00, 0x01, 0x02, 0x00, 0xe0, 0x03, 0x07, 0x90, 0xde, 0xcb, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x37, 0x01, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20,
0x47, 0x6d, 0x62, 0x48, 0x00, 0x32, 0x2e, 0x30, 0x00, 0x30, 0x33, 0x2f, 0x31, 0x33, 0x2f, 0x32,
0x30, 0x30, 0x38, 0x00, 0x00
};

View File

@ -0,0 +1,50 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
DefinitionBlock(
"dsdt.aml",
"DSDT",
0x02, // DSDT revision: ACPI v2.0
"COREv2", // OEM id
"COREBOOT", // OEM table id
0x20090419 // OEM revision
)
{
// Some generic macros
#include "acpi/platform.asl"
// global NVS and variables
#include "../../../southbridge/intel/sch/acpi/globalnvs.asl"
// General Purpose Events
//#include "acpi/gpe.asl"
//#include "acpi/thermal.asl"
Scope (\_SB) {
Device (PCI0)
{
#include "../../../northbridge/intel/sch/acpi/sch.asl"
#include "../../../southbridge/intel/sch/acpi/sch.asl"
}
}
/* Chipset specific sleep states */
#include "../../../southbridge/intel/sch/acpi/sleepstates.asl"
}

View File

@ -0,0 +1,165 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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 <device/pci.h>
#include <arch/acpi.h>
/* FIXME: This needs to go into a separate .h file
* to be included by the ich7 smi handler, ich7 smi init
* code and the mainboard fadt.
*/
#define APM_CNT 0xb2
#define CST_CONTROL 0x85
#define PST_CONTROL 0x80
#define ACPI_DISABLE 0x1e
#define ACPI_ENABLE 0xe1
#define GNVS_UPDATE 0xea
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
{
acpi_header_t *header = &(fadt->header);
u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe;
memset((void *) fadt, 0, sizeof(acpi_fadt_t));
memcpy(header->signature, "FACP", 4);
header->length = sizeof(acpi_fadt_t);
header->revision = 3;
memcpy(header->oem_id, "CORE ", 6);
memcpy(header->oem_table_id, "COREBOOT", 8);
memcpy(header->asl_compiler_id, "CORE", 4);
header->asl_compiler_revision = 1;
fadt->firmware_ctrl = (unsigned long) facs;
fadt->dsdt = (unsigned long) dsdt;
fadt->model = 1;
fadt->preferred_pm_profile = PM_MOBILE;
fadt->sci_int = 0x9;
fadt->smi_cmd = APM_CNT;
fadt->acpi_enable = ACPI_ENABLE;
fadt->acpi_disable = ACPI_DISABLE;
fadt->s4bios_req = 0x0;
fadt->pstate_cnt = PST_CONTROL;
fadt->pm1a_evt_blk = pmbase;
fadt->pm1b_evt_blk = 0x0;
fadt->pm1a_cnt_blk = pmbase + 0x4;
fadt->pm1b_cnt_blk = 0x0;
fadt->pm2_cnt_blk = pmbase + 0x20;
fadt->pm_tmr_blk = pmbase + 0x8;
fadt->gpe0_blk = pmbase + 0x28;
fadt->gpe1_blk = 0;
fadt->pm1_evt_len = 4;
fadt->pm1_cnt_len = 2;
// XXX: pm2_cnt_len is probably wrong. find out right value (hint: it's != 0)
fadt->pm2_cnt_len = 2;
fadt->pm_tmr_len = 4;
fadt->gpe0_blk_len = 8;
fadt->gpe1_blk_len = 0;
fadt->gpe1_base = 0;
fadt->cst_cnt = CST_CONTROL;
fadt->p_lvl2_lat = 1;
fadt->p_lvl3_lat = 85;
fadt->flush_size = 1024;
fadt->flush_stride = 16;
fadt->duty_offset = 1;
fadt->duty_width = 0;
fadt->day_alrm = 0xd;
fadt->mon_alrm = 0x00;
fadt->century = 0x00;
fadt->iapc_boot_arch = 0x03;
fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;
fadt->reset_reg.space_id = 0;
fadt->reset_reg.bit_width = 0;
fadt->reset_reg.bit_offset = 0;
fadt->reset_reg.resv = 0;
fadt->reset_reg.addrl = 0x0;
fadt->reset_reg.addrh = 0x0;
fadt->reset_value = 0;
fadt->x_firmware_ctl_l = (unsigned long)facs;
fadt->x_firmware_ctl_h = 0;
fadt->x_dsdt_l = (unsigned long)dsdt;
fadt->x_dsdt_h = 0;
fadt->x_pm1a_evt_blk.space_id = 1;
fadt->x_pm1a_evt_blk.bit_width = 32;
fadt->x_pm1a_evt_blk.bit_offset = 0;
fadt->x_pm1a_evt_blk.resv = 0;
fadt->x_pm1a_evt_blk.addrl = pmbase;
fadt->x_pm1a_evt_blk.addrh = 0x0;
fadt->x_pm1b_evt_blk.space_id = 1;
fadt->x_pm1b_evt_blk.bit_width = 0;
fadt->x_pm1b_evt_blk.bit_offset = 0;
fadt->x_pm1b_evt_blk.resv = 0;
fadt->x_pm1b_evt_blk.addrl = 0x0;
fadt->x_pm1b_evt_blk.addrh = 0x0;
fadt->x_pm1a_cnt_blk.space_id = 1;
fadt->x_pm1a_cnt_blk.bit_width = 16;
fadt->x_pm1a_cnt_blk.bit_offset = 0;
fadt->x_pm1a_cnt_blk.resv = 0;
fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
fadt->x_pm1a_cnt_blk.addrh = 0x0;
fadt->x_pm1b_cnt_blk.space_id = 1;
fadt->x_pm1b_cnt_blk.bit_width = 0;
fadt->x_pm1b_cnt_blk.bit_offset = 0;
fadt->x_pm1b_cnt_blk.resv = 0;
fadt->x_pm1b_cnt_blk.addrl = 0x0;
fadt->x_pm1b_cnt_blk.addrh = 0x0;
fadt->x_pm2_cnt_blk.space_id = 1;
fadt->x_pm2_cnt_blk.bit_width = 8;
fadt->x_pm2_cnt_blk.bit_offset = 0;
fadt->x_pm2_cnt_blk.resv = 0;
fadt->x_pm2_cnt_blk.addrl = pmbase + 0x20;
fadt->x_pm2_cnt_blk.addrh = 0x0;
fadt->x_pm_tmr_blk.space_id = 1;
fadt->x_pm_tmr_blk.bit_width = 32;
fadt->x_pm_tmr_blk.bit_offset = 0;
fadt->x_pm_tmr_blk.resv = 0;
fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
fadt->x_pm_tmr_blk.addrh = 0x0;
fadt->x_gpe0_blk.space_id = 1;
fadt->x_gpe0_blk.bit_width = 64;
fadt->x_gpe0_blk.bit_offset = 0;
fadt->x_gpe0_blk.resv = 0;
fadt->x_gpe0_blk.addrl = pmbase + 0x28;
fadt->x_gpe0_blk.addrh = 0x0;
fadt->x_gpe1_blk.space_id = 1;
fadt->x_gpe1_blk.bit_width = 0;
fadt->x_gpe1_blk.bit_offset = 0;
fadt->x_gpe1_blk.resv = 0;
fadt->x_gpe1_blk.addrl = 0x0;
fadt->x_gpe1_blk.addrh = 0x0;
header->checksum =
acpi_checksum((void *) fadt, header->length);
}

View File

@ -0,0 +1,93 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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
*/
static u32 mainboard_cim_verb_data[] = {
/* coreboot specific header */
0x111d76d5, // Codec Vendor / Device ID: IDT / 92HD81
0x00000000, // Subsystem ID
0x0000000a, // Number of jacks
//Codec 92HD81 Yangtze 4ch Pin Port A, data = 0x02a11040
0x0A71C40,
0x0A71D10,
0x0A71EA1,
0x0A71F02,
//;Codec 92HD81 Yangtze 4ch Pin Port B, data = 0x0221101f
0x0B71C1F,
0x0B71D10,
0x0B71E21,
0x0B71F02,
//;Codec 92HD81 Yangtze 4ch Pin Port C, data = 0x400000f0
0x0C71CF0,
0x0C71D00,
0x0C71E00,
0x0C71F40,
//;Codec 92HD81 Yangtze 4ch Pin Port D, data = 0x10104110
0x0D71C10,
0x0D71D41,
0x0D71E10,
0x0D71F10,
//;Codec 92HD81 Yangtze 4ch Pin Port E, data = 0x400000f0
0x0E71CF0,
0x0E71D00,
0x0E71E00,
0x0E71F40,
//;Codec 92HD81 Yangtze 4ch Pin Port F, data = 0x400000f0
0x0F71CF0,
0x0F71D00,
0x0F71E00,
0x0F71F40,
//;Codec 92HD81 Yangtze 4ch Pin MonoOut, data = 0x40f000f0
0x1071CF0,
0x1071D00,
0x1071EF0,
0x1071F40,
//;Codec 92HD81 Yangtze 4ch Pin DMic0, data = 0x400000f0
0x1171CF0,
0x1171D00,
0x1171E00,
0x1171F40,
//;Codec 92HD81 Yangtze 4ch Pin Dig0Pin, data = 0x10402150
0x1F71C50,
0x1F71D21,
0x1F71E40,
0x1F71F10,
//;Codec 92HD81 Yangtze 4ch Pin Dig1Pin, data = 0x400000f0
0x2071CF0,
0x2071D00,
0x2071E00,
0x2071F40,
//; BTL Gain
0x017F417
// ; Gain = 16.79dB
};
extern const u32 *cim_verb_data;
extern u32 cim_verb_data_size;

View File

@ -0,0 +1,56 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2008 coresystems GmbH
*
* 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 <arch/pirq_routing.h>
const struct irq_routing_table intel_irq_routing_table = {
PIRQ_SIGNATURE, /* u32 signature */
PIRQ_VERSION, /* u16 version */
32+16*CONFIG_IRQ_SLOT_COUNT, /* Max. number of devices on the bus */
0x00, /* Interrupt router bus */
(0x1f << 3) | 0x0, /* Interrupt router dev */
0, /* IRQs devoted exclusively to PCI usage */
0x8086, /* Vendor */
0x8119, /* Device*/
0, /* Miniport */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0xdf, /* Checksum (has to be set to some value that
* would give 0 after the sum of all bytes
* for this structure (including checksum).
*/
{
/* bus, dev | fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
{0x00, (0x02 << 3) | 0x0, {{0x60, 0x5cb8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
{0x00, (0x1e << 3) | 0x0, {{0x60, 0x5cb8}, {0x61, 0x5cb8}, {0x62, 0x5cb8}, {0x00, 0x0000}}, 0x0, 0x0},
{0x00, (0x1f << 3) | 0x0, {{0x62, 0x5cb8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
{0x00, (0x1a << 3) | 0x0, {{0x60, 0x5cb8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
{0x00, (0x1d << 3) | 0x0, {{0x64, 0x8200}, {0x65, 0x8200}, {0x66, 0x8200}, {0x67, 0x8200}}, 0x0, 0x0},
{0x00, (0x1b << 3) | 0x0, {{0x60, 0x5cb8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
{0x00, (0x1c << 3) | 0x0, {{0x60, 0x5cb8}, {0x61, 0x5cb8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
{0x01, (0x00 << 3) | 0x0, {{0x60, 0x5cb8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
{0x02, (0x00 << 3) | 0x0, {{0x61, 0x5cb8}, {0x62, 0x5cb8}, {0x63, 0x5cb8}, {0x60, 0x5cb8}}, 0x2, 0x0},
{0x00, (0x00 << 3) | 0x0, {{0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0},
}
};
unsigned long write_pirq_routing_table(unsigned long addr)
{
return copy_pirq_routing_table(addr);
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
* Copyright (C) 2010 coresystems GmbH
*
* 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 <device/device.h>
#include <console/console.h>
#include <boot/tables.h>
#include "chip.h"
#include "hda_verb.h"
static void verb_setup(void)
{
cim_verb_data = mainboard_cim_verb_data;
cim_verb_data_size = sizeof(mainboard_cim_verb_data);
}
static void mainboard_enable(device_t dev)
{
verb_setup();
}
struct chip_operations mainboard_ops = {
CHIP_NAME("iW Rainbow G6 Mainboard")
.enable_dev = mainboard_enable,
};

View File

@ -0,0 +1,52 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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 <arch/io.h>
#include <arch/romcc_io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
#include "southbridge/intel/i82801gx/nvs.h" // FIXME: this should point to its own copy of nvs
/* The southbridge SMI handler checks whether gnvs has a
* valid pointer before calling the trap handler
*/
//extern global_nvs_t *gnvs;
int mainboard_io_trap_handler(int smif)
{
switch (smif) {
case 0x99:
printk(BIOS_DEBUG, "Sample\n");
//gnvs->smif = 0;
break;
default:
return 0;
}
/* On success, the IO Trap Handler returns 0
* On failure, the IO Trap Handler returns a value != 0
*
* For now, we force the return value to 0 and log all traps to
* see what's going on.
*/
//gnvs->smif = 0;
return 1;
}

View File

@ -0,0 +1,110 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2008 coresystems GmbH
*
* 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 <arch/smp/mpspec.h>
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
void *smp_write_config_table(void *v)
{
struct mp_config_table *mc;
int isa_bus;
mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
mptable_init(mc, "IWRAINBOWG6", LAPIC_ADDR);
smp_write_processors(mc);
mptable_write_buses(mc, NULL, &isa_bus);
smp_write_ioapic(mc, 2, 0x20, 0xfec00000);
{
device_t dev;
struct resource *res;
dev = dev_find_slot(1, PCI_DEVFN(0x1e,0));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 3, 0x20, res->base);
}
}
dev = dev_find_slot(1, PCI_DEVFN(0x1c,0));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 4, 0x20, res->base);
}
}
dev = dev_find_slot(4, PCI_DEVFN(0x1e,0));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 5, 0x20, res->base);
}
}
dev = dev_find_slot(4, PCI_DEVFN(0x1c,0));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 8, 0x20, res->base);
}
}
}
/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#
*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x0, 0x1, 0x0);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x1, 0x1, 0x1);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x0, 0x1, 0x2);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x3, 0x1, 0x3);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x4, 0x1, 0x4);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x6, 0x1, 0x6);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x7, 0x1, 0x7);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x1, 0x8, 0x1, 0x8);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x9, 0x1, 0x9);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0xc, 0x1, 0xc);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0xd, 0x1, 0xd);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0xe, 0x1, 0xe);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x8, 0x1, 0x10);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x74, 0x1, 0x10);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x75, 0x1, 0x11);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x76, 0x1, 0x12);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x77, 0x1, 0x13);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x6c, 0x1, 0x10);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x78, 0x1, 0x10);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x79, 0x1, 0x11);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x7a, 0x1, 0x12);
/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x0, MP_APIC_ALL, 0x0);
smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, isa_bus, 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);
printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
mc, smp_next_mpe_entry(mc));
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);
}

View File

@ -0,0 +1,379 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <stdint.h>
#include <string.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <device/pci_def.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/cache.h>
#include <arch/cpu.h>
#include <console/console.h>
#if 0
#include "ram/ramtest.c"
#include "southbridge/intel/sch/early_smbus.c"
#endif
//#include "pc80/mc146818rtc_early.c"
//#include "pc80/serial.c"
#define RFID_TEST 0
#if RFID_TEST
#define RFID_ADDR 0xA0
#define RFID_SELECT_CARD_COMMAND 0x01
#define SELECT_COMMAND_LENGTH 0x01
#define SMBUS_BASE_ADDRESS 0x400
static u32 sch_SMbase_read(void)
{
u32 SMBusBase;
SMBusBase = pci_read_config32(PCI_DEV(0, 0x1f, 0), 0x40); /*SM Bus Address */
SMBusBase &= 0xFFFF;
printk(BIOS_DEBUG, "SM Bus Base. =%x\r\n", SMBusBase);
return SMBusBase;
}
static void sch_SMbase_init(void)
{
u32 SMBusBase;
SMBusBase = sch_SMbase_read();
outb(0x3F, SMBusBase + SMBCLKDIV);
}
static void sch_SMbus_regs(void)
{
u32 SMBusBase;
SMBusBase = sch_SMbase_read();
printk(BIOS_DEBUG, "SMBHSTCNT. =%x\r\n", inb(SMBusBase + SMBHSTCNT));
printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n", inb(SMBusBase + SMBHSTSTS));
printk(BIOS_DEBUG, "SMBCLKDIV. =%x\r\n", inb(SMBusBase + SMBCLKDIV));
printk(BIOS_DEBUG, "SMBHSTADD. =%x\r\n", inb(SMBusBase + SMBHSTADD));
printk(BIOS_DEBUG, "SMBHSTCMD. =%x\r\n", inb(SMBusBase + SMBHSTCMD));
}
void smb_clear()
{
u32 SMBusBase;
SMBusBase = sch_SMbase_read();
outb(0x00, SMBusBase + SMBHSTCNT);
outb(0x07, SMBusBase + SMBHSTSTS);
}
void data_clear()
{
u32 SMBusBase;
SMBusBase = sch_SMbase_read();
outb(0x00, SMBusBase + SMBHSTDAT0);
outb(0x00, SMBusBase + SMBHSTCMD);
outb(0x00, SMBusBase + SMBHSTDAT1);
outb(0x00, SMBusBase + SMBHSTDATB);
outb(0x00, SMBusBase + (SMBHSTDATB + 0x1));
outb(0x00, SMBusBase + (SMBHSTDATB + 0x2));
outb(0x00, SMBusBase + (SMBHSTDATB + 0x3));
outb(0x00, SMBusBase + (SMBHSTDATB + 0x4));
outb(0x00, SMBusBase + (SMBHSTDATB + 0x5));
outb(0x00, SMBusBase + (SMBHSTDATB + 0x6));
}
void transaction1(unsigned char dev_addr)
{
int temp, a;
u32 SMBusBase;
SMBusBase = sch_SMbase_read();
printk(BIOS_DEBUG, "Transaction 1");
//clear the control and status registers
smb_clear();
//clear the data register
data_clear();
//program TSA register
outb(dev_addr, SMBusBase + SMBHSTADD);
//program command register
outb(0x04, SMBusBase + SMBHSTCMD);
//write data register
outb(0x04, SMBusBase + SMBHSTDAT0);
outb(0x04, SMBusBase + SMBHSTDATB);
outb(0x09, SMBusBase + (SMBHSTDATB + 0x1));
outb(0x11, SMBusBase + (SMBHSTDATB + 0x2));
outb(0x22, SMBusBase + (SMBHSTDATB + 0x3));
//set the control register
outb(0x15, SMBusBase + SMBHSTCNT);
//check the status register for busy state
//sch_SMbus_regs ();
temp = inb(SMBusBase + SMBHSTSTS);
//printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n",temp);
//printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",inb(SMBusBase+SMBHSTSTS));
do {
temp = inb(SMBusBase + SMBHSTSTS);
printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n", temp);
//sch_SMbus_regs ();
printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",
inb(SMBusBase + SMBHSTSTS));
if (temp > 0)
break;
} while (1);
switch (temp) {
case 1:
printk(BIOS_DEBUG, "SM Bus Success");
break;
default:
printk(BIOS_DEBUG, "SM Bus error %d", temp);
break;
}
sch_SMbus_regs();
printk(BIOS_DEBUG, "Command in TRansaction 1=%x\r\n\n",
inb(SMBusBase + SMBHSTCMD));
}
void transaction2(unsigned char dev_addr)
{
int temp, a;
u32 SMBusBase;
SMBusBase = sch_SMbase_read();
printk(BIOS_DEBUG, "Transaction 2");
//clear the control and status registers
smb_clear();
//clear the data register
data_clear();
//program TSA register
outb(dev_addr, SMBusBase + SMBHSTADD);
//program command register
outb(0x03, SMBusBase + SMBHSTCMD);
//write data register
outb(0x02, SMBusBase + SMBHSTDAT0);
outb(0x03, SMBusBase + SMBHSTDATB);
outb(0x09, SMBusBase + (SMBHSTDATB + 0x1));
outb(0x15, SMBusBase + SMBHSTCNT);
//check the status register for busy state
//sch_SMbus_regs ();
temp = inb(SMBusBase + SMBHSTSTS);
//printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n",temp);
//printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",inb(SMBusBase+SMBHSTSTS));
do {
temp = inb(SMBusBase + SMBHSTSTS);
printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n", temp);
//sch_SMbus_regs ();
printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",
inb(SMBusBase + SMBHSTSTS));
if (temp > 0)
break;
} while (1);
switch (temp) {
case 1:
printk(BIOS_DEBUG, "SM Bus Success");
break;
default:
printk(BIOS_DEBUG, "SM Bus error %d", temp);
break;
}
sch_SMbus_regs();
printk(BIOS_DEBUG, "Command in TRansaction 2=%x\r\n\n",
inb(SMBusBase + SMBHSTCMD));
}
void transaction3(unsigned char dev_addr)
{
int temp, index, length;
u32 SMBusBase;
SMBusBase = sch_SMbase_read();
printk(BIOS_DEBUG, "smb_read_multiple_bytes");
smb_clear();
data_clear();
outb(dev_addr, SMBusBase + SMBHSTADD);
outb(0x03, SMBusBase + SMBHSTCMD);
outb(0x11, SMBusBase + SMBHSTCNT);
//data_clear();
outb(dev_addr + 1, SMBusBase + SMBHSTADD);
outb(0x15, SMBusBase + SMBHSTCNT);
// sch_SMbus_regs ();
//check the status register for busy state
//temp=inb(SMBusBase+SMBHSTSTS);
//printk(BIOS_DEBUG, "SM Bus Busy.. status =%x\r\n",temp);
//sch_SMbus_regs ();
//printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",inb(SMBusBase+SMBHSTSTS));
do {
temp = inb(SMBusBase + SMBHSTSTS);
printk(BIOS_DEBUG, "SMBHSTSTS. =%x\r\n",
inb(SMBusBase + SMBHSTSTS));
//sch_SMbus_regs ();
if (temp > 0)
break;
} while (1);
switch (temp) {
case 1:
printk(BIOS_DEBUG, "SM Bus Success\n");
break;
default:
printk(BIOS_DEBUG, "SM Bus error %d", temp);
break;
}
sch_SMbus_regs();
printk(BIOS_DEBUG, "ADDRESS is.. %x\r\n", inb(SMBusBase + SMBHSTADD));
length = inb(SMBusBase + SMBHSTDAT0);
printk(BIOS_DEBUG, "Length is.. %x\r\n", inb(SMBusBase + SMBHSTDAT0));
printk(BIOS_DEBUG, "Command is... %x\r\n", inb(SMBusBase + SMBHSTDATB));
printk(BIOS_DEBUG, "Status .. %x\r\n", inb(SMBusBase + SMBHSTDATB + 1));
for (index = 0; index < length; index++)
printk(BIOS_DEBUG, "Serial Byte[%x]..%x\r\n", index,
inb(SMBusBase + SMBHSTDATB + index));
}
int selectcard(void)
{
int i;
printk(BIOS_DEBUG, "%s", "\r\nCase 9....... \n\r");
// send the length byte and command code through RFID interface
transaction1(RFID_ADDR);
transaction2(RFID_ADDR);
transaction3(RFID_ADDR);
return (1);
}
#endif
#include "northbridge/intel/sch/early_init.c"
#include "northbridge/intel/sch/raminit.h"
#include "northbridge/intel/sch/raminit.c"
static void sch_enable_lpc(void)
{
/* Initialize the FWH decode/Enable registers according to platform design */
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xD0, 0x00112233);
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xD4, 0xC0000000);
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x60, 0x808A8B8B);
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x64, 0x8F898F89);
}
static void sch_shadow_CMC(void)
{
u32 reg32;
/* FIXME: proper dest, proper src, and wbinvd, too */
memcpy((void *)CMC_SHADOW, (void *)0xfffd0000, 64 * 1024);
// __asm__ volatile ("wbinvd \n"
//);
printk(BIOS_DEBUG, "copy done ");
memcpy((void *)0x3f5f0000, (void *)0x3faf0000, 64 * 1024);
printk(BIOS_DEBUG, "copy 2 done ");
reg32 = cpuid_eax(0x00000001);
printk(BIOS_INFO, "CPU ID: %d.\n", reg32);
reg32 = cpuid_eax(0x80000008);
printk(BIOS_INFO, "Physical Address size: %d.\n", (reg32 & 0xFF));
printk(BIOS_INFO, "Virtual Address size: %d.\n", ((reg32 & 0xFF00) >> 8));
sch_port_access_write_ram_cmd(0xB8, 4, 0, 0x3faf0000);
printk(BIOS_DEBUG, "1 ");
sch_port_access_write_ram_cmd(0xBA, 4, 0, reg32);
printk(BIOS_DEBUG, "2 ");
}
static void poulsbo_setup_Stage1Regs(void)
{
u32 reg32;
printk(BIOS_DEBUG, "E000/F000 Routing ");
reg32 = sch_port_access_read(2, 3, 4);
sch_port_access_write(2, 3, 4, (reg32 | 0x6));
}
static void poulsbo_setup_Stage2Regs(void)
{
u32 reg32;
printk(BIOS_DEBUG, "Reserved");
reg32 = pci_read_config32(PCI_DEV(0, 0x2, 0), 0x62);
pci_write_config32(PCI_DEV(0, 0x2, 0), 0x62, (reg32 | 0x3));
/*Slot capabilities */
pci_write_config32(PCI_DEV(0, 28, 0), 0x54, 0x80500);
pci_write_config32(PCI_DEV(0, 28, 1), 0x54, 0x100500);
/* FIXME: CPU ID identification */
printk(BIOS_DEBUG, " done.\n");
}
void main(unsigned long bist)
{
int boot_mode = 0;
if (bist == 0) {
enable_lapic();
}
sch_enable_lpc();
/* Set up the console */
uart_init();
console_init();
/* Halt if there was a built in self test failure */
// report_bist_failure(bist);
// outl (0x00,0x1088);
/* Perform some early chipset initialization required
* before RAM initialization can work
*/
sch_early_initialization();
sdram_initialize(boot_mode);
sch_shadow_CMC();
poulsbo_setup_Stage1Regs();
poulsbo_setup_Stage2Regs();
#if 0
sch_SMbase_init ();
/* Perform some initialization that must run before stage2 */
#endif
/* This should probably go away. Until now it is required
* and mainboard specific
*/
/* Chipset Errata! */
pci_write_config16(PCI_DEV(0, 0x2, 0), GGC, 0x20);
pci_write_config32(PCI_DEV(0, 0x2, 0), 0xc4, 0x00000002);
pci_write_config32(PCI_DEV(0, 0x2, 0), 0xe0, 0x00008000);
pci_write_config32(PCI_DEV(0, 0x2, 0), 0xf0, 0x00000005);
pci_write_config16(PCI_DEV(0, 0x2, 0), 0xf7, 0x80);
pci_write_config16(PCI_DEV(0, 0x2, 0), 0x4, 0x7);
#if RFID_TEST
sch_SMbase_init();
selectcard();
#endif
}

View File

@ -8,3 +8,4 @@ source src/northbridge/intel/i82810/Kconfig
source src/northbridge/intel/i82830/Kconfig
source src/northbridge/intel/i855/Kconfig
source src/northbridge/intel/i945/Kconfig
source src/northbridge/intel/sch/Kconfig

View File

@ -9,3 +9,4 @@ subdirs-$(CONFIG_NORTHBRIDGE_INTEL_I82830) += i82830
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_I855) += i855
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_I945GC) += i945
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_I945GM) += i945
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_SCH) += sch

View File

@ -0,0 +1,29 @@
#
# This file is part of the coreboot project.
#
# Copyright (C) 2007-2009 coresystems GmbH
#
# 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
#
config NORTHBRIDGE_INTEL_SCH
bool
select HAVE_HIGH_TABLES
if NORTHBRIDGE_INTEL_SCH
config FALLBACK_VGA_BIOS_ID
string
default "8086,8108"
endif

View File

@ -0,0 +1,23 @@
#
# This file is part of the coreboot project.
#
# Copyright (C) 2007-2009 coresystems GmbH
#
# 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
#
driver-y += northbridge.c
driver-y += gma.c
driver-y += port_access.c
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c

View File

@ -0,0 +1,74 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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 <types.h>
#include <string.h>
#include <console/console.h>
#include <arch/acpi.h>
#include <arch/acpigen.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
unsigned long acpi_fill_mcfg(unsigned long current)
{
device_t dev;
u32 pciexbar = 0;
u32 pciexbar_reg;
int max_buses;
dev = dev_find_device(0x8086, 0x27a0, 0);
if (!dev)
return current;
pciexbar_reg=pci_read_config32(dev, 0x48);
// MMCFG not supported or not enabled.
if (!(pciexbar_reg & (1 << 0)))
return current;
switch ((pciexbar_reg >> 1) & 3) {
case 0: // 256MB
pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28));
max_buses = 256;
break;
case 1: // 128M
pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
max_buses = 128;
break;
case 2: // 64M
pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)|(1 << 26));
max_buses = 64;
break;
default: // RSVD
return current;
}
if (!pciexbar)
return current;
#if CONFIG_GENERATE_ACPI_TABLES
current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current,
pciexbar, 0x0, 0x0, max_buses - 1);
#endif
return current;
}

View File

@ -0,0 +1,237 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
Name(_HID,EISAID("PNP0A08")) // PCIe
Name(_CID,EISAID("PNP0A03")) // PCI
Device (MCHC)
{
Name(_ADR, 0x00000000) // 0:0.0
OperationRegion(MCHP, PCI_Config, 0x00, 0x100)
Field (MCHP, DWordAcc, NoLock, Preserve)
{
Offset (0x40), // EPBAR
EPEN, 1, // Enable
, 11, //
EPBR, 20, // EPBAR
Offset (0x44), // MCHBAR
MHEN, 1, // Enable
, 13, //
MHBR, 18, // MCHBAR
Offset (0x48), // PCIe BAR
PXEN, 1, // Enable
PXSZ, 2, // BAR size
, 23, //
PXBR, 6, // PCIe BAR
Offset (0x4c), // DMIBAR
DMEN, 1, // Enable
, 11, //
DMBR, 20, // DMIBAR
// ...
Offset (0x90), // PAM0
, 4,
PM0H, 2,
, 2,
Offset (0x91), // PAM1
PM1L, 2,
, 2,
PM1H, 2,
, 2,
Offset (0x92), // PAM2
PM2L, 2,
, 2,
PM2H, 2,
, 2,
Offset (0x93), // PAM3
PM3L, 2,
, 2,
PM3H, 2,
, 2,
Offset (0x94), // PAM4
PM4L, 2,
, 2,
PM4H, 2,
, 2,
Offset (0x95), // PAM5
PM5L, 2,
, 2,
PM5H, 2,
, 2,
Offset (0x96), // PAM6
PM6L, 2,
, 2,
PM6H, 2,
, 2,
Offset (0x9c), // Top of Low Used Memory
, 3,
TLUD, 5,
Offset (0xa0), // Top of Used Memory
TOM, 16,
}
}
// Current Resource Settings
Method (_CRS, 0, Serialized)
{
Name (MCRS, ResourceTemplate()
{
// Bus Numbers
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
0x0000, 0x0000, 0x00ff, 0x0000, 0x0100,,, PB00)
// IO Region 0
DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8,,, PI00)
// PCI Config Space
Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008)
// IO Region 1
DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, 0x0d00, 0xffff, 0x0000, 0xf300,,, PI01)
// VGA memory (0xa0000-0xbffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
0x00020000,,, ASEG)
// OPROM reserved (0xc0000-0xc3fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000c0000, 0x000c3fff, 0x00000000,
0x00004000,,, OPR0)
// OPROM reserved (0xc4000-0xc7fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000c4000, 0x000c7fff, 0x00000000,
0x00004000,,, OPR1)
// OPROM reserved (0xc8000-0xcbfff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000c8000, 0x000cbfff, 0x00000000,
0x00004000,,, OPR2)
// OPROM reserved (0xcc000-0xcffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000cc000, 0x000cffff, 0x00000000,
0x00004000,,, OPR3)
// OPROM reserved (0xd0000-0xd3fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000d0000, 0x000d3fff, 0x00000000,
0x00004000,,, OPR4)
// OPROM reserved (0xd4000-0xd7fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000d4000, 0x000d7fff, 0x00000000,
0x00004000,,, OPR5)
// OPROM reserved (0xd8000-0xdbfff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000d8000, 0x000dbfff, 0x00000000,
0x00004000,,, OPR6)
// OPROM reserved (0xdc000-0xdffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000dc000, 0x000dffff, 0x00000000,
0x00004000,,, OPR7)
// BIOS Extension (0xe0000-0xe3fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000e0000, 0x000e3fff, 0x00000000,
0x00004000,,, ESG0)
// BIOS Extension (0xe4000-0xe7fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000e4000, 0x000e7fff, 0x00000000,
0x00004000,,, ESG1)
// BIOS Extension (0xe8000-0xebfff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000e8000, 0x000ebfff, 0x00000000,
0x00004000,,, ESG2)
// BIOS Extension (0xec000-0xeffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000ec000, 0x000effff, 0x00000000,
0x00004000,,, ESG3)
// System BIOS (0xf0000-0xfffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x000f0000, 0x000fffff, 0x00000000,
0x00010000,,, FSEG)
// PCI Memory Region (Top of memory-0xfebfffff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0x00000000, 0xfebfffff, 0x00000000,
0x00000000,,, PM01)
// TPM Area (0xfed40000-0xfed44fff)
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, 0xfed40000, 0xfed44fff, 0x00000000,
0x00000000,,, TPMR)
})
// Find PCI resource area in MCRS
CreateDwordField(MCRS, PM01._MIN, PMIN)
CreateDwordField(MCRS, PM01._MAX, PMAX)
CreateDwordField(MCRS, PM01._LEN, PLEN)
// Fix up PCI memory region:
// Enter actual TOLUD. The TOLUD register contains bits 27-31 of
// the top of memory address.
ShiftLeft (^MCHC.TLUD, 27, PMIN)
Add(Subtract(PMAX, PMIN), 1, PLEN)
Return (MCRS)
}
/* IRQ assignment is mainboard specific. Get it from mainboard ACPI code */
#include "acpi/northbridge_pci_irqs.asl"

View File

@ -0,0 +1,324 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
Device (GFX0)
{
Name (_ADR, 0x00020000)
/* Display Output Switching */
Method (_DOS, 1)
{
/* Windows 2000 and Windows XP call _DOS to enable/disable
* Display Output Switching during init and while a switch
* is already active
*/
Store (And(Arg0, 7), DSEN)
}
/* We try to support as many i945 systems as possible,
* so keep the number of DIDs flexible.
*/
Method (_DOD, 0)
{
If (LEqual(NDID, 1)) {
Name(DOD1, Package() {
0xffffffff
})
Store (Or(0x00010000, DID1), Index(DOD1, 0))
Return(DOD1)
}
If (LEqual(NDID, 2)) {
Name(DOD2, Package() {
0xffffffff,
0xffffffff
})
Store (Or(0x00010000, DID2), Index(DOD2, 0))
Store (Or(0x00010000, DID2), Index(DOD2, 1))
Return(DOD2)
}
If (LEqual(NDID, 3)) {
Name(DOD3, Package() {
0xffffffff,
0xffffffff,
0xffffffff
})
Store (Or(0x00010000, DID3), Index(DOD3, 0))
Store (Or(0x00010000, DID3), Index(DOD3, 1))
Store (Or(0x00010000, DID3), Index(DOD3, 2))
Return(DOD3)
}
If (LEqual(NDID, 4)) {
Name(DOD4, Package() {
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff
})
Store (Or(0x00010000, DID4), Index(DOD4, 0))
Store (Or(0x00010000, DID4), Index(DOD4, 1))
Store (Or(0x00010000, DID4), Index(DOD4, 2))
Store (Or(0x00010000, DID4), Index(DOD4, 3))
Return(DOD4)
}
If (LGreater(NDID, 4)) {
Name(DOD5, Package() {
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff
})
Store (Or(0x00010000, DID5), Index(DOD5, 0))
Store (Or(0x00010000, DID5), Index(DOD5, 1))
Store (Or(0x00010000, DID5), Index(DOD5, 2))
Store (Or(0x00010000, DID5), Index(DOD5, 3))
Store (Or(0x00010000, DID5), Index(DOD5, 4))
Return(DOD5)
}
/* Some error happened, but we have to return something */
Return (Package() {0x00000400})
}
Device(DD01)
{
/* Device Unique ID */
Method(_ADR, 0, Serialized)
{
If(LEqual(DID1, 0)) {
Return (1)
} Else {
Return (And(0xffff, DID1))
}
}
/* Device Current Status */
Method(_DCS, 0)
{
TRAP(1)
If (And(CSTE, 1)) {
Return (0x1f)
}
Return(0x1d)
}
/* Query Device Graphics State */
Method(_DGS, 0)
{
If (And(NSTE, 1)) {
Return(1)
}
Return(0)
}
/* Device Set State */
Method(_DSS, 1)
{
/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
* display switch was completed
*/
If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
Store (NSTE, CSTE)
}
}
}
Device(DD02)
{
/* Device Unique ID */
Method(_ADR, 0, Serialized)
{
If(LEqual(DID2, 0)) {
Return (2)
} Else {
Return (And(0xffff, DID2))
}
}
/* Device Current Status */
Method(_DCS, 0)
{
TRAP(1)
If (And(CSTE, 2)) {
Return (0x1f)
}
Return(0x1d)
}
/* Query Device Graphics State */
Method(_DGS, 0)
{
If (And(NSTE, 2)) {
Return(1)
}
Return(0)
}
/* Device Set State */
Method(_DSS, 1)
{
/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
* display switch was completed
*/
If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
Store (NSTE, CSTE)
}
}
}
Device(DD03)
{
/* Device Unique ID */
Method(_ADR, 0, Serialized)
{
If(LEqual(DID3, 0)) {
Return (3)
} Else {
Return (And(0xffff, DID3))
}
}
/* Device Current Status */
Method(_DCS, 0)
{
TRAP(1)
If (And(CSTE, 4)) {
Return (0x1f)
}
Return(0x1d)
}
/* Query Device Graphics State */
Method(_DGS, 0)
{
If (And(NSTE, 4)) {
Return(1)
}
Return(0)
}
/* Device Set State */
Method(_DSS, 1)
{
/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
* display switch was completed
*/
If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
Store (NSTE, CSTE)
}
}
}
Device(DD04)
{
/* Device Unique ID */
Method(_ADR, 0, Serialized)
{
If(LEqual(DID4, 0)) {
Return (4)
} Else {
Return (And(0xffff, DID4))
}
}
/* Device Current Status */
Method(_DCS, 0)
{
TRAP(1)
If (And(CSTE, 8)) {
Return (0x1f)
}
Return(0x1d)
}
/* Query Device Graphics State */
Method(_DGS, 0)
{
If (And(NSTE, 4)) {
Return(1)
}
Return(0)
}
/* Device Set State */
Method(_DSS, 1)
{
/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
* display switch was completed
*/
If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
Store (NSTE, CSTE)
}
}
}
Device(DD05)
{
/* Device Unique ID */
Method(_ADR, 0, Serialized)
{
If(LEqual(DID5, 0)) {
Return (5)
} Else {
Return (And(0xffff, DID5))
}
}
/* Device Current Status */
Method(_DCS, 0)
{
TRAP(1)
If (And(CSTE, 16)) {
Return (0x1f)
}
Return(0x1d)
}
/* Query Device Graphics State */
Method(_DGS, 0)
{
If (And(NSTE, 4)) {
Return(1)
}
Return(0)
}
/* Device Set State */
Method(_DSS, 1)
{
/* If Parameter Arg0 is (1 << 31) | (1 << 30), the
* display switch was completed
*/
If (LEqual(And(Arg0, 0xc0000000), 0xc0000000)) {
Store (NSTE, CSTE)
}
}
}
}

View File

@ -0,0 +1,47 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
Device (PEGP)
{
Name (_ADR, 0x00010000)
// PCI Interrupt Routing.
Method (_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 16 },
Package() { 0x0000ffff, 1, 0, 17 },
Package() { 0x0000ffff, 2, 0, 18 },
Package() { 0x0000ffff, 3, 0, 19 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
})
}
}
}

View File

@ -0,0 +1,88 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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 "../../../northbridge/intel/sch/acpi/hostbridge.asl"
/* PCI Device Resource Consumption */
Device (PDRC)
{
Name (_HID, EISAID("PNP0C02"))
Name (_UID, 1)
// This does not seem to work correctly yet - set values statically for
// now.
//Name (PDRS, ResourceTemplate() {
// Memory32Fixed(ReadWrite, 0x00000000, 0x00004000, RCRB) // RCBA
// Memory32Fixed(ReadWrite, 0x00000000, 0x00004000, MCHB) // MCHBAR
// Memory32Fixed(ReadWrite, 0x00000000, 0x00001000, DMIB) // DMIBAR
// Memory32Fixed(ReadWrite, 0x00000000, 0x00001000, EGPB) // EPBAR
// Memory32Fixed(ReadWrite, 0x00000000, 0x00000000, PCIE) // PCIE BAR
// Memory32Fixed(ReadWrite, 0xfed20000, 0x00070000, ICHB) // Misc ICH
//})
Name (PDRS, ResourceTemplate() {
Memory32Fixed(ReadWrite, 0xfed1c000, 0x00004000) // RCBA
Memory32Fixed(ReadWrite, 0xfed14000, 0x00004000) // MCHBAR
Memory32Fixed(ReadWrite, 0xfed18000, 0x00001000) // DMIBAR
Memory32Fixed(ReadWrite, 0xfed19000, 0x00001000) // EPBAR
Memory32Fixed(ReadWrite, 0xf0000000, 0x04000000) // PCIE BAR
Memory32Fixed(ReadWrite, 0xfed20000, 0x00020000) // Misc ICH
Memory32Fixed(ReadWrite, 0xfed40000, 0x00005000) // Misc ICH
Memory32Fixed(ReadWrite, 0xfed45000, 0x0004b000) // Misc ICH
})
// Current Resource Settings
Method (_CRS, 0, Serialized)
{
//CreateDwordField(PDRS, ^RCRB._BAS, RBR0)
//ShiftLeft(\_SB.PCI0.LPCB.RCBA, 14, RBR0)
//CreateDwordField(PDRS, ^MCHB._BAS, MBR0)
//ShiftLeft(\_SB.PCI0.MCHC.MHBR, 14, MBR0)
//CreateDwordField(PDRS, ^DMIB._BAS, DBR0)
//ShiftLeft(\_SB.PCI0.MCHC.DMBR, 12, DBR0)
//CreateDwordField(PDRS, ^EGPB._BAS, EBR0)
//ShiftLeft(\_SB.PCI0.MCHC.EPBR, 12, EBR0)
//CreateDwordField(PDRS, ^PCIE._BAS, PBR0)
//ShiftLeft(\_SB.PCI0.MCHC.PXBR, 26, PBR0)
//CreateDwordField(PDRS, ^PCIE._LEN, PSZ0)
//ShiftLeft(0x10000000, \_SB.PCI0.MCHC.PXSZ, PSZ0)
Return(PDRS)
}
}
// PCIe graphics port 0:1.0
#include "../../../northbridge/intel/sch/acpi/peg.asl"
// Integrated graphics 0:2.0
#include "../../../northbridge/intel/sch/acpi/igd.asl"
Scope (\)
{
// backlight control, display switching, lid
#include "acpi/video.asl"
}

View File

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2010 coresystems GmbH
*
* 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
*/
struct northbridge_intel_sch_config {
};
extern struct chip_operations northbridge_intel_sch_ops;

View File

@ -0,0 +1,209 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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 "sch.h"
#include "southbridge/intel/sch/sch.h"
#if 0
static void sch_set_mtrr (void)
{
msr_t msr;
printk(BIOS_DEBUG, "1");
msr.hi = 0x06060606;
msr.lo = 0x06060606;
wrmsr (0x250, msr);
printk(BIOS_DEBUG, "2");
msr.hi = 0x06060606;
msr.lo = 0x06060606;
wrmsr (0x258, msr);
printk(BIOS_DEBUG, "3");
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x259, msr);
printk(BIOS_DEBUG, "4");
msr.hi = 0x04040404;
msr.lo = 0x04040404;
wrmsr (0x268, msr);
printk(BIOS_DEBUG, "5");
msr.hi = 0x04040404;
msr.lo = 0x04040404;
wrmsr (0x269, msr);
printk(BIOS_DEBUG, "6");
msr.hi = 0x04040404;
msr.lo = 0x04040404;
wrmsr (0x26A, msr);
printk(BIOS_DEBUG, "7");
msr.hi = 0x04040404;
msr.lo = 0x04040404;
wrmsr (0x26B, msr);
printk(BIOS_DEBUG, "8");
msr.hi = 0x04040404;
msr.lo = 0x04040404;
wrmsr (0x26C, msr);
printk(BIOS_DEBUG, "9");
msr.hi = 0x05050505;
msr.lo = 0x05050505;
wrmsr (0x26D, msr);
printk(BIOS_DEBUG, "10");
msr.hi = 0x05050505;
msr.lo = 0x05050505;
wrmsr (0x26E, msr);
printk(BIOS_DEBUG, "11");
msr.hi = 0x05050505;
msr.lo = 0x05050505;
wrmsr (0x26f, msr);
printk(BIOS_DEBUG, "12");
msr.hi = 0x0;
msr.lo = 0x6;
wrmsr (0x202, msr);
printk(BIOS_DEBUG, "13");
msr.hi = 0x0;
msr.lo = 0xC0000800;
wrmsr (0x203, msr);
printk(BIOS_DEBUG, "14");
msr.hi = 0x0;
msr.lo = 0x3FAF0000;
wrmsr (0x204, msr);
printk(BIOS_DEBUG, "15");
msr.hi = 0x0;
msr.lo = 0xFFFF0800;
wrmsr (0x205, msr);
printk(BIOS_DEBUG, "16");
msr.hi = 0x0;
msr.lo = 0x3FB00000;
wrmsr (0x206, msr);
printk(BIOS_DEBUG, "16");
msr.hi = 0x0;
msr.lo = 0xFFF00800;
wrmsr (0x207, msr);
printk(BIOS_DEBUG, "17");
msr.hi = 0x0;
msr.lo = 0x3FC00000;
wrmsr (0x208, msr);
printk(BIOS_DEBUG, "18");
msr.hi = 0x0;
msr.lo = 0xFFC00800;
wrmsr (0x209, msr);
printk(BIOS_DEBUG, "19");
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x20A, msr);
printk(BIOS_DEBUG, "20");
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x20B, msr);
printk(BIOS_DEBUG, "21");
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x20a, msr);
printk(BIOS_DEBUG, "22");
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x20B, msr);
printk(BIOS_DEBUG, "23");
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x20c, msr);
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x20d, msr);
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x20E, msr);
msr.hi = 0x0;
msr.lo = 0x0;
wrmsr (0x20F, msr);
msr.hi = 0x0;
msr.lo = 0XC00;
wrmsr (0x2FF, msr);
printk(BIOS_DEBUG, "end");
}
#endif
static void sch_detect_chipset(void)
{
u16 reg16;
u8 reg8;
printk(BIOS_INFO, "\n");
reg16 = pci_read_config16(PCI_DEV(0, 0x00, 0), 0x2);
switch (reg16)
{
case 0x8101:
printk(BIOS_INFO, "UL11L/US15L");
break;
case 0x8100:
printk(BIOS_INFO, "US15W");
break;
default:
printk(BIOS_INFO, "Unknown (%02x)", reg16); /* Others reserved. */
}
printk(BIOS_INFO, " Chipset\n");
reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0x8);
switch (reg8)
{
case 3:
printk(BIOS_INFO, "Qual. Sample ES1, Stepping B1");
break;
case 4:
printk(BIOS_INFO, "Qual. Sample ES2, Stepping C0");
break;
case 5:
printk(BIOS_INFO, "Qual. Sample ES2-Prime, Stepping D0");
break;
case 6:
printk(BIOS_INFO, "Qual. Sample QS, Stepping D1");
break;
default:
printk(BIOS_INFO, "Unknown (%02x)", reg8); /* Others reserved. */
}
}
static void sch_setup_non_standard_bars(void)
{
printk(BIOS_DEBUG, "Setting up ACPI PM1 block ");
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x48, (0x80000000 |DEFAULT_PMBASE)); /*Address 1000 size 16B*/
printk(BIOS_DEBUG, "Setting up ACPI P block ");
sch_port_access_write(4,0x70,4,0x80001010);/*Address 1010 size 16B*/
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x40, 0x80001040); /*SM Bus Address 1040 size 64B*/
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x44, 0x80001080); /*GPIO Address 1080 size 64B*/
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x4C, 0x800010C0); /*GPE0 Address 10C0 size 64B*/
sch_port_access_write(2,4,4,0x3F703F76); /* FIXME: SMM Control */
pci_write_config32(PCI_DEV(0, 0x02, 0), 0x5C, 0x3F800000); /*Base of Stolen memory Address 1080 size 64B*/
sch_port_access_write(0,0,4, DEFAULT_PCIEXBAR | 1); // pre-b1
sch_port_access_write(2,9,4, DEFAULT_PCIEXBAR | 1); // b1+
/*RCBA*/
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xF0, (DEFAULT_RCBABASE| 1 ));
printk(BIOS_DEBUG, " done.\n");
}
static void sch_early_initialization(void)
{
/* Print some chipset specific information */
sch_detect_chipset();
/* Setup all non standard BARs */
sch_setup_non_standard_bars();
}

View File

@ -0,0 +1,67 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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 <device/pci_ids.h>
static void gma_func0_init(struct device *dev)
{
u32 reg32;
/* IGD needs to be Bus Master */
reg32 = pci_read_config32(dev, PCI_COMMAND);
pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
pci_dev_init(dev);
}
static void gma_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations gma_pci_ops = {
.set_subsystem = gma_set_subsystem,
};
static struct device_operations gma_func0_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = gma_func0_init,
.scan_bus = 0,
.enable = 0,
.ops_pci = &gma_pci_ops,
};
static const struct pci_driver sch_gma_func0_driver __pci_driver = {
.ops = &gma_func0_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8108,
};

View File

@ -0,0 +1,339 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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 <arch/io.h>
#include <stdint.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/hypertransport.h>
#include <stdlib.h>
#include <string.h>
#include <bitops.h>
#include <cpu/cpu.h>
#include <boot/tables.h>
#include "chip.h"
#include "sch.h"
static int get_pcie_bar(u32 *base, u32 *len)
{
device_t dev;
u32 pciexbar_reg;
dev = dev_find_slot(0, PCI_DEVFN(0, 0));
if (!dev)
return 0;
// FIXME: determine at runtime
#ifdef POULSBO_PRE_B1
pciexbar_reg = sch_port_access_read(0,0,4);
#else
pciexbar_reg = sch_port_access_read(2,9,4);
#endif
if (!(pciexbar_reg & (1 << 0)))
return 0;
switch ((pciexbar_reg >> 1) & 3) {
case 0: // 256MB
*base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28));
*len = 256 * 1024 * 1024;
return 1;
case 1: // 128M
*base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
*len = 128 * 1024 * 1024;
return 1;
case 2: // 64M
*base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)|(1 << 26));
*len = 64 * 1024 * 1024;
return 1;
}
return 0;
}
/* IDG memory */
uint64_t uma_memory_base=0, uma_memory_size=0;
static void add_fixed_resources(struct device *dev, int index)
{
struct resource *resource;
u32 pcie_config_base, pcie_config_size;
printk(BIOS_DEBUG, "Adding UMA memory area\n");
resource = new_resource(dev, index);
resource->base = (resource_t) uma_memory_base;
resource->size = (resource_t) uma_memory_size;
resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) {
printk(BIOS_DEBUG, "Adding PCIe config bar\n");
resource = new_resource(dev, index+1);
resource->base = (resource_t) pcie_config_base;
resource->size = (resource_t) pcie_config_size;
resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
}
printk(BIOS_DEBUG, "Adding CMC shadow area\n");
resource = new_resource(dev, index+1);
resource->base = (resource_t) CMC_SHADOW;
resource->size = (resource_t) (64 * 1024);
resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
}
#if CONFIG_WRITE_HIGH_TABLES==1
#include <cbmem.h>
#endif
static void pci_domain_set_resources(device_t dev)
{
uint32_t pci_tolm;
uint8_t reg8;
uint16_t reg16;
unsigned long long tomk, tolud;
/* Can we find out how much memory we can use at most
* this way?
*/
pci_tolm = find_pci_tolm(dev->link_list);
printk(BIOS_DEBUG, "pci_tolm: 0x%x\n", pci_tolm);
printk(BIOS_SPEW, "Base of stolen memory: 0x%08x\n",
pci_read_config32(dev_find_slot(0, PCI_DEVFN(2, 0)), 0x5c));
tolud = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), 0x9c);
printk(BIOS_SPEW, "Top of Low Used DRAM: 0x%08llx\n", tolud << 24);
tomk = tolud << 14;
/* Note: subtract IGD device and TSEG */
reg8 = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), 0x9e);
if (reg8 & 1)
{
int tseg_size = 0;
printk(BIOS_DEBUG, "TSEG decoded, subtracting ");
reg8 >>= 1;
reg8 &= 3;
switch (reg8) {
case 0:
tseg_size = 1024;
break; /* TSEG = 1M */
case 1:
tseg_size = 2048;
break; /* TSEG = 2M */
case 2:
tseg_size = 8192;
break; /* TSEG = 8M */
}
printk(BIOS_DEBUG, "%dM\n", tseg_size >> 10);
tomk -= tseg_size;
}
reg16 = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0, 0)), GGC);
if (!(reg16 & 2))
{
int uma_size = 0;
printk(BIOS_DEBUG, "IGD decoded, subtracting ");
reg16 >>= 4;
reg16 &= 7;
switch (reg16)
{
case 1:
uma_size = 1024;
break;
case 2:
uma_size = 4096;
break;
case 3:
uma_size = 8192;
break;
}
printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
tomk -= uma_size;
/* For reserving UMA memory in the memory map */
uma_memory_base = tomk * 1024ULL;
uma_memory_size = uma_size * 1024ULL;
}
/* The following needs to be 2 lines, otherwise the second
* number is always 0
*/
printk(BIOS_INFO, "Available memory: %dK", (uint32_t)tomk);
printk(BIOS_INFO, " (%dM)\n", (uint32_t)(tomk >> 10));
/* Report the memory regions */
ram_resource(dev, 3, 0, 640);
ram_resource(dev, 4, 768, (tomk - 768));
if (tomk > 4 * 1024 * 1024) {
ram_resource(dev, 5, 4096 * 1024, tomk - 4 * 1024 * 1024);
}
add_fixed_resources(dev, 6);
assign_resources(dev->link_list);
#if CONFIG_WRITE_HIGH_TABLES==1
/* Leave some space for ACPI, PIRQ and MP tables */
high_tables_base = (tomk * 1024) - HIGH_MEMORY_SIZE;
high_tables_size = HIGH_MEMORY_SIZE;
#endif
}
/* TODO We could determine how many PCIe busses we need in
* the bar. For now that number is hardcoded to a max of 64.
* See e7525/northbridge.c for an example.
*/
static struct device_operations pci_domain_ops = {
.read_resources = pci_domain_read_resources,
.set_resources = pci_domain_set_resources,
.enable_resources = NULL,
.init = NULL,
.scan_bus = pci_domain_scan_bus,
#if CONFIG_MMCONF_SUPPORT_DEFAULT
.ops_pci_bus = &pci_ops_mmconf,
#else
.ops_pci_bus = &pci_cf8_conf1,
#endif
};
static void mc_read_resources(device_t dev)
{
struct resource *resource;
pci_dev_read_resources(dev);
/* So, this is one of the big mysteries in the coreboot resource
* allocator. This resource should make sure that the address space
* of the PCIe memory mapped config space bar. But it does not.
*/
/* We use 0xcf as an unused index for our PCIe bar so that we find it again */
resource = new_resource(dev, 0xcf);
resource->flags =
IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED |
IORESOURCE_ASSIGNED;
get_pcie_bar((u32*)&resource->base, (u32*)&resource->size);
printk(BIOS_DEBUG, "Adding PCIe enhanced config space BAR 0x%08lx-0x%08lx.\n",
(unsigned long)(resource->base), (unsigned long)(resource->base + resource->size));
}
static void mc_set_resources(device_t dev)
{
struct resource *resource;
/* Report the PCIe BAR */
resource = find_resource(dev, 0xcf);
if (resource) {
report_resource_stored(dev, resource, "<mmconfig>");
}
/* And call the normal set_resources */
pci_dev_set_resources(dev);
}
static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
#if CONFIG_HAVE_ACPI_RESUME
extern u8 acpi_slp_type;
static void northbridge_init(struct device *dev)
{
switch (pci_read_config32(dev, SKPAD)) {
case 0xcafebabe:
printk(BIOS_DEBUG, "Normal boot.\n");
acpi_slp_type=0;
break;
case 0xcafed00d:
printk(BIOS_DEBUG, "S3 Resume.\n");
acpi_slp_type=3;
break;
default:
printk(BIOS_DEBUG, "Unknown boot method, assuming normal.\n");
acpi_slp_type=0;
break;
}
}
#endif
static struct pci_operations intel_pci_ops = {
.set_subsystem = intel_set_subsystem,
};
static struct device_operations mc_ops = {
.read_resources = mc_read_resources,
.set_resources = mc_set_resources,
.enable_resources = pci_dev_enable_resources,
#if CONFIG_HAVE_ACPI_RESUME
.init = northbridge_init,
#endif
.scan_bus = 0,
.ops_pci = &intel_pci_ops,
};
static const struct pci_driver mc_driver __pci_driver = {
.ops = &mc_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8100,
};
static void cpu_bus_init(device_t dev)
{
initialize_cpus(dev->link_list);
}
static void cpu_bus_noop(device_t dev)
{
}
static struct device_operations cpu_bus_ops = {
.read_resources = cpu_bus_noop,
.set_resources = cpu_bus_noop,
.enable_resources = cpu_bus_noop,
.init = cpu_bus_init,
.scan_bus = 0,
};
static void enable_dev(device_t dev)
{
/* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops;
} else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops;
}
}
struct chip_operations northbridge_intel_sch_ops = {
CHIP_NAME("Intel SCH Northbridge")
.enable_dev = enable_dev,
};

View File

@ -0,0 +1,108 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 coresystems GmbH
*
* 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
*/
typedef struct {
u16 osys;
u8 smif;
u8 prm0;
u8 prm1;
u8 scif;
u8 prm2;
u8 prm3;
u8 lckf;
u8 prm4;
u8 prm5;
u32 p80d;
u8 lids;
u8 pwrs;
u8 dbgs;
u8 linxs;
u8 rsvd;
u8 actt;
u8 psvt;
u8 tc1v;
u8 tc2v;
u8 tspv;
u8 crtt;
u8 dtse;
u8 dts1;
u8 dts2;
u8 rsvd2;
u8 bnum;
u8 b0sc, b1sc, b2sc;
u8 b0ss, b1ss, b2ss;
u8 rsvd3[3];
u8 apic;
u8 mpen;
u8 bten;
u8 ppcm;
u8 pcp0;
u8 pcp1;
u8 rsvd4[4];
u8 natp;
u8 cmap;
u8 cmbp;
u8 lptp;
u8 fdcp;
u8 rfdv;
u8 hotk;
u8 rtcf;
u8 util;
u8 acin;
u8 igds;
u8 tlst;
u8 cadl;
u8 padl;
u16 cste;
u16 pste;
u16 nste;
u16 sste;
u8 ndid;
u32 did1;
u32 did2;
u32 did3;
u32 did4;
u32 did5;
u8 rsvd5[0xb];
u8 brtl;
u8 odds;
u8 alse;
u8 alaf;
u8 llow;
u8 lhih;
u8 rsvd6;
u8 emae;
u16 emap;
u16 emal;
u8 rsvd7;
u8 mefe;
u8 igps;
u8 rsvd8[2];
u8 tpmp;
u8 tpme;
u8 rsvd9[8];
u8 gtf0[7];
u8 gtf2[7];
u8 idem;
u8 idet;
u8 dock;
} global_nvs_t;

View File

@ -0,0 +1,66 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
static inline __attribute__ ((always_inline))
u8 pcie_read_config8(device_t dev, unsigned int where)
{
unsigned long addr;
addr = DEFAULT_PCIEXBAR | dev | where;
return read8(addr);
}
static inline __attribute__ ((always_inline))
u16 pcie_read_config16(device_t dev, unsigned int where)
{
unsigned long addr;
addr = DEFAULT_PCIEXBAR | dev | where;
return read16(addr);
}
static inline __attribute__ ((always_inline))
u32 pcie_read_config32(device_t dev, unsigned int where)
{
unsigned long addr;
addr = DEFAULT_PCIEXBAR | dev | where;
return read32(addr);
}
static inline __attribute__ ((always_inline))
void pcie_write_config8(device_t dev, unsigned int where, u8 value)
{
unsigned long addr;
addr = DEFAULT_PCIEXBAR | dev | where;
write8(addr, value);
}
static inline __attribute__ ((always_inline))
void pcie_write_config16(device_t dev, unsigned int where, u16 value)
{
unsigned long addr;
addr = DEFAULT_PCIEXBAR | dev | where;
write16(addr, value);
}
static inline __attribute__ ((always_inline))
void pcie_write_config32(device_t dev, unsigned int where, u32 value)
{
unsigned long addr;
addr = DEFAULT_PCIEXBAR | dev | where;
write32(addr, value);
}

View File

@ -0,0 +1,75 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <stdint.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <device/pci_def.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include "sch.h"
/*
* Restricted Access Regions:
*
* MCR - Message Control Register
* 31 24 16 8 4 0
* ----------------------------------------------------------------------------
* | | | Target | Write | |
* | Opcode | Port | register | byte | Reserved |
* | | | Address | Enables | |
* ----------------------------------------------------------------------------
*
* MDR - Message Data Register
* 31 0
* ----------------------------------------------------------------------------
* | |
* | Data |
* | |
* ----------------------------------------------------------------------------
*
*/
#define MSG_OPCODE_READ 0xD0000000
#define MSG_OPCODE_WRITE 0xE0000000
#define MCR 0xD0
#define MDR 0xD4
int sch_port_access_read(int port,int reg, int bytes)
{
pci_write_config32(PCI_DEV(0, 0, 0), MCR, (MSG_OPCODE_READ |(port <<16) | (reg << 8) ));
return pci_read_config32(PCI_DEV(0, 0, 0), MDR);
}
void sch_port_access_write(int port,int reg,int bytes,long data)
{
pci_write_config32(PCI_DEV(0, 0, 0), MDR,data);
pci_write_config32(PCI_DEV(0, 0, 0), MCR, (MSG_OPCODE_WRITE |(port <<16) | (reg << 8) ));
pci_read_config32(PCI_DEV(0, 0, 0), MDR);
}
void sch_port_access_write_ram_cmd(int cmd,int port,int reg,int data)
{
pci_write_config32(PCI_DEV(0, 0, 0), MDR,data);
pci_write_config32(PCI_DEV(0, 0, 0), MCR, ((cmd << 24) |(port <<16) | (reg << 8)));
pci_read_config32(PCI_DEV(0, 0, 0), MDR);
}

View File

@ -0,0 +1,331 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#include <spd.h>
#include "raminit.h"
#include "sch.h"
#define DEBUG_RAM_SETUP
#define SOFTSTRSP(base, off) *((volatile u8 *)((base) + (off)))
/* Debugging macros. */
#if defined(DEBUG_RAM_SETUP)
#define PRINTK_DEBUG(x...) printk(BIOS_DEBUG, x)
#else
#define PRINTK_DEBUG(x...)
#endif
#define BOOT_MODE_RESUME 1
#define BOOT_MODE_NORMAL 0
#include "port_access.c"
static void detect_fsb(struct sys_info *sysinfo)
{
u32 reg32;
reg32 = sch_port_access_read(5, 3, 4);
if (reg32 & BIT(3)) {
sysinfo->fsb_frequency = 533;
} else {
sysinfo->fsb_frequency = 400;
}
}
static u32 detect_softstrap_base(void)
{
u32 reg32, base_addr;
reg32 = sch_port_access_read(4, 0x71, 2);
reg32 &= 0x700;
reg32 = reg32 >> 7;
switch (reg32) {
case 7:
base_addr = 0xFFFB0000;
break;
case 6:
base_addr = 0xFFFC0000;
break;
case 5:
base_addr = 0xFFFD0000;
break;
case 4:
base_addr = 0xFFFE0000;
break;
}
return base_addr;
}
static void detect_softstraps(struct sys_info *sysinfo)
{
u8 reg8, temp;
u32 sbase = detect_softstrap_base();
reg8 = SOFTSTRSP(sbase, 0x87f2);
sysinfo->ranks = reg8;
if (reg8 == 0) {
sysinfo->ram_param_source = RAM_PARAM_SOURCE_SPD;
/* FIXME: implement SPD reading */
die("no support for reading DIMM config from SPD yet!");
return;
} else {
sysinfo->ram_param_source = RAM_PARAM_SOURCE_SOFTSTRAP;
/*Timings from soft strap */
reg8 = SOFTSTRSP(sbase, 0x87f0);
temp = reg8 & 0x30;
temp = temp >> 4;
sysinfo->cl = temp;
temp = reg8 & 0x0c;
temp = temp >> 2;
sysinfo->trcd = temp;
temp = reg8 & 0x03;
sysinfo->trp = temp;
/*Geometry from Softstrap */
reg8 = SOFTSTRSP(sbase, 0x87f1);
temp = reg8 & 0x06;
temp = temp >> 1;
sysinfo->device_density = temp;
temp = reg8 & 0x01;
sysinfo->data_width = temp;
/*Refresh rate default 7.8us */
sysinfo->refresh = 3;
}
}
static void program_sch_dram_data(struct sys_info *sysinfo)
{
u32 reg32;
/* Program DRP DRAM Rank Population and Interface Register
* as per data in sysinfo SCH port 1 register 0 .. 0XFF
*/
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4);
reg32 &= ~(DRP_FIELDS); /* Clear all DRP fields we'll change */
/* Rank0 Device Width, Density, Enable */
reg32 |= (sysinfo->data_width) | ((sysinfo->device_density) << 1) | (1 << 3);
/* Rank1 Device Width, Density, Enable */
reg32 |= (sysinfo->data_width << 4) | ((sysinfo->device_density) << 5) | (1 << 7);
sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4, reg32);
/*
Program DTR DRAM Timing Register as per data in sysinfo SCH port 1 register 1
tRD_dly = 2 (15:13 = 010b)
0X3F
*/
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DTR, 4);
reg32 &= ~(DTR_FIELDS); /* Clear all DTR fields we'll change */
reg32 = (sysinfo->trp);
reg32 |= (sysinfo->trcd) << 2;
reg32 |= (sysinfo->cl) << 4;
reg32 |= 0X4000; /* tRD_dly = 2 (15:13 = 010b) */
sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DTR, 4, reg32);
/* DCO DRAM Controller Operation Register as per data in sysinfo SCH port 1 register 2 0XF */
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4);
reg32 &= ~(DCO_FIELDS); /*Clear all DTR fields we'll change */
if (sysinfo->fsb_frequency == 533) {
reg32 |= 1;
} else {
reg32 &= ~(BIT(0));
}
reg32 = 0x006911c; // FIXME ?
sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4, reg32);
}
static void program_dll_config(struct sys_info *sysinfo)
{
if (sysinfo->fsb_frequency == 533) {
sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x21, 4, 0x46464646);
sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x22, 4, 0x46464646);
} else {
sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x21, 4, 0x58585858);
sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x22, 4, 0x58585858);
}
sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x23, 4, 0x2222);
if (sysinfo->fsb_frequency == 533) {
sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x20, 4, 0x993B);
} else {
sch_port_access_write(SCH_MSG_DUNIT_PORT, 0x20, 4, 0xCC3B);
}
}
static void do_jedec_init(struct sys_info *sysinfo)
{
u32 reg32, rank, cmd, temp, num_ranks;
/* Performs JEDEC memory initializattion for all memory rows */
/* Set CKE0/1 low */
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4);
reg32 |= DRP_CKE_DIS;
sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4, reg32);
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4);
rank = 0;
num_ranks = sysinfo->ranks;
do {
/* Start clocks */
reg32 =
sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4);
reg32 &= ~(DRP_SCK_DIS); /* Enable all SCK/SCKB by def. */
sch_port_access_write(1, SCH_MSG_DUNIT_REG_DRP, 4, reg32);
/* Program miscellaneous SCH registers on rank 0 initialization */
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4);
if (rank == 0) {
program_dll_config(sysinfo);
}
printk(BIOS_DEBUG, "Setting up RAM \n");
/*
Wait 200us
reg32 = inb(ACPI_BASE + 8); PM1 Timer
reg32 &=0xFFFFFF;
reg32 +=0x2EE;
do
{
reg32 = inb(ACPI_BASE + 8);PM1 Timer
reg32 &= 0xFFFFFF;
}while (reg32 < 0x2EE); */
/* Apply NOP */
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_NOP;
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/* Set CKE=high */
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4);
reg32 &= 0xFFFF9FFF; /* Clear both the CKE static disables */
sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4, reg32);
/* Wait 400ns (not needed when executing from flash)
Precharge all
*/
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DRP, 4);
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_PALL;
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/*EMRS(2); High temp self refresh=disabled, partial array self refresh=full */
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_EMRS2;
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/*EMRS(3) (no command) */
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_EMRS3;
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/*EMRS(1); Enable DLL (Leave all bits in the command at 0) */
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_EMRS1;
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/*MRS; Reset DLL (Set memory address bit 8) */
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_MRS;
cmd |= (SCH_JEDEC_DLLRESET << SCH_DRAMINIT_ADDR_OFFSET);
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/*Precharge all */
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_PALL;
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/*Issue 2 auto-refresh commands */
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_AREF;
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/*MRS command including tCL, tWR, burst length (always 4) */
cmd = rank;
cmd |= (SCH_DRAMINIT_CMD_MRS + JEDEC_STATIC_PARAM); /*Static param */
temp = sysinfo->cl;
temp += TCL_LOW; /*Adjust for the TCL base */
temp = temp << ((SCH_JEDEC_CL_OFFSET + SCH_DRAMINIT_ADDR_OFFSET)); /*Ready the CAS latency */
cmd |= temp;
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/* Wait 200 clocks (max of 1us, so no need to delay)
Issue EMRS(1):OCD default
*/
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_EMRS1;
cmd |= (SCH_JEDEC_OCD_DEFAULT << SCH_DRAMINIT_ADDR_OFFSET);
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
/*Issue EMRS(1): OCD cal. mode exit. */
cmd = rank;
cmd |= SCH_DRAMINIT_CMD_EMRS1;
cmd |= (SCH_JEDEC_DQS_DIS << SCH_DRAMINIT_ADDR_OFFSET);
sch_port_access_write_ram_cmd(SCH_OPCODE_DRAMINIT, SCH_MSG_DUNIT_PORT, 0, cmd);
rank += SCH_DRAMINIT_RANK_MASK;
num_ranks--;
} while (num_ranks);
}
/**
* @param boot_mode: 0 = normal, 1 = resume
*/
void sdram_initialize(int boot_mode)
{
struct sys_info sysinfo;
u32 reg32;
printk(BIOS_DEBUG, "Setting up RAM controller.\n");
memset(&sysinfo, 0, sizeof(sysinfo));
detect_fsb(&sysinfo);
detect_softstraps(&sysinfo);
program_sch_dram_data(&sysinfo);
/* cold boot */
if (boot_mode == BOOT_MODE_NORMAL) {
do_jedec_init(&sysinfo);
} else {
program_dll_config(&sysinfo);
}
/* raminit complete */
reg32 = sch_port_access_read(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4);
reg32 |= DCO_IC;
reg32 |= ((sysinfo.refresh) << 2);
reg32 = 0x006919c;
sch_port_access_write(SCH_MSG_DUNIT_PORT, SCH_MSG_DUNIT_REG_DCO, 4, reg32);
/* setting up TOM */
reg32 = 0x10000000;
reg32 = reg32 >> sysinfo.data_width;
reg32 = reg32 << sysinfo.device_density;
reg32 = reg32 << sysinfo.ranks;
reg32 = 0x40000000;
sch_port_access_write(2, 8, 4, reg32);
/* resume mode */
if (boot_mode == BOOT_MODE_RESUME) {
sch_port_access_write_ram_cmd(SCH_OPCODE_WAKEFULLON,
SCH_MSG_DUNIT_PORT, 0, 0);
}
sch_port_access_write(2, 0, 4, 0x98);
sch_port_access_write(2, 3, 4, 0x7);
sch_port_access_write(3, 2, 4, 0x408);
sch_port_access_write(4, 0x71, 4, 0x600);
}

View File

@ -0,0 +1,182 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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
*/
#ifndef RAMINIT_H
#define RAMINIT_H
/**
* Bit Equates
**/
#define BIT(x) (1<<x)
#define EBP_TRP_MASK (BIT(1) | BIT(0))
#define TRP_LOW 3h
#define TRP_HIGH 5h
#define EBP_TRP_OFFSET 0 /* Start of TRP field in EBP*/
#define EBP_TRCD_MASK (BIT(3) | BIT(2))
#define TRCD_LOW 3h
#define TRCD_HIGH 5h
#define EBP_TRCD_OFFSET 2 /* Start of TRCD field in EBP*/
#define EBP_TCL_MASK (BIT(5) | BIT(4))
#define TCL_LOW 3 /* Minimum supported CL*/
#define TCL_HIGH 5 /* Maximum supported CL*/
#define EBP_TCL_OFFSET 4 /* EBP bit( )for CL mask*/
#define EBP_DDR2_CL_5_0 BIT(5) /* CL 5.0 = 10b*/
#define EBP_DDR2_CL_4_0 BIT(4) /* CL 4.0 = 01b*/
#define EBP_DDR2_CL_3_0 00h /* CL 3.0 = 00b*/
#define EBP_FREQ_MASK (BIT(10)| BIT(9))
#define EBP_FREQ_OFFSET 9 /* EBP bit( )for frequency mask*/
#define EBP_FREQ_400 0 /* 400MHz EBP[10:9] = 00b*/
#define EBP_FREQ_533 BIT(9) /* 533MHz EBP[10:9] = 01b*/
#define EBP_REFRESH_MASK (BIT(12)| BIT(11))
#define EBP_REFRESH_OFFSET 11 /* Bit offset of refresh field*/
#define EBP_REF_DIS 00h /* Mask for refresh disabled*/
#define EBP_REF_128CLK BIT(11) /* Mask for 128 clks referesh rate*/
#define EBP_REF_3_9 BIT(12) /* Mask for 3.9us refresh rate*/
#define EBP_REF_7_8 (BIT(12)| BIT(11))/* Mask for 7.8us refresh rate*/
#define EBP_WIDTH_MASK BIT(15)
#define EBP_WIDTH_OFFSET 15 /* Bit offset of EBP width field*/
#define EBP_SOCKET_X16 BIT(15) /* Bit mask of x8/x16 bit*/
#define EBP_DENSITY_MASK (BIT(17)| BIT(16))
#define EBP_DENSITY_OFFSET 16
#define EBP_DENSITY_512 BIT(16) /* 512Mbit density*/
#define EBP_DENSITY_1024 BIT(17) /* 1024Mbit density*/
#define EBP_DENSITY_2048 (BIT(17)| BIT(16))/* 2048Mbit density*/
#define EBP_RANKS_MASK BIT(18)
#define EBP_RANKS_OFFSET 18
#define EBP_RANKS BIT(18) /* Bit offset of # of ranks bit*/
#define EBP_PACKAGE_TYPE BIT(19) /* Package type (stacked or not)*/
#define EBP_2X_MASK BIT(20)
#define EBP_2X_OFFSET 20 /* Bit offset of ebp 2x refresh field*/
#define EBP_2X_AUTO_REFRESH BIT(20) /* Bit mask of 2x refresh field*/
#define EBP_DRAM_PARM_MASK BIT(21)
#define EBP_DRAM_PARM_OFFSET 21
#define EBP_DRAM_PARM_SPD 0 /* Use SPD to get DRAM parameters*/
#define EBP_DRAM_PARM_CMC BIT(21) /* DRAM parameters in CMC binary*/
#define EBP_BOOT_PATH BIT(31)
#define HB_REG_MCR 0xD0 /* Message Control Register */
#define HB_REG_MCR_OP_OFFSET 24 /* Offset of the opcode field in MCR */
#define HB_REG_MCR_PORT_OFFSET 16 /* Offset of the port field in MCR */
#define HB_REG_MCR_REG_OFFSET 8 /* Offset of the register field in MCR */
#define HB_REG_MDR 0xD4 /* Message Data Register */
/* SCH Message OpCodes and Attributes*/
#define SCH_OPCODE_WAKEFULLON 0x2 /* SCH message bus "Wake Full On" opcode*/
#define SCH_OPCODE_DRAMINIT 0xA0 /* SCH message bus "DRAM Init" opcode */
#define SCH_DRAMINIT_CMD_MRS 0x4000 /* MRS command */
#define SCH_DRAMINIT_CMD_EMRS1 0x8 /* EMRS 1 command */
#define SCH_DRAMINIT_CMD_EMRS2 0x10 /* EMRS 2 command */
#define SCH_DRAMINIT_CMD_EMRS3 0x18 /* EMRS 3 command */
#define SCH_DRAMINIT_CMD_CBR 0x1 /* CBR command */
#define SCH_DRAMINIT_CMD_AREF 0x10001 /* Refresh command, MA10=0->All */
#define SCH_DRAMINIT_CMD_PALL 0x10002 /* Precharge command, MA10=1->All */
#define SCH_DRAMINIT_CMD_BACT 0x3 /* Bank activate command */
#define SCH_DRAMINIT_CMD_NOP 0x7 /* NOP command */
#define SCH_DRAMINIT_RANK_OFFSET 21 /* Offset of the rank selection bit */
#define SCH_DRAMINIT_RANK_MASK BIT(21)
#define SCH_DRAMINIT_ADDR_OFFSET 6 /* Offset of the address field in MDR */
#define SCH_DRAMINIT_INTLV BIT(3) /* Interleave burst type */
#define SCH_DRAMINIT_BL4 2 /* Burst Length = 4 */
#define SCH_DRAMINIT_CL_OFFSET 4 /* CAS Latency bit offset */
#define SCH_DRAMINIT_OCD_DEFAULT 0xE000 /* OCD Default command */
#define SCH_DRAMINIT_DQS_DIS BIT(16) /* DQS Disable command */
#define SCH_OPCODE_READ 0xD0 /* SCH message bus "read" opcode */
#define SCH_OPCODE_WRITE 0xE0 /* SCH message bus "write" opcode */
/* SCH Message Ports and Registers*/
#define SCH_MSG_DUNIT_PORT 0x1 /* DRAM unit port */
#define SCH_MSG_DUNIT_REG_DRP 0x0 /* DRAM Rank Population and Interface */
#define DRP_FIELDS 0xFF /* Pertinent fields in DRP */
#define DRP_RANK0_OFFSET 3 /* Rank 0 enable offset */
#define DRP_RANK1_OFFSET 7 /* Rank 1 enable offset */
#define DRP_DENSITY0_OFFSET 1 /* Density offset - Rank 0 */
#define DRP_DENSITY1_OFFSET 5 /* Density offset - Rank 1 */
#define DRP_WIDTH0_OFFSET 0 /* Width offset - Rank 0 */
#define DRP_WIDTH1_OFFSET 4 /* Width offset - Rank 1 */
#define DRP_CKE_DIS (BIT(14)| BIT(13)) /* CKE disable bits for both ranks */
#define DRP_CKE_DIS0 BIT(13) /* CKE disable bit - Rank 0 */
#define DRP_CKE_DIS1 BIT(14) /* CKE disable bit - Rank 1 */
#define DRP_SCK_DIS (BIT(11)| BIT(10)) /* SCK/SCKB disable bits */
#define DRP_SCK_DIS1 BIT(11) /* SCK[1]/SCKB[1] disable */
#define DRP_SCK_DIS0 BIT(10) /* SCK[0]/SCKB[0] disable */
#define SCH_MSG_DUNIT_REG_DTR 0x01 /* DRAM Timing Register */
#define DTR_FIELDS 0x3F /* Pertinent fields in DTR */
#define DTR_TCL_OFFSET 4 /* CAS latency offset */
#define DTR_TRCD_OFFSET 2 /* RAS CAS Delay Offset */
#define DTR_TRP_OFFSET 0 /* RAS Precharge Delay Offset */
#define SCH_MSG_DUNIT_REG_DCO 0x2 /* DRAM Control Register */
#define DCO_FIELDS 0xF /* Pertinent fields in DCO */
#define DCO_REFRESH_OFFSET 2 /* Refresh Rate Field Offset */
#define DCO_FREQ_OFFSET 0 /* DRAM Frequency Field Offset */
#define DCO_IC BIT(7) /* Initialization complete bit */
#define SCH_MSG_PUNIT_PORT 04h /* Punit Port */
#define SCH_MSG_PUNIT_REG_PCR 71h /* Punit Control Register */
#define SCH_MSG_TEST_PORT 05h /* Test port */
#define SCH_MSG_TEST_REG_MSR 03h /* Mode and Status Register */
/* Jedec initialization mapping into the MDR address field for DRAM init messages*/
#define SCH_JEDEC_DLLRESET BIT(8) /* DLL Reset bit( ) */
#define SCH_JEDEC_INTLV BIT(3) /* Interleave/NOT(Sequential) bit( ) */
#define SCH_JEDEC_CL_OFFSET 4 /* Offset of the CAS latency field */
#define SCH_JEDEC_OCD_DEFAULT (BIT(7)| BIT(8)| BIT(9)) /* OCD default value */
#define SCH_JEDEC_DQS_DIS BIT(10) /* DQS disable bit */
#define SCH_JEDEC_BL4 BIT(1) /* Burst length 4 value */
/*static values used during JEDEC iniatialization. These values are not
dependent on memory or chipset configuration.*/
#define JEDEC_STATIC_PARAM ((SCH_JEDEC_INTLV << SCH_DRAMINIT_ADDR_OFFSET) + (SCH_JEDEC_BL4 << SCH_DRAMINIT_ADDR_OFFSET))
#define DIMM_SOCKETS 2
#define DIMM_SPD_BASE 0x50
#define DIMM_TCO_BASE 0x30
/* Burst length is always 8 */
#define BURSTLENGTH 8
#define RAM_PARAM_SOURCE_SOFTSTRAP 1
#define RAM_PARAM_SOURCE_SPD 0
struct sys_info {
u16 memory_frequency; /* 400 or 533*/
u16 fsb_frequency; /* 400 or 533*/
u8 trp; /*3,4,5 DRAM clocks */
u8 trcd; /*3,4,5 DRAM clocks */
u8 cl; /*CAS Latency 3,4,5*/
u8 refresh; /*Refresh rate disabled,128 DRAM clocks,3.9us,7.8us */
u8 data_width; /*x8/x16 data width */
u8 device_density; /*SDRAM Device Density 512/1024/2048Mbit */
u8 ranks; /*Single/Double */
u8 ram_param_source; /*DRAM Parameter Source SPD/SoftStraps(R) Block (down memory) */
u8 boot_path;
} __attribute__ ((packed));
void sdram_initialize(int boot_mode);
#endif /* RAMINIT_H */

View File

@ -0,0 +1,54 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2008 coresystems GmbH
* Copyright (C) 2009-2010 iWave Systems
*
* 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
*/
#ifndef __SCH_PULSBO_H__
#define __SCH_PULSBO_H__ 1
int sch_port_access_read(int port,int reg, int bytes);
void sch_port_access_write(int port,int reg,int bytes,long data);
void sch_port_access_write_ram_cmd(int cmd,int port,int reg,int data);
/* Southbridge IO BARs */
/* TODO Make sure these don't get changed by stage2 */
#define SCH_ENABLE_BIT (1<<31)
#define DEFAULT_ACPIPBLKBASE 0x510
#define DEFAULT_SMBUSBASE 0x540
#define DEFAULT_GPIOBASE 0x588
#define DEFAULT_GPE0BASE 0x5C0
#define DEFAULT_SMMCNTRLBASE 0x3F703F76
#define DEFAULT_RCBABASE 0xfed1c000
#define DEFAULT_PCIEXBAR 0xe0000000 /* 4 KB per PCIe device */
/* IGD */
#define GGC 0x52
/* Root Complex Register Block */
#define RCBA8(x) *((volatile u8 *)(DEFAULT_RCBABASE + x))
#define RCBA16(x) *((volatile u16 *)(DEFAULT_RCBABASE + x))
#define RCBA32(x) *((volatile u32 *)(DEFAULT_RCBABASE + x))
/* FIXME: should probably be in southbridge, but is setup in romstage, too */
#define CMC_SHADOW 0x3faf0000
#endif

View File

@ -9,3 +9,4 @@ source src/southbridge/intel/i82801ex/Kconfig
source src/southbridge/intel/i82801gx/Kconfig
source src/southbridge/intel/i82870/Kconfig
source src/southbridge/intel/pxhd/Kconfig
source src/southbridge/intel/sch/Kconfig

View File

@ -9,4 +9,4 @@ subdirs-$(CONFIG_SOUTHBRIDGE_INTEL_I82801EX) += i82801ex
subdirs-$(CONFIG_SOUTHBRIDGE_INTEL_I82801GX) += i82801gx
subdirs-$(CONFIG_SOUTHBRIDGE_INTEL_I82870) += i82870
subdirs-$(CONFIG_SOUTHBRIDGE_INTEL_PXHD) += pxhd
subdirs-$(CONFIG_SOUTHBRIDGE_INTEL_SCH) += sch

View File

@ -0,0 +1,32 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2010 coresystems GmbH
##
## 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
##
config SOUTHBRIDGE_INTEL_SCH
bool
select TINY_BOOTBLOCK
select HAVE_USBDEBUG
config EHCI_BAR
hex
default 0xfef00000 if SOUTHBRIDGE_INTEL_SCH
config EHCI_DEBUG_OFFSET
hex
default 0xa0 if SOUTHBRIDGE_INTEL_SCH

View File

@ -0,0 +1,41 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2010 coresystems GmbH
##
## 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
##
driver-y += south.c
driver-y += audio.c
driver-y += lpc.c
driver-y += ide.c
driver-y += pcie.c
driver-y += usb.c
driver-y += usb_ehci.c
driver-y += usb_client.c
driver-y += mmc.c
driver-y += smbus.c
ramstage-y += reset.c
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c
romstage-$(CONFIG_USBDEBUG) += usb_debug.c
cbfs-files-y += cmc.bin
cmc.bin-name := cmc.bin
cmc.bin-type := 0xaa
cmc.bin-position := 0xfffd0000

View File

@ -0,0 +1,39 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* Intel i82801G AC'97 Audio and Modem */
// Intel AC'97 Audio 0:1e.2
Device (AUD0)
{
Name (_ADR, 0x001e0002)
}
// Intel AC'97 Modem 0:1e.3
Device (MODM)
{
Name (_ADR, 0x001e0003)
Name (_PRW, Package(){ 5, 4 })
}

View File

@ -0,0 +1,36 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* Intel i82801G HDA */
// Intel High Definition Audio (Azalia) 0:1b.0
Device (HDEF)
{
Name (_ADR, 0x001b0000)
// Power Resources for Wake
Name (_PRW, Package(){
5, // Bit 5 of GPE
4 // Can wake from S4 state.
})
}

View File

@ -0,0 +1,161 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* Global Variables */
Name(\PICM, 0) // IOAPIC/8259
Name(\DSEN, 1) // Display Output Switching Enable
/* Global ACPI memory region. This region is used for passing information
* between coreboot (aka "the system bios"), ACPI, and the SMI handler.
* Since we don't know where this will end up in memory at ACPI compile time,
* we have to fix it up in coreboot's ACPI creation phase.
*/
OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0x100)
Field (GNVS, ByteAcc, NoLock, Preserve)
{
/* Miscellaneous */
Offset (0x00),
OSYS, 16, // 0x00 - Operating System
SMIF, 8, // 0x02 - SMI function
PRM0, 8, // 0x03 - SMI function parameter
PRM1, 8, // 0x04 - SMI function parameter
SCIF, 8, // 0x05 - SCI function
PRM2, 8, // 0x06 - SCI function parameter
PRM3, 8, // 0x07 - SCI function parameter
LCKF, 8, // 0x08 - Global Lock function for EC
PRM4, 8, // 0x09 - Lock function parameter
PRM5, 8, // 0x0a - Lock function parameter
P80D, 32, // 0x0b - Debug port (IO 0x80) value
LIDS, 8, // 0x0f - LID state (open = 1)
PWRS, 8, // 0x10 - Power State (AC = 1)
DBGS, 8, // 0x11 - Debug State
LINX, 8, // 0x12 - Linux OS
DCKN, 8, // 0x13 - PCIe docking state
/* Thermal policy */
Offset (0x14),
ACTT, 8, // 0x14 - active trip point
PSVT, 8, // 0x15 - passive trip point
TC1V, 8, // 0x16 - passive trip point TC1
TC2V, 8, // 0x17 - passive trip point TC2
TSPV, 8, // 0x18 - passive trip point TSP
CRTT, 8, // 0x19 - critical trip point
DTSE, 8, // 0x1a - Digital Thermal Sensor enable
DTS1, 8, // 0x1b - DT sensor 1
DTS2, 8, // 0x1c - DT sensor 2
/* Battery Support */
Offset (0x1e),
BNUM, 8, // 0x1e - number of batteries
B0SC, 8, // 0x1f - BAT0 stored capacity
B1SC, 8, // 0x20 - BAT1 stored capacity
B2SC, 8, // 0x21 - BAT2 stored capacity
B0SS, 8, // 0x22 - BAT0 stored status
B1SS, 8, // 0x23 - BAT1 stored status
B2SS, 8, // 0x24 - BAT2 stored status
/* Processor Identification */
Offset (0x28),
APIC, 8, // 0x28 - APIC Enabled by coreboot
MPEN, 8, // 0x29 - Multi Processor Enable
PCP0, 8, // 0x2a - PDC CPU/CORE 0
PCP1, 8, // 0x2b - PDC CPU/CORE 1
PPCM, 8, // 0x2c - Max. PPC state
/* Super I/O & CMOS config */
Offset (0x32),
NATP, 8, // 0x32 - ...
/* Integrated Graphics Device */
Offset (0x3c),
IGDS, 8, // 0x3c - IGD state (primary = 1)
TLST, 8, // 0x3d - Display Toggle List pointer
CADL, 8, // 0x3e - Currently Attached Devices List
PADL, 8, // 0x3f - Previously Attached Devices List
CSTE, 16, // 0x40 - Current display state
NSTE, 16, // 0x42 - Next display state
SSTE, 16, // 0x44 - Set display state
Offset (0x46),
NDID, 8, // 0x46 - Number of Device IDs
DID1, 32, // 0x47 - Device ID 1
DID2, 32, // 0x4b - Device ID 2
DID3, 32, // 0x4f - Device ID 3
DID4, 32, // 0x53 - Device ID 4
DID5, 32, // 0x57 - Device ID 5
/* Backlight Control */
Offset (0x64),
BLCS, 8, // 0x64 - Backlight control possible?
BRTL, 8, // 0x65 - Brightness Level
ODDS, 8, // 0x66
/* Ambient Light Sensors */
Offset (0x6e),
ALSE, 8, // 0x6e - ALS enable
ALAF, 8, // 0x6f - Ambient light adjustment factor
LLOW, 8, // 0x70 - LUX Low
LHIH, 8, // 0x71 - LUX High
/* EMA */
Offset (0x78),
EMAE, 8, // 0x78 - EMA enable
EMAP, 16, // 0x79 - EMA pointer
EMAL, 16, // 0x7b - EMA length
/* MEF */
Offset (0x82),
MEFE, 8, // 0x82 - MEF enable
/* TPM support */
Offset (0x8c),
TPMP, 8, // 0x8c - TPM
TPME, 8, // 0x8d - TPM enable
/* SATA */
Offset (0x96),
GTF0, 56, // 0x96 - GTF task file buffer for port 0
GTF1, 56, // 0x9d - GTF task file buffer for port 1
GTF2, 56, // 0xa4 - GTF task file buffer for port 2
IDEM, 8, // 0xab - IDE mode (compatible / enhanced)
IDET, 8, // 0xac - IDE
/* IGD OpRegion */
Offset (0xb4),
ASLB, 32, // 0xb4 - IGD OpRegion Base Address
IBTT, 8, // 0xb8 - IGD boot panel device
IPAT, 8, // 0xb9 - IGD panel type cmos option
ITVF, 8, // 0xba - IGD TV format cmos option
ITVM, 8, // 0xbb - IGD TV minor format option
IPSC, 8, // 0xbc - IGD panel scaling
IBLC, 8, // 0xbd - IGD BLC config
IBIA, 8, // 0xbe - IGD BIA config
ISSC, 8, // 0xbf - IGD SSC config
I409, 8, // 0xc0 - IGD 0409 modified settings
I509, 8, // 0xc1 - IGD 0509 modified settings
I609, 8, // 0xc2 - IGD 0609 modified settings
I709, 8, // 0xc3 - IGD 0709 modified settings
IDMM, 8, // 0xc4 - IGD DVMT Mode
IDMS, 8, // 0xc5 - IGD DVMT memory size
IF1E, 8, // 0xc6 - IGD function 1 enable
HVCO, 8, // 0xc7 - IGD HPLL VCO
NXD1, 32, // 0xc8 - IGD _DGS next DID1
NXD2, 32, // 0xcc - IGD _DGS next DID2
NXD3, 32, // 0xd0 - IGD _DGS next DID3
NXD4, 32, // 0xd4 - IGD _DGS next DID4
NXD5, 32, // 0xd8 - IGD _DGS next DID5
NXD6, 32, // 0xdc - IGD _DGS next DID6
NXD7, 32, // 0xe0 - IGD _DGS next DID7
NXD8, 32, // 0xe4 - IGD _DGS next DID8
/* Mainboard Specific (TODO move elsewhere) */
Offset (0xf0),
DOCK, 8, // 0xf0 - Docking Status
}

View File

@ -0,0 +1,493 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
Device (LNKA)
{
Name (_HID, EISAID("PNP0C0F"))
Name (_UID, 1)
// Disable method
Method (_DIS, 0, Serialized)
{
Store (0x80, PRTA)
}
// Possible Resource Settings for this Link
Name (_PRS, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared)
{ 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
})
// Current Resource Settings for this link
Method (_CRS, 0, Serialized)
{
Name (RTLA, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared) {}
})
CreateWordField(RTLA, 1, IRQ0)
// Clear the WordField
Store (Zero, IRQ0)
// Set the bit from PRTA
ShiftLeft(1, And(PRTA, 0x0f), IRQ0)
Return (RTLA)
}
// Set Resource Setting for this IRQ link
Method (_SRS, 1, Serialized)
{
CreateWordField(Arg0, 1, IRQ0)
// Which bit is set?
FindSetRightBit(IRQ0, Local0)
Decrement(Local0)
Store(Local0, PRTA)
}
// Status
Method (_STA, 0, Serialized)
{
If(And(PRTA, 0x80)) {
Return (0x9)
} Else {
Return (0xb)
}
}
}
Device (LNKB)
{
Name (_HID, EISAID("PNP0C0F"))
Name (_UID, 2)
// Disable method
Method (_DIS, 0, Serialized)
{
Store (0x80, PRTB)
}
// Possible Resource Settings for this Link
Name (_PRS, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared)
{ 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
})
// Current Resource Settings for this link
Method (_CRS, 0, Serialized)
{
Name (RTLB, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared) {}
})
CreateWordField(RTLB, 1, IRQ0)
// Clear the WordField
Store (Zero, IRQ0)
// Set the bit from PRTB
ShiftLeft(1, And(PRTB, 0x0f), IRQ0)
Return (RTLB)
}
// Set Resource Setting for this IRQ link
Method (_SRS, 1, Serialized)
{
CreateWordField(Arg0, 1, IRQ0)
// Which bit is set?
FindSetRightBit(IRQ0, Local0)
Decrement(Local0)
Store(Local0, PRTB)
}
// Status
Method (_STA, 0, Serialized)
{
If(And(PRTB, 0x80)) {
Return (0x9)
} Else {
Return (0xb)
}
}
}
Device (LNKC)
{
Name (_HID, EISAID("PNP0C0F"))
Name (_UID, 3)
// Disable method
Method (_DIS, 0, Serialized)
{
Store (0x80, PRTC)
}
// Possible Resource Settings for this Link
Name (_PRS, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared)
{ 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
})
// Current Resource Settings for this link
Method (_CRS, 0, Serialized)
{
Name (RTLC, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared) {}
})
CreateWordField(RTLC, 1, IRQ0)
// Clear the WordField
Store (Zero, IRQ0)
// Set the bit from PRTC
ShiftLeft(1, And(PRTC, 0x0f), IRQ0)
Return (RTLC)
}
// Set Resource Setting for this IRQ link
Method (_SRS, 1, Serialized)
{
CreateWordField(Arg0, 1, IRQ0)
// Which bit is set?
FindSetRightBit(IRQ0, Local0)
Decrement(Local0)
Store(Local0, PRTC)
}
// Status
Method (_STA, 0, Serialized)
{
If(And(PRTC, 0x80)) {
Return (0x9)
} Else {
Return (0xb)
}
}
}
Device (LNKD)
{
Name (_HID, EISAID("PNP0C0F"))
Name (_UID, 4)
// Disable method
Method (_DIS, 0, Serialized)
{
Store (0x80, PRTD)
}
// Possible Resource Settings for this Link
Name (_PRS, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared)
{ 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
})
// Current Resource Settings for this link
Method (_CRS, 0, Serialized)
{
Name (RTLD, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared) {}
})
CreateWordField(RTLD, 1, IRQ0)
// Clear the WordField
Store (Zero, IRQ0)
// Set the bit from PRTD
ShiftLeft(1, And(PRTD, 0x0f), IRQ0)
Return (RTLD)
}
// Set Resource Setting for this IRQ link
Method (_SRS, 1, Serialized)
{
CreateWordField(Arg0, 1, IRQ0)
// Which bit is set?
FindSetRightBit(IRQ0, Local0)
Decrement(Local0)
Store(Local0, PRTD)
}
// Status
Method (_STA, 0, Serialized)
{
If(And(PRTD, 0x80)) {
Return (0x9)
} Else {
Return (0xb)
}
}
}
Device (LNKE)
{
Name (_HID, EISAID("PNP0C0F"))
Name (_UID, 5)
// Disable method
Method (_DIS, 0, Serialized)
{
Store (0x80, PRTE)
}
// Possible Resource Settings for this Link
Name (_PRS, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared)
{ 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
})
// Current Resource Settings for this link
Method (_CRS, 0, Serialized)
{
Name (RTLE, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared) {}
})
CreateWordField(RTLE, 1, IRQ0)
// Clear the WordField
Store (Zero, IRQ0)
// Set the bit from PRTE
ShiftLeft(1, And(PRTE, 0x0f), IRQ0)
Return (RTLE)
}
// Set Resource Setting for this IRQ link
Method (_SRS, 1, Serialized)
{
CreateWordField(Arg0, 1, IRQ0)
// Which bit is set?
FindSetRightBit(IRQ0, Local0)
Decrement(Local0)
Store(Local0, PRTE)
}
// Status
Method (_STA, 0, Serialized)
{
If(And(PRTE, 0x80)) {
Return (0x9)
} Else {
Return (0xb)
}
}
}
Device (LNKF)
{
Name (_HID, EISAID("PNP0C0F"))
Name (_UID, 6)
// Disable method
Method (_DIS, 0, Serialized)
{
Store (0x80, PRTF)
}
// Possible Resource Settings for this Link
Name (_PRS, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared)
{ 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
})
// Current Resource Settings for this link
Method (_CRS, 0, Serialized)
{
Name (RTLF, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared) {}
})
CreateWordField(RTLF, 1, IRQ0)
// Clear the WordField
Store (Zero, IRQ0)
// Set the bit from PRTF
ShiftLeft(1, And(PRTF, 0x0f), IRQ0)
Return (RTLF)
}
// Set Resource Setting for this IRQ link
Method (_SRS, 1, Serialized)
{
CreateWordField(Arg0, 1, IRQ0)
// Which bit is set?
FindSetRightBit(IRQ0, Local0)
Decrement(Local0)
Store(Local0, PRTF)
}
// Status
Method (_STA, 0, Serialized)
{
If(And(PRTF, 0x80)) {
Return (0x9)
} Else {
Return (0xb)
}
}
}
Device (LNKG)
{
Name (_HID, EISAID("PNP0C0F"))
Name (_UID, 7)
// Disable method
Method (_DIS, 0, Serialized)
{
Store (0x80, PRTG)
}
// Possible Resource Settings for this Link
Name (_PRS, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared)
{ 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
})
// Current Resource Settings for this link
Method (_CRS, 0, Serialized)
{
Name (RTLG, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared) {}
})
CreateWordField(RTLG, 1, IRQ0)
// Clear the WordField
Store (Zero, IRQ0)
// Set the bit from PRTG
ShiftLeft(1, And(PRTG, 0x0f), IRQ0)
Return (RTLG)
}
// Set Resource Setting for this IRQ link
Method (_SRS, 1, Serialized)
{
CreateWordField(Arg0, 1, IRQ0)
// Which bit is set?
FindSetRightBit(IRQ0, Local0)
Decrement(Local0)
Store(Local0, PRTG)
}
// Status
Method (_STA, 0, Serialized)
{
If(And(PRTG, 0x80)) {
Return (0x9)
} Else {
Return (0xb)
}
}
}
Device (LNKH)
{
Name (_HID, EISAID("PNP0C0F"))
Name (_UID, 8)
// Disable method
Method (_DIS, 0, Serialized)
{
Store (0x80, PRTH)
}
// Possible Resource Settings for this Link
Name (_PRS, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared)
{ 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
})
// Current Resource Settings for this link
Method (_CRS, 0, Serialized)
{
Name (RTLH, ResourceTemplate()
{
IRQ(Level, ActiveLow, Shared) {}
})
CreateWordField(RTLH, 1, IRQ0)
// Clear the WordField
Store (Zero, IRQ0)
// Set the bit from PRTH
ShiftLeft(1, And(PRTH, 0x0f), IRQ0)
Return (RTLH)
}
// Set Resource Setting for this IRQ link
Method (_SRS, 1, Serialized)
{
CreateWordField(Arg0, 1, IRQ0)
// Which bit is set?
FindSetRightBit(IRQ0, Local0)
Decrement(Local0)
Store(Local0, PRTH)
}
// Status
Method (_STA, 0, Serialized)
{
If(And(PRTH, 0x80)) {
Return (0x9)
} Else {
Return (0xb)
}
}
}

View File

@ -0,0 +1,266 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
// Intel LPC Bus Device - 0:1f.0
Device (LPCB)
{
Name(_ADR, 0x001f0000)
OperationRegion(LPC0, PCI_Config, 0x00, 0x100)
Field (LPC0, AnyAcc, NoLock, Preserve)
{
Offset (0x40),
PMBS, 16, // PMBASE
Offset (0x60), // Interrupt Routing Registers
PRTA, 8,
PRTB, 8,
PRTC, 8,
PRTD, 8,
Offset (0x68),
PRTE, 8,
PRTF, 8,
PRTG, 8,
PRTH, 8,
Offset (0x80), // IO Decode Ranges
IOD0, 8,
IOD1, 8,
Offset (0xf0), // RCBA
RCEN, 1,
, 13,
RCBA, 18,
}
// #include "../../../southbridge/intel/sch/acpi/irqlinks.asl"
#include "irqlinks.asl"
#include "acpi/ec.asl"
Device (DMAC) // DMA Controller
{
Name(_HID, EISAID("PNP0200"))
Name(_CRS, ResourceTemplate()
{
IO (Decode16, 0x00, 0x00, 0x01, 0x20)
IO (Decode16, 0x81, 0x81, 0x01, 0x11)
IO (Decode16, 0x93, 0x93, 0x01, 0x0d)
IO (Decode16, 0xc0, 0xc0, 0x01, 0x20)
DMA (Compatibility, NotBusMaster, Transfer8_16) { 4 }
})
}
Device (FWH) // Firmware Hub
{
Name (_HID, EISAID("INT0800"))
Name (_CRS, ResourceTemplate()
{
Memory32Fixed(ReadOnly, 0xff000000, 0x01000000)
})
}
Device (HPET)
{
Name (_HID, EISAID("PNP0103"))
Name (_CID, 0x010CD041)
Name(BUF0, ResourceTemplate()
{
Memory32Fixed(ReadOnly, 0xfed00000, 0x400, FED0)
})
Method (_STA, 0) // Device Status
{
If (HPTE) {
// Note: Ancient versions of Windows don't want
// to see the HPET in order to work right
If (LGreaterEqual(OSYS, 2001)) {
Return (0xf) // Enable and show device
} Else {
Return (0xb) // Enable and don't show device
}
}
Return (0x0) // Not enabled, don't show.
}
Method (_CRS, 0, Serialized) // Current resources
{
If (HPTE) {
CreateDWordField(BUF0, \_SB.PCI0.LPCB.HPET.FED0._BAS, HPT0)
If (Lequal(HPAS, 1)) {
Store(0xfed01000, HPT0)
}
If (Lequal(HPAS, 2)) {
Store(0xfed02000, HPT0)
}
If (Lequal(HPAS, 3)) {
Store(0xfed03000, HPT0)
}
}
Return (BUF0)
}
}
Device(PIC) // 8259 Interrupt Controller
{
Name(_HID,EISAID("PNP0000"))
Name(_CRS, ResourceTemplate()
{
IO (Decode16, 0x20, 0x20, 0x01, 0x02)
IO (Decode16, 0x24, 0x24, 0x01, 0x02)
IO (Decode16, 0x28, 0x28, 0x01, 0x02)
IO (Decode16, 0x2c, 0x2c, 0x01, 0x02)
IO (Decode16, 0x30, 0x30, 0x01, 0x02)
IO (Decode16, 0x34, 0x34, 0x01, 0x02)
IO (Decode16, 0x38, 0x38, 0x01, 0x02)
IO (Decode16, 0x3c, 0x3c, 0x01, 0x02)
IO (Decode16, 0xa0, 0xa0, 0x01, 0x02)
IO (Decode16, 0xa4, 0xa4, 0x01, 0x02)
IO (Decode16, 0xa8, 0xa8, 0x01, 0x02)
IO (Decode16, 0xac, 0xac, 0x01, 0x02)
IO (Decode16, 0xb0, 0xb0, 0x01, 0x02)
IO (Decode16, 0xb4, 0xb4, 0x01, 0x02)
IO (Decode16, 0xb8, 0xb8, 0x01, 0x02)
IO (Decode16, 0xbc, 0xbc, 0x01, 0x02)
IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
IRQNoFlags () { 2 }
})
}
Device(MATH) // FPU
{
Name (_HID, EISAID("PNP0C04"))
Name (_CRS, ResourceTemplate()
{
IO (Decode16, 0xf0, 0xf0, 0x01, 0x01)
IRQNoFlags() { 13 }
})
}
Device(LDRC) // LPC device: Resource consumption
{
Name (_HID, EISAID("PNP0C02"))
Name (_UID, 2)
Name (_CRS, ResourceTemplate()
{
IO (Decode16, 0x2e, 0x2e, 0x1, 0x02) // First SuperIO
IO (Decode16, 0x4e, 0x4e, 0x1, 0x02) // Second SuperIO
IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status
IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved
IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved
IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved
IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post
IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved
IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI
// IO (Decode16, 0x680, 0x680, 0x1, 0x70) // IO ???
IO (Decode16, 0x800, 0x800, 0x1, 0x10) // ACPI I/O trap
IO (Decode16, 0x0500, 0x0500, 0x1, 0x80) // ICH7-M ACPI
IO (Decode16, 0x0480, 0x0480, 0x1, 0x40) // ICH7-M GPIO
// IO (Decode16, 0x1640, 0x1640, 0x1, 0x10) // IO ???
})
}
Device (RTC) // Real Time Clock
{
Name (_HID, EISAID("PNP0B00"))
Name (_CRS, ResourceTemplate()
{
IO (Decode16, 0x70, 0x70, 1, 8)
IRQNoFlags() { 8 }
})
}
Device (TIMR) // Intel 8254 timer
{
Name(_HID, EISAID("PNP0100"))
Name(_CRS, ResourceTemplate()
{
IO (Decode16, 0x40, 0x40, 0x01, 0x04)
IO (Decode16, 0x50, 0x50, 0x10, 0x04)
IRQNoFlags() {0}
})
}
#include "acpi/superio.asl"
Device (PS2K) // Keyboard
{
Name(_HID, EISAID("PNP0303"))
Name(_CID, EISAID("PNP030B"))
Name(_CRS, ResourceTemplate()
{
IO (Decode16, 0x60, 0x60, 0x01, 0x01)
IO (Decode16, 0x64, 0x64, 0x01, 0x01)
IRQ (Edge, ActiveHigh, Exclusive) { 0x01 } // IRQ 1
})
Method (_STA, 0)
{
Return (0xf)
}
}
Device (PS2M) // Mouse
{
Name(_HID, EISAID("PNP0F13"))
Name(_CRS, ResourceTemplate()
{
IRQ (Edge, ActiveHigh, Exclusive) { 0x0c } // IRQ 12
})
Method(_STA, 0)
{
Return (0xf)
}
}
Device (FDC0) // Floppy controller
{
Name (_HID, EisaId ("PNP0700"))
Method (_STA, 0, NotSerialized)
{
Return (0x0f) // FIXME
}
Name(_CRS, ResourceTemplate()
{
IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
IRQNoFlags () {6}
DMA (Compatibility, NotBusMaster, Transfer8) {2}
})
Name(_PRS, ResourceTemplate()
{
IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
IRQNoFlags () {6}
DMA (Compatibility, NotBusMaster, Transfer8) {2}
})
}
}

View File

@ -0,0 +1,80 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
// Intel PATA Controller 0:1f.1
Device (PATA)
{
Name (_ADR, 0x001f0001)
Device (PRID)
{
Name (_ADR, 0)
// Get Timing Mode
Method (_GTM)
{
Name(PBUF, Buffer(20) {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00 })
CreateDwordField (PBUF, 0, PIO0)
CreateDwordField (PBUF, 4, DMA0)
CreateDwordField (PBUF, 8, PIO1)
CreateDwordField (PBUF, 12, DMA1)
CreateDwordField (PBUF, 16, FLAG)
// TODO fill return structure
Return (PBUF)
}
// Set Timing Mode
Method (_STM, 3)
{
CreateDwordField (Arg0, 0, PIO0)
CreateDwordField (Arg0, 4, DMA0)
CreateDwordField (Arg0, 8, PIO1)
CreateDwordField (Arg0, 12, DMA1)
CreateDwordField (Arg0, 16, FLAG)
// TODO: Do the deed
}
Device (DSK0)
{
Name (_ADR, 0)
// TODO: _RMV ?
// TODO: _GTF ?
}
Device (DSK1)
{
Name (_ADR, 1)
// TODO: _RMV ?
// TODO: _GTF ?
}
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
// Intel PCI to PCI bridge 0:1e.0
Device (PCIB)
{
Name (_ADR, 0x001e0000)
Device (SLT1)
{
Name (_ADR, 0x00000000)
Name (_PRW, Package(){ 11, 4 })
}
Device (SLT2)
{
Name (_ADR, 0x00010000)
Name (_PRW, Package(){ 11, 4 })
}
Device (SLT3)
{
Name (_ADR, 0x00020000)
Name (_PRW, Package(){ 11, 4 })
}
Device (SLT6)
{
Name (_ADR, 0x00050000)
Name (_PRW, Package(){ 11, 4 })
}
Device (LANC)
{
Name (_ADR, 0x00080000)
Name (_PRW, Package(){ 11, 3 })
}
Device (LANR)
{
Name (_ADR, 0x00000000)
Name (_PRW, Package(){ 11, 3 })
}
// TODO: How many slots, where?
// PCI Interrupt Routing.
// If PICM is set, interrupts are routed over the i8259, otherwise
// over the IOAPIC. (Really? If they're above 15 they need to be routed
// fixed over the IOAPIC?)
Method (_PRT)
{
#include "acpi/southbridge_pci_irqs.asl"
}
}

View File

@ -0,0 +1,186 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* Intel i82801G PCIe support */
// PCI Express Ports
Device (RP01)
{
NAME(_ADR, 0x001c0000) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Method(_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 16 },
Package() { 0x0000ffff, 1, 0, 17 },
Package() { 0x0000ffff, 2, 0, 18 },
Package() { 0x0000ffff, 3, 0, 19 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
})
}
}
}
Device (RP02)
{
NAME(_ADR, 0x001c0001) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Method(_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 17 },
Package() { 0x0000ffff, 1, 0, 18 },
Package() { 0x0000ffff, 2, 0, 19 },
Package() { 0x0000ffff, 3, 0, 16 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
})
}
}
}
Device (RP03)
{
NAME(_ADR, 0x001c0002) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Method(_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 18 },
Package() { 0x0000ffff, 1, 0, 19 },
Package() { 0x0000ffff, 2, 0, 16 },
Package() { 0x0000ffff, 3, 0, 17 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKB, 0 }
})
}
}
}
Device (RP04)
{
NAME(_ADR, 0x001c0003) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Method(_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 19 },
Package() { 0x0000ffff, 1, 0, 16 },
Package() { 0x0000ffff, 2, 0, 17 },
Package() { 0x0000ffff, 3, 0, 18 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKC, 0 }
})
}
}
}
Device (RP05)
{
NAME(_ADR, 0x001c0004) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Method(_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 16 },
Package() { 0x0000ffff, 1, 0, 17 },
Package() { 0x0000ffff, 2, 0, 18 },
Package() { 0x0000ffff, 3, 0, 19 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
})
}
}
}
Device (RP06)
{
NAME(_ADR, 0x001c0005) // FIXME: Have a macro for PCI Devices -> ACPI notation?
//#include "pcie_port.asl"
Method(_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 17 },
Package() { 0x0000ffff, 1, 0, 18 },
Package() { 0x0000ffff, 2, 0, 19 },
Package() { 0x0000ffff, 3, 0, 16 }
})
} Else {
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
})
}
}
}

View File

@ -0,0 +1,165 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* Intel i82801G support
*/
Scope(\)
{
// IO-Trap at 0x800. This is the ACPI->SMI communication interface.
OperationRegion(IO_T, SystemIO, 0x800, 0x10)
Field(IO_T, ByteAcc, NoLock, Preserve)
{
Offset(0x8),
TRP0, 8 // IO-Trap at 0x808
}
// ICH7 Power Management Registers, located at PMBASE (0x1f.0 0x40.l)
// this doesn't work as ACPI initializes regions and packages first, devices second.
// use dynamic operation region? if so, how? XXX
//OperationRegion(PMIO, SystemIO, And(\_SB_.PCI0.LPCB.PMBS, 0xfffc), 0x80)
OperationRegion(PMIO, SystemIO, 0x500, 0x80)
Field(PMIO, ByteAcc, NoLock, Preserve)
{
Offset(0x42), // General Purpose Control
, 1, // skip 1 bit
GPEC, 1, // TCO status
, 9, // skip 9 more bits
SCIS, 1, // TCO DMI status
, 6 // To the end of the word
}
// ICH7 GPIO IO mapped registers (0x1f.0 reg 0x48.l)
OperationRegion(GPIO, SystemIO, 0x1180, 0x3c)
Field(GPIO, ByteAcc, NoLock, Preserve)
{
Offset(0x00), // GPIO Use Select
GU00, 8,
GU01, 8,
GU02, 8,
GU03, 8,
Offset(0x04), // GPIO IO Select
GIO0, 8,
GIO1, 8,
GIO2, 8,
GIO3, 8,
Offset(0x0c), // GPIO Level
GL00, 8,
GL01, 8,
, 3,
GP27, 1, // SATA_PWR_EN #0
GP28, 1, // SATA_PWR_EN #1
, 3,
Offset(0x18), // GPIO Blink
GB00, 8,
GB01, 8,
GB02, 8,
GB03, 8,
Offset(0x2c), // GPIO Invert
GIV0, 8,
GIV1, 8,
GIV2, 8,
GIV3, 8,
Offset(0x30), // GPIO Use Select 2
GU04, 8,
GU05, 8,
GU06, 8,
GU07, 8,
Offset(0x34), // GPIO IO Select 2
GIO4, 8,
GIO5, 8,
GIO6, 8,
GIO7, 8,
Offset(0x38), // GPIO Level 2
, 5,
GP37, 1, // PATA_PWR_EN
GP38, 1, // Battery / Power (?)
GP39, 1, // ??
GL05, 8,
GL06, 8,
GL07, 8
}
// ICH7 Root Complex Register Block. Memory Mapped through RCBA)
OperationRegion(RCRB, SystemMemory, 0xfed1c000, 0x4000)
Field(RCRB, DWordAcc, Lock, Preserve)
{
Offset(0x0000), // Backbone
Offset(0x1000), // Chipset
Offset(0x3000), // Legacy Configuration Registers
Offset(0x3404), // High Performance Timer Configuration
HPAS, 2, // Address Select
, 5,
HPTE, 1, // Address Enable
Offset(0x3418), // FD (Function Disable)
, 1, // Reserved
PATD, 1, // PATA disable
SATD, 1, // SATA disable
SMBD, 1, // SMBUS disable
HDAD, 1, // Azalia disable
A97D, 1, // AC'97 disable
M97D, 1, // AC'97 disable
ILND, 1, // Internal LAN disable
US1D, 1, // UHCI #1 disable
US2D, 1, // UHCI #2 disable
US3D, 1, // UHCI #3 disable
US4D, 1, // UHCI #4 disable
, 2, // Reserved
LPBD, 1, // LPC bridge disable
EHCD, 1, // EHCI disable
Offset(0x341a), // FD Root Ports
RP1D, 1, // Root Port 1 disable
RP2D, 1, // Root Port 2 disable
RP3D, 1, // Root Port 3 disable
RP4D, 1, // Root Port 4 disable
RP5D, 1, // Root Port 5 disable
RP6D, 1 // Root Port 6 disable
}
}
// 0:1b.0 High Definition Audio (Azalia)
#include "../../../southbridge/intel/sch/acpi/audio.asl"
// PCI Express Ports
#include "../../../southbridge/intel/sch/acpi/pcie.asl"
// USB
#include "../../../southbridge/intel/sch/acpi/usb.asl"
// PCI Bridge
#include "../../../southbridge/intel/sch/acpi/pci.asl"
// AC97 Audio and Modem
#include "../../../southbridge/intel/sch/acpi/ac97.asl"
// LPC Bridge
#include "../../../southbridge/intel/sch/acpi/lpc.asl"
// PATA
#include "../../../southbridge/intel/sch/acpi/pata.asl"
// SMBus
#include "../../../southbridge/intel/sch/acpi/smbus.asl"

View File

@ -0,0 +1,27 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
Name(\_S0, Package(4){0x0,0x0,0,0})
Name(\_S1, Package(4){0x1,0x0,0,0})
Name(\_S3, Package(4){0x5,0x0,0,0})
Name(\_S4, Package(4){0x6,0x0,0,0})
Name(\_S5, Package(4){0x7,0x0,0,0})

View File

@ -0,0 +1,246 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
// Intel SMBus Controller 0:1f.3
Device (SBUS)
{
Name (_ADR, 0x001f0003)
OperationRegion (SMBP, PCI_Config, 0x00, 0x100)
Field(SMBP, DWordAcc, NoLock, Preserve)
{
Offset(0x40),
, 2,
I2CE, 1
}
/*
OperationRegion (SMBI, SystemIO, 0x400, 0x20)
Field (SMBI, ByteAcc, NoLock, Preserve)
{
HSTS, 8, // Host Status
, 8,
HCNT, 8, // Host Control
HCMD, 8, // Host Command
TXSA, 8, // Transmit Slave Address
DAT0, 8, // Host Data 0
DAT1, 8, // Host Data 1
HBDB, 8, // Host Block Data Byte
PECK, 8, // Packet Error Check
RXSA, 8, // Receive Slave Address
RXDA, 16, // Receive Slave Data
AUXS, 8, // Auxiliary Status
AUXC, 8, // Auxiliary Control
SLPC, 8, // SMLink Pin Control
SBPC, 8, // SMBus Pin Control
SSTS, 8, // Slave Status
SCMD, 8, // Slave Command
NADR, 8, // Notify Device Address
NDLB, 8, // Notify Data Low Byte
NDLH, 8, // Notify Data High Byte
}
// Kill all SMBus communication
Method (KILL, 0, Serialized)
{
Or (HCNT, 0x02, HCNT) // Send Kill
Or (HSTS, 0xff, HSTS) // Clean Status
}
// Check if last operation completed
// return Failure = 0, Success = 1
Method (CMPL, 0, Serialized)
{
Store (4000, Local0) // Timeout 200ms in 50us steps
While (Local0) {
If (And(HSTS, 0x02)) { // Completion Status?
Return (1) // Operation Completed
} Else {
Stall (50)
Decrement (Local0)
If (LEqual(Local0, 0)) {
KILL()
}
}
}
Return (0) // Failure
}
// Wait for SMBus to become ready
Method (SRDY, 0, Serialized)
{
Store (200, Local0) // Timeout 200ms
While (Local0) {
If (And(HSTS, 0x40)) { // IN_USE?
Sleep(1) // Wait 1ms
Decrement(Local0) // timeout--
If (LEqual(Local0, 0)) {
Return (1)
}
} Else {
Store (0, Local0) // We're ready
}
}
Store (4000, Local0) // Timeout 200ms (50us * 4000)
While (Local0) {
If (And (HSTS, 0x01)) { // Host Busy?
Stall(50) // Wait 50us
Decrement(Local0) // timeout--
If (LEqual(Local0, 0)) {
KILL()
}
} Else {
Return (0) // Success
}
}
Return (1) // Failure
}
// SMBus Send Byte
// Arg0: Address
// Arg1: Data
// Return: 1 = Success, 0=Failure
Method (SSXB, 2, Serialized)
{
// Is the SMBus Controller Ready?
If (SRDY()) {
Return (0)
}
// Send Byte
Store (0, I2CE) // SMBus Enable
Store (0xbf, HSTS)
Store (Arg0, TXSA) // Write Address
Store (Arg1, HCMD) // Write Data
Store (0x48, HCNT) // Start + Byte Data Protocol
If (CMPL()) {
Or (HSTS, 0xff, HSTS) // Clean up
Return (1) // Success
}
Return (0)
}
// SMBus Receive Byte
// Arg0: Address
// Return: 0xffff = Failure, Data (8bit) = Success
Method (SRXB, 2, Serialized)
{
// Is the SMBus Controller Ready?
If (SRDY()) {
Return (0xffff)
}
// Receive Byte
Store (0, I2CE) // SMBus Enable
Store (0xbf, HSTS)
Store (Or (Arg0, 1), TXSA) // Write Address
Store (0x44, HCNT) // Start
If (CMPL()) {
Or (HSTS, 0xff, HSTS) // Clean up
Return (DAT0) // Success
}
Return (0xffff)
}
// SMBus Write Byte
// Arg0: Address
// Arg1: Command
// Arg2: Data
// Return: 1 = Success, 0=Failure
Method (SWRB, 3, Serialized)
{
// Is the SMBus Controller Ready?
If (SRDY()) {
Return (0)
}
// Send Byte
Store (0, I2CE) // SMBus Enable
Store (0xbf, HSTS)
Store (Arg0, TXSA) // Write Address
Store (Arg1, HCMD) // Write Command
Store (Arg2, DAT0) // Write Data
Store (0x48, HCNT) // Start + Byte Protocol
If (CMPL()) {
Or (HSTS, 0xff, HSTS) // Clean up
Return (1) // Success
}
Return (0)
}
// SMBus Read Byte
// Arg0: Address
// Arg1: Command
// Return: 0xffff = Failure, Data (8bit) = Success
Method (SRDB, 2, Serialized)
{
// Is the SMBus Controller Ready?
If (SRDY()) {
Return (0xffff)
}
// Receive Byte
Store (0, I2CE) // SMBus Enable
Store (0xbf, HSTS)
Store (Or (Arg0, 1), TXSA) // Write Address
Store (Arg1, HCMD) // Command
Store (0x48, HCNT) // Start
If (CMPL()) {
Or (HSTS, 0xff, HSTS) // Clean up
Return (DAT0) // Success
}
Return (0xffff)
}
*/
// Todo: Does anyone ever use these?
// Missing: Read / Write Word
// Missing: Read / Write Block
}

View File

@ -0,0 +1,217 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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
*/
/* Intel i82801G USB support */
// USB Controller 0:1d.0
Device (USB1)
{
Name(_ADR, 0x001d0000)
OperationRegion(U01P, PCI_Config, 0, 256)
Field(U01P, DWordAcc, NoLock, Preserve)
{
Offset(0xc4),
U1WE, 2 // USB Wake Enable
}
Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
Method (_PSW, 1) // Power State Wake method
{
// USB Controller can wake OS from Sleep State
If (Arg0) {
Store (3, U1WE)
} Else {
Store (0, U1WE)
}
}
// Leave USB ports on for to allow Wake from USB
Method(_S3D,0) // Highest D State in S3 State
{
Return (2)
}
Method(_S4D,0) // Highest D State in S4 State
{
Return (2)
}
}
// USB Controller 0:1d.1
Device (USB2)
{
Name(_ADR, 0x001d0001)
OperationRegion(U02P, PCI_Config, 0, 256)
Field(U02P, DWordAcc, NoLock, Preserve)
{
Offset(0xc4),
U2WE, 2 // USB Wake Enable
}
Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
Method (_PSW, 1) // Power State Wake method
{
// USB Controller can wake OS from Sleep State
If (Arg0) {
Store (3, U2WE)
} Else {
Store (0, U2WE)
}
}
// Leave USB ports on for to allow Wake from USB
Method(_S3D,0) // Highest D State in S3 State
{
Return (2)
}
Method(_S4D,0) // Highest D State in S4 State
{
Return (2)
}
}
// USB Controller 0:1d.2
Device (USB3)
{
Name(_ADR, 0x001d0002)
OperationRegion(U03P, PCI_Config, 0, 256)
Field(U03P, DWordAcc, NoLock, Preserve)
{
Offset(0xc4),
U3WE, 2 // USB Wake Enable
}
Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
Method (_PSW, 1) // Power State Wake method
{
// USB Controller can wake OS from Sleep State
If (Arg0) {
Store (3, U3WE)
} Else {
Store (0, U3WE)
}
}
// Leave USB ports on for to allow Wake from USB
Method(_S3D,0) // Highest D State in S3 State
{
Return (2)
}
Method(_S4D,0) // Highest D State in S4 State
{
Return (2)
}
}
// USB Controller 0:1d.3
Device (USB4)
{
Name(_ADR, 0x001d0003)
OperationRegion(U04P, PCI_Config, 0, 256)
Field(U04P, DWordAcc, NoLock, Preserve)
{
Offset(0xc4),
U4WE, 2 // USB Wake Enable
}
Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
Method (_PSW, 1) // Power State Wake method
{
// USB Controller can wake OS from Sleep State
If (Arg0) {
Store (3, U4WE)
} Else {
Store (0, U4WE)
}
}
// Leave USB ports on for to allow Wake from USB
Method(_S3D,0) // Highest D State in S3 State
{
Return (2)
}
Method(_S4D,0) // Highest D State in S4 State
{
Return (2)
}
}
// EHCI Controller 0:1d.7
Device (EHC1)
{
Name(_ADR, 0x001d0007)
Name (_PRW, Package(){ 13, 4 }) // Power Resources for Wake
// Leave USB ports on for to allow Wake from USB
Method(_S3D,0) // Highest D State in S3 State
{
Return (2)
}
Method(_S4D,0) // Highest D State in S4 State
{
Return (2)
}
Device (HUB7)
{
Name (_ADR, 0x00000000)
// How many are there?
Device (PRT1) { Name (_ADR, 1) } // USB Port 0
Device (PRT2) { Name (_ADR, 2) } // USB Port 1
Device (PRT3) { Name (_ADR, 3) } // USB Port 2
Device (PRT4) { Name (_ADR, 4) } // USB Port 3
Device (PRT5) { Name (_ADR, 5) } // USB Port 4
Device (PRT6) { Name (_ADR, 6) } // USB Port 5
}
}

View File

@ -0,0 +1,325 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Advanced Micro Devices, Inc.
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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 <device/pci_ids.h>
#include <device/pci_ops.h>
#include <arch/io.h>
#include <delay.h>
#define HDA_ICII_REG 0x68
#define HDA_ICII_BUSY (1 << 0)
#define HDA_ICII_VALID (1 << 1)
typedef struct southbridge_intel_sch_config config_t;
static int set_bits(u32 port, u32 mask, u32 val)
{
u32 reg32;
int count;
/* Write (val & mask) to port */
val &= mask;
reg32 = read32(port);
reg32 &= ~mask;
reg32 |= val;
write32(port, reg32);
/* Wait for readback of register to
* match what was just written to it
*/
count = 50;
do {
/* Wait 1ms based on BKDG wait time */
mdelay(1);
reg32 = read32(port);
reg32 &= mask;
} while ((reg32 != val) && --count);
/* Timeout occurred */
if (!count)
return -1;
return 0;
}
static int codec_detect(u32 base)
{
u32 reg32;
int count;
/* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
if (set_bits(base + 0x08, 1, 1) == -1)
goto no_codec;
/* clear STATESTS bits (BAR + 0xE)[2:0] */
reg32 = read32(base + 0x0E);
reg32 |= 7;
write32(base + 0x0E, reg32);
/* Wait for readback of register to
* match what was just written to it
*/
count = 50;
do {
/* Wait 1ms based on BKDG wait time */
mdelay(1);
reg32 = read32(base + 0x0E);
} while ((reg32 != 0) && --count);
/* Timeout occured */
if (!count)
goto no_codec;
/* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
if (set_bits(base + 0x08, 1, 0) == -1)
goto no_codec;
/* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
if (set_bits(base + 0x08, 1, 1) == -1)
goto no_codec;
/* Read in Codec location (BAR + 0xe)[2..0]*/
reg32 = read32(base + 0xe);
reg32 &= 0x0f;
if (!reg32)
goto no_codec;
return reg32;
no_codec:
/* Codec Not found */
/* Put HDA back in reset (BAR + 0x8) [0] */
set_bits(base + 0x08, 1, 0);
printk(BIOS_DEBUG, "sch_audio: No codec!\n");
return 0;
}
const u32 * cim_verb_data = NULL;
u32 cim_verb_data_size = 0;
static u32 find_verb(struct device *dev, u32 viddid, const u32 ** verb)
{
printk(BIOS_DEBUG, "sch_audio: dev=%s\n", dev_path(dev));
printk(BIOS_DEBUG, "sch_audio: Reading viddid=%x\n", viddid);
int idx=0;
while (idx < (cim_verb_data_size / sizeof(u32))) {
u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
verb_size++; // we ship an additional gain value
if (cim_verb_data[idx] != viddid) {
idx += verb_size + 3; // skip verb + header
continue;
}
*verb = &cim_verb_data[idx+3];
return verb_size;
}
/* Not all codecs need to load another verb */
return 0;
}
/**
* Wait 50usec for the codec to indicate it is ready
* no response would imply that the codec is non-operative
*/
static int wait_for_ready(u32 base)
{
/* Use a 50 usec timeout - the Linux kernel uses the
* same duration */
int timeout = 50;
while(timeout--) {
u32 reg32 = read32(base + HDA_ICII_REG);
if (!(reg32 & HDA_ICII_BUSY))
return 0;
udelay(1);
}
return -1;
}
/**
* Wait 50usec for the codec to indicate that it accepted
* the previous command. No response would imply that the code
* is non-operative
*/
static int wait_for_valid(u32 base)
{
/* Use a 50 usec timeout - the Linux kernel uses the
* same duration */
int timeout = 25;
write32(base + 0x68, 1);
while(timeout--)
{
udelay(1);
}
timeout = 50;
while(timeout--)
{
u32 reg32 = read32(base + 0x68);
if ((reg32 & ((1 << 1) | (1 << 0))) ==(1 << 1))
{
write32(base + 0x68, 2);
return 0;
}
udelay(1);
}
return 1;
}
static void codec_init(struct device *dev, u32 base, int addr)
{
u32 reg32;
const u32 *verb;
u32 verb_size;
int i;
printk(BIOS_DEBUG, "sch_audio: Initializing codec #%d\n", addr);
/* 1 */
if (wait_for_ready(base) == -1)
return;
reg32 = (addr << 28) | 0x000f0000;
write32(base + 0x60, reg32);
if (wait_for_valid(base) == -1)
return;
reg32 = read32(base + 0x0);
printk(BIOS_DEBUG, "sch_audio: GCAP: %08x\n", reg32);
reg32 = read32(base + 0x4);
printk(BIOS_DEBUG, "sch_audio: OUTPAY: %08x\n", reg32);
reg32 = read32(base + 0x6);
printk(BIOS_DEBUG, "sch_audio: INPAY: %08x\n", reg32);
reg32 = read32(base + 0x64);
/* 2 */
printk(BIOS_DEBUG, "sch_audio: codec viddid: %08x\n", reg32);
verb_size = find_verb(dev, reg32, &verb);
if (!verb_size) {
printk(BIOS_DEBUG, "sch_audio: No verb!\n");
return;
}
printk(BIOS_DEBUG, "sch_audio: verb_size: %d\n", verb_size);
/* 3 */
for (i = 0; i < verb_size; i++) {
if (wait_for_ready(base) == -1)
return;
write32(base + 0x60, verb[i]);
if (wait_for_valid(base) == -1)
return;
}
printk(BIOS_DEBUG, "sch_audio: verb loaded.\n");
}
static void codecs_init(struct device *dev, u32 base, u32 codec_mask)
{
int i;
for (i = 2; i >= 0; i--) {
if (codec_mask & (1 << i))
codec_init(dev, base, i);
}
}
static void sch_audio_init(struct device *dev)
{
u32 base;
struct resource *res;
u32 codec_mask;
u32 reg32;
res = find_resource(dev, 0x10);
if (!res)
return;
reg32 = pci_read_config32(dev, PCI_COMMAND);
pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MEMORY);
// NOTE this will break as soon as the sch_audio get's a bar above
// 4G. Is there anything we can do about it?
base = (u32)res->base;
printk(BIOS_DEBUG, "sch_audio: base = %08x\n", (u32)base);
codec_mask = codec_detect(base);
if (codec_mask) {
printk(BIOS_DEBUG, "sch_audio: codec_mask = %02x\n", codec_mask);
codecs_init(dev, base, codec_mask);
}
else
{
/* No audio codecs found disable HD audio controller*/
pci_write_config32(dev, 0x10, 0);
pci_write_config32(dev, PCI_COMMAND, 0);
reg32 = pci_read_config32(dev, 0xFC);
pci_write_config32(dev, 0xFC, reg32 | 1);
}
}
static void sch_audio_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations sch_audio_pci_ops = {
.set_subsystem = sch_audio_set_subsystem,
};
static struct device_operations sch_audio_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = sch_audio_init,
.scan_bus = 0,
.ops_pci = &sch_audio_pci_ops,
};
/* SCH audio function */
static const struct pci_driver sch_audio __pci_driver = {
.ops = &sch_audio_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x811B,
};

View File

@ -0,0 +1,40 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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
*/
#ifndef SOUTHBRIDGE_INTEL_SCH_CHIP_H
#define SOUTHBRIDGE_INTEL_SCH_CHIP_H
struct southbridge_intel_sch_config {
/**
* Interrupt Routing configuration
* If bit7 is 1, the interrupt is disabled.
*/
uint8_t pirqa_routing;
uint8_t pirqb_routing;
uint8_t pirqc_routing;
uint8_t pirqd_routing;
uint8_t pirqe_routing;
uint8_t pirqf_routing;
uint8_t pirqg_routing;
uint8_t pirqh_routing;
};
extern struct chip_operations southbridge_intel_sch_ops;
#endif

View File

@ -0,0 +1,63 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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 <arch/io.h>
#include <arch/romcc_io.h>
#include <console/console.h>
#include <device/pci_ids.h>
#include <device/pci_def.h>
#include "i82801gx.h"
#include "smbus.h"
void enable_smbus(void)
{
device_t dev;
/* Set the SMBus device statically. */
dev = PCI_DEV(0x0, 0x1f, 0x3);
/* Check to make sure we've got the right device. */
if (pci_read_config16(dev, 0x2) != 0x27da) {
die("SMBus controller not found!");
}
/* Set SMBus I/O base. */
pci_write_config32(dev, SMB_BASE,
SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
/* Set SMBus enable. */
pci_write_config8(dev, HOSTC, HST_EN);
/* Set SMBus I/O space enable. */
pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
/* Disable interrupt generation. */
outb(0, SMBUS_IO_BASE + SMBHSTCTL);
/* Clear any lingering errors, so transactions can run. */
outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
print_debug("SMBus controller enabled.\n");
}
int smbus_read_byte(unsigned device, unsigned address)
{
return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
}

View File

@ -0,0 +1,98 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <device/pci_ids.h>
/* PCI Configuration Space (D31:F1): IDE */
#define INTR_LN 0x3c
#define IDE_TIM_PRI 0x80 /* IDE timings, primary */
extern int sch_port_access_read(int port,int reg, int bytes);
static void ide_init(struct device *dev)
{
u32 ideTimingConfig;
u32 reg32;
printk(BIOS_DEBUG, "sch_ide: initializing... ");
reg32 = pci_read_config32(dev, PCI_COMMAND);
pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_IO | PCI_COMMAND_MASTER);
/* Program the clock */
if (sch_port_access_read(5,3,4) & (1<<3))
{
/*533MHz
Read PCI MC register*/
reg32 = pci_read_config32(dev, 0x60);
pci_write_config32(dev,0x60,reg32 | 1);
}
else
{
/*400MHz*/
reg32 = pci_read_config32(dev, 0x60);
reg32 &=~(1);
pci_write_config32(dev,0x60,reg32);
}
/* Enable primary IDE interface.
80=04 81=00 82=02 83=80
*/
ideTimingConfig = 0x80020000;
printk(BIOS_DEBUG, "IDE0 ");
pci_write_config32(dev, IDE_TIM_PRI, ideTimingConfig);
/* Set Interrupt Line */
/* Interrupt Pin is set by D31IP.PIP */
printk(BIOS_DEBUG, "\n");
}
static void ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations ide_pci_ops = {
.set_subsystem = ide_set_subsystem,
};
static struct device_operations ide_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = ide_init,
.scan_bus = 0,
.ops_pci = &ide_pci_ops,
};
static const struct pci_driver sch_ide __pci_driver = {
.ops = &ide_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x811A,
};

View File

@ -0,0 +1,194 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <device/pci_ids.h>
#include <arch/io.h>
#include "chip.h"
/*SCH LPC defines*/
#define SCH_ACPI_CTL 0x58
#define SCH_SIRQ_CTL 0x68
#define PIRQA_ROUT 0x60
#define PIRQB_ROUT 0x61
#define PIRQC_ROUT 0x62
#define PIRQD_ROUT 0x63
#define PIRQE_ROUT 0x64
#define PIRQF_ROUT 0x65
#define PIRQG_ROUT 0x66
#define PIRQH_ROUT 0x67
typedef struct southbridge_intel_sch_config config_t;
/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
* 0x00 - 0000 = Reserved
* 0x01 - 0001 = Reserved
* 0x02 - 0010 = Reserved
* 0x03 - 0011 = IRQ3
* 0x04 - 0100 = IRQ4
* 0x05 - 0101 = IRQ5
* 0x06 - 0110 = IRQ6
* 0x07 - 0111 = IRQ7
* 0x08 - 1000 = Reserved
* 0x09 - 1001 = IRQ9
* 0x0A - 1010 = IRQ10
* 0x0B - 1011 = IRQ11
* 0x0C - 1100 = IRQ12
* 0x0D - 1101 = Reserved
* 0x0E - 1110 = IRQ14
* 0x0F - 1111 = IRQ15
* PIRQ[n]_ROUT[7] - PIRQ Routing Control
* 0x80 - The PIRQ is not routed.
*/
#define PIRQA 0x03
#define PIRQB 0x05
#define PIRQC 0x06
#define PIRQD 0x07
#define PIRQE 0x09
#define PIRQF 0x0A
#define PIRQG 0x0B
#define PIRQH 0x0C
static void sch_pirq_init(device_t dev)
{
device_t irq_dev;
/* Get the chip configuration */
config_t *config = dev->chip_info;
pci_write_config8(dev, PIRQA_ROUT, config->pirqa_routing);
pci_write_config8(dev, PIRQB_ROUT, config->pirqb_routing);
pci_write_config8(dev, PIRQC_ROUT, config->pirqc_routing);
pci_write_config8(dev, PIRQD_ROUT, config->pirqd_routing);
pci_write_config8(dev, PIRQE_ROUT, config->pirqe_routing);
pci_write_config8(dev, PIRQF_ROUT, config->pirqf_routing);
pci_write_config8(dev, PIRQG_ROUT, config->pirqg_routing);
pci_write_config8(dev, PIRQH_ROUT, config->pirqh_routing);
/* Eric Biederman once said we should let the OS do this.
* I am not so sure anymore he was right.
*/
for(irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next)
{
u8 int_pin=0, int_line=0;
if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
continue;
int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
switch (int_pin)
{
case 1: /* INTA# */ int_line = config->pirqa_routing; break;
case 2: /* INTB# */ int_line = config->pirqb_routing; break;
case 3: /* INTC# */ int_line = config->pirqc_routing; break;
case 4: /* INTD# */ int_line = config->pirqd_routing; break;
}
if (!int_line)
continue;
pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
}
}
static void sch_fixups(struct device *dev)
{
u32 rcba_base;
/* This needs to happen after PCI enumeration
RCBA32(0x1d40) |= 1;*/
rcba_base = pci_read_config32(dev, 0xF0);
/*Remove the enable bit*/
rcba_base = rcba_base >> 1;
rcba_base = rcba_base << 1;
*((volatile u32 *)(rcba_base +0x104)) &= 0xFF00FFFF;
}
static void lpc_init(struct device *dev)
{
printk(BIOS_DEBUG, "SCH: lpc_init\n");
/* Setup the PIRQ. */
sch_pirq_init(dev);
pci_write_config8(dev, SCH_SIRQ_CTL,0x80);
sch_fixups(dev);
}
static void sch_lpc_read_resources(device_t dev)
{
struct resource *res;
/* Get the normal PCI resources of this device. */
pci_dev_read_resources(dev);
/* Add an extra subtractive resource for both memory and I/O. */
res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
res->base = 0;
res->size = 0xe000;
res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
res->base = 0xff800000;
res->size = 0x00800000; /* 8 MB for flash */
res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
res = new_resource(dev, 3); /* IOAPIC */
res->base = 0xfec00000;
res->size = 0x00001000;
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}
static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations pci_ops = {
.set_subsystem = set_subsystem,
};
static struct device_operations device_ops = {
.read_resources = sch_lpc_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = lpc_init,
.scan_bus = scan_static_bus,
.ops_pci = &pci_ops,
};
/* SCH LPC Interface */
static const struct pci_driver sch_lpc __pci_driver = {
.ops = &device_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8119,
};

View File

@ -0,0 +1,82 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <device/pci_ids.h>
#include <arch/io.h>
static void sch_mmc_init(struct device *dev)
{
u32 reg32;
printk(BIOS_DEBUG, "MMC: Setting up controller.. ");
reg32 = pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER;
reg32 |= PCI_COMMAND_MEMORY;
pci_write_config32(dev, PCI_COMMAND, reg32);
printk(BIOS_DEBUG, "done.\n");
}
static void sch_mmc_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations lops_pci = {
.set_subsystem = &sch_mmc_set_subsystem,
};
static struct device_operations sch_mmc_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = sch_mmc_init,
.scan_bus = 0,
.ops_pci = &lops_pci,
};
static const struct pci_driver sch_mmc1 __pci_driver = {
.ops = &sch_mmc_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x811C,
};
static const struct pci_driver sch_mmc2 __pci_driver = {
.ops = &sch_mmc_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x811D,
};
static const struct pci_driver sch_mmc3 __pci_driver = {
.ops = &sch_mmc_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x811E,
};

View File

@ -0,0 +1,98 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <device/pci_ids.h>
static void pci_init(struct device *dev)
{
u16 reg16;
u32 reg32;
printk(BIOS_DEBUG, "Initializing SCH PCIe bridge.\n");
/* Enable Bus Master */
reg32 = pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER;
pci_write_config32(dev, PCI_COMMAND, reg32);
/* Set Cache Line Size to 0x10 */
// This has no effect but the OS might expect it
pci_write_config8(dev, 0x0c, 0x10);
//pci_write_config32(dev, 0x18, 0x11);
//reg16 = pci_read_config16(dev, 0x3e);
//reg16 &= ~(1 << 0); /* disable parity error response */
// reg16 &= ~(1 << 1); /* disable SERR */
//reg16 |= (1 << 2); /* ISA enable */
//pci_write_config16(dev, 0x3e, reg16);
/*Slot implimented*/
reg16 = pci_read_config16(dev, 0x42);
reg16 |= (1 << 8);
pci_write_config16(dev, 0x42, reg16);
reg16 = pci_read_config16(dev, 0x48);
reg16 |= 0xf;
pci_write_config16(dev, 0x48, reg16);
}
static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
/* NOTE: This is not the default position! */
if (!vendor || !device) {
pci_write_config32(dev, 0x94,
pci_read_config32(dev, 0));
} else {
pci_write_config32(dev, 0x94,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations pci_ops = {
.set_subsystem = pcie_set_subsystem,
};
static struct device_operations device_ops = {
.read_resources = pci_bus_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.init = pci_init,
.scan_bus = pci_scan_bridge,
.ops_pci = &pci_ops,
};
/* Port 1 */
static const struct pci_driver sch_pcie_port1 __pci_driver = {
.ops = &device_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8110,
};
/*Port 2 */
static const struct pci_driver sch_pcie_port2 __pci_driver = {
.ops = &device_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8112,
};

View File

@ -0,0 +1,34 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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 <arch/io.h>
#include <reset.h>
void soft_reset(void)
{
outb(0x04, 0xcf9);
}
void hard_reset(void)
{
outb(0x02, 0xcf9);
outb(0x06, 0xcf9);
}

View File

@ -0,0 +1,40 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2010 coresystems GmbH
*
* 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
*/
#ifndef SOUTHBRIDGE_INTEL_SCH_SCH_H
#define SOUTHBRIDGE_INTEL_SCH_SCH_H
#define DEFAULT_PMBASE 0x500
/* SMBus I/O bits. */
#define SMBHSTSTAT 0x0
#define SMBHSTCTL 0x2
#define SMBHSTCMD 0x3
#define SMBXMITADD 0x4
#define SMBHSTDAT0 0x5
#define SMBHSTDAT1 0x6
#define SMBBLKDAT 0x7
#define SMBTRNSADD 0x9
#define SMBSLVDATA 0xa
#define SMLINK_PIN_CTL 0xe
#define SMBUS_PIN_CTL 0xf
#define SMBUS_TIMEOUT (10 * 1000 * 100)
#endif

View File

@ -0,0 +1,79 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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/path.h>
#include <device/smbus.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <arch/io.h>
#include "sch.h"
#include "smbus.h"
static int lsmbus_read_byte(device_t dev, u8 address)
{
u16 device;
struct resource *res;
struct bus *pbus;
device = dev->path.i2c.device;
pbus = get_pbus_smbus(dev);
res = find_resource(pbus->dev, 0x20);
return do_smbus_read_byte(res->base, device, address);
}
static struct smbus_bus_operations lops_smbus_bus = {
.read_byte = lsmbus_read_byte,
};
static void smbus_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations smbus_pci_ops = {
.set_subsystem = smbus_set_subsystem,
};
static struct device_operations smbus_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = 0,
.scan_bus = scan_static_bus,
.ops_smbus_bus = &lops_smbus_bus,
.ops_pci = &smbus_pci_ops,
};
/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
static const struct pci_driver i82801gx_smbus __pci_driver = {
.ops = &smbus_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x27da,
};

View File

@ -0,0 +1,99 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
* Copyright (C) 2009 coresystems GmbH
*
* 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 <device/smbus_def.h>
static void smbus_delay(void)
{
inb(0x80);
}
static int smbus_wait_until_ready(u16 smbus_base)
{
unsigned loops = SMBUS_TIMEOUT;
unsigned char byte;
do {
smbus_delay();
if (--loops == 0)
break;
byte = inb(smbus_base + SMBHSTSTAT);
} while (byte & 1);
return loops ? 0 : -1;
}
static int smbus_wait_until_done(u16 smbus_base)
{
unsigned loops = SMBUS_TIMEOUT;
unsigned char byte;
do {
smbus_delay();
if (--loops == 0)
break;
byte = inb(smbus_base + SMBHSTSTAT);
} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
return loops ? 0 : -1;
}
static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
{
unsigned char global_status_register;
unsigned char byte;
if (smbus_wait_until_ready(smbus_base) < 0) {
return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
}
/* Setup transaction */
/* Disable interrupts */
outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
/* Set the device I'm talking too */
outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
/* Set the command/address... */
outb(address & 0xff, smbus_base + SMBHSTCMD);
/* Set up for a byte data read */
outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
(smbus_base + SMBHSTCTL));
/* Clear any lingering errors, so the transaction will run */
outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
/* Clear the data byte... */
outb(0, smbus_base + SMBHSTDAT0);
/* Start the command */
outb((inb(smbus_base + SMBHSTCTL) | 0x40),
smbus_base + SMBHSTCTL);
/* Poll for transaction completion */
if (smbus_wait_until_done(smbus_base) < 0) {
return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
}
global_status_register = inb(smbus_base + SMBHSTSTAT);
/* Ignore the "In Use" status... */
global_status_register &= ~(3 << 5);
/* Read results of transaction */
byte = inb(smbus_base + SMBHSTDAT0);
if (global_status_register != (1 << 1)) {
return SMBUS_ERROR;
}
return byte;
}

View File

@ -0,0 +1,348 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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 <device/device.h>
#include <device/pci.h>
#include <console/console.h>
#include <arch/io.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/smm.h>
#include <cpu/cpu.h>
#include <string.h>
#include "chip.h"
#include "sch.h"
extern unsigned char _binary_smm_start;
extern unsigned char _binary_smm_size;
/* I945 */
#define SMRAM 0x9d
#define D_OPEN (1 << 6)
#define D_CLS (1 << 5)
#define D_LCK (1 << 4)
#define G_SMRAME (1 << 3)
#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
/* ICH7 */
#define PM1_STS 0x00
#define PM1_EN 0x02
#define PM1_CNT 0x04
#define PM1_TMR 0x08
#define PROC_CNT 0x10
#define LV2 0x14
#define LV3 0x15
#define LV4 0x16
#define PM2_CNT 0x20 // mobile only
#define GPE0_STS 0x28
#define GPE0_EN 0x2c
#define SMI_EN 0x30
#define EL_SMI_EN (1 << 25) // Intel Quick Resume Technology
#define INTEL_USB2_EN (1 << 18) // Intel-Specific USB2 SMI logic
#define LEGACY_USB2_EN (1 << 17) // Legacy USB2 SMI logic
#define PERIODIC_EN (1 << 14) // SMI on PERIODIC_STS in SMI_STS
#define TCO_EN (1 << 13) // Enable TCO Logic (BIOSWE et al)
#define MCSMI_EN (1 << 11) // Trap microcontroller range access
#define BIOS_RLS (1 << 7) // asserts SCI on bit set
#define SWSMI_TMR_EN (1 << 6) // start software smi timer on bit set
#define APMC_EN (1 << 5) // Writes to APM_CNT cause SMI#
#define SLP_SMI_EN (1 << 4) // Write to SLP_EN in PM1_CNT asserts SMI#
#define LEGACY_USB_EN (1 << 3) // Legacy USB circuit SMI logic
#define BIOS_EN (1 << 2) // Assert SMI# on setting GBL_RLS bit
#define EOS (1 << 1) // End of SMI (deassert SMI#)
#define GBL_SMI_EN (1 << 0) // SMI# generation at all?
#define SMI_STS 0x34
#define ALT_GP_SMI_EN 0x38
#define ALT_GP_SMI_STS 0x3a
#define GPE_CNTL 0x42
#define DEVACT_STS 0x44
#define SS_CNT 0x50
#define C3_RES 0x54
/* While we read PMBASE dynamically in case it changed, let's
* initialize it with a sane value
*/
static u16 pmbase = DEFAULT_PMBASE;
/**
* @brief read and clear PM1_STS
* @return PM1_STS register
*/
static u16 reset_pm1_status(void)
{
u16 reg16;
reg16 = inw(pmbase + PM1_STS);
/* set status bits are cleared by writing 1 to them */
outw(reg16, pmbase + PM1_STS);
return reg16;
}
static void dump_pm1_status(u16 pm1_sts)
{
printk(BIOS_DEBUG, "PM1_STS: ");
if (pm1_sts & (1 << 15)) printk(BIOS_DEBUG, "WAK ");
if (pm1_sts & (1 << 14)) printk(BIOS_DEBUG, "PCIEXPWAK ");
if (pm1_sts & (1 << 11)) printk(BIOS_DEBUG, "PRBTNOR ");
if (pm1_sts & (1 << 10)) printk(BIOS_DEBUG, "RTC ");
if (pm1_sts & (1 << 8)) printk(BIOS_DEBUG, "PWRBTN ");
if (pm1_sts & (1 << 5)) printk(BIOS_DEBUG, "GBL ");
if (pm1_sts & (1 << 4)) printk(BIOS_DEBUG, "BM ");
if (pm1_sts & (1 << 0)) printk(BIOS_DEBUG, "TMROF ");
printk(BIOS_DEBUG, "\n");
}
/**
* @brief read and clear SMI_STS
* @return SMI_STS register
*/
static u32 reset_smi_status(void)
{
u32 reg32;
reg32 = inl(pmbase + SMI_STS);
/* set status bits are cleared by writing 1 to them */
outl(reg32, pmbase + SMI_STS);
return reg32;
}
static void dump_smi_status(u32 smi_sts)
{
printk(BIOS_DEBUG, "SMI_STS: ");
if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
printk(BIOS_DEBUG, "\n");
}
/**
* @brief read and clear GPE0_STS
* @return GPE0_STS register
*/
static u32 reset_gpe0_status(void)
{
u32 reg32;
reg32 = inl(pmbase + GPE0_STS);
/* set status bits are cleared by writing 1 to them */
outl(reg32, pmbase + GPE0_STS);
return reg32;
}
static void dump_gpe0_status(u32 gpe0_sts)
{
int i;
printk(BIOS_DEBUG, "GPE0_STS: ");
for (i=31; i<= 16; i--) {
if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
}
if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
printk(BIOS_DEBUG, "\n");
}
/**
* @brief read and clear TCOx_STS
* @return TCOx_STS registers
*/
static u32 reset_tco_status(void)
{
u32 tcobase = pmbase + 0x60;
u32 reg32;
reg32 = inl(tcobase + 0x04);
/* set status bits are cleared by writing 1 to them */
outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
if (reg32 & (1 << 18))
outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
return reg32;
}
static void dump_tco_status(u32 tco_sts)
{
printk(BIOS_DEBUG, "TCO_STS: ");
if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
printk(BIOS_DEBUG, "\n");
}
/**
* @brief Set the EOS bit
*/
static void smi_set_eos(void)
{
// FIXME: disabled until SMM actually works
#if 0
u8 reg8;
reg8 = inb(pmbase + SMI_EN);
reg8 |= EOS;
outb(reg8, pmbase + SMI_EN);
#endif
}
extern uint8_t smm_relocation_start, smm_relocation_end;
static void smm_relocate(void)
{
u32 smi_en;
printk(BIOS_DEBUG, "Initializing SMM handler...");
pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), 0x40) & 0xfffc;
printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase);
smi_en = inl(pmbase + SMI_EN);
if (smi_en & APMC_EN) {
printk(BIOS_INFO, "SMI# handler already enabled?\n");
return;
}
/* copy the SMM relocation code */
memcpy((void *)0x38000, &smm_relocation_start,
&smm_relocation_end - &smm_relocation_start);
printk(BIOS_DEBUG, "\n");
dump_smi_status(reset_smi_status());
dump_pm1_status(reset_pm1_status());
dump_gpe0_status(reset_gpe0_status());
dump_tco_status(reset_tco_status());
/* Enable SMI generation:
* - on TCO events
* - on APMC writes (io 0xb2)
* - on writes to SLP_EN (sleep states)
* - on writes to GBL_RLS (bios commands)
* No SMIs:
* - on microcontroller writes (io 0x62/0x66)
*/
outl(smi_en | (TCO_EN | APMC_EN | SLP_SMI_EN | BIOS_EN |
EOS | GBL_SMI_EN), pmbase + SMI_EN);
/**
* There are several methods of raising a controlled SMI# via
* software, among them:
* - Writes to io 0xb2 (APMC)
* - Writes to the Local Apic ICR with Delivery mode SMI.
*
* Using the local apic is a bit more tricky. According to
* AMD Family 11 Processor BKDG no destination shorthand must be
* used.
* The whole SMM initialization is quite a bit hardware specific, so
* I'm not too worried about the better of the methods at the moment
*/
/* raise an SMI interrupt */
printk(BIOS_SPEW, " ... raise SMI#\n");
outb(0x00, 0xb2);
}
static void smm_install(void)
{
/* enable the SMM memory window */
pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
D_OPEN | G_SMRAME | C_BASE_SEG);
/* copy the real SMM handler */
memcpy((void *)0xa0000, &_binary_smm_start, (size_t)&_binary_smm_size);
wbinvd();
/* close the SMM memory window and enable normal SMM */
pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
G_SMRAME | C_BASE_SEG);
}
void smm_init(void)
{
smm_relocate();
smm_install();
smi_set_eos();
}
void smm_lock(void)
{
/* LOCK the SMM memory window and enable normal SMM.
* After running this function, only a full reset can
* make the SMM registers writable again.
*/
printk(BIOS_DEBUG, "Locking SMM.\n");
pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
D_LCK | G_SMRAME | C_BASE_SEG);
}
void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
{
/* The GDT or coreboot table is going to live here. But a long time
* after we relocated the GNVS, so this is not troublesome.
*/
*(u32 *)0x500 = (u32)gnvs;
*(u32 *)0x504 = (u32)tcg;
*(u32 *)0x508 = (u32)smi1;
outb(0xea, 0xb2);
}

View File

@ -0,0 +1,418 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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 <arch/io.h>
#include <arch/romcc_io.h>
#include <console/console.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/smm.h>
#include "sch.h"
#define DEBUG_SMI
#define APM_CNT 0xb2
#define APM_STS 0xb3
#define ACPI_DISABLE 0x1e
#define ACPI_ENABLE 0xe1
/* I945 */
#define SMRAM 0x9d
#define D_OPEN (1 << 6)
#define D_CLS (1 << 5)
#define D_LCK (1 << 4)
#define G_SMRANE (1 << 3)
#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
/* ICH7 */
#define PM1_STS 0x00
#define PM1_EN 0x02
#define PM1_CNT 0x04
#define PM1_TMR 0x08
#define PROC_CNT 0x10
#define LV2 0x14
#define LV3 0x15
#define LV4 0x16
#define PM2_CNT 0x20 // mobile only
#define GPE0_STS 0x28
#define GPE0_EN 0x2c
#define SMI_EN 0x30
#define EL_SMI_EN (1 << 25) // Intel Quick Resume Technology
#define INTEL_USB2_EN (1 << 18) // Intel-Specific USB2 SMI logic
#define LEGACY_USB2_EN (1 << 17) // Legacy USB2 SMI logic
#define PERIODIC_EN (1 << 14) // SMI on PERIODIC_STS in SMI_STS
#define TCO_EN (1 << 13) // Enable TCO Logic (BIOSWE et al)
#define MCSMI_EN (1 << 11) // Trap microcontroller range access
#define BIOS_RLS (1 << 7) // asserts SCI on bit set
#define SWSMI_TMR_EN (1 << 6) // start software smi timer on bit set
#define APMC_EN (1 << 5) // Writes to APM_CNT cause SMI#
#define SLP_SMI_EN (1 << 4) // Write to SLP_EN in PM1_CNT asserts SMI#
#define LEGACY_USB_EN (1 << 3) // Legacy USB circuit SMI logic
#define BIOS_EN (1 << 2) // Assert SMI# on setting GBL_RLS bit
#define EOS (1 << 1) // End of SMI (deassert SMI#)
#define GBL_SMI_EN (1 << 0) // SMI# generation at all?
#define SMI_STS 0x34
#define ALT_GP_SMI_EN 0x38
#define ALT_GP_SMI_STS 0x3a
#define GPE_CNTL 0x42
#define DEVACT_STS 0x44
#define SS_CNT 0x50
#define C3_RES 0x54
//#include "i82801gx_nvs.h"
/* While we read PMBASE dynamically in case it changed, let's
* initialize it with a sane value
*/
static u16 pmbase = DEFAULT_PMBASE;
// disabled because SMM doesn't actually work yet
#if 0
/**
* @brief read and clear PM1_STS
* @return PM1_STS register
*/
static u16 reset_pm1_status(void)
{
u16 reg16;
reg16 = inw(pmbase + PM1_STS);
/* set status bits are cleared by writing 1 to them */
outw(reg16, pmbase + PM1_STS);
return reg16;
}
static void dump_pm1_status(u16 pm1_sts)
{
printk(BIOS_DEBUG, "PM1_STS: ");
if (pm1_sts & (1 << 15)) printk(BIOS_DEBUG, "WAK ");
if (pm1_sts & (1 << 14)) printk(BIOS_DEBUG, "PCIEXPWAK ");
if (pm1_sts & (1 << 11)) printk(BIOS_DEBUG, "PRBTNOR ");
if (pm1_sts & (1 << 10)) printk(BIOS_DEBUG, "RTC ");
if (pm1_sts & (1 << 8)) printk(BIOS_DEBUG, "PWRBTN ");
if (pm1_sts & (1 << 5)) printk(BIOS_DEBUG, "GBL ");
if (pm1_sts & (1 << 4)) printk(BIOS_DEBUG, "BM ");
if (pm1_sts & (1 << 0)) printk(BIOS_DEBUG, "TMROF ");
printk(BIOS_DEBUG, "\n");
}
/**
* @brief read and clear SMI_STS
* @return SMI_STS register
*/
static u32 reset_smi_status(void)
{
u32 reg32;
reg32 = inl(pmbase + SMI_STS);
/* set status bits are cleared by writing 1 to them */
outl(reg32, pmbase + SMI_STS);
return reg32;
}
static void dump_smi_status(u32 smi_sts)
{
printk(BIOS_DEBUG, "SMI_STS: ");
if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
printk(BIOS_DEBUG, "\n");
}
/**
* @brief read and clear GPE0_STS
* @return GPE0_STS register
*/
static u32 reset_gpe0_status(void)
{
u32 reg32;
reg32 = inl(pmbase + GPE0_STS);
/* set status bits are cleared by writing 1 to them */
outl(reg32, pmbase + GPE0_STS);
return reg32;
}
static void dump_gpe0_status(u32 gpe0_sts)
{
int i;
printk(BIOS_DEBUG, "GPE0_STS: ");
for (i=31; i<= 16; i--) {
if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
}
if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
printk(BIOS_DEBUG, "\n");
}
/**
* @brief read and clear TCOx_STS
* @return TCOx_STS registers
*/
static u32 reset_tco_status(void)
{
u32 tcobase = pmbase + 0x60;
u32 reg32;
reg32 = inl(tcobase + 0x04);
/* set status bits are cleared by writing 1 to them */
outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
if (reg32 & (1 << 18))
outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
return reg32;
}
static void dump_tco_status(u32 tco_sts)
{
printk(BIOS_DEBUG, "TCO_STS: ");
if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
printk(BIOS_DEBUG, "\n");
}
#endif
/* We are using PCIe accesses for now
* 1. the chipset can do it
* 2. we don't need to worry about how we leave 0xcf8/0xcfc behind
*/
//#include "../../../northbridge/intel/i945/pcie_config.c"
int southbridge_io_trap_handler(int smif)
{
//global_nvs_t *gnvs = (global_nvs_t *)0xc00;
switch (smif) {
case 0x32:
printk(BIOS_DEBUG, "OS Init\n");
//gnvs->smif = 0;
break;
default:
/* Not handled */
return 0;
}
/* On success, the IO Trap Handler returns 0
* On failure, the IO Trap Handler returns a value != 0
*
* For now, we force the return value to 0 and log all traps to
* see what's going on.
*/
//gnvs->smif = 0;
return 1; /* IO trap handled */
}
/**
* @brief Set the EOS bit
*/
void southbridge_smi_set_eos(void)
{
u8 reg8;
reg8 = inb(pmbase + SMI_EN);
reg8 |= EOS;
outb(reg8, pmbase + SMI_EN);
}
/**
* @brief Interrupt handler for SMI#
*
* @param smm_revision revision of the smm state save map
*/
void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
{
// FIXME: the necessary magic isn't available yet. the code
// below is a partially adapted ICH7 version of the handler
#if 0
u8 reg8;
u16 pmctrl;
u16 pm1_sts;
u32 smi_sts, gpe0_sts, tco_sts;
pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x48) & 0xfffc;
printk(BIOS_SPEW, "SMI#: pmbase = 0x%04x\n", pmbase);
/* We need to clear the SMI status registers, or we won't see what's
* happening in the following calls.
*/
smi_sts = reset_smi_status();
dump_smi_status(smi_sts);
if (smi_sts & (1 << 21)) { // MONITOR
global_nvs_t *gnvs = (global_nvs_t *)0xc00;
u32 reg32;
reg32 = RCBA32(0x1e00); TRSR - Trap Status Register
//#if 0
/* Comment in for some useful debug */
for (i=0; i<4; i++) {
if (reg32 & (1 << i)) {
printk(BIOS_DEBUG, " io trap #%d\n", i);
}
}
//#endif
RCBA32(0x1e00) = reg32; TRSR
reg32 = RCBA32(0x1e10);
if ((reg32 & 0xfffc) != 0x808) {
printk(BIOS_DEBUG, " trapped io address = 0x%x\n", reg32 & 0xfffc);
printk(BIOS_DEBUG, " AHBE = %x\n", (reg32 >> 16) & 0xf);
printk(BIOS_DEBUG, " read/write: %s\n", (reg32 & (1 << 24)) ? "read" :
"write");
}
if (!(reg32 & (1 << 24))) {
/* Write Cycle */
reg32 = RCBA32(0x1e18);
printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", reg32);
}
if (gnvs->smif)
io_trap_handler(gnvs->smif); // call function smif
}
if (smi_sts & (1 << 13)) { // TCO
tco_sts = reset_tco_status();
dump_tco_status(tco_sts);
if (tco_sts & (1 << 8)) { // BIOSWR
u8 bios_cntl;
bios_cntl = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
if (bios_cntl & 1) {
/* BWE is RW, so the SMI was caused by a
* write to BWE, not by a write to the BIOS
*/
/* This is the place where we notice someone
* is trying to tinker with the BIOS. We are
* trying to be nice and just ignore it. A more
* resolute answer would be to power down the
* box.
*/
printk(BIOS_DEBUG, "Switching back to RO\n");
pcie_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
} /* No else for now? */
}
}
if (smi_sts & (1 << 8)) { // PM1
pm1_sts = reset_pm1_status();
dump_pm1_status(pm1_sts);
}
if (smi_sts & (1 << 9)) { // GPE0
gpe0_sts = reset_gpe0_status();
dump_gpe0_status(gpe0_sts);
}
if (smi_sts & (1 << 5)) { // APM
/* Emulate B2 register as the FADT / Linux expects it */
reg8 = inb(0xb2);
switch (reg8) {
case ACPI_DISABLE:
pmctrl = inw(pmbase + 0x04);
pmctrl |= (1 << 0);
outw(pmctrl, pmbase + 0x04);
printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
break;
case ACPI_ENABLE:
pmctrl = inw(pmbase + 0x04);
pmctrl &= ~(1 << 0);
outw(pmctrl, pmbase + 0x04);
printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
break;
}
}
if (smi_sts & (1 << 4)) { // SLP_SMI
u32 reg32;
/* First, disable further SMIs */
reg8 = inb(pmbase + SMI_EN);
reg8 &= ~SLP_SMI_EN;
outb(reg8, pmbase + SMI_EN);
/* Next, do the deed, we should change
* power on after power loss bits here
* if we're going to S5
*/
/* Write back to the SLP register to cause the
* originally intended event again. We need to set BIT13
* (SLP_EN) though to make the sleep happen.
*/
reg32 = inl(pmbase + 0x04);
printk(BIOS_DEBUG, "SMI#: SLP = 0x%08x\n", reg32);
printk(BIOS_DEBUG, "SMI#: Powering off.\n");
outl(reg32 | (1 << 13), pmbase + 0x04);
}
#endif
}

View File

@ -0,0 +1,27 @@
/*
* This file is part of the coreboot project.
*
*
* 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>
struct chip_operations southbridge_intel_sch_ops = {
CHIP_NAME("Intel SCH Southbridge")
};

View File

@ -0,0 +1,91 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2010 coresystems GmbH
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <device/pci_ids.h>
static void usb_init(struct device *dev)
{
u32 reg32;
/* USB Specification says the device must be Bus Master */
printk(BIOS_DEBUG, "UHCI: Setting up controller.. ");
reg32 = pci_read_config32(dev, PCI_COMMAND);
pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
/*Disable clock gating*/
reg32 = pci_read_config32(dev, 0xFC);
reg32 |= (1 << 2);
pci_write_config32(dev, 0xFC, reg32);
pci_write_config8(dev,0xF8,0x86);
pci_write_config8(dev,0xF9,0x0F);
pci_write_config8(dev,0xFA,0x06);
reg32 = pci_read_config32(dev, 0x4);
printk(BIOS_DEBUG, "PCI_COMMAND %x.\n",reg32);
reg32 = pci_read_config32(dev, 0x20);
printk(BIOS_DEBUG, "PCI_BASE %x.\n",reg32);
reg32 = pci_read_config32(dev, 0xFC);
printk(BIOS_DEBUG, "PCI_FD %x.\n",reg32);
printk(BIOS_DEBUG, "done.\n");
}
static void usb_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations usb_pci_ops = {
.set_subsystem = usb_set_subsystem,
};
static struct device_operations usb_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = usb_init,
.scan_bus = 0,
.ops_pci = &usb_pci_ops,
};
/* */
static const struct pci_driver sch_usb0 __pci_driver = {
.ops = &usb_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8114,
};
static const struct pci_driver sch_usb1 __pci_driver = {
.ops = &usb_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8115,
};
static const struct pci_driver sch_usb2 __pci_driver = {
.ops = &usb_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8116,
};

View File

@ -0,0 +1,68 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <device/pci_ids.h>
#include <arch/io.h>
static void usb_client_init(struct device *dev)
{
u32 reg32;
printk(BIOS_DEBUG, "USB Client: Setting up controller.. ");
reg32 = pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER;
reg32 |= PCI_COMMAND_MEMORY;
pci_write_config32(dev, PCI_COMMAND, reg32);
printk(BIOS_DEBUG, "done.\n");
}
static void usb_client_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
static struct pci_operations lops_pci = {
.set_subsystem = &usb_client_set_subsystem,
};
static struct device_operations usb_client_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = usb_client_init,
.scan_bus = 0,
.ops_pci = &lops_pci,
};
/* */
static const struct pci_driver sch_usb_client __pci_driver = {
.ops = &usb_client_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8118,
};

View File

@ -0,0 +1,49 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009 coresystems GmbH
*
* 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 <stdint.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <console/console.h>
#include <usbdebug.h>
#include <device/pci_def.h>
/* Required for successful build, but currently empty. */
void set_debug_port(unsigned int port)
{
/* Not needed, the southbridges hardcode physical USB port 1. */
}
void sch_enable_usbdebug(unsigned int port)
{
u32 dbgctl;
device_t dev = PCI_DEV(0, 0x1d, 7); /* USB EHCI, D29:F7 */
/* Set the EHCI BAR address. */
pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
/* Enable access to the EHCI memory space registers. */
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
/* Force ownership of the Debug Port to the EHCI controller. */
printk(BIOS_DEBUG, "Enabling OWNER_CNT\n");
dbgctl = read32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET);
dbgctl |= (1 << 30);
write32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET, dbgctl);
}

View File

@ -0,0 +1,93 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2010 coresystems GmbH
* Copyright (C) 2009-2010 iWave Systems
*
* 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 <device/pci_ids.h>
#include <arch/io.h>
static void usb_ehci_init(struct device *dev)
{
u32 reg32;
printk(BIOS_DEBUG, "EHCI: Setting up controller.. ");
reg32 = pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER;
pci_write_config32(dev, PCI_COMMAND, reg32);
/*Disable clock gating
reg32 = pci_read_config32(dev, 0xc0);
reg32 |= (1 << 2);
pci_write_config32(dev, 0xc0, reg32);*/
//pci_write_config32(dev, 0x3c, 0x17);
reg32 = pci_read_config32(dev, 0xFC);
reg32 |= (1 << 28);
pci_write_config32(dev, 0xFC, reg32);
reg32 = pci_read_config32(dev, 0x4);
printk(BIOS_DEBUG, "PCI_COMMAND %x.\n",reg32);
reg32 = pci_read_config32(dev, 0x20);
printk(BIOS_DEBUG, "PCI_BASE %x.\n",reg32);
reg32 = pci_read_config32(dev, 0xC0);
printk(BIOS_DEBUG, "PCI_FD %x.\n",reg32);
printk(BIOS_DEBUG, "done.\n");
}
static void usb_ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
u8 access_cntl;
access_cntl = pci_read_config8(dev, 0x80);
/* Enable writes to protected registers. */
pci_write_config8(dev, 0x80, access_cntl | 1);
if (!vendor || !device) {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
/* Restore protection. */
pci_write_config8(dev, 0x80, access_cntl);
}
static struct pci_operations lops_pci = {
.set_subsystem = &usb_ehci_set_subsystem,
};
static struct device_operations usb_ehci_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = usb_ehci_init,
.scan_bus = 0,
.ops_pci = &lops_pci,
};
/* */
static const struct pci_driver sch_usb_ehci __pci_driver = {
.ops = &usb_ehci_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8117,
};