Lenovo ThinkPad X60 / X60s Support

Adds support for Lenovo X60 series ThinkPads. So far, only X60s
(Model 1703) has been tested.

It's a basic patch without SMI and ACPI, as this makes it easier to
review. SMI and ACPI patches will follow.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
Acked-by: Peter Stuge <peter@stuge.se>


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6360 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Sven Schnelle 2011-02-14 20:02:47 +00:00 committed by Peter Stuge
parent b912289573
commit e2ca71efd9
29 changed files with 3830 additions and 0 deletions

View File

@ -68,6 +68,8 @@ config VENDOR_KONTRON
bool "Kontron"
config VENDOR_LANNER
bool "Lanner"
config VENDOR_LENOVO
bool "Lenovo"
config VENDOR_LIPPERT
bool "Lippert"
config VENDOR_MITAC
@ -147,6 +149,7 @@ source "src/mainboard/iwill/Kconfig"
source "src/mainboard/jetway/Kconfig"
source "src/mainboard/kontron/Kconfig"
source "src/mainboard/lanner/Kconfig"
source "src/mainboard/lenovo/Kconfig"
source "src/mainboard/lippert/Kconfig"
source "src/mainboard/mitac/Kconfig"
source "src/mainboard/msi/Kconfig"

View File

@ -0,0 +1,22 @@
if VENDOR_LENOVO
choice
prompt "Mainboard model"
config BOARD_LENOVO_X60
bool "ThinkPad X60 / X60s"
help
The following X60 series ThinkPad machines have been verified to
work correctly:
ThinkPad X60s (Model 1703)
endchoice
source "src/mainboard/lenovo/x60/Kconfig"
config MAINBOARD_VENDOR
string
default "Lenovo"
endif # VENDOR_LENOVO

View File

@ -0,0 +1,56 @@
if BOARD_LENOVO_X60
config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
select ARCH_X86
select CPU_INTEL_CORE
select CPU_INTEL_SOCKET_MFCPGA478
select NORTHBRIDGE_INTEL_I945GM
select SOUTHBRIDGE_INTEL_I82801GX
select SOUTHBRIDGE_RICOH_RL5C476
select SUPERIO_NSC_PC87382
select SUPERIO_NSC_PC87392
select EC_LENOVO_PMH7
select EC_ACPI
select BOARD_HAS_FADT
select HAVE_OPTION_TABLE
select HAVE_PIRQ_TABLE
select HAVE_MP_TABLE
select MMCONF_SUPPORT
select GFXUMA
select BOARD_ROMSIZE_KB_2048
select CHANNEL_XOR_RANDOMIZATION
config MAINBOARD_DIR
string
default lenovo/x60
config DCACHE_RAM_BASE
hex
default 0xffdf8000
config DCACHE_RAM_SIZE
hex
default 0x8000
config MAINBOARD_PART_NUMBER
string
default "ThinkPad X60 / X60s"
config MMCONF_BASE_ADDRESS
hex
default 0xf0000000
config IRQ_SLOT_COUNT
int
default 18
config MAX_CPUS
int
default 2
config MAX_PHYSICAL_CPUS
int
default 1
endif

View File

@ -0,0 +1,23 @@
##
## 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
##
ramstage-y += m3885.c
driver-y += rtl8168.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += mainboard_smi.c

View File

@ -0,0 +1,339 @@
/*
* 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
*/
Name(\CBA1, 0x60)
Name(\CBA2, 0x60)
Device (BAT1)
{
Name(_HID, EisaId("PNP0C0A"))
Name(_UID, 1)
Name(_PCL, Package(){ _SB })
Name(PSTA, 0x1f)
Name(PBIF, Package() {
0x00,
0x78,
0x64,
0x01,
0x2b5c, // Capacity?
0x05,
0x03,
0x01,
0x01,
"???", // Name
"???", // Number
"???", // Type
"???" // Vendor
})
Name(PBST, Package() { 0x01, 0x16, 0x64, 0x2b5c })
/* Status */
Method(_STA, 0)
{
If(\_SB.PCI0.LPCB.EC0.ECON) {
If(\_SB.PCI0.LPCB.EC0.P62S) {
Return(0x0f)
} Else {
Return(0x1f)
}
} Else {
Return(0x0f)
}
}
/* Battery Info */
Method(_BIF, 0)
{
If(\_SB.PCI0.LPCB.EC0.ECON) {
If(\_SB.PCI0.LPCB.EC0.P62S) {
IVBI()
IVBS()
} Else {
UPBI()
}
}
Return(PBIF)
}
/* Battery Status */
Method(_BST, 0)
{
If(\_SB.PCI0.LPCB.EC0.ECON) {
UPBS()
}
Return(PBST)
}
/* Update Battery Info */
Method(UPBI, 0)
{
Store (0x78, Index(PBIF, 1))
Store (0x64, Index(PBIF, 2))
Store (0x2b5c, Index(PBIF, 4))
Store ("Bat1", Index(PBIF, 9))
Store ("001", Index(PBIF, 10))
Store ("LION", Index(PBIF, 11))
Store ("Panasonic", Index(PBIF, 12))
}
Method(UPBS, 0)
{
Store(\_SB.PCI0.LPCB.EC0.QEVT, Local0)
If (Not(Local0)) {
Store(0, GP38)
Sleep(0x64)
Store(GP38, Local0)
If (Not(Local0)) {
Store (RDW(0x0d), Local0)
If (LNotEqual(Local0, 0xeeee)) {
If (LLessEqual(Local0, 0x64)) {
Store(Local0, CBA1)
}
}
}
}
Store (CBA1, Local0)
Store (Local0, Index(PBST, 2))
Store (DerefOf(Index(PBIF, 4)), Index(PBST, 3))
Store (0, Local1)
If (PWRS) {
If (LLess(Local0, 0x64)) {
Store (2, Local1)
}
} Else {
If (LLessEqual(Local0, 0x5)) {
Store (4, Local1)
} Else {
Store (1, Local1)
}
}
Store (Local1, Index(PBST, 0))
If (\_SB.PCI0.LPCB.EC0.P63S) {
Store (0x16, Index(PBST, 1))
} Else {
Store (0x0b, Index(PBST, 1))
}
}
// Invalidate Battery Info
Method(IVBI, 0)
{
Store (0xffffffff, Index(PBIF, 1))
Store (0xffffffff, Index(PBIF, 2))
Store (0xffffffff, Index(PBIF, 4))
Store ("Bad", Index(PBIF, 9))
Store ("Bad", Index(PBIF, 10))
Store ("Bad", Index(PBIF, 11))
Store ("Bad", Index(PBIF, 12))
Store (1, PBIF)
}
Method(IVBS, 0)
{
Store (0x0, Index(PBST, 0))
Store (0xffffffff, Index(PBST, 1))
Store (0xffffffff, Index(PBST, 2))
Store (0xffffffff, Index(PBST, 3))
}
}
Device (BAT2)
{
Name(_HID, EisaId("PNP0C0A"))
Name(_UID, 2)
Name(_PCL, Package(){ _SB })
Name(PSTA, 0x1f)
Name(PBIF, Package() {
0x00,
0x78,
0x64,
0x01,
0x2b5c, // Capacity?
0x05,
0x03,
0x01,
0x01,
"???", // Name
"???", // Number
"???", // Type
"???" // Vendor
})
Name(PBST, Package() { 0x01, 0x16, 0x64, 0x2b5c })
/* Status */
Method(_STA, 0)
{
If(\_SB.PCI0.LPCB.EC0.ECON) {
If(\_SB.PCI0.LPCB.EC0.P63S) {
Return(0x0f)
} Else {
Return(0x1f)
}
} Else {
Return(0x0f)
}
}
/* Battery Info */
Method(_BIF, 0)
{
If(\_SB.PCI0.LPCB.EC0.ECON) {
If(\_SB.PCI0.LPCB.EC0.P63S) {
IVBI()
IVBS()
} Else {
UPBI()
}
}
Return(PBIF)
}
/* Battery Status */
Method(_BST, 0)
{
If(\_SB.PCI0.LPCB.EC0.ECON) {
UPBS()
}
Return(PBST)
}
/* Update Battery Info */
Method(UPBI, 0)
{
Store (0x78, Index(PBIF, 1))
Store (0x64, Index(PBIF, 2))
Store (0x2b5c, Index(PBIF, 4))
Store ("Bat2", Index(PBIF, 9))
Store ("002", Index(PBIF, 10))
Store ("LION", Index(PBIF, 11))
Store ("Panasonic", Index(PBIF, 12))
}
Method(UPBS, 0)
{
Store(\_SB.PCI0.LPCB.EC0.QEVT, Local0)
If (Not(Local0)) {
Store(0, GP38)
Sleep(0x64)
Store(GP38, Local0)
If (Not(Local0)) {
Store (RDW(0x0d), Local0)
If (LNotEqual(Local0, 0xeeee)) {
If (LLessEqual(Local0, 0x64)) {
Store(Local0, CBA2)
}
}
}
}
Store (CBA2, Local0)
Store (Local0, Index(PBST, 2))
Store (DerefOf(Index(PBIF, 4)), Index(PBST, 3))
Store (0, Local1)
If (PWRS) {
If (LLess(Local0, 0x64)) {
Store (2, Local1)
}
} Else {
If (LLessEqual(Local0, 0x5)) {
Store (4, Local1)
} Else {
Store (1, Local1)
}
}
Store (Local1, Index(PBST, 0))
If (\_SB.PCI0.LPCB.EC0.P62S) {
Store (0x16, Index(PBST, 1))
} Else {
Store (0x0b, Index(PBST, 1))
}
}
// Invalidate Battery Info
Method(IVBI, 0)
{
Store (0xffffffff, Index(PBIF, 1))
Store (0xffffffff, Index(PBIF, 2))
Store (0xffffffff, Index(PBIF, 4))
Store ("Bad", Index(PBIF, 9))
Store ("Bad", Index(PBIF, 10))
Store ("Bad", Index(PBIF, 11))
Store ("Bad", Index(PBIF, 12))
Store (1, PBIF)
}
Method(IVBS, 0)
{
Store (0x0, Index(PBST, 0))
Store (0xffffffff, Index(PBST, 1))
Store (0xffffffff, Index(PBST, 2))
Store (0xffffffff, Index(PBST, 3))
}
}
Method (RDW, 1)
{
Store (0x16, \_SB.PCI0.LPCB.EC0.SMAD)
Store (Arg0, \_SB.PCI0.LPCB.EC0.SMCM)
Store (0x09, \_SB.PCI0.LPCB.EC0.SMPR)
While (LNotEqual(\_SB.PCI0.LPCB.EC0.SMPR, 0x00)) {
Stall (1)
}
Return (\_SB.PCI0.LPCB.EC0.SMW0)
}
Device (ADP1)
{
Name (_HID, "ACPI0003")
Method (_PSR, 0)
{
If (\_SB.PCI0.LPCB.EC0.ECON) {
Store (\_SB.PCI0.LPCB.EC0.P60S, Local0)
If (Local0) {
Store (0, PWRS)
} Else {
Store (1, PWRS)
}
}
Stall (0x02)
Return (PWRS)
}
Method (_PCL, 0)
{
Return (_SB)
}
}

