diff options
author | Ronald G. Minnich <rminnich@gmail.com> | 2009-10-01 00:02:28 +0000 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2009-10-01 00:02:28 +0000 |
commit | 61d66db14d9f8790982a299314101e8c5125c36d (patch) | |
tree | cb0171e5a5384544e29cc2b96918869bc5a2c1e1 /src/mainboard | |
parent | 26dd71c2d766f0630216aa5b8055b1f3b1e339ed (diff) |
This is now set up more like the real hardware likes it.
Some of this trickery was determined with serialice.
There are several lovely undocumented features to the chipset.
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4698 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/mainboard')
-rw-r--r-- | src/mainboard/dell/s1850/auto.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/mainboard/dell/s1850/auto.c b/src/mainboard/dell/s1850/auto.c index ad3619e76d..51bd74bb12 100644 --- a/src/mainboard/dell/s1850/auto.c +++ b/src/mainboard/dell/s1850/auto.c @@ -173,8 +173,13 @@ static inline void bmc_foad(void) } /* end IPMI garbage */ + static void main(unsigned long bist) { + u8 b; + u16 w; + u32 l; + int do_reset; /* * * @@ -191,6 +196,80 @@ static void main(unsigned long bist) } }; + /* using SerialICE, we've seen this basic reset sequence on the dell. + * we don't understand it as it uses undocumented registers, but + * we're going to clone it. + */ + /* enable a hidden device. */ + b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4); + b |= 0x8; + pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b); + + /* read-write lock in CMOS on LPC bridge on ICH5 */ + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd8, 4); + + /* operate on undocumented device */ + l = pci_read_config32(PCI_DEV(0, 0, 2), 0xa4); + l |= 0x1000; + pci_write_config32(PCI_DEV(0, 0, 2), 0xa4, l); + + l = pci_read_config32(PCI_DEV(0, 0, 2), 0x9c); + l |= 0x8000; + pci_write_config32(PCI_DEV(0, 0, 2), 0x9c, l); + + /* disable undocumented device */ + b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4); + b &= ~0x8; + pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b); + + /* set up LPC bridge bits, some of which reply on undocumented + * registers + */ + + b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xd8); + b |= 4; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd8, b); + + b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xd4); + b |= 2; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd4, b); + + /* ACPI base address */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x40, 0x800); + + /* Enable specific ACPI features */ + b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0x44); + b |= 0x10; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x44, b); + + /* ACPI control */ + w = inw(0x868); + outw(w|0x800, 0x868); + w = inw(0x866); + outw(w|2, 0x866); + + /* SMBUS */ + pci_write_config16(PCI_DEV(0, 0x1f, 3), 0x20, 0x08c0); + + /* unknown */ + b = inb(0x8c2); + outb(0xdf, 0x8c2); + + /* another device enable? */ + b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4); + b |= 2; + pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b); + + /* ?? */ + l = pci_read_config32(PCI_DEV(0, 0, 8), 0xc0); + do_reset = l & 0x8000000; + l |= 0x8000000; + pci_write_config32(PCI_DEV(0, 0, 2), 0xc0, l); + + if (! do_reset) { + outb(2, 0xcf9); + outb(6, 0xcf9); + } if (bist == 0) { /* Skip this if there was a built in self test failure */ early_mtrr_init(); |