From 5cd81730ecef18690f92d193b0381c103a5b3d9b Mon Sep 17 00:00:00 2001 From: Eric Biederman Date: Thu, 11 Mar 2004 15:01:31 +0000 Subject: - Moved hlt() to it's own header. - Reworked pnp superio device support. Now complete superio support is less than 100 lines. - Added support for hard coding resource assignments in Config.lb - Minor bug fixes to romcc - Initial support for catching the x86 processor BIST error codes. I've only seen this trigger once in production during a very suspcious reset but... - added raminit_test to test the code paths in raminit.c for the Opteron - Removed the IORESOURCE_SET bit and added IORESOURCE_ASSIGNED and IORESOURCE_STORED so we can tell what we have really done. - Added generic AGP/IOMMU setting code to x86 - Added an implementation of memmove and removed reserved identifiers from memcpy - Added minimal support for booting on pre b3 stepping K8 cores - Moved the checksum on amd8111 boards because our default location was on top of extended RTC registers - On the Hdama added support for enabling i2c hub so we can get at the temperature sensors. Not that i2c bus was implemented well enough to make that useful. - Redid the Opteron port so we should only need one reset and most of memory initialization is done in cpu_fixup. This is much, much faster. - Attempted to make the VGA IO region assigment work. The code seems to work now... - Redid the error handling in amdk8/raminit.c to distinguish between a bad value and a smbus error, and moved memory clearing out to cpufixup. - Removed CONFIG_KEYBOARD as it was useless. See pc87360/superio.c for how to setup a legacy keyboard properly. - Reworked the register values for standard hardware, moving the defintions from chip.h into the headers of the initialization routines. This is much saner and is actually implemented. - Made the hdama port an under clockers BIOS. I debuged so many interesting problems. - On amd8111_lpc added setup of architectural/legacy hardware - Enabled PCI error reporting as much as possible. - Enhanded build_opt_tbl to generate a header of the cmos option locations so that romcc compiled code can query the cmos options. - In romcc gracefully handle function names that degenerate into function pointers - Bumped the version to 1.1.6 as we are getting closer to 2.0 TODO finish optimizing the HT links of non dual boards TODO make all Opteron board work again TODO convert all superio devices to use the new helpers TODO convert the via/epia to freebios2 conventions TODO cpu fixup/setup by cpu type git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1390 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/southbridge/amd/amd8111/Config.lb | 5 +- src/southbridge/amd/amd8111/amd8111.c | 21 ++++---- src/southbridge/amd/amd8111/amd8111_acpi.c | 41 ++++++++++++++- src/southbridge/amd/amd8111/amd8111_early_smbus.c | 3 +- src/southbridge/amd/amd8111/amd8111_ide.c | 3 -- src/southbridge/amd/amd8111/amd8111_lpc.c | 35 +++++++++++-- src/southbridge/amd/amd8111/amd8111_pci.c | 61 +++++++++++++++++++++++ src/southbridge/amd/amd8111/amd8111_usb.c | 2 + src/southbridge/amd/amd8111/amd8111_usb2.c | 3 +- src/southbridge/amd/amd8131/amd8131_bridge.c | 43 +++++++++++++--- 10 files changed, 184 insertions(+), 33 deletions(-) create mode 100644 src/southbridge/amd/amd8111/amd8111_pci.c (limited to 'src/southbridge') diff --git a/src/southbridge/amd/amd8111/Config.lb b/src/southbridge/amd/amd8111/Config.lb index 904b0995b5..5bbbaba65e 100644 --- a/src/southbridge/amd/amd8111/Config.lb +++ b/src/southbridge/amd/amd8111/Config.lb @@ -5,5 +5,6 @@ driver amd8111_lpc.o driver amd8111_ide.o driver amd8111_acpi.o driver amd8111_usb2.o -#driver amd8111_ac97.o -#driver amd8111_nic.o +driver amd8111_ac97.o +driver amd8111_nic.o +driver amd8111_pci.o diff --git a/src/southbridge/amd/amd8111/amd8111.c b/src/southbridge/amd/amd8111/amd8111.c index 8dde5f13c6..d3fdf3b7ba 100644 --- a/src/southbridge/amd/amd8111/amd8111.c +++ b/src/southbridge/amd/amd8111/amd8111.c @@ -26,27 +26,24 @@ void amd8111_enable(device_t dev) lpc_dev = dev_find_slot(dev->bus->secondary, devfn); index = dev->path.u.pci.devfn & 7; } - if ((!lpc_dev) || (index >= 16) || - (lpc_dev->vendor != PCI_VENDOR_ID_AMD) || - (lpc_dev->device != PCI_DEVICE_ID_AMD_8111_ISA)) { + if ((!lpc_dev) || (index >= 16)) { return; } - + if ((lpc_dev->vendor != PCI_VENDOR_ID_AMD) || + (lpc_dev->device != PCI_DEVICE_ID_AMD_8111_ISA)) { + uint32_t id; + id = pci_read_config32(lpc_dev, PCI_VENDOR_ID); + if (id != (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8111_ISA << 16))) { + return; + } + } reg = reg_old = pci_read_config16(lpc_dev, 0x48); reg &= ~(1 << index); if (dev->enable) { reg |= (1 << index); } if (reg != reg_old) { -#if 1 - printk_warning("amd8111_enable dev: %s", dev_path(dev)); - printk_warning(" lpc_dev: %s index: %d reg: %04x -> %04x ", - dev_path(lpc_dev), index, reg_old, reg); -#endif pci_write_config16(lpc_dev, 0x48, reg); -#if 1 - printk_warning("done\n"); -#endif } } diff --git a/src/southbridge/amd/amd8111/amd8111_acpi.c b/src/southbridge/amd/amd8111/amd8111_acpi.c index 3a5a594f57..e3b7038e46 100644 --- a/src/southbridge/amd/amd8111/amd8111_acpi.c +++ b/src/southbridge/amd/amd8111/amd8111_acpi.c @@ -4,11 +4,15 @@ #include #include #include +#include +#include #include "amd8111.h" #define PREVIOUS_POWER_STATE 0x43 #define MAINBOARD_POWER_OFF 0 #define MAINBOARD_POWER_ON 1 +#define SLOW_CPU_OFF 0 +#define SLOW_CPU__ON 1 #ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL #define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON @@ -19,6 +23,8 @@ static void acpi_init(struct device *dev) { uint8_t byte; uint16_t word; + uint16_t pm10_bar; + uint32_t dword; int on; #if 0 @@ -57,10 +63,43 @@ static void acpi_init(struct device *dev) pci_write_config8(dev, PREVIOUS_POWER_STATE, byte); printk_info("set power %s after power fail\n", on?"on":"off"); + /* Throttle the CPU speed down for testing */ + on = SLOW_CPU_OFF; + get_option(&on, "slow_cpu"); + if(on) { + pm10_bar = (pci_read_config16(dev, 0x58)&0xff00); + outl(((on<<1)+0x10) ,(pm10_bar + 0x10)); + dword = inl(pm10_bar + 0x10); + on = 8-on; + printk_debug("Throttling CPU %2d.%1.1d percent.\n", + (on*12)+(on>>1),(on&1)*5); + } +} + +static void acpi_read_resources(device_t dev) +{ + /* Handle the generic bars */ + pci_dev_read_resources(dev); + + if ((dev->resources + 1) < MAX_RESOURCES) { + struct resource *resource = &dev->resource[dev->resources]; + dev->resources++; + resource->base = 0; + resource->size = 256; + resource->align = log2(256); + resource->gran = log2(256); + resource->limit = 65536; + resource->flags = IORESOURCE_IO; + resource->index = 0x58; + } + else { + printk_err("%s Unexpected resource shortage\n", + dev_path(dev)); + } } static struct device_operations acpi_ops = { - .read_resources = pci_dev_read_resources, + .read_resources = acpi_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .init = acpi_init, diff --git a/src/southbridge/amd/amd8111/amd8111_early_smbus.c b/src/southbridge/amd/amd8111/amd8111_early_smbus.c index 4bc515c75d..5157609639 100644 --- a/src/southbridge/amd/amd8111/amd8111_early_smbus.c +++ b/src/southbridge/amd/amd8111/amd8111_early_smbus.c @@ -17,7 +17,7 @@ static void enable_smbus(void) die("SMBUS controller not found\r\n"); } uint8_t enable; - print_debug("SMBus controller enabled\r\n"); + print_spew("SMBus controller enabled\r\n"); pci_write_config32(dev, 0x58, SMBUS_IO_BASE | 1); enable = pci_read_config8(dev, 0x41); pci_write_config8(dev, 0x41, enable | (1 << 7)); @@ -134,6 +134,5 @@ static void smbus_write_byte(unsigned device, unsigned address, unsigned char va /* poll for transaction completion */ smbus_wait_until_done(); - return; } diff --git a/src/southbridge/amd/amd8111/amd8111_ide.c b/src/southbridge/amd/amd8111/amd8111_ide.c index 4502bb3c45..6f8e018fe6 100644 --- a/src/southbridge/amd/amd8111/amd8111_ide.c +++ b/src/southbridge/amd/amd8111/amd8111_ide.c @@ -12,9 +12,6 @@ static void ide_init(struct device *dev) uint16_t word; int enable_a=1, enable_b=1; - - printk_debug("ide_init\n"); - word = pci_read_config16(dev, 0x40); /* Ensure prefetch is disabled */ word &= ~((1 << 15) | (1 << 13)); diff --git a/src/southbridge/amd/amd8111/amd8111_lpc.c b/src/southbridge/amd/amd8111/amd8111_lpc.c index 535cbece66..b6e25d2c5e 100644 --- a/src/southbridge/amd/amd8111/amd8111_lpc.c +++ b/src/southbridge/amd/amd8111/amd8111_lpc.c @@ -7,8 +7,10 @@ #include #include #include +#include #include "amd8111.h" +#define NMI_OFF 0 struct ioapicreg { unsigned int reg; @@ -100,8 +102,7 @@ static void lpc_init(struct device *dev) { uint8_t byte; int pwr_on=-1; - - printk_debug("lpc_init\n"); + int nmi_option; /* IO APIC initialization */ byte = pci_read_config8(dev, 0x4B); @@ -127,6 +128,31 @@ static void lpc_init(struct device *dev) byte |= (1 << 5); pci_write_config8(dev, 0x41, byte); + /* Enable Error reporting */ + /* Set up sync flood detected */ + byte = pci_read_config8(dev, 0x47); + byte |= (1 << 1); + pci_write_config8(dev, 0x47, byte); + + /* Set up NMI on errors */ + byte = pci_read_config8(dev, 0x40); + byte |= (1 << 1); /* clear PW2LPC error */ + byte |= (1 << 6); /* clear LPCERR */ + pci_write_config8(dev, 0x40, byte); + nmi_option = NMI_OFF; + get_option(&nmi_option, "nmi"); + if(nmi_option) { + byte |= (1 << 7); /* set NMI */ + pci_write_config8(dev, 0x40, byte); + } + + /* Initialize the real time clock */ + rtc_init(0); + + /* Initialize isa dma */ + isa_dma_init(); + + /* Initialize the High Precision Event Timers */ enable_hpet(dev); } @@ -146,7 +172,7 @@ static void amd8111_lpc_read_resources(device_t dev) dev->resource[reg].align = 0; dev->resource[reg].gran = 0; dev->resource[reg].limit = 0; - dev->resource[reg].flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_SET; + dev->resource[reg].flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; dev->resource[reg].index = 0; reg++; @@ -155,7 +181,7 @@ static void amd8111_lpc_read_resources(device_t dev) dev->resource[reg].align = 0; dev->resource[reg].gran = 0; dev->resource[reg].limit = 0; - dev->resource[reg].flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_SET; + dev->resource[reg].flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; dev->resource[reg].index = 0; reg++; @@ -176,4 +202,3 @@ static struct pci_driver lpc_driver __pci_driver = { .vendor = PCI_VENDOR_ID_AMD, .device = PCI_DEVICE_ID_AMD_8111_ISA, }; - diff --git a/src/southbridge/amd/amd8111/amd8111_pci.c b/src/southbridge/amd/amd8111/amd8111_pci.c new file mode 100644 index 0000000000..29d3fb88d8 --- /dev/null +++ b/src/southbridge/amd/amd8111/amd8111_pci.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include "amd8111.h" + +static void pci_init(struct device *dev) +{ + + /* Enable pci error detecting */ + uint32_t dword; + + /* System error enable */ + dword = pci_read_config32(dev, 0x04); + dword |= (1<<8); /* System error enable */ + dword |= (7<<28); /* Clear possible errors */ + pci_write_config32(dev, 0x04, dword); + + /* System,Parity,timer,and abort error enable */ + dword = pci_read_config32(dev, 0x3c); + dword |= (1<<16); /* Parity */ + dword |= (1<<17); /* System */ + dword |= (1<<21); /* Master abort */ +// dword &= ~(1<<21); /* Master abort */ + dword |= (1<<27); /* Discard timer */ + dword |= (1<<26); /* DTSTAT error clear */ + pci_write_config32(dev, 0x3c, dword); + + /* CRC flood enable */ + dword = pci_read_config32(dev, 0xc4); + dword |= (1<<1); /* CRC Flood enable */ + dword |= (1<<8); /* Clear any CRC errors */ + dword |= (1<<4); /* Clear any LKFAIL errors */ + pci_write_config32(dev, 0xc4, dword); + + /* Clear possible errors */ + dword = pci_read_config32(dev, 0x1c); + dword |= (1<<27); /* STA */ + dword |= (1<<28); /* RTA */ + dword |= (1<<29); /* RMA */ + dword |= (1<<30); /* RSE */ + dword |= (1<<31); /* DPE */ + dword |= (1<<24); /* MDPE */ + pci_write_config32(dev, 0x1c, dword); +} + +static struct device_operations pci_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pci_init, + .scan_bus = pci_scan_bridge, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_8111_PCI, +}; + diff --git a/src/southbridge/amd/amd8111/amd8111_usb.c b/src/southbridge/amd/amd8111/amd8111_usb.c index 46cfabbcda..407729a381 100644 --- a/src/southbridge/amd/amd8111/amd8111_usb.c +++ b/src/southbridge/amd/amd8111/amd8111_usb.c @@ -9,6 +9,7 @@ static void usb_init(struct device *dev) { uint32_t cmd; +#if 0 printk_debug("USB: Setting up controller.. "); cmd = pci_read_config32(dev, PCI_COMMAND); pci_write_config32(dev, PCI_COMMAND, @@ -17,6 +18,7 @@ static void usb_init(struct device *dev) printk_debug("done.\n"); +#endif } diff --git a/src/southbridge/amd/amd8111/amd8111_usb2.c b/src/southbridge/amd/amd8111/amd8111_usb2.c index 15ed69b0f1..e6dd1e9da2 100644 --- a/src/southbridge/amd/amd8111/amd8111_usb2.c +++ b/src/southbridge/amd/amd8111/amd8111_usb2.c @@ -13,6 +13,7 @@ static void usb2_init(struct device *dev) { uint32_t cmd; +#if 0 printk_debug("USB: Setting up controller.. "); cmd = pci_read_config32(dev, PCI_COMMAND); pci_write_config32(dev, PCI_COMMAND, @@ -21,7 +22,7 @@ static void usb2_init(struct device *dev) printk_debug("done.\n"); - +#endif } static struct device_operations usb2_ops = { diff --git a/src/southbridge/amd/amd8131/amd8131_bridge.c b/src/southbridge/amd/amd8131/amd8131_bridge.c index e730997bbc..b96f46db45 100644 --- a/src/southbridge/amd/amd8131/amd8131_bridge.c +++ b/src/southbridge/amd/amd8131/amd8131_bridge.c @@ -6,11 +6,16 @@ #include #include #include +#include + +#define NMI_OFF 0 static void pcix_init(device_t dev) { + uint32_t dword; uint16_t word; uint8_t byte; + int nmi_option; /* Enable memory write and invalidate ??? */ byte = pci_read_config8(dev, 0x04); @@ -40,6 +45,37 @@ static void pcix_init(device_t dev) pci_write_config16(dev, 0xaa, word); word = pci_read_config16(dev, 0xac); pci_write_config16(dev, 0xae, word); + + /* Set up error reporting, enable all */ + /* system error enable */ + dword = pci_read_config32(dev, 0x04); + dword |= (1<<8); + pci_write_config32(dev, 0x04, dword); + + /* system and error parity enable */ + dword = pci_read_config32(dev, 0x3c); + dword |= (3<<16); + pci_write_config32(dev, 0x3c, dword); + + /* NMI enable */ + nmi_option = NMI_OFF; + get_option(&nmi_option, "nmi"); + if(nmi_option) { + dword = pci_read_config32(dev, 0x44); + dword |= (1<<0); + pci_write_config32(dev, 0x44, dword); + } + + /* Set up CRC flood enable */ + dword = pci_read_config32(dev, 0xc0); + if(dword) { /* do device A only */ + dword = pci_read_config32(dev, 0xc4); + dword |= (1<<1); + pci_write_config32(dev, 0xc4, dword); + dword = pci_read_config32(dev, 0xc8); + dword |= (1<<1); + pci_write_config32(dev, 0xc8, dword); + } return; } @@ -69,13 +105,6 @@ static void ioapic_enable(device_t dev) value &= ~((1 << 1) | (1 << 0)); } pci_write_config32(dev, 0x44, value); - -//BY LYH - value = pci_read_config32(dev, 0x4); - value |= 6; - pci_write_config32(dev, 0x4, value); -//BY LYH END - } static struct device_operations ioapic_ops = { -- cgit v1.2.3