View File

@ -0,0 +1,173 @@
/*
* 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)
Name (_GPE, 23) // GPI07 / GPE23 -> Runtime SCI
Name (ECON, 0)
Name (QEVT, 0)
OperationRegion(ERAM, EmbeddedControl, 0x00, 0xff)
Field (ERAM, ByteAcc, NoLock, Preserve)
{
Offset(0x04), // Command interface
CMCM, 8,
CMD1, 8,
CMD2, 8,
CMD3, 8,
Offset(0x18), // SMBus
SMPR, 8,
SMST, 8,
SMAD, 8,
SMCM, 8,
Offset(0x1c),
SMW0, 16,
//SMD0, 264,
Offset(0x3d),
SMAA, 8,
Offset(0x78), // GPIs
P60S, 1,
P61S, 1,
P62S, 1,
P63S, 1,
P64S, 1,
P65S, 1,
P66S, 1,
P67S, 1,
Offset(0x83), // Thermal
RTMP, 8,
TML0, 8,
TMH0, 8,
Offset(0x87),
TMCR, 8,
Offset(0x89),
TML1, 8,
TMH1, 8
}
Method (_CRS, 0)
{
Name (ECMD, ResourceTemplate()
{
IO (Decode16, 0x62, 0x62, 1, 1)
IO (Decode16, 0x66, 0x66, 1, 1)
})
Return (ECMD)
}
Method (_REG, 2)
{
// This method is needed by Windows XP/2000 for
// EC initialization before a driver is loaded
If (LEqual(Arg0, 0x03)) {
Store (Arg1, ECON)
}
}
// EC Query methods
Method (_Q11, 0)
{
Store("_Q11: Fn-F8 (Sleep Button) pressed", Debug)
Notify(SLPB, 0x80)
}
Method (_Q12, 0)
{
Store("_Q12: Fn-F9 (Display Switch) pressed", Debug)
// Store(1, TLST)
// HKDS(10)
}
Method (_Q30, 0)
{
Store("_Q30: AC In/Out", Debug)
Notify(ADP1, 0x80) // Tell the Power Adapter
PNOT() // and the CPU and Battery
}
Method (_Q31, 0)
{
Store("_Q31: LID Open/Close", Debug)
Notify(LID0, 0x80)
}
Method (_Q32, 0)
{
Store("_Q32: Battery 1 In/Out", Debug)
If (ECON) {
Store (P62S, Local0)
If (Not(Local0)) {
Notify(BAT1, 0x80)
}
}
}
Method (_Q33, 0)
{
Store("_Q33: Battery 2 In/Out", Debug)
If (ECON) {
Store (P63S, Local0)
If (Not(Local0)) {
Notify(BAT2, 0x80)
}
}
}
Method (_Q34, 0)
{
Store("_Q34: LPT/FDD", Debug)
// PHSS(0x70)
}
Method (_Q35, 0)
{
Store("_Q35: Processor is hot", Debug)
}
Method (_Q36, 0)
{
Store("_Q36: Thermal Warning", Debug)
}
Method (_Q37, 0)
{
Store("_Q37: PME", Debug)
}
Method (_Q38, 0)
{
Store("_Q38: Thermal", Debug)
}
Method (_Q39, 0)
{
Store("_Q39: Thermal", Debug)
}
// TODO Scope _SB devices for AC power, LID, Power button
}

View File

@ -0,0 +1,117 @@
/*
* 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
*/
Scope (_GPE)
{
/* The event numbers correspond to the bit numbers in the
* GPE0_EN register PMBASE + 0x2C.
*/
// Thermal Event
Method (_L00, 0)
{
}
// Hot Plug
Method (_L01, 0)
{
}
// Software GPE
Method (_L02, 0)
{
}
// USB1
Method (_L03, 0)
{
}
// USB2
Method (_L04, 0)
{
}
// AC97
Method (_L05, 0)
{
}
// _L06 TCOSCI
// SMBus (Reserved!)
Method (_L07, 0)
{
}
// COM1/COM2 (RI)
Method (_L08, 0)
{
}
// PCIe
Method (_L09, 0)
{
}
// _L0A BatLow / Quick Resume
// PME
Method (_L0B, 0)
{
}
// USB3
Method (_L0C, 0)
{
}
// PME B0
Method (_L0D, 0)
{
}
// USB4
Method (_L0E, 0)
{
}
// _L10 - _L1f: GPIn
// GPI13
Method (_L1D, 0)
{
}
}

View File

@ -0,0 +1,85 @@
/*
* 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 },
// Onboard graphics (IGD) 0:2.0
Package() { 0x0002ffff, 0, 0, 16 },
// High Definition Audio 0:1b.0
Package() { 0x001bffff, 0, 0, 22 },
// PCIe Root Ports 0:1c.x
Package() { 0x001cffff, 0, 0, 17 },
Package() { 0x001cffff, 1, 0, 16 },
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 0:1e.2, 0:1e.3
Package() { 0x001effff, 0, 0, 22 },
Package() { 0x001effff, 1, 0, 20 },
// LPC device 0:1f.0
Package() { 0x001fffff, 0, 0, 18 },
Package() { 0x001fffff, 1, 0, 19 },
Package() { 0x001fffff, 1, 0, 20 },
Package() { 0x001fffff, 3, 0, 16 }
})
} Else {
Return (Package() {
// PCIe Graphics 0:1.0
Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKA, 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.LNKG, 0 },
// PCIe Root Ports 0:1c.x
Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x001cffff, 1, \_SB.PCI0.LPCB.LNKA, 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 0:1e.2, 0:1e.3
Package() { 0x001effff, 0, \_SB.PCI0.LPCB.LNKG, 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 },
Package() { 0x001fffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
})
}
}

View File

@ -0,0 +1,91 @@
/*
* 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() {
// PCI Slot 1 routes ????
Package() { 0x0000ffff, 0, 0, 21},
Package() { 0x0000ffff, 1, 0, 22},
Package() { 0x0000ffff, 2, 0, 23},
Package() { 0x0000ffff, 3, 0, 20},
// PCI Slot 2 routes ????
Package() { 0x0001ffff, 0, 0, 22},
Package() { 0x0001ffff, 1, 0, 21},
Package() { 0x0001ffff, 2, 0, 20},
Package() { 0x0001ffff, 3, 0, 23},
// PCI Slot 3 routes ????
Package() { 0x0002ffff, 0, 0, 18},
Package() { 0x0002ffff, 1, 0, 19},
Package() { 0x0002ffff, 2, 0, 17},
Package() { 0x0002ffff, 3, 0, 16},
Package() { 0x0003ffff, 0, 0, 16},
Package() { 0x0003ffff, 1, 0, 17},
Package() { 0x0003ffff, 2, 0, 18},
Package() { 0x0003ffff, 3, 0, 19},
Package() { 0x0005ffff, 0, 0, 17},
Package() { 0x0005ffff, 1, 0, 20},
Package() { 0x0005ffff, 2, 0, 22},
Package() { 0x0005ffff, 3, 0, 21},
Package() { 0x0008ffff, 0, 0, 20},
})
} Else {
Return (Package() {
// PCI Slot 1 routes FGHE
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKF, 0},
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKG, 0},
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKH, 0},
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKE, 0},
// PCI Slot 2 routes GFEH
Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKG, 0},
Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKF, 0},
Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKE, 0},
Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKH, 0},
// PCI Slot 3 routes CDBA
Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKC, 0},
Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKD, 0},
Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKB, 0},
Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKA, 0},
Package() { 0x0003ffff, 0, \_SB.PCI0.LPCB.LNKA, 0},
Package() { 0x0003ffff, 1, \_SB.PCI0.LPCB.LNKB, 0},
Package() { 0x0003ffff, 2, \_SB.PCI0.LPCB.LNKC, 0},
Package() { 0x0003ffff, 3, \_SB.PCI0.LPCB.LNKD, 0},
Package() { 0x0005ffff, 0, \_SB.PCI0.LPCB.LNKB, 0},
Package() { 0x0005ffff, 1, \_SB.PCI0.LPCB.LNKE, 0},
Package() { 0x0005ffff, 2, \_SB.PCI0.LPCB.LNKG, 0},
Package() { 0x0005ffff, 3, \_SB.PCI0.LPCB.LNKF, 0},
Package() { 0x0008ffff, 0, \_SB.PCI0.LPCB.LNKE, 0},
})
}

View File

@ -0,0 +1,44 @@
/*
* 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 (LID0)
{
Name(_HID, EisaId("PNP0C0D"))
Method(_LID, 0)
{
Return (1)
}
}
Device (SLPB)
{
Name(_HID, EisaId("PNP0C0E"))
}
Device (PWRB)
{
Name(_HID, EisaId("PNP0C0C"))
// Wake
Name(_PRW, Package(){0x1d, 0x04})
}
#include "acpi/battery.asl"

View File

@ -0,0 +1,206 @@
/*
* 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
*/
/* These come from the dynamically created CPU SSDT */
External(PDC0)
External(PDC1)
/* 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})
}
// Power notification
External (\_PR_.CPU0, DeviceObj)
External (\_PR_.CPU1, DeviceObj)
Method (PNOT)
{
If (MPEN) {
If(And(PDC0, 0x08)) {
Notify (\_PR_.CPU0, 0x80) // _PPC
If (And(PDC0, 0x10)) {
Sleep(100)
Notify(\_PR_.CPU0, 0x81) // _CST
}
}
If(And(PDC1, 0x08)) {
Notify (\_PR_.CPU1, 0x80) // _PPC
If (And(PDC1, 0x10)) {
Sleep(100)
Notify(\_PR_.CPU1, 0x81) // _CST
}
}
} Else { // UP
Notify (\_PR_.CPU0, 0x80)
Sleep(0x64)
Notify(\_PR_.CPU0, 0x81)
}
// Notify the Batteries
Notify(BAT1, 0x80) // Execute BAT1 _BST
Notify(BAT2, 0x80) // Execute BAT2 _BST
}
/* System Bus */
Scope(\_SB)
{
/* This method is placed on the top level, so we can make sure it's the
* first executed _INI method.
*/
Method(_INI, 0)
{
/* The DTS data in NVS is probably not up to date.
* Update temperature values and make sure AP thermal
* interrupts can happen
*/
// TRAP(71) // TODO
/* Determine the Operating System and save the value in OSYS.
* We have to do this in order to be able to work around
* certain windows bugs.
*
* OSYS value | Operating System
* -----------+------------------
* 2000 | Windows 2000
* 2001 | Windows XP(+SP1)
* 2002 | Windows XP SP2
* 2006 | Windows Vista
* ???? | Windows 7
*/
/* Let's assume we're running at least Windows 2000 */
Store (2000, OSYS)
If (CondRefOf(_OSI, Local0)) {
/* Linux answers _OSI with "True" for a couple of
* Windows version queries. But unlike Windows it
* needs a Video repost, so let's determine whether
* we're running Linux.
*/
If (_OSI("Linux")) {
Store (1, LINX)
}
If (_OSI("Windows 2001")) {
Store (2001, OSYS)
}
If (_OSI("Windows 2001 SP1")) {
Store (2001, OSYS)
}
If (_OSI("Windows 2001 SP2")) {
Store (2002, OSYS)
}
If (_OSI("Windows 2006")) {
Store (2006, OSYS)
}
}
/* And the OS workarounds start right after we know what we're
* running: Windows XP SP1 needs to have C-State coordination
* enabled in SMM.
*/
If (LAnd(LEqual(OSYS, 2001), MPEN)) {
// TRAP(61) // TODO
}
/* SMM power state and C4-on-C3 settings need to be updated */
// TRAP(43) // TODO
}
}

View File

@ -0,0 +1,379 @@
/*
* 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
*/
/* SMSC LPC47N227 */
Device (SIO1)
{
Name (_HID, EISAID("PNP0A05"))
Name (_UID, 1)
OperationRegion(SIOR, SystemIO, 0x2e, 0x02)
Field (SIOR, ByteAcc, Nolock, Preserve)
{
INDX, 8,
DATA, 8
}
Mutex (SIOM, 0x00)
Method (READ, 3)
{
Acquire (SIOM, 0xffff)
If (LEqual(Arg0, 0)) {
Store (0x55, INDX)
Store (Arg1, INDX)
Store (DATA, Local1)
Store (0xaa, INDX)
}
And (Local1, Arg2, Local1)
Release(SIOM)
Return(Local1)
}
Method (WRIT, 3)
{
Acquire (SIOM, 0xffff)
If (LEqual(Arg0, 0)) {
Store (0x55, INDX)
Store (Arg1, INDX)
Store (Arg2, DATA)
Store (0xaa, INDX)
}
Release(SIOM)
}
Device (COMA)
{
Name(_HID, EISAID("PNP0501"))
Name(_UID, 1)
Name(_PRW, Package() { 0x08, 0x03 })
/* Device Status */
Method (_STA, 0)
{
// Device disabled by coreboot?
If (LEqual(CMAP, 0)) {
Return (0)
}
// Is the hardware enabled?
Store (READ(0, 0x24, 0xff), Local0)
If (LEqual(Local0, 0)) {
Return (0xd)
} Else {
// Power Enabled?
Store (READ(0, 0x02, 0x08), Local0)
If (LEqual(Local0, 0)) {
Return (0x0d)
} Else {
Return (0x0f)
}
}
}
/* Device Disable */
Method (_DIS, 0)
{
WRIT(0, 0x24, 0x00)
Store(READ(0, 0x28, 0x0f), Local0)
WRIT(0, 0x28, Local0)
Store(READ(0, 0x02, 0xff), Local0)
Not(0x08, Local1)
And(Local0, Local1, Local0)
WRIT(0, 0x02, Local0)
}
/* Possible Resource Settings */
Name(_PRS, ResourceTemplate() {
StartDependentFn(0, 1) {
IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8)
IRQNoFlags() { 4 }
} EndDependentFn()
})
/* Current Resource Settings */
Method(_CRS, 0)
{
Name(NONE, ResourceTemplate() {
IO(Decode16, 0x000, 0x000, 0x0, 0x1)
IRQNoFlags() { }
})
Name(RSRC, ResourceTemplate() {
IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8, _IOA)
IRQNoFlags(_IRA) { 4 }
})
And (_STA(), 0x02, Local0)
If (LEqual(Local0, 0)) {
Return(NONE)
}
CreateByteField(RSRC,
\_SB.PCI0.LPCB.SIO1.COMA._CRS._IOA._MIN, IOLO)
CreateByteField(RSRC, 0x03, IOHI) // Why?
CreateByteField(RSRC,
\_SB.PCI0.LPCB.SIO1.COMA._CRS._IOA._MAX, IORL)
CreateByteField(RSRC, 0x05, IORH) // Why?
CreateByteField(RSRC,
\_SB.PCI0.LPCB.SIO1.COMA._CRS._IRA._INT, IRQL)
Store (READ(0, 0x24, 0xff), Local0)
And (Local0, 0xc0, Local1)
ShiftRight(Local1, 0x06, Local1)
ShiftLeft(Local0, 0x02, Local0)
Store(Local0, IOLO)
Store(Local1, IOHI)
Store(IOLO, IORL)
Store(IOHI, IORH)
/* Interrupt */
Store(READ(0, 0x28, 0xf0), Local0)
ShiftRight(Local0, 4, Local0)
ShiftLeft(1, Local0, IRQL)
Return(RSRC)
}
/* Set Resource Settings */
Method(_SRS, 1)
{
CreateByteField(Arg0, 0x02, IOLO)
CreateByteField(Arg0, 0x03, IOHI)
CreateByteField(Arg0, 0x09, IRQL)
WRIT(0, 0x24, 0)
FindSetRightBit(IRQL, Local0)
Decrement(Local0)
ShiftLeft(Local0, 4, Local0)
Store(READ(0, 0x28, 0x0f), Local1)
Or(Local0, Local1, Local0)
WRIT(0, 0x28, Local0)
Store(IOLO, Local0)
ShiftRight(Local0, 2, Local0)
And(Local0, 0xfe, Local0)
Store(IOHI, Local1)
ShiftLeft(Local1, 6, Local1)
Or (Local0, Local1, Local0)
WRIT(0, 0x24, Local0)
Store(READ(0, 0x02, 0xff), Local0)
Or(Local0, 0x08, Local0)
WRIT(0, 0x02, Local0)
Store(READ(0, 0x07, 0xff), Local0)
Not(0x40, Local1)
And (Local0, Local1, Local0)
WRIT(0, 0x07, Local0)
}
/* D0 state - Line drivers are on */
Method (_PS0, 0)
{
Store(READ(0, 0x02, 0xff), Local0)
Or(Local0, 0x08, Local0)
WRIT(0, 0x02, Local0)
Store (READ(0, 0x07, 0xff), Local0)
Not(0x40, Local1)
And(Local0, Local1, Local0)
WRIT(0, 0x07, Local0)
}
/* D3 State - Line drivers are off */
Method(_PS3, 0)
{
Store(READ(0, 0x02, 0xff), Local0)
Not(0x08, Local1)
And(Local0, Local1, Local0)
WRIT(0, 0x02, Local0)
}
}
Device (COMB)
{
Name(_HID, EISAID("PNP0501"))
Name(_UID, 2)
Name(_PRW, Package() { 0x08, 0x03 })
/* Device Status */
Method (_STA, 0)
{
// Device disabled by coreboot?
If (LEqual(CMBP, 0)) {
Return (0)
}
/* IRDA? */
Store(READ(0, 0x0c, 0x38), Local0)
If (LNotEqual(Local0, Zero)) {
Return (0)
}
// Is the hardware enabled?
Store (READ(0, 0x25, 0xff), Local0)
If (LEqual(Local0, 0)) {
Return (0xd)
} Else {
// Power Enabled?
Store (READ(0, 0x02, 0x80), Local0)
If (LEqual(Local0, 0)) {
Return (0x0d)
} Else {
Return (0x0f)
}
}
}
/* Device Disable */
Method (_DIS, 0)
{
WRIT(0, 0x25, 0x00)
Store(READ(0, 0x28, 0xf0), Local0)
WRIT(0, 0x28, Local0)
Store(READ(0, 0x02, 0xff), Local0)
Not(0x80, Local1)
And(Local0, Local1, Local0)
WRIT(0, 0x02, Local0)
}
/* Possible Resource Settings */
Name(_PRS, ResourceTemplate() {
StartDependentFn(0, 1) {
IO(Decode16, 0x2f8, 0x2f8, 0x8, 0x8)
IRQNoFlags() { 3 }
} EndDependentFn()
})
/* Current Resource Settings */
Method(_CRS, 0)
{
Name(NONE, ResourceTemplate() {
IO(Decode16, 0x000, 0x000, 0x0, 0x1)
IRQNoFlags() { }
})
Name(RSRC, ResourceTemplate() {
IO(Decode16, 0x2f8, 0x2f8, 0x8, 0x8, _IOB)
IRQNoFlags(_IRB) { 3 }
})
And (_STA(), 0x02, Local0)
If (LEqual(Local0, 0)) {
Return(NONE)
}
CreateByteField(RSRC,
\_SB.PCI0.LPCB.SIO1.COMB._CRS._IOB._MIN, IOLO)
CreateByteField(RSRC, 0x03, IOHI)
CreateByteField(RSRC,
\_SB.PCI0.LPCB.SIO1.COMB._CRS._IOB._MAX, IORL)
CreateByteField(RSRC, 0x05, IORH)
CreateByteField(RSRC,
\_SB.PCI0.LPCB.SIO1.COMB._CRS._IRB._INT, IRQL)
Store (READ(0, 0x25, 0xff), Local0)
And (Local0, 0xc0, Local1)
ShiftRight(Local1, 0x06, Local1)
ShiftLeft(Local0, 0x02, Local0)
Store(Local0, IOLO)
Store(Local1, IOHI)
Store(IOLO, IORL)
Store(IOHI, IORH)
/* Interrupt */
Store(READ(0, 0x28, 0x0f), Local0)
ShiftRight(Local0, 4, Local0)
ShiftLeft(1, Local0, IRQL)
Return(RSRC)
}
/* Set Resource Settings */
Method(_SRS, 1)
{
CreateByteField(Arg0, 0x02, IOLO)
CreateByteField(Arg0, 0x03, IOHI)
CreateByteField(Arg0, 0x09, IRQL)
WRIT(0, 0x25, 0)
FindSetRightBit(IRQL, Local0)
Decrement(Local0)
Store(READ(0, 0x28, 0xf0), Local1)
Or(Local0, Local1, Local0)
WRIT(0, 0x28, Local0)
Store(IOLO, Local0)
ShiftRight(Local0, 2, Local0)
And(Local0, 0xfe, Local0)
Store(IOHI, Local1)
ShiftLeft(Local1, 6, Local1)
Or (Local0, Local1, Local0)
WRIT(0, 0x25, Local0)
Store(READ(0, 0x0c, 0xff), Local0)
Not(0x38, Local1)
And(Local0, Local1, Local0)
WRIT(0, 0x0c, Local0)
Store(READ(0, 0x02, 0xff), Local0)
Or(Local0, 0x80, Local0)
WRIT(0, 0x02, Local0)
Store(READ(0, 0x07, 0xff), Local0)
Not(0x20, Local1)
And (Local0, Local1, Local0)
WRIT(0, 0x07, Local0)
}
/* D0 state - Line drivers are on */
Method (_PS0, 0)
{
Store(READ(0, 0x02, 0xff), Local0)
Or(Local0, 0x80, Local0)
WRIT(0, 0x02, Local0)
Store (READ(0, 0x07, 0xff), Local0)
Not(0x20, Local1)
And(Local0, Local1, Local0)
WRIT(0, 0x07, Local0)
}
/* D3 State - Line drivers are off */
Method(_PS3, 0)
{
Store(READ(0, 0x02, 0xff), Local0)
Not(0x80, Local1)
And(Local0, Local1, Local0)
WRIT(0, 0x02, Local0)
}
}
}

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.CPU0, \_PR.CPU1})
}
Return (Package() {\_PR.CPU0})
}
// 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,368 @@
/*
* 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 <console/console.h>
#include <arch/io.h>
#include <arch/ioapic.h>
#include <arch/acpi.h>
#include <arch/acpigen.h>
#include <arch/smp/mpspec.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include "dmi.h"
extern const unsigned char AmlCode[];
#if CONFIG_HAVE_ACPI_SLIC
unsigned long acpi_create_slic(unsigned long current);
#endif
#define OLD_ACPI 0
#if OLD_ACPI
static void acpi_create_gnvs(global_nvs_t *gnvs)
{
memset (gnvs, 0, sizeof(global_nvs_t));
gnvs->LIDS = 1;
gnvs->PWRS = 1;
gnvs->ACTT = 0x37;
gnvs->PSVT = 0x4f;
gnvs->TC1V = 0x00;
gnvs->TC2V = 0x0a;
gnvs->TSPV = 0x02;
gnvs->CRTT = 0x77;
gnvs->B0SC = 0x54;
gnvs->APIC = 0x01;
gnvs->MPEN = 0x01;
gnvs->PPCM = 0x02;
gnvs->PCP0 = 0xbf;
gnvs->PCP1 = 0xbf;
gnvs->CMAP = 0x01;
gnvs->CMBP = 0x01;
gnvs->LT0 = 0x01;
gnvs->FDCP = 0x01;
gnvs->CMCP = 0x01;
gnvs->CMDP = 0x01;
gnvs->P2M = 0x02;
gnvs->IGDS = 0x01;
gnvs->CADL = 0x09;
gnvs->PADL = 0x09;
gnvs->NDID = 3;
gnvs->DID1 = 0x80000100;
gnvs->DID2 = 0x80000240;
gnvs->DID3 = 0x80000410;
gnvs->DID4 = 0x80000410;
gnvs->DID5 = 0x00000005;
gnvs->ALAF = 0x64;
gnvs->LLOW = 0x2c;
gnvs->LHIH = 0x01;
// tolud = pci_read_config32(dev_find_slot(0, PCI_DEVFN(2, 0)), 0x5c);
// oemb->topm = tolud;
}
#endif
#include "southbridge/intel/i82801gx/nvs.h"
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);
/* LAPIC_NMI */
current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
current, 0,
MP_IRQ_POLARITY_HIGH |
MP_IRQ_TRIGGER_EDGE, 0x01);
current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
current, 1, MP_IRQ_POLARITY_HIGH |
MP_IRQ_TRIGGER_EDGE, 0x01);
/* INT_SRC_OVR */
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE);
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
current, 0, 9, 9, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_LEVEL);
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;
void *gnvs;
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);
/* Fix up global NVS region for SMI handler. The GNVS region lives
* in the (high) table area. The low memory map looks like this:
*
* 0x00000000 - 0x000003ff Real Mode IVT
* 0x00000020 - 0x0000019c Low MP Table (XXX conflict?)
* 0x00000400 - 0x000004ff BDA (somewhat unused)
* 0x00000500 - 0x0000052f Moved GDT
* 0x00000530 - 0x00000b64 coreboot table
* 0x0007c000 - 0x0007dfff OS boot sector (unused?)
* 0x0007e000 - 0x0007ffff free to use (so no good for acpi+smi)
* 0x00080000 - 0x0009fbff usable ram
* 0x0009fc00 - 0x0009ffff EBDA (unused?)
* 0x000a0000 - 0x000bffff VGA memory
* 0x000c0000 - 0x000cffff VGA option rom
* 0x000d0000 - 0x000dffff free for other option roms?
* 0x000e0000 - 0x000fffff SeaBIOS? (conflict with low tables:)
* 0x000f0000 - 0x000f03ff PIRQ table
* 0x000f0400 - 0x000f66?? ACPI tables
* 0x000f66?? - 0x000f???? DMI tables
*/
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%08x\n", i, (u32)current);
*(u32*)(((u32)dsdt) + i) = current; // 0x92 bytes
break;
}
}
/* And fill it */
acpi_create_gnvs((global_nvs_t *)current);
/* Keep pointer around */
gnvs = (void *)current;
current += 0x100;
ALIGN_CURRENT;
/* And tell SMI about it */
smm_setup_structures(gnvs, 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");
/* Enable Dummy DCC ON# for DVI */
printk(BIOS_DEBUG, "Laptop handling...\n");
outb(inb(0x60f) & ~(1 << 5), 0x60f);
return current;
}

View File

@ -0,0 +1,21 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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-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
#
# -----------------------------------------------------------------
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 8 h 0 boot_default
936 1 e 8 cmos_defaults_loaded
937 1 e 1 lpt
#938 46 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
8 0 No
8 1 Yes
# -----------------------------------------------------------------
checksums
checksum 392 983 984

View File

@ -0,0 +1,130 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2009 coresystems GmbH
## Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
##
## 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
##
chip northbridge/intel/i945
device lapic_cluster 0 on
chip cpu/intel/socket_mFCPGA478
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 # vga controller
device pci 02.1 on end # display controller
chip southbridge/intel/i82801gx
register "pirqa_routing" = "0x0b"
register "pirqb_routing" = "0x0b"
register "pirqc_routing" = "0x0b"
register "pirqd_routing" = "0x0b"
register "pirqe_routing" = "0x0b"
register "pirqf_routing" = "0x0b"
register "pirqg_routing" = "0x0b"
register "pirqh_routing" = "0x0b"
# GPI routing
# 0 No effect (default)
# 1 SMI# (if corresponding ALT_GPI_SMI_EN bit is also set)
# 2 SCI (if corresponding GPIO_EN bit is also set)
register "gpi13_routing" = "2"
register "gpi12_routing" = "2"
register "gpi8_routing" = "2"
register "sata_ahci" = "0x0"
register "gpe0_en" = "0x11000006"
device pci 1b.0 on end # Audio Controller
device pci 1c.0 on end # Ethernet
device pci 1c.1 on end # Atheros WLAN
device pci 1d.0 on end # USB UHCI
device pci 1d.1 on end # USB UHCI
device pci 1d.2 on end # USB UHCI
device pci 1d.3 on end # USB UHCI
device pci 1d.7 on end # USB2 EHCI
device pci 1f.0 on # PCI-LPC bridge
chip ec/lenovo/pmh7
device pnp ff.1 on # dummy
end
end
chip ec/acpi
device pnp ff.2 on # dummy
io 0x60 = 0x62
io 0x62 = 0x66
io 0x64 = 0x1600
io 0x66 = 0x1604
end
end
chip superio/nsc/pc87382
device pnp 164e.2 on # IR
io 0x60 = 0x2f8
end
device pnp 164e.3 off # Serial Port
io 0x60 = 0x3f8
end
device pnp 164e.7 on # GPIO
io 0x60 = 0x1680
end
device pnp 164e.19 on # DLPC
io 0x60 = 0x164c
end
end
chip superio/nsc/pc87392
device pnp 2e.0 off #FDC
end
device pnp 2e.1 on # Parallel Port
io 0x60 = 0x3bc
irq 0x70 = 7
end
device pnp 2e.2 off # Serial Port / IR
io 0x60 = 0x2f8
irq 0x70 = 4
end
device pnp 2e.3 on # Serial Port
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.7 on # GPIO
io 0x60 = 0x1620
end
device pnp 2e.a off # WDT
end
end
end
device pci 1f.1 off end # IDE
device pci 1f.2 on end # SATA
device pci 1f.3 on end # SMBus
end
chip southbridge/ricoh/rl5c476
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, 0x29, 0x1f, 0x02, 0x03, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5f, 0x44, 0x4d, 0x49, 0x5f, 0x61, 0x35, 0x00, 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,56 @@
/*
* 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",
0x03, // DSDT revision: ACPI v3.0
"COREv4", // OEM id
"COREBOOT", // OEM table id
0x20090419 // OEM revision
)
{
// Some generic macros
#include "acpi/platform.asl"
// global NVS and variables
#include "../../../southbridge/intel/i82801gx/acpi/globalnvs.asl"
// General Purpose Events
#include "acpi/gpe.asl"
// mainboard specific devices
#include "acpi/mainboard.asl"
// Thermal Zone
#include "acpi/thermal.asl"
Scope (\_SB) {
Device (PCI0)
{
#include "../../../northbridge/intel/i945/acpi/i945.asl"
#include "../../../southbridge/intel/i82801gx/acpi/ich7.asl"
}
}
/* Chipset specific sleep states */
#include "../../../southbridge/intel/i82801gx/acpi/sleepstates.asl"
}

View File

@ -0,0 +1,164 @@
/*
* 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 <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 = 0;
fadt->firmware_ctrl = (unsigned long) facs;
fadt->dsdt = (unsigned long) dsdt;
fadt->model = 0x00;
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;
fadt->pm2_cnt_len = 1;
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 = 0x23;
fadt->flush_size = 0;
fadt->flush_stride = 0;
fadt->duty_offset = 1;
fadt->duty_width = 3;
fadt->day_alrm = 0xd;
fadt->mon_alrm = 0x00;
fadt->century = 0x32;
fadt->iapc_boot_arch = 0x00;
fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE |
ACPI_FADT_DOCKING_SUPPORTED;
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 = 0;
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 = 0;
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 = 0;
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,61 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 * 15, /* 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 */
0x122e, /* Device */
0, /* Miniport */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0xf5, /* 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, {{0x00, 0xdef8}, {0x61, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* VGA 0:02.0 */
{0x00, (0x1b << 3) | 0x0, {{0x00, 0xdef8}, {0x61, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* HD Audio 0:1b.0 */
{0x00, (0x1c << 3) | 0x0, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe 0:1c.0 */
{0x00, (0x1c << 3) | 0x1, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe 0:1c.1 */
{0x00, (0x1c << 3) | 0x2, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe 0:1c.2 */
{0x00, (0x1c << 3) | 0x3, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe 0:1c.3 */
{0x00, (0x1d << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB 0:1d.0 */
{0x00, (0x1d << 3) | 0x1, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB 0:1d.1 */
{0x00, (0x1d << 3) | 0x2, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB 0:1d.2 */
{0x00, (0x1d << 3) | 0x3, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB 0:1d.3 */
{0x00, (0x1e << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* PCI 0:1e.0 */
{0x00, (0x1f << 3) | 0x0, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* LPC 0:1f.0 */
{0x00, (0x1f << 3) | 0x1, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* IDE 0:1f.1 */
{0x00, (0x1f << 3) | 0x2, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* SATA 0:1f.2 */
}
};
unsigned long write_pirq_routing_table(unsigned long addr)
{
return copy_pirq_routing_table(addr);
}

View File

@ -0,0 +1,416 @@
/*
* 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 <types.h>
#include <stdlib.h>
#include <console/console.h>
#include <arch/io.h>
#include <delay.h>
#include <ec/acpi/ec.h>
#include "m3885.h"
#define TH0LOW 80
#define TH0HIGH 85
#define TH0CRIT 120
#define TH1LOW 75
#define TH1HIGH 80
static u8 variables[] = {
/* Offs, AND, OR */
0x08, 0x48, 0x6C, // Keyboard ScanCode Set & LED Data (kState1)
0x0a, 0x01, 0x00, // Keyboard Shift flags (kState3)
0x0c, 0x80, 0x08, // Keyboard State flags (kState5)
0x11, 0xff, 0x06, // Make/Break Debounce #'s (debounce)
0x13, 0xff, 0x00, // HotKey1 ScanCode (hotKey1)
0x14, 0xff, 0x00, // HotKey2 ScanCode (hotKey2)
0x15, 0xff, 0x3f, // HotKey3 ScanCode (hotKey3)
0x16, 0xff, 0x00, // HotKey4 ScanCode (hotKey4)
0x17, 0xff, 0x00, // HotKey5 ScanCode (hotKey5)
0x18, 0xff, 0x0e, // HotKey6 ScanCode (hotKey6)
0x19, 0xff, 0x9f, // HotKey1 Task = c5 Command Data (keyTsk1)
0x1a, 0xff, 0x9f, // HotKey2 Task = c5 Command Data (keyTsk2)
0x1b, 0xff, 0x6a, // HotKey3 Task = c5 Command Data (keyTsk3)
0x1c, 0xff, 0x9f, // HotKey4 Task = c5 Command Data (keyTsk4)
0x1d, 0xff, 0x9f, // HotKey5 Task = c5 Command Data (keyTsk5)
0x1e, 0xff, 0x87, // FuncKey Task = c5 Command Data (funcTsk)
0x1f, 0xff, 0x9f, // Delayed Task = c5 Command Data (dlyTsk1)
0x20, 0xff, 0x9f, // Wake-Up Task = c5 Command Data (wakeTsk)
//
0x21, 0xff, 0x08, // WigglePin Pulse Width * 2.4ms (tmPulse)
0x24, 0xff, 0x30, // Keyboard State Flags (kState7)
//
0x2b, 0xff, 0x00, //
0x2c, 0xff, 0x80, // Set Fn-Key 8
0x2d, 0xff, 0x02, // Set Fn-Key 9
0x2e, 0xff, 0x00, // Set Fn-Key 1-8 task (0 = SMI)
0x2f, 0xff, 0x00, // Set Fn-Key 9-12 task (1 = SCI)
};
static u8 matrix[] = {
0xc1,0xc0,0xd8,0xdb,0xbf,0x05,0x76,0xbf, // (0x00-0x07)
0xbf,0x80,0x78,0xbf,0xbf,0x07,0x88,0xc2, // (0x08-0x0f)
0x03,0x09,0xd9,0x16,0xbf,0x06,0x0e,0x81, // (0x10-0x17)
0xbf,0xbf,0xee,0xbf,0xbf,0x55,0x9a,0x89, // (0x18-0x1f)
0x1e,0x15,0x36,0xda,0xe8,0xbf,0x0d,0xbf, // (0x20-0x27)
0xbf,0xbf,0xbf,0xa3,0xbf,0x4e,0x66,0x8b, // (0x28-0x2f)
0x1d,0x2e,0xe6,0xe7,0xe5,0x1c,0x58,0xbf, // (0x30-0x37)
0x82,0xbf,0xf0,0xbf,0xbf,0x5b,0x5d,0x8c, // (0x38-0x3f)
0x22,0x25,0x2c,0x35,0xe1,0x1a,0x96,0xbf, // (0x40-0x47)
0xbf,0xbf,0xec,0xbf,0xbf,0x54,0xf1,0x8f, // (0x48-0x4f)
0x1b,0x2a,0x2b,0x32,0xe9,0x31,0x29,0x61, // (0x50-0x57)
0xbf,0xbf,0x8d,0xbf,0x86,0xc3,0x92,0x93, // (0x58-0x5f)
0x21,0x23,0x34,0x33,0x41,0xe0,0xbf,0xbf, // (0x60-0x67)
0xbf,0x85,0xeb,0xbf,0xb6,0xbf,0x91,0xbf, // (0x68-0x6f)
0x26,0x24,0x2d,0xe3,0xe2,0xe4,0xbf,0xbf, // (0x70-0x77)
0x87,0xbf,0xea,0xbf,0xbf,0x52,0x90,0x8e, // (0x78-0x7f)
};
static u8 function_ram[] = {
0x04,0xbd,0x0c,0xbe,0x7e,0x9a,0x8a,0xb6, // (0xc0-0xc3)
0x92,0x8f,0x93,0x8e,0x81,0x86,0x82,0x87, // (0xc4-0xc7)
0x8a,0x9a,0x8d,0x7e,0x88,0x84,0x7e,0x78, // (0xc8-0xcb)
0x77,0x07,0x77,0x98,0x89,0xb2,0x05,0x9b, // (0xcc-0xcf)
0x78,0x84,0x07,0x88,0x8a,0x7e,0x05,0xa6, // (0xd0-0xd3)
0x06,0xa7,0x04,0xa8,0x0c,0xa9,0x03,0xaa, // (0xd4-0xd7)
0x0b,0xc1,0x83,0xc0,0x0a,0xad,0x01,0xae, // (0xd8-0xdb)
0x09,0xaf,0x78,0xb0,0x07,0xb1,0x1a,0x61, // (0xdc-0xdf)
0x3b,0x69,0x42,0x72,0x4b,0x7a,0x3c,0x6b, // (0xe0-0xe3)
0x43,0x73,0x44,0x74,0x3d,0x6c,0x3e,0x75, // (0xe4-0xe7)
0x46,0x7d,0x3a,0x70,0x49,0x71,0x4a,0x94, // (0xe8-0xeb)
0x4c,0x79,0x4c,0x7c,0x45,0x7c,0x45,0x79, // (0xec-0xef)
0x4d,0x7b,0x5a,0x95,0x4c,0x7b,0x45,0x7b, // (0xf0-0xf3)
0x4d,0x79,0x4d,0x7c,0x4e,0x7b,0x54,0x95, // (0xf4-0xf7)
0x52,0x7c,0x45,0x94,0x4a,0x79,0xb3,0x95, // (0xf8-0xfb)
0xb4,0x7b,0xb5,0x7c,0x00,0x00,0x55,0x79, // (0xfc-0xff)
};
#define KBD_DATA 0x60
#define KBD_SC 0x64
#define KBD_IBF (1 << 1) // 1: input buffer full (data ready for ec)
#define KBD_OBF (1 << 0) // 1: output buffer full (data ready for host)
static int send_kbd_command(u8 command)
{
int timeout;
timeout = 0x7ff;
while ((inb(KBD_SC) & KBD_IBF) && --timeout) {
udelay(10);
if ((timeout & 0xff) == 0)
printk(BIOS_SPEW, ".");
}
if (!timeout) {
printk(BIOS_DEBUG, "Timeout while sending command 0x%02x to EC!\n",
command);
// return -1;
}
outb(command, KBD_SC);
return 0;
}
static int send_kbd_data(u8 data)
{
int timeout;
timeout = 0x7ff;
while ((inb(KBD_SC) & KBD_IBF) && --timeout) { // wait for IBF = 0
udelay(10);
if ((timeout & 0xff) == 0)
printk(BIOS_SPEW, ".");
}
if (!timeout) {
printk(BIOS_DEBUG, "Timeout while sending data 0x%02x to EC!\n",
data);
// return -1;
}
outb(data, KBD_DATA);
return 0;
}
static u8 recv_kbd_data(void)
{
int timeout;
u8 data;
timeout = 0x7fff;
while (--timeout) { // Wait for OBF = 1
if (inb(KBD_SC) & KBD_OBF) {
break;
}
udelay(10);
if ((timeout & 0xff) == 0)
printk(BIOS_SPEW, ".");
}
if (!timeout) {
printk(BIOS_DEBUG, "\nTimeout while receiving data from EC!\n");
// return -1;
}
data = inb(KBD_DATA);
return data;
}
static u8 m3885_get_variable(u8 index)
{
u8 ret;
send_kbd_command(0xb8);
send_kbd_data(index);
send_kbd_command(0xbc);
send_kbd_command(0xff);
ret = recv_kbd_data();
printk(BIOS_SPEW, "m3885: get variable %02x = %02x\n", index, ret);
return ret;
}
static void m3885_set_variable(u8 index, u8 data)
{
printk(BIOS_SPEW, "m3885: set variable %02x = %02x\n", index, data);
send_kbd_command(0xb8);
send_kbd_data(index);
send_kbd_command(0xbd);
send_kbd_data(data);
}
static void m3885_set_proc_ram(u8 index, u8 data)
{
printk(BIOS_SPEW, "m3885: set procram %02x = %02x\n", index, data);
send_kbd_command(0xb8);
send_kbd_data(index);
send_kbd_command(0xbb);
send_kbd_data(data);
}
static u8 m3885_get_proc_ram(u8 index)
{
u8 ret;
send_kbd_command(0xb8);
send_kbd_data(index);
send_kbd_command(0xba);
// send_kbd_command(0xff);
ret = recv_kbd_data();
printk(BIOS_SPEW, "m3885: get procram %02x = %02x\n", index, ret);
return ret;
}
static u8 m3885_read_port(void)
{
u8 reg8;
reg8 = m3885_get_variable(0x0c);
reg8 &= ~(7 << 4);
reg8 |= (4 << 4); // bank 4
m3885_set_variable(0x0c, reg8);
/* P6YSTATE */
return m3885_get_proc_ram(0xf8);
}
void m3885_configure_multikey(void)
{
int i;
u8 reg8;
u8 kstate5_flags, offs, maxvars;
/* ram bank 0 */
kstate5_flags = m3885_get_variable(0x0c);
m3885_set_variable(0x0c, kstate5_flags & ~(7 << 4));
/* Write Matrix to bank 0 */
for (i=0; i < ARRAY_SIZE(matrix); i++) {
m3885_set_proc_ram(i + 0x80, matrix[i]);
}
/* ram bank 2 */
m3885_set_variable(0x0c, (kstate5_flags & (~(7 << 4))) | (2 << 4));
/* Get the number of variables */
maxvars = m3885_get_variable(0x00);
printk(BIOS_DEBUG, "M388x has %d variables in bank 2.\n", maxvars);
if (maxvars >= 35) {
offs = m3885_get_variable(0x23);
if ((offs > 0xc0) || (offs < 0x80)) {
printk(BIOS_DEBUG, "M388x does not have a valid ram offset (0x%x)\n", offs);
} else {
printk(BIOS_DEBUG, "Writing Fn-Table to M388x RAM offset 0x%x\n", offs);
for (i=0; i < ARRAY_SIZE(function_ram); i++) {
m3885_set_proc_ram(i + offs, function_ram[i]);
}
}
} else {
printk(BIOS_DEBUG, "Could not load Function-RAM (%d).\n", maxvars);
}
// restore original bank
m3885_set_variable(0x0c, kstate5_flags);
maxvars = m3885_get_variable(0x00);
printk(BIOS_DEBUG, "M388x has %d variables in original bank.\n", maxvars);
for (i=0; i<ARRAY_SIZE(variables); i+=3) {
if(variables[i + 0] > maxvars)
continue;
reg8 = m3885_get_variable(variables[i + 0]);
reg8 &= ~(variables[i + 1]);
reg8 |= variables[i + 2]; // & ~variables[i + 1];
m3885_set_variable(variables[i + 0], reg8);
}
/* OEM Init */
/* Set Bank 1 */
m3885_set_variable(0x0c, (kstate5_flags & ~(7 << 4)) | (1 << 4));
/* Set SMI# at P5.1 */
/* SMI Control -> p5.1 = EXTSMI# */
m3885_set_proc_ram(0xff, 0xc1);
/* Set Fn-Key Task 0 -> SMI#/SCI */
m3885_set_proc_ram(0x6d, 0x81);
/* Set Fn-Key Task 1 -> SCI */
m3885_set_proc_ram(0x6c, 0x80);
/* Number of Thermal Sensors */
m3885_set_proc_ram(0xf2, 0x02);
/* Critical Task */
m3885_set_proc_ram(0xf3, 0x5d);
/* Thermal Polling Period */
m3885_set_proc_ram(0xf9, 0x0a);
/* ReadPort */
// m3885_set_variable(0x0c, (kstate5_flags & ~(7 << 4)) | (4 << 4));
/* AC PRESN# */
if (m3885_read_port() & (1 << 0))
reg8 = 0x8a;
else
reg8 = 0x9a;
m3885_set_proc_ram(0xd0, reg8); // P60SPEC
/* SENSE1# */
if (m3885_read_port() & (1 << 2))
reg8 = 0x8a;
else
reg8 = 0x9a;
m3885_set_proc_ram(0xd2, reg8); // P62SPEC
/* SENSE2# */
if (m3885_read_port() & (1 << 3))
reg8 = 0x8a;
else
reg8 = 0x9a;
m3885_set_proc_ram(0xd3, reg8); // P63SPEC
/* Low Active Port */
m3885_set_proc_ram(0xd1, 0x88); // P61SPEC
m3885_set_proc_ram(0xd6, 0x88); // P66SPEC
m3885_set_proc_ram(0xd7, 0x88); // P67SPEC
/* High Active Port */
m3885_set_proc_ram(0xd4, 0x98); // P64SPEC
m3885_set_proc_ram(0xd5, 0x98); // P65SPEC
/* Set P60TASK-P67TASK */
/* SCI */
m3885_set_proc_ram(0xda, 0x80); // P62TASK SENSE1#
m3885_set_proc_ram(0xdb, 0x80); // P63TASK SENSE2#
m3885_set_proc_ram(0xdd, 0x80); // P65TASK PROCHOT
m3885_set_proc_ram(0xde, 0x80); // P65TASK THERMTRIP#
m3885_set_proc_ram(0xdf, 0x80); // P65TASK PME#
/* SMI/SCI */
m3885_set_proc_ram(0xd8, 0x81); // P60TASK, AC_PRESN#
m3885_set_proc_ram(0xd9, 0x81); // P61TASK, LID#
m3885_set_proc_ram(0xdc, 0x81); // P64TASK, FDD/LPT#
/* Thermal */
/* Bank 5 */
m3885_set_variable(0x0c, (kstate5_flags & ~(7 << 4)) | (5 << 4));
/* Thermal 0: Active cooling, Speed Step Down */
m3885_set_proc_ram(0x81, 0x9c); // THRM0
m3885_set_proc_ram(0x82, 0x01); // THRM0 CMD
m3885_set_proc_ram(0x84, TH0LOW); // THRM0 LOW
m3885_set_proc_ram(0x85, TH0HIGH); // THRM0 HIGH
m3885_set_proc_ram(0x86, 0x81); // Set Task SMI#/SCI
m3885_set_proc_ram(0x87, TH0CRIT); // THRM0 CRIT
/* Thermal 1: Passive cooling, Fan On */
m3885_set_proc_ram(0x89, 0x9c); // THRM1
m3885_set_proc_ram(0x8a, 0x01); // THRM1 CMD
m3885_set_proc_ram(0x8c, TH1LOW); // THRM1 LOW
m3885_set_proc_ram(0x8d, TH1HIGH); // THRM1 HIGH
m3885_set_proc_ram(0x8e, 0x81); // Set Task SMI#/SCI
/* Switch Task to SMI */
udelay(100 * 1000); // 100ms
outb(KBD_SC, 0xca);
udelay(100 * 1000); // 100ms
outb(KBD_DATA, 0x17);
/* Set P22 to high level, keyboard backlight default off */
udelay(100 * 1000); // 100ms
outb(KBD_SC, 0xc5);
udelay(100 * 1000); // 100ms
outb(KBD_DATA, 0x4a);
}
u8 m3885_gpio(u8 value)
{
#if 0
int timeout;
#endif
/* First write data */
ec_write(M3885_CMDAT1, value);
/* Issue command: ACCESS GPIO */
ec_write(M3885_CMCMD, 0xc5);
#if 0
/* CMCMD is 0 when the command is completed */
timeout = 0xf;
while (ec_read(M3885_CMCMD) && --timeout) {
udelay(10);
printk(BIOS_DEBUG, ".");
}
if (!timeout) {
printk(BIOS_DEBUG, "\nTimeout while waiting for M3885 command!\n");
}
/* If it was a read function: Pin state */
return ec_read(M3885_CMDAT1);
#else
return 0;
#endif
}

View File

@ -0,0 +1,76 @@
/*
* 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 _MAINBOARD_M3885_H
#define _MAINBOARD_M3885_H
#define M3885_CMCMD 0x04
#define M3885_CMDAT1 0x05
#define M3885_CMDAT2 0x06
#define M3885_CMDAT3 0x07
#define M3885_GPIO_LEVEL (0<<7)
#define M3885_GPIO_PULSE (1<<7)
#define M3885_GPIO_READ (0<<5)
#define M3885_GPIO_SET (1<<5)
#define M3885_GPIO_CLEAR (2<<5)
#define M3885_GPIO_TOGGLE (3<<5)
#define M3885_GPIO_P14 (0x00<<0)
#define M3885_GPIO_P15 (0x01<<0)
#define M3885_GPIO_P16 (0x02<<0)
#define M3885_GPIO_P17 (0x03<<0)
#define M3885_GPIO_P54 (0x04<<0)
#define M3885_GPIO_P55 (0x05<<0)
#define M3885_GPIO_P56 (0x06<<0)
#define M3885_GPIO_P57 (0x07<<0)
#define M3885_GPIO_P20 (0x08<<0)
#define M3885_GPIO_P21 (0x09<<0)
#define M3885_GPIO_P22 (0x0a<<0)
#define M3885_GPIO_P23 (0x0b<<0)
#define M3885_GPIO_P24 (0x0c<<0)
#define M3885_GPIO_P25 (0x0d<<0)
#define M3885_GPIO_P26 (0x0e<<0)
#define M3885_GPIO_P27 (0x0f<<0)
#define M3885_GPIO_P40 (0x10<<0)
#define M3885_GPIO_P41 (0x11<<0)
#define M3885_GPIO_P42 (0x12<<0)
#define M3885_GPIO_P43 (0x13<<0)
#define M3885_GPIO_P44 (0x14<<0)
#define M3885_GPIO_P45 (0x15<<0)
#define M3885_GPIO_P46 (0x16<<0)
#define M3885_GPIO_P47 (0x17<<0)
#define M3885_GPIO_P60 (0x18<<0)
#define M3885_GPIO_P61 (0x19<<0)
#define M3885_GPIO_P62 (0x1a<<0)
#define M3885_GPIO_P63 (0x1b<<0)
#define M3885_GPIO_P64 (0x1c<<0)
#define M3885_GPIO_P65 (0x1d<<0)
#define M3885_GPIO_P66 (0x1e<<0)
#define M3885_GPIO_P67 (0x1f<<0)
void m3885_configure_multikey(void);
u8 m3885_gpio(u8 value);
#endif

View File

@ -0,0 +1,83 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 <arch/io.h>
#include <boot/tables.h>
#include <delay.h>
#include <arch/coreboot_tables.h>
#include "chip.h"
#include <device/pci_def.h>
#include <device/pci_ops.h>
#include <arch/io.h>
#include <ec/lenovo/pmh7/pmh7.h>
#include <ec/acpi/ec.h>
static void backlight_enable(void)
{
pmh7_register_set_bit(0x50, 5);
}
static void trackpoint_enable(void)
{
ec_write(0x0b, 0x03);
}
static void wlan_enable(void)
{
ec_write(0x3a, 0x20);
}
static void mainboard_enable(device_t dev)
{
backlight_enable();
trackpoint_enable();
/* FIXME: this should be ACPI's task
* but for now, enable it here */
wlan_enable();
/* enable ACPI events */
ec_write(0x00, 0xa6);
ec_write(0x01, 0x05);
ec_write(0x02, 0xa0);
ec_write(0x03, 0x05);
/* set mask of enabled beeps */
ec_write(0x04, 0xfe);
ec_write(0x05, 0x96);
/* Unknown, but required for hotkeys
Maybe a mask for enabled keys? */
ec_write(0x12, 0xff);
ec_write(0x13, 0xff);
ec_write(0x14, 0xf4);
ec_write(0x15, 0x3c);
}
struct chip_operations mainboard_ops = {
CHIP_NAME(CONFIG_MAINBOARD_VENDOR " " CONFIG_MAINBOARD_PART_NUMBER)
.enable_dev = mainboard_enable,
};

View File

@ -0,0 +1,53 @@
/*
* 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"
/* 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,85 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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/smp/mpspec.h>
#include <arch/ioapic.h>
#include <string.h>
#include <stdint.h>
static 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, LAPIC_ADDR);
smp_write_processors(mc);
mptable_write_buses(mc, NULL, &isa_bus);
/* I/O APICs: APIC ID Version State Address */
smp_write_ioapic(mc, 2, 0x20, IO_APIC_ADDR);
/* Legacy Interrupts */
mptable_add_isa_interrupts(mc, isa_bus, 0x2, 0);
smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, isa_bus, 0x00, MP_APIC_ALL, 0x00);
smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x00, MP_APIC_ALL, 0x01);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x01 << 2), 0x02, 0x10); /* PCIe root 0.02.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x02 << 2), 0x02, 0x10); /* VGA 0.02.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1b << 2), 0x02, 0x11); /* HD Audio 0:1b.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1c << 2), 0x02, 0x14); /* PCIe 0:1c.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1c << 2) | 0x01, 0x02, 0x15); /* PCIe 0:1c.1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1c << 2) | 0x02, 0x02, 0x16); /* PCIe 0:1c.2 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1c << 2) | 0x03, 0x02, 0x17); /* PCIe 0:1c.3 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1d << 2) , 0x02, 0x10); /* USB 0:1d.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1d << 2) | 0x01, 0x02, 0x11); /* USB 0:1d.1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1d << 2) | 0x02, 0x02, 0x12); /* USB 0:1d.2 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1d << 2) | 0x03, 0x02, 0x13); /* USB 0:1d.3 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1f << 2) , 0x02, 0x17); /* LPC 0:1f.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1f << 2) | 0x01, 0x02, 0x10); /* IDE 0:1f.1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1f << 2) | 0x02, 0x02, 0x10); /* SATA 0:1f.2 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x05, (0x00 << 2) | 0x00, 0x02, 0x10); /* Cardbus 5:00.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x05, (0x00 << 2) | 0x01, 0x02, 0x11); /* Firewire 5:00.1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x05, (0x00 << 2) | 0x02, 0x02, 0x12); /* SDHC 5:00.2 */
smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_HIGH, isa_bus, 0, MP_APIC_ALL, 0);
smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_HIGH, isa_bus, 0, MP_APIC_ALL, 1);
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,411 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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
*/
// __PRE_RAM__ means: use "unsigned" for device, not a struct.
#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 <lib.h>
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <usbdebug.h>
#include <cpu/x86/bist.h>
#include "northbridge/intel/i945/i945.h"
#include "northbridge/intel/i945/raminit.h"
#include "southbridge/intel/i82801gx/i82801gx.h"
void setup_ich7_gpios(void)
{
printk(BIOS_DEBUG, " GPIOS...");
/* X60 GPIO:
1: HDD_PRESENCE#
6: Unknown (Pulled high by R215 to VCC3B)
7: BDC_PRESENCE#
8: H8_WAKE#
9: RTC_BAT_IN#
10: Unknown (Pulled high by R700 to VCC3M
12: H8SCI#
13: SLICE_ON_3M#
14: Unknown (Pulled high by R321 to VCC3)
15: Unknown (Pulled high by R258 to VCC3)
19: Unknown (Pulled low by R594)
21: Unknown (Pulled high by R145 to VCC3)
22: FWH_WP#
25: MDC_KILL#
33: HDD_PRESENCE_2#
35: CLKREQ_SATA#
36: PLANARID0
37: PLANARID1
38: PLANARID2
39: PLANARID3
48: FWH_TBL#
*/
outl(0x1f40f7c2, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */
outl(0xe0e8ffc3, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */
outl(0xfbf6ddfd, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */
/* Output Control Registers */
outl(0x00040000, DEFAULT_GPIOBASE + 0x18); /* GPO_BLINK */
/* Input Control Registers */
outl(0x000039ff, DEFAULT_GPIOBASE + 0x2c); /* GPI_INV */
outl(0x000100f2, DEFAULT_GPIOBASE + 0x30); /* GPIO_USE_SEL2 */
outl(0x000000f0, DEFAULT_GPIOBASE + 0x34); /* GP_IO_SEL2 */
outl(0x00030043, DEFAULT_GPIOBASE + 0x38); /* GP_LVL */
}
static void ich7_enable_lpc(void)
{
// Enable Serial IRQ
pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x64, 0xd0);
// decode range
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x80, 0x0210);
// decode range
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x1f0d);
/* range 0x1600 - 0x167f */
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x84, 0x1601);
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x86, 0x007c);
/* range 0x15e0 - 0x10ef */
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x88, 0x15e1);
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8a, 0x000c);
/* range 0x1680 - 0x169f */
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8c, 0x1681);
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8e, 0x001c);
}
static void pnp_write_register(device_t dev, int reg, int val)
{
unsigned int port = dev >> 8;
outb(reg, port);
outb(val, port+1);
}
static void dock_write_register(int reg, int value)
{
outb(reg, 0x164e);
outb(value, 0x164f);
/* original software reads the chip id after every
I/O operation. Not sure if they are doing it for
some code switching depending on hardware or just
to have a delay after every operation.
Do it the same way for now, we may remove it later
if it isn't needed
*/
outb(0x20, 0x164e);
inb(0x164f);
}
static void dock_dlpc_init(void)
{
/* Select DLPC module */
dock_write_register(0x07, 0x19);
/* DLPC Base Address 0x164c */
dock_write_register(0x60, 0x16);
dock_write_register(0x61, 0x4c);
/* Activate DLPC */
dock_write_register(0x30, 0x01);
outb(0x07, 0x164c);
while(!(inb(0x164c) & 8))
udelay(100 * 100);
}
static void dock_gpio_set_mode(int port, int mode)
{
dock_write_register(0xf0, port);
dock_write_register(0xf1, mode);
}
static void dock_gpio_init(void)
{
/* Select GPIO module */
dock_write_register(0x07, 0x07);
/* GPIO Base Address 0x1680 */
dock_write_register(0x60, 0x16);
dock_write_register(0x61, 0x80);
/* Activate GPIO */
dock_write_register(0x30, 0x01);
dock_gpio_set_mode(0x00, 3);
dock_gpio_set_mode(0x01, 3);
dock_gpio_set_mode(0x02, 0);
dock_gpio_set_mode(0x03, 3);
dock_gpio_set_mode(0x04, 4);
dock_gpio_set_mode(0x20, 4);
dock_gpio_set_mode(0x21, 4);
dock_gpio_set_mode(0x23, 4);
}
static void connect_dock(void)
{
/* Enable 14.318MHz CLK on CLKIN */
dock_write_register(0x29, 0x00);
dock_write_register(0x29, 0xa0);
dock_gpio_init();
/* Assert D_PLTRST# */
outb(0xfe, 0x1680);
dock_dlpc_init();
/* Deassert D_PLTRST# */
outb(0xff, 0x1680);
}
static void early_superio_config(void)
{
device_t dev;
dev=PNP_DEV(0x2e, 0x00);
pnp_write_register(dev, 0x29, 0x06);
/* Enable COM1 */
pnp_write_register(dev, 0x07, 0x03);
pnp_write_register(dev, 0x60, 0x03);
pnp_write_register(dev, 0x61, 0xf8);
pnp_write_register(dev, 0x30, 0x01);
}
static void rcba_config(void)
{
/* Set up virtual channel 0 */
RCBA32(0x0014) = 0x80000001;
RCBA32(0x001c) = 0x03128010;
/* Device 1f interrupt pin register */
RCBA32(0x3100) = 0x00001230;
RCBA32(0x3108) = 0x40004321;
/* PCIe Interrupts */
RCBA32(0x310c) = 0x00004321;
/* HD Audio Interrupt */
RCBA32(0x3110) = 0x00000002;
/* dev irq route register */
RCBA16(0x3140) = 0x1007;
RCBA16(0x3142) = 0x0076;
RCBA16(0x3144) = 0x3210;
RCBA16(0x3146) = 0x7654;
RCBA16(0x3148) = 0x0010;
/* Enable IOAPIC */
RCBA8(0x31ff) = 0x03;
/* Enable upper 128bytes of CMOS */
RCBA32(0x3400) = (1 << 2);
/* Disable unused devices */
RCBA32(0x3418) = FD_PCIE6 | FD_PCIE5 | FD_INTLAN | FD_ACMOD | FD_ACAUD;
RCBA32(0x3418) |= (1 << 0); // Required.
}
static void early_ich7_init(void)
{
uint8_t reg8;
uint32_t reg32;
// program secondary mlt XXX byte?
pci_write_config8(PCI_DEV(0, 0x1e, 0), 0x1b, 0x20);
// reset rtc power status
reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4);
reg8 &= ~(1 << 2);
pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8);
// usb transient disconnect
reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xad);
reg8 |= (3 << 0);
pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xad, reg8);
reg32 = pci_read_config32(PCI_DEV(0, 0x1d, 7), 0xfc);
reg32 |= (1 << 29) | (1 << 17);
pci_write_config32(PCI_DEV(0, 0x1d, 7), 0xfc, reg32);
reg32 = pci_read_config32(PCI_DEV(0, 0x1d, 7), 0xdc);
reg32 |= (1 << 31) | (1 << 27);
pci_write_config32(PCI_DEV(0, 0x1d, 7), 0xdc, reg32);
RCBA32(0x0088) = 0x0011d000;
RCBA16(0x01fc) = 0x060f;
RCBA32(0x01f4) = 0x86000040;
RCBA32(0x0214) = 0x10030549;
RCBA32(0x0218) = 0x00020504;
RCBA8(0x0220) = 0xc5;
reg32 = RCBA32(0x3410);
reg32 |= (1 << 6);
RCBA32(0x3410) = reg32;
reg32 = RCBA32(0x3430);
reg32 &= ~(3 << 0);
reg32 |= (1 << 0);
RCBA32(0x3430) = reg32;
RCBA32(0x3418) |= (1 << 0);
RCBA16(0x0200) = 0x2008;
RCBA8(0x2027) = 0x0d;
RCBA16(0x3e08) |= (1 << 7);
RCBA16(0x3e48) |= (1 << 7);
RCBA32(0x3e0e) |= (1 << 7);
RCBA32(0x3e4e) |= (1 << 7);
// next step only on ich7m b0 and later:
reg32 = RCBA32(0x2034);
reg32 &= ~(0x0f << 16);
reg32 |= (5 << 16);
RCBA32(0x2034) = reg32;
}
#include <cbmem.h>
void main(unsigned long bist)
{
u32 reg32;
int boot_mode = 0;
if (bist == 0)
enable_lapic();
/* Force PCIRST# */
pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, SBR);
udelay(200 * 1000);
pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, 0);
ich7_enable_lpc();
connect_dock();
early_superio_config();
/* Set up the console */
uart_init();
#if CONFIG_USBDEBUG
i82801gx_enable_usbdebug(1);
early_usbdebug_init();
#endif
console_init();
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
if (MCHBAR16(SSKPD) == 0xCAFE) {
printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n");
outb(0x6, 0xcf9);
while (1) asm("hlt");
}
/* Perform some early chipset initialization required
* before RAM initialization can work
*/
i945_early_initialization();
/* Read PM1_CNT */
reg32 = inl(DEFAULT_PMBASE + 0x04);
printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
if (((reg32 >> 10) & 7) == 5) {
#if CONFIG_HAVE_ACPI_RESUME
printk(BIOS_DEBUG, "Resume from S3 detected.\n");
boot_mode = 2;
/* Clear SLP_TYPE. This will break stage2 but
* we care for that when we get there.
*/
outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
#else
printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
#endif
}
/* Enable SPD ROMs and DDR-II DRAM */
enable_smbus();
#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8
dump_spd_registers();
#endif
sdram_initialize(boot_mode);
/* Perform some initialization that must run before stage2 */
early_ich7_init();
/* This should probably go away. Until now it is required
* and mainboard specific
*/
rcba_config();
/* Chipset Errata! */
fixup_i945_errata();
/* Initialize the internal PCIe links before we go into stage2 */
i945_late_initialization();
#if !CONFIG_HAVE_ACPI_RESUME
#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8
#if CONFIG_DEBUG_RAM_SETUP
sdram_dump_mchbar_registers();
{
/* This will not work if TSEG is in place! */
u32 tom = pci_read_config32(PCI_DEV(0,2,0), 0x5c);
printk(BIOS_DEBUG, "TOM: 0x%08x\n", tom);
ram_check(0x00000000, 0x000a0000);
ram_check(0x00100000, tom);
}
#endif
#endif
#endif
MCHBAR16(SSKPD) = 0xCAFE;
#if CONFIG_HAVE_ACPI_RESUME
/* Start address of high memory tables */
unsigned long high_ram_base = get_top_of_ram() - HIGH_MEMORY_SIZE;
/* If there is no high memory area, we didn't boot before, so
* this is not a resume. In that case we just create the cbmem toc.
*/
if ((boot_mode == 2) && cbmem_reinit((u64)high_ram_base)) {
void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
/* copy 1MB - 64K to high tables ram_base to prevent memory corruption
* through stage 2. We could keep stuff like stack and heap in high tables
* memory completely, but that's a wonderful clean up task for another
* day.
*/
if (resume_backup_memory)
memcpy(resume_backup_memory, (void *)CONFIG_RAMBASE, HIGH_MEMORY_SAVE);
/* Magic for S3 resume */
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafed00d);
}
#endif
/* Set legacy Brightness control to full brightness */
pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, 0xff);
}

View File

@ -0,0 +1,49 @@
/*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* This code should work for all ICH* southbridges with a NIC. */
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
static void nic_init(struct device *dev)
{
printk(BIOS_DEBUG, "Initializing RTL8168 Gigabit Ethernet\n");
// Nothing to do yet, but this has to be here to keep
// coreboot from trying to execute an option ROM.
}
static struct device_operations nic_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = nic_init,
.scan_bus = 0,
};
static const struct pci_driver rtl8169_nic __pci_driver = {
.ops = &nic_ops,
.vendor = 0x10ec,
.device = 0x8168,
};