summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Biederman <ebiederm@xmission.com>2003-10-11 06:20:25 +0000
committerEric Biederman <ebiederm@xmission.com>2003-10-11 06:20:25 +0000
commit83b991afff40e12a8b6756af06a472842edb1a66 (patch)
treea441ff0d88afcb0a07cf22dc3653db3e07a05c98 /src
parent080038bfbd8fdf08bac12476a3789495e6f705ca (diff)
downloadcoreboot-83b991afff40e12a8b6756af06a472842edb1a66.tar.xz
- O2, enums, and switch statements work in romcc
- Support for compiling romcc on non x86 platforms - new romc options -msse and -mmmx for specifying extra registers to use - Bug fixes to device the device disable/enable framework and an amd8111 implementation - Move the link specification to the chip specification instead of the path - Allow specifying devices with internal bridges. - Initial via epia support - Opteron errata fixes git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1200 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/lib/console.inc2
-rw-r--r--src/arch/i386/lib/cpu.c2
-rw-r--r--src/boot/hardwaremain.c1
-rw-r--r--src/config/Config.lb4
-rw-r--r--src/config/Options.lb2
-rw-r--r--src/cpu/k8/cpufixup.c149
-rw-r--r--src/cpu/p6/mtrr.c2
-rw-r--r--src/devices/chip.c30
-rw-r--r--src/devices/device.c32
-rw-r--r--src/devices/device_util.c15
-rw-r--r--src/devices/hypertransport.c16
-rw-r--r--src/devices/pci_device.c51
-rw-r--r--src/devices/root_device.c2
-rw-r--r--src/include/cpu/k8/mtrr.h4
-rw-r--r--src/include/device/chip.h3
-rw-r--r--src/include/device/device.h4
-rw-r--r--src/include/device/path.h2
-rw-r--r--src/mainboard/amd/quartet/mptable.c4
-rw-r--r--src/mainboard/arima/hdama/Config.lb46
-rw-r--r--src/mainboard/arima/hdama/auto.c37
-rw-r--r--src/mainboard/arima/hdama/failover.c4
-rw-r--r--src/mainboard/arima/hdama/irq_tables.c57
-rw-r--r--src/mainboard/arima/hdama/mainboard.c1
-rw-r--r--src/mainboard/arima/hdama/mptable.c12
-rw-r--r--src/northbridge/amd/amdk8/Config.lb1
-rw-r--r--src/northbridge/amd/amdk8/coherent_ht.c124
-rw-r--r--src/northbridge/amd/amdk8/cpu_rev.c25
-rw-r--r--src/northbridge/amd/amdk8/misc_control.c42
-rw-r--r--src/northbridge/amd/amdk8/northbridge.c2
-rw-r--r--src/northbridge/amd/amdk8/raminit.c320
-rw-r--r--src/northbridge/via/vt8601/northbridge.c94
-rw-r--r--src/pc80/vgabios.c851
-rw-r--r--src/pc80/vgachip.h2
-rw-r--r--src/southbridge/amd/amd8111/Config.lb4
-rw-r--r--src/southbridge/amd/amd8111/amd8111.c56
-rw-r--r--src/southbridge/amd/amd8111/amd8111.h12
-rw-r--r--src/southbridge/amd/amd8111/amd8111_ac97.c41
-rw-r--r--src/southbridge/amd/amd8111/amd8111_acpi.c26
-rw-r--r--src/southbridge/amd/amd8111/amd8111_early_smbus.c14
-rw-r--r--src/southbridge/amd/amd8111/amd8111_ide.c1
-rw-r--r--src/southbridge/amd/amd8111/amd8111_lpc.c18
-rw-r--r--src/southbridge/amd/amd8111/amd8111_nic.c25
-rw-r--r--src/southbridge/amd/amd8111/amd8111_usb.c2
-rw-r--r--src/southbridge/amd/amd8111/amd8111_usb2.c7
-rw-r--r--src/southbridge/amd/amd8131/amd8131_bridge.c19
-rw-r--r--src/southbridge/via/vt8231/chip.h14
-rw-r--r--src/southbridge/via/vt8231/vt8231.c708
-rw-r--r--src/southbridge/via/vt8231/vt8231_early_serial.c107
-rw-r--r--src/southbridge/via/vt8231/vt8231_early_smbus.c316
-rw-r--r--src/superio/NSC/pc87360/chip.h6
-rw-r--r--src/superio/NSC/pc87360/superio.c11
51 files changed, 1963 insertions, 1367 deletions
diff --git a/src/arch/i386/lib/console.inc b/src/arch/i386/lib/console.inc
index 2f031e5d10..b617b8c1d0 100644
--- a/src/arch/i386/lib/console.inc
+++ b/src/arch/i386/lib/console.inc
@@ -526,5 +526,7 @@ console_tx_string:
jmp console_tx_string
console0:
+#if 0
CONSOLE_INFO_TX_STRING($console_test)
+#endif
diff --git a/src/arch/i386/lib/cpu.c b/src/arch/i386/lib/cpu.c
index baa029c02c..ad982dbc6c 100644
--- a/src/arch/i386/lib/cpu.c
+++ b/src/arch/i386/lib/cpu.c
@@ -125,7 +125,7 @@ unsigned long cpu_initialize(struct mem_range *mem)
*/
unsigned long processor_id = this_processors_id();
printk_notice("Initializing CPU #%d\n", processor_id);
-
+
/* some cpus need a fixup done. This is the hook for doing that. */
cpufixup(mem);
diff --git a/src/boot/hardwaremain.c b/src/boot/hardwaremain.c
index 687b102bbe..6231d1167e 100644
--- a/src/boot/hardwaremain.c
+++ b/src/boot/hardwaremain.c
@@ -160,7 +160,6 @@ void hardwaremain(int boot_complete)
/* If we have already booted attempt a hard reboot */
if (boot_complete) {
- printk_spew("calling hard_reset\n");
hard_reset();
}
CONFIGURE(CONF_PASS_PRE_PCI);
diff --git a/src/config/Config.lb b/src/config/Config.lb
index ee617c9a60..822f76906c 100644
--- a/src/config/Config.lb
+++ b/src/config/Config.lb
@@ -7,7 +7,7 @@ makedefine LIBGCC_FILE_NAME := $(shell $(CC) -print-libgcc-file-name)
makedefine GCC_INC_DIR := $(shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp")
makedefine CPPFLAGS := -I$(TOP)/src/include -I$(TOP)/src/arch/$(ARCH)/include -I$(GCC_INC_DIR) $(CPUFLAGS)
-makedefine ROMCCPPFLAGS := -D__ROMCC__=0 -D__ROMCC_MINOR__=34
+makedefine ROMCCPPFLAGS := -D__ROMCC__=0 -D__ROMCC_MINOR__=36
makedefine CFLAGS := $(CPU_OPT) $(CPPFLAGS) -Os -nostdinc -nostdlib -fno-builtin -Wall
makedefine HOSTCFLAGS:= -Os -Wall
@@ -116,7 +116,7 @@ end
makerule ./romcc
depends "$(TOP)/util/romcc/romcc.c"
- action "$(HOSTCC) -g $(HOSTCFLAGS) -DVERSION='\"0.34\"' -DRELEASE_DATE='\"4 July 2003\"' $< -o $@"
+ action "$(HOSTCC) -g $(HOSTCFLAGS) -DVERSION='\"0.36\"' -DRELEASE_DATE='\"10 October 2003\"' $< -o $@"
end
makerule build_opt_tbl
diff --git a/src/config/Options.lb b/src/config/Options.lb
index 98d9e8a3bd..1a12e76dbe 100644
--- a/src/config/Options.lb
+++ b/src/config/Options.lb
@@ -117,7 +117,7 @@ define OBJCOPY
comment "Objcopy command"
end
define LINUXBIOS_VERSION
- default "1.1.4"
+ default "1.1.5"
export always
comment "LinuxBIOS version"
end
diff --git a/src/cpu/k8/cpufixup.c b/src/cpu/k8/cpufixup.c
index d5ccfc299d..6aa6722579 100644
--- a/src/cpu/k8/cpufixup.c
+++ b/src/cpu/k8/cpufixup.c
@@ -4,15 +4,67 @@
#include <cpu/p6/msr.h>
#include <cpu/k8/mtrr.h>
#include <device/device.h>
+#include "../../northbridge/amd/amdk8/cpu_rev.c"
#include <device/chip.h>
-
#include "chip.h"
+#define MCI_STATUS 0x401
+
+static inline void disable_cache(void)
+{
+ unsigned int tmp;
+ /* Disable cache */
+ /* Write back the cache and flush TLB */
+ asm volatile (
+ "movl %%cr0, %0\n\t"
+ "orl $0x40000000, %0\n\t"
+ "wbinvd\n\t"
+ "movl %0, %%cr0\n\t"
+ "wbinvd\n\t"
+ :"=r" (tmp)
+ ::"memory");
+}
+
+static inline void enable_cache(void)
+{
+ unsigned int tmp;
+ // turn cache back on.
+ asm volatile (
+ "movl %%cr0, %0\n\t"
+ "andl $0x9fffffff, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (tmp)
+ ::"memory");
+}
+
+static inline msr_t rdmsr_amd(unsigned index)
+{
+ msr_t result;
+ __asm__ __volatile__ (
+ "rdmsr"
+ : "=a" (result.lo), "=d" (result.hi)
+ : "c" (index), "D" (0x9c5a203a)
+ );
+ return result;
+}
+
+static inline void wrmsr_amd(unsigned index, msr_t msr)
+{
+ __asm__ __volatile__ (
+ "wrmsr"
+ : /* No outputs */
+ : "c" (index), "a" (msr.lo), "d" (msr.hi), "D" (0x9c5a203a)
+ );
+}
+
void k8_cpufixup(struct mem_range *mem)
{
unsigned long mmio_basek, tomk;
unsigned long i;
msr_t msr;
+
+ disable_cache();
+
/* Except for the PCI MMIO hold just before 4GB there are no
* significant holes in the address space, so just account
* for those two and move on.
@@ -32,28 +84,15 @@ void k8_cpufixup(struct mem_range *mem)
mmio_basek = tomk;
}
-#if 1
- /* Report the amount of memory. */
- print_debug("cpufixup RAM: 0x");
- print_debug_hex32(tomk);
- print_debug(" KB\r\n");
-#endif
-
- /* Now set top of memory */
- msr.lo = (tomk & 0x003fffff) << 10;
- msr.hi = (tomk & 0xffc00000) >> 22;
- wrmsr(TOP_MEM2, msr);
-
- /* Leave a 64M hole between TOP_MEM and TOP_MEM2
- * so I can see my rom chip and other I/O devices.
- */
- if (tomk >= 0x003f0000) {
- tomk = 0x3f0000;
- } // tom_k = 0x3c0000;
- msr.lo = (tomk & 0x003fffff) << 10;
- msr.hi = (tomk & 0xffc00000) >> 22;
- wrmsr(TOP_MEM, msr);
+ /* Setup TOP_MEM */
+ msr.hi = mmio_basek >> 22;
+ msr.lo = mmio_basek << 10;
+ wrmsr(TOP_MEM, msr);
+ /* Setup TOP_MEM2 */
+ msr.hi = tomk >> 22;
+ msr.lo = tomk << 10;
+ wrmsr(TOP_MEM2, msr);
/* zero the IORR's before we enable to prevent
* undefined side effects.
@@ -66,6 +105,64 @@ void k8_cpufixup(struct mem_range *mem)
msr = rdmsr(SYSCFG_MSR);
msr.lo |= SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_TOM2En;
wrmsr(SYSCFG_MSR, msr);
+
+ /* zero the machine check error status registers */
+ msr.lo = 0;
+ msr.hi = 0;
+ for(i=0; i<5; i++) {
+ wrmsr(MCI_STATUS + (i*4),msr);
+ }
+
+ if (is_cpu_pre_c0()) {
+ /* Erratum 63... */
+ msr = rdmsr(HWCR_MSR);
+ msr.lo |= (1 << 6);
+ wrmsr(HWCR_MSR, msr);
+ /* Erratum 69... */
+#if 1
+ msr = rdmsr_amd(BU_CFG_MSR);
+ msr.hi |= (1 << (45 - 32));
+ wrmsr_amd(BU_CFG_MSR, msr);
+#endif
+ /* Erratum 81... */
+#if 1
+ msr = rdmsr_amd(DC_CFG_MSR);
+ msr.lo |= (1 << 10);
+ wrmsr_amd(DC_CFG_MSR, msr);
+#endif
+
+ }
+ /* Erratum 89 ... */
+ msr = rdmsr(NB_CFG_MSR);
+ msr.lo |= 1 << 3;
+
+ if (!is_cpu_pre_c0()) {
+ /* Erratum 86 Disable data masking on C0 and
+ * later processor revs.
+ * FIXME this is only needed if ECC is enabled.
+ */
+ msr.hi |= 1 << (36 - 32);
+ }
+ wrmsr(NB_CFG_MSR, msr);
+#if 1 /* The following erratum fixes reset the cpu ???? */
+
+ /* Erratum 97 ... */
+ if (!is_cpu_pre_c0()) {
+ msr = rdmsr_amd(DC_CFG_MSR);
+ msr.lo |= 1 << 3;
+ wrmsr_amd(DC_CFG_MSR, msr);
+ }
+
+ /* Erratum 94 ... */
+ msr = rdmsr_amd(IC_CFG_MSR);
+ msr.lo |= 1 << 11;
+ wrmsr_amd(IC_CFG_MSR, msr);
+
+#endif
+
+ /* Erratum 91 prefetch miss is handled in the kernel */
+
+ enable_cache();
}
static
@@ -87,10 +184,6 @@ void k8_enable(struct chip *chip, enum chip_pass pass)
}
struct chip_control cpu_k8_control = {
- enable: k8_enable,
- name: "AMD K8"
+ .enable = k8_enable,
+ .name = "AMD K8",
};
-
-
-
-
diff --git a/src/cpu/p6/mtrr.c b/src/cpu/p6/mtrr.c
index b067883316..1225fafe08 100644
--- a/src/cpu/p6/mtrr.c
+++ b/src/cpu/p6/mtrr.c
@@ -92,7 +92,7 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
base.lo = basek << 10;
if (sizek < 4*1024*1024) {
- mask.hi = 0x0F;
+ mask.hi = 0x0FF;
mask.lo = ~((sizek << 10) -1);
}
else {
diff --git a/src/devices/chip.c b/src/devices/chip.c
index b7eace38f0..c9e1ac5643 100644
--- a/src/devices/chip.c
+++ b/src/devices/chip.c
@@ -46,16 +46,33 @@ void chip_enumerate(struct chip *chip)
int identical_paths;
identical_paths =
(i > 0) &&
- (path_eq(&chip->path[i - 1].path, &chip->path[i].path)) &&
- (chip->path[i - 1].channel == chip->path[i].channel);
+ (path_eq(&chip->path[i - 1].path, &chip->path[i].path));
if (!identical_paths) {
+ struct bus *parent;
+ int bus;
link = 0;
dev = 0;
+ parent = chip->bus;
switch(chip->path[i].path.type) {
case DEVICE_PATH_NONE:
break;
+ case DEVICE_PATH_PCI:
+ bus = chip->path[i].path.u.pci.bus;
+ if (bus != 0) {
+ device_t dev;
+ int i = 1;
+ dev = chip->dev;
+ while(dev && (i != bus)) {
+ dev = dev->next;
+ i++;
+ }
+ if ((i == bus) && dev) {
+ parent = &dev->link[0];
+ }
+ }
+ /* Fall through */
default:
- dev = alloc_dev(chip->bus, &chip->path[i].path);
+ dev = alloc_dev(parent, &chip->path[i].path);
break;
}
}
@@ -63,12 +80,13 @@ void chip_enumerate(struct chip *chip)
link += 1;
}
if (dev) {
- printk_spew("path %s %s\n", dev_path(dev), identical_paths?"identical":"");
+ printk_spew("path (%p) %s %s", dev, dev_path(dev), identical_paths?"identical":"");
+ printk_spew(" parent: (%p) %s\n",dev->bus->dev, dev_path(dev->bus->dev));
+ dev->chip = chip;
dev->enable = chip->path[i].enable;
dev->links = link + 1;
for(child = chip->children; child; child = child->next) {
- if (!child->bus &&
- child->path[0].channel == i) {
+ if (!child->bus && child->link == i) {
child->bus = &dev->link[link];
}
}
diff --git a/src/devices/device.c b/src/devices/device.c
index 289c0766ea..c6dd5fc4ad 100644
--- a/src/devices/device.c
+++ b/src/devices/device.c
@@ -115,6 +115,9 @@ static void read_resources(struct bus *bus)
dev_path(curdev));
continue;
}
+ if (!curdev->enable) {
+ continue;
+ }
curdev->ops->read_resources(curdev);
/* Read in subtractive resources behind the current device */
links = 0;
@@ -251,16 +254,12 @@ void compute_allocate_resource(
min_align = 0;
base = bridge->base;
- printk_spew("%s: bus %p, bridge %p, type_mask 0x%x, type 0x%x\n",
- __FUNCTION__,
- bus, bridge, type_mask, type);
- printk_spew("vendor 0x%x device 0x%x class 0x%x \n",
- bus->dev->vendor, bus->dev->device, bus->dev->class);
- printk_spew("%s compute_allocate_%s: base: %08lx size: %08lx align: %d gran: %d\n",
- dev_path(bus->dev),
- (bridge->flags & IORESOURCE_IO)? "io":
- (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
- base, bridge->size, bridge->align, bridge->gran);
+ printk_spew("%s compute_allocate_%s: base: %08lx size: %08lx align: %d gran: %d\n",
+ dev_path(bus->dev),
+ (bridge->flags & IORESOURCE_IO)? "io":
+ (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
+ base, bridge->size, bridge->align, bridge->gran);
+
/* We want different minimum alignments for different kinds of
* resources. These minimums are not device type specific
@@ -406,6 +405,9 @@ void assign_resources(struct bus *bus)
dev_path(curdev));
continue;
}
+ if (!curdev->enable) {
+ continue;
+ }
curdev->ops->set_resources(curdev);
}
printk_debug("ASSIGNED RESOURCES, bus %d\n", bus->secondary);
@@ -422,6 +424,9 @@ void enable_resources(struct device *dev)
dev_path(dev));
return;
}
+ if (!dev->enable) {
+ return;
+ }
dev->ops->enable_resources(dev);
}
@@ -444,13 +449,12 @@ void dev_enumerate(void)
void dev_configure(void)
{
struct device *root = &dev_root;
- printk_info("%s: Allocating resources...", __FUNCTION__);
+ printk_info("Allocating resources...");
printk_debug("\n");
root->ops->read_resources(root);
- printk_spew("%s: done reading resources...\n", __FUNCTION__);
/* Make certain the io devices are allocated somewhere
* safe.
*/
@@ -465,10 +469,8 @@ void dev_configure(void)
root->resource[1].flags |= IORESOURCE_SET;
// now just set things into registers ... we hope ...
root->ops->set_resources(root);
- printk_spew("%s: done setting resources...\n", __FUNCTION__);
allocate_vga_resource();
- printk_spew("%s: done vga resources...\n", __FUNCTION__);
printk_info("done.\n");
}
@@ -494,7 +496,7 @@ void dev_initialize(void)
printk_info("Initializing devices...\n");
for (dev = all_devices; dev; dev = dev->next) {
- if (dev->ops && dev->ops->init) {
+ if (dev->enable && dev->ops && dev->ops->init) {
printk_debug("%s init\n", dev_path(dev));
dev->ops->init(dev);
}
diff --git a/src/devices/device_util.c b/src/devices/device_util.c
index 384a3be8e0..6652c86ea0 100644
--- a/src/devices/device_util.c
+++ b/src/devices/device_util.c
@@ -30,15 +30,17 @@ device_t alloc_find_dev(struct bus *parent, struct device_path *path)
*/
struct device *dev_find_slot(unsigned int bus, unsigned int devfn)
{
- struct device *dev;
+ struct device *dev, *result;
+ result = 0;
for (dev = all_devices; dev; dev = dev->next) {
if ((dev->bus->secondary == bus) &&
(dev->path.u.pci.devfn == devfn)) {
+ result = dev;
break;
}
}
- return dev;
+ return result;
}
/** Find a device of a given vendor and type
@@ -88,6 +90,9 @@ const char *dev_path(device_t dev)
}
else {
switch(dev->path.type) {
+ case DEVICE_PATH_ROOT:
+ memcpy(buffer, "Root Device", 12);
+ break;
case DEVICE_PATH_PCI:
sprintf(buffer, "PCI: %02x:%02x.%01x",
dev->bus->secondary,
@@ -116,8 +121,12 @@ int path_eq(struct device_path *path1, struct device_path *path2)
switch(path1->type) {
case DEVICE_PATH_NONE:
break;
+ case DEVICE_PATH_ROOT:
+ equal = 1;
+ break;
case DEVICE_PATH_PCI:
- equal = path1->u.pci.devfn == path2->u.pci.devfn;
+ equal = (path1->u.pci.bus == path2->u.pci.bus) &&
+ (path1->u.pci.devfn == path2->u.pci.devfn);
break;
case DEVICE_PATH_PNP:
equal = (path1->u.pnp.port == path2->u.pnp.port) &&
diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c
index 0c1dc3959a..326f343662 100644
--- a/src/devices/hypertransport.c
+++ b/src/devices/hypertransport.c
@@ -4,6 +4,7 @@
#include <device/path.h>
#include <device/pci.h>
#include <device/hypertransport.h>
+#include <device/chip.h>
#include <part/hard_reset.h>
#include <part/fallback_boot.h>
@@ -243,11 +244,19 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
/* Add this device to the pci bus chain */
*chain_last = dev;
/* Run the magice enable/disable sequence for the device */
- if (dev->ops && dev->ops->enable) {
- dev->ops->enable(dev);
+ if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
+ dev->chip->control->enable_dev(dev);
}
/* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID);
+
+ /* If the chain is fully enumerated quit */
+ if (id == 0xffffffff || id == 0x00000000 ||
+ id == 0x0000ffff || id == 0xffff0000) {
+ printk_err("Missing static device: %s\n",
+ dev_path(dev));
+ break;
+ }
}
/* Update the device chain tail */
for(func = dev; func; func = func->sibling) {
@@ -268,7 +277,8 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
/* Find the hypertransport link capability */
pos = ht_lookup_slave_capability(dev);
if (pos == 0) {
- printk_err("Hypertransport link capability not found");
+ printk_err("%s Hypertransport link capability not found",
+ dev_path(dev));
break;
}
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c
index 806734c18b..031d855fbf 100644
--- a/src/devices/pci_device.c
+++ b/src/devices/pci_device.c
@@ -18,6 +18,7 @@
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
+#include <device/chip.h>
#include <part/hard_reset.h>
#include <part/fallback_boot.h>
@@ -175,7 +176,6 @@ static void pci_bridge_read_bases(struct device *dev)
/* FIXME handle bridges without some of the optional resources */
- printk_spew("%s: path %s\n", __FUNCTION__, dev_path(dev));
/* Initialize the io space constraints on the current bus */
dev->resource[reg].base = 0;
dev->resource[reg].size = 0;
@@ -215,7 +215,6 @@ static void pci_bridge_read_bases(struct device *dev)
reg++;
dev->resources = reg;
- printk_spew("DONE %s: path %s\n", __FUNCTION__, dev_path(dev));
}
@@ -455,11 +454,13 @@ static void set_pci_ops(struct device *dev)
break;
default:
bad:
- printk_err("%s [%04x/%04x/%06x] has unknown header "
- "type %02x, ignoring.\n",
- dev_path(dev),
- dev->vendor, dev->device,
- dev->class >> 8, dev->hdr_type);
+ if (dev->enable) {
+ printk_err("%s [%04x/%04x/%06x] has unknown header "
+ "type %02x, ignoring.\n",
+ dev_path(dev),
+ dev->vendor, dev->device,
+ dev->class >> 8, dev->hdr_type);
+ }
}
return;
}
@@ -556,17 +557,16 @@ unsigned int pci_scan_bus(struct bus *bus,
}
else {
/* Run the magic enable/disable sequence for the device */
- if (dev->ops && dev->ops->enable) {
- dev->ops->enable(dev);
+ if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
+ dev->chip->control->enable_dev(dev);
}
/* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID);
}
-
/* Read the rest of the pci configuration information */
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
class = pci_read_config32(dev, PCI_CLASS_REVISION);
-
+
/* Store the interesting information in the device structure */
dev->vendor = id & 0xffff;
dev->device = (id >> 16) & 0xffff;
@@ -576,20 +576,19 @@ unsigned int pci_scan_bus(struct bus *bus,
/* Look at the vendor and device id, or at least the
* header type and class and figure out which set of configuration
- * methods to use.
+ * methods to use. Unless we already have some pci ops.
*/
- if (!dev->ops) {
- set_pci_ops(dev);
- /* Error if we don't have some pci operations for it */
- if (!dev->ops) {
- printk_err("%s No device operations\n",
- dev_path(dev));
- continue;
- }
- /* Now run the magic enable/disable sequence for the device */
- if (dev->ops && dev->ops->enable) {
- dev->ops->enable(dev);
- }
+ set_pci_ops(dev);
+ /* Error if we don't have some pci operations for it */
+ if (dev->enable && !dev->ops) {
+ printk_err("%s No device operations\n",
+ dev_path(dev));
+ continue;
+ }
+
+ /* Now run the magic enable/disable sequence for the device */
+ if (dev->ops && dev->ops->enable) {
+ dev->ops->enable(dev);
}
printk_debug("%s [%04x/%04x] %s\n",
@@ -632,8 +631,7 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
struct bus *bus;
uint32_t buses;
uint16_t cr;
-
- printk_spew("%s: dev %p, max %d\n", __FUNCTION__, dev, max);
+
bus = &dev->link[0];
dev->links = 1;
@@ -707,7 +705,6 @@ static void pci_level_irq(unsigned char intNum)
}
}
-
/*
This function assigns IRQs for all functions contained within
the indicated device address. If the device does not exist or does
diff --git a/src/devices/root_device.c b/src/devices/root_device.c
index ae02277363..4a076a1bb3 100644
--- a/src/devices/root_device.c
+++ b/src/devices/root_device.c
@@ -123,6 +123,8 @@ struct device_operations default_dev_ops_root = {
struct device dev_root = {
.ops = &default_dev_ops_root,
.bus = &dev_root.link[0],
+ .path = { .type = DEVICE_PATH_ROOT },
+ .enable = 1,
.links = 1,
.link = {
[0] = {
diff --git a/src/include/cpu/k8/mtrr.h b/src/include/cpu/k8/mtrr.h
index 5f08a51215..5a965eebb8 100644
--- a/src/include/cpu/k8/mtrr.h
+++ b/src/include/cpu/k8/mtrr.h
@@ -30,5 +30,9 @@
#define TOP_MEM 0xC001001A
#define TOP_MEM2 0xC001001D
#define HWCR_MSR 0xC0010015
+#define NB_CFG_MSR 0xC001001f
+#define IC_CFG_MSR 0xC0011021
+#define DC_CFG_MSR 0xC0011022
+#define BU_CFG_MSR 0xC0011023
#endif /* CPU_K8_MTRR_H */
diff --git a/src/include/device/chip.h b/src/include/device/chip.h
index a98625a7ab..dc078a96b7 100644
--- a/src/include/device/chip.h
+++ b/src/include/device/chip.h
@@ -49,6 +49,7 @@ enum chip_pass {
*/
struct chip;
+struct device;
/* there is one of these for each TYPE of chip */
struct chip_control {
@@ -56,6 +57,7 @@ struct chip_control {
char *name;
void (*enable)(struct chip *, enum chip_pass);
void (*enumerate)(struct chip *chip);
+ void (*enable_dev)(struct device *dev);
};
@@ -72,6 +74,7 @@ struct bus;
#define MAX_CHIP_PATHS 16
#endif
struct chip {
+ unsigned link;
struct chip_control *control; /* for this device */
struct chip_device_path path[MAX_CHIP_PATHS]; /* can be 0, in which case the default is taken */
char *configuration; /* can be 0. */
diff --git a/src/include/device/device.h b/src/include/device/device.h
index e7b0317db3..1b2b0169dc 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -35,6 +35,7 @@ struct bus {
* combination:
*/
+struct chip;
struct device {
struct bus * bus; /* bus this device is on */
device_t sibling; /* next device on this bus */
@@ -72,6 +73,7 @@ struct device {
unsigned long rom_address;
struct device_operations *ops;
+ struct chip *chip;
};
extern struct device dev_root; /* root bus */
@@ -94,7 +96,7 @@ extern void enumerate_static_device(void);
extern const char *dev_path(device_t dev);
/* Helper functions */
-device_t alloc_find_dev(struct bus *bus, struct device_path *path);
+device_t alloc_find_dev(struct bus *parent, struct device_path *path);
device_t dev_find_device (unsigned int vendor, unsigned int device, device_t from);
device_t dev_find_class (unsigned int class, device_t from);
device_t dev_find_slot (unsigned int bus, unsigned int devfn);
diff --git a/src/include/device/path.h b/src/include/device/path.h
index cf89a68466..20d76d1bbe 100644
--- a/src/include/device/path.h
+++ b/src/include/device/path.h
@@ -3,6 +3,7 @@
enum device_path_type {
DEVICE_PATH_NONE = 0,
+ DEVICE_PATH_ROOT,
DEVICE_PATH_PCI,
DEVICE_PATH_PNP,
DEVICE_PATH_I2C,
@@ -10,6 +11,7 @@ enum device_path_type {
struct pci_path
{
+ unsigned bus;
unsigned devfn;
};
diff --git a/src/mainboard/amd/quartet/mptable.c b/src/mainboard/amd/quartet/mptable.c
index 94ac735744..6c29589a81 100644
--- a/src/mainboard/amd/quartet/mptable.c
+++ b/src/mainboard/amd/quartet/mptable.c
@@ -7,8 +7,8 @@
void *smp_write_config_table(void *v, unsigned long * processor_map)
{
static const char sig[4] = "PCMP";
- static const char oem[8] = "LNXI ";
- static const char productid[12] = "HDAMA ";
+ static const char oem[8] = "AMD ";
+ static const char productid[12] = "QUARTET ";
struct mp_config_table *mc;
unsigned char bus_num;
unsigned char bus_isa;
diff --git a/src/mainboard/arima/hdama/Config.lb b/src/mainboard/arima/hdama/Config.lb
index b056124b74..2604021cc7 100644
--- a/src/mainboard/arima/hdama/Config.lb
+++ b/src/mainboard/arima/hdama/Config.lb
@@ -161,7 +161,7 @@ makerule ./auto.E
end
makerule ./auto.inc
depends "./auto.E ./romcc"
- action "./romcc -mcpu=k8 -O ./auto.E > auto.inc"
+ action "./romcc -mcpu=k8 -O2 ./auto.E > auto.inc"
end
##
@@ -231,32 +231,36 @@ northbridge amd/amdk8 "mc0"
pci 0:18.1
pci 0:18.2
pci 0:18.3
- southbridge amd/amd8131 "amd8131"
+ southbridge amd/amd8131 "amd8131" link 0
pci 0:0.0
pci 0:0.1
pci 0:1.0
pci 0:1.1
end
- southbridge amd/amd8111 "amd8111"
+ southbridge amd/amd8111 "amd8111" link 0
pci 0:0.0
- pci 0:1.0
- pci 0:1.1
- pci 0:1.2
- pci 0:1.3
- pci 0:1.5
- pci 0:1.6
- superio NSC/pc87360
- pnp 1:2e.0
- pnp 1:2e.1
- pnp 1:2e.2
- pnp 1:2e.3
- pnp 1:2e.4
- pnp 1:2e.5
- pnp 1:2e.6
- pnp 1:2e.7
- pnp 1:2e.8
- pnp 1:2e.9
- pnp 1:2e.a
+ pci 0:1.0 on
+ pci 0:1.1 on
+ pci 0:1.2 on
+ pci 0:1.3 on
+ pci 0:1.5 off
+ pci 0:1.6 off
+ pci 1:0.0 on
+ pci 1:0.1 on
+ pci 1:0.2 on
+ pci 1:1.0 off
+ superio NSC/pc87360 link 1
+ pnp 2e.0
+ pnp 2e.1
+ pnp 2e.2
+ pnp 2e.3
+ pnp 2e.4
+ pnp 2e.5
+ pnp 2e.6
+ pnp 2e.7
+ pnp 2e.8
+ pnp 2e.9
+ pnp 2e.a
register "com1" = "{1, 0, 0x3f8, 4}"
register "lpt" = "{1}"
end
diff --git a/src/mainboard/arima/hdama/auto.c b/src/mainboard/arima/hdama/auto.c
index f0651d1b09..244d0ea305 100644
--- a/src/mainboard/arima/hdama/auto.c
+++ b/src/mainboard/arima/hdama/auto.c
@@ -1,5 +1,4 @@
#define ASSEMBLY 1
-
#include <stdint.h>
#include <device/pci_def.h>
#include <cpu/p6/apic.h>
@@ -17,25 +16,32 @@
#include "cpu/p6/boot_cpu.c"
#include "northbridge/amd/amdk8/reset_test.c"
#include "debug.c"
+#include "northbridge/amd/amdk8/cpu_rev.c"
#define SIO_BASE 0x2e
-#define MAXIMUM_CONSOLE_LOGLEVEL 9
-#define DEFAULT_CONSOLE_LOGLEVEL 9
static void memreset_setup(void)
{
- /* Set the memreset low */
- outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
- /* Ensure the BIOS has control of the memory lines */
- outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
+ if (is_cpu_pre_c0()) {
+ /* Set the memreset low */
+ outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
+ /* Ensure the BIOS has control of the memory lines */
+ outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
+ }
+ else {
+ /* Ensure the CPU has controll of the memory lines */
+ outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 29);
+ }
}
static void memreset(int controllers, const struct mem_controller *ctrl)
{
- udelay(800);
- /* Set memreset_high */
- outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28);
- udelay(90);
+ if (is_cpu_pre_c0()) {
+ udelay(800);
+ /* Set memreset_high */
+ outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28);
+ udelay(90);
+ }
}
static unsigned int generate_row(uint8_t node, uint8_t row, uint8_t maxnodes)
@@ -92,9 +98,6 @@ static void coherent_ht_mainboard(unsigned cpus)
{
}
-#include "northbridge/amd/amdk8/cpu_ldtstop.c"
-#include "southbridge/amd/amd8111/amd8111_ldtstop.c"
-
#include "northbridge/amd/amdk8/raminit.c"
#include "northbridge/amd/amdk8/coherent_ht.c"
#include "sdram/generic_sdram.c"
@@ -201,7 +204,7 @@ static void main(void)
enumerate_ht_chain(0);
distinguish_cpu_resets(0);
-#if 1
+#if 0
print_pci_devices();
#endif
enable_smbus();
@@ -211,10 +214,10 @@ static void main(void)
memreset_setup();
sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
-#if 1
+#if 0
dump_pci_devices();
#endif
-#if 1
+#if 0
dump_pci_device(PCI_DEV(0, 0x18, 2));
#endif
diff --git a/src/mainboard/arima/hdama/failover.c b/src/mainboard/arima/hdama/failover.c
index 8eeeaef7e1..bd9c17020e 100644
--- a/src/mainboard/arima/hdama/failover.c
+++ b/src/mainboard/arima/hdama/failover.c
@@ -27,6 +27,10 @@ static void main(void)
asm("jmp __cpu_reset");
}
}
+ /* Is this a deliberate reset by the bios */
+ else if (bios_reset_detected() && last_boot_normal()) {
+ asm("jmp __normal_image");
+ }
/* Is this a secondary cpu? */
else if (!boot_cpu() && last_boot_normal()) {
asm("jmp __normal_image");
diff --git a/src/mainboard/arima/hdama/irq_tables.c b/src/mainboard/arima/hdama/irq_tables.c
index 2c0095c177..142864fbb1 100644
--- a/src/mainboard/arima/hdama/irq_tables.c
+++ b/src/mainboard/arima/hdama/irq_tables.c
@@ -1,43 +1,34 @@
-/* This file was generated by getpir.c, do not modify!
- (but if you do, please run checkpir on it to verify)
- Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
-
- Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
-*/
-
#include <arch/pirq_routing.h>
-
const struct irq_routing_table intel_irq_routing_table = {
PIRQ_SIGNATURE, /* u32 signature */
PIRQ_VERSION, /* u16 version */
- 32+16*18, /* there can be total 18 devices on the bus */
- 1, /* Where the interrupt router lies (bus) */
- 0x23, /* Where the interrupt router lies (dev) */
- 0, /* IRQs devoted exclusively to PCI usage */
+ 32+16*9, /* there can be total 9 devices on the bus */
+ 1, /* Where the interrupt router lies (bus) */
+ (4<<3)|3, /* Where the interrupt router lies (dev) */
+ 0x0, /* IRQs devoted exclusively to PCI usage */
0x1022, /* Vendor */
0x746b, /* Device */
- 0, /* Crap (miniport) */
+ 0, /* Crap (miniport) */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
- 0x35, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
- {
- {0,0xc0, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0},
- {0,0x50, {{0x1, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0},
- {0x2,0x8, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x3, 0},
- {0x2,0x10, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x4, 0},
- {0x2,0x18, {{0x4, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0x0, 0},
- {0x2,0x20, {{0x4, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0x0, 0},
- {0x2,0x28, {{0x2, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0xa, 0},
- {0,0x58, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0},
- {0x3,0x8, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x1, 0},
- {0x3,0x10, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x2, 0},
- {0x3,0x18, {{0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}}, 0x9, 0},
- {0,0x30, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0},
- {0x1,0, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0x4, 0xdef8}}, 0, 0},
- {0x1,0x28, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x5, 0},
- {0x1,0x20, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x6, 0},
- {0x1,0x30, {{0x3, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0xb, 0},
- {0,0x38, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0},
- {0,0xc8, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0},
+ 0xb0, /* u8 checksum , mod 256 checksum must give zero */
+ { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
+ /* PCI Slot 1 */
+ {0x03, (0x01<<3)|0, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}}, 0x01, 0},
+ /* PCI Slot 2 */
+ {0x03, (0x02<<3)|0, {{0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}, {0x02, 0xdef8}}, 0x02, 0},
+ /* PCI Slot 3 */
+ {0x02, (0x01<<3)|0, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}}, 0x03, 0},
+ /* PCI Slot 4 */
+ {0x02, (0x02<<3)|0, {{0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}, {0x02, 0xdef8}}, 0x04, 0},
+ /* PCI Slot 5 */
+ {0x04, (0x05<<3)|0, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}}, 0x05, 0},
+ /* PCI Slot 6 */
+ {0x04, (0x04<<3)|0, {{0x01, 0xdef8}, {0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}}, 0x06, 0},
+ /* Onboard NICS */
+ {0x02, (0x03<<3)|0, {{0x04, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0},
+ {0x02, (0x04<<3)|0, {{0x04, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0},
+ /* Let Linux know about bus 1 */
+ {0x01, (0x04<<3)|3, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0},
}
};
diff --git a/src/mainboard/arima/hdama/mainboard.c b/src/mainboard/arima/hdama/mainboard.c
index c5812ece3f..82041282f6 100644
--- a/src/mainboard/arima/hdama/mainboard.c
+++ b/src/mainboard/arima/hdama/mainboard.c
@@ -1,4 +1,3 @@
-
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
diff --git a/src/mainboard/arima/hdama/mptable.c b/src/mainboard/arima/hdama/mptable.c
index 94ac735744..bd9df2e3ac 100644
--- a/src/mainboard/arima/hdama/mptable.c
+++ b/src/mainboard/arima/hdama/mptable.c
@@ -48,8 +48,8 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
else {
printk_debug("ERROR - could not find PCI 1:03.0, using defaults\n");
- bus_8111_1 = 3;
- bus_isa = 4;
+ bus_8111_1 = 4;
+ bus_isa = 5;
}
/* 8131-1 */
dev = dev_find_slot(1, PCI_DEVFN(0x01,0));
@@ -60,7 +60,7 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
else {
printk_debug("ERROR - could not find PCI 1:01.0, using defaults\n");
- bus_8131_1 = 1;
+ bus_8131_1 = 2;
}
/* 8131-2 */
dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
@@ -71,7 +71,7 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
else {
printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
- bus_8131_2 = 2;
+ bus_8131_2 = 3;
}
}
@@ -144,10 +144,6 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
bus_isa, 0x00, MP_APIC_ALL, 0x01);
- /* AGP Slot */
- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
- 0x03, (6<<2)|0, 0x02, 0x12);
-
/* PCI Slot 1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_8131_2, (1<<2)|0, 0x02, 0x11);
diff --git a/src/northbridge/amd/amdk8/Config.lb b/src/northbridge/amd/amdk8/Config.lb
index 6112ed18c8..0110e218ce 100644
--- a/src/northbridge/amd/amdk8/Config.lb
+++ b/src/northbridge/amd/amdk8/Config.lb
@@ -1,3 +1,4 @@
config chip.h
object northbridge.o
driver misc_control.o
+driver mcf0_control.o
diff --git a/src/northbridge/amd/amdk8/coherent_ht.c b/src/northbridge/amd/amdk8/coherent_ht.c
index b2839159c7..f05ee3d22d 100644
--- a/src/northbridge/amd/amdk8/coherent_ht.c
+++ b/src/northbridge/amd/amdk8/coherent_ht.c
@@ -100,43 +100,6 @@ static void disable_probes(void)
print_debug("done.\r\n");
}
-//BY LYH
-#define WAIT_TIMES 1000
-static void wait_ap_stop(u8 node)
-{
- unsigned long reg;
- unsigned long i;
- for(i=0;i<WAIT_TIMES;i++) {
- unsigned long regx;
- regx = pci_read_config32(NODE_HT(node),0x6c);
- if((regx & (1<<4))==1) break;
- }
- reg = pci_read_config32(NODE_HT(node),0x6c);
- reg &= ~(1<<4); // clear it
- pci_write_config32(NODE_HT(node), 0x6c, reg);
-
-}
-static void notify_bsp_ap_is_stopped(void)
-{
- unsigned long reg;
- unsigned long apic_id;
- apic_id = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
- apic_id >>= 24;
-#if 0
- print_debug("applicaton cpu apic_id: ");
- print_debug_hex32(apic_id);
- print_debug("\r\n");
-#endif
- /* AP apic_id == node_id ? */
- if(apic_id != 0) {
- /* set the ColdResetbit to notify BSP that AP is stopped */
- reg = pci_read_config32(NODE_HT(apic_id), 0x6C);
- reg |= 1<<4;
- pci_write_config32(NODE_HT(apic_id), 0x6C, reg);
- }
-
-}
-//BY LYH END
static void enable_routing(u8 node)
{
@@ -169,15 +132,8 @@ static void enable_routing(u8 node)
print_debug_hex32(node);
val=pci_read_config32(NODE_HT(node), 0x6c);
- val &= ~((1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0));
- pci_write_config32(NODE_HT(node), 0x6c, val);
-//BY LYH
-#if 1
- if(node!=0) {
- wait_ap_stop(node);
- }
-#endif
-//BY LYH END
+ val &= ~((1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0));
+ pci_write_config32(NODE_HT(node), 0x6c, val);
print_debug(" done.\r\n");
}
@@ -225,6 +181,62 @@ static bool check_connection(u8 src, u8 dest, u8 link)
return 1;
}
+static void optimize_connection(u8 node1, u8 link1, u8 node2, u8 link2)
+{
+ static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
+ static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
+ uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
+ uint8_t width_cap1, width_cap2, width_cap, width, ln_width1, ln_width2;
+ uint8_t freq;
+ /* Set link width and frequency */
+
+ /* Get the frequency capabilities */
+ freq_cap1 = pci_read_config16(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_FREQ_CAP);
+ freq_cap2 = pci_read_config16(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_FREQ_CAP);
+
+ /* Calculate the highest possible frequency */
+#if 1
+ /* FIXME!!!!!!!
+ * This method of computing the fastes frequency is broken.
+ * Because the frequencies (i.e. 100Mhz) are not ordered.
+ */
+ freq = log2(freq_cap1 & freq_cap2 & 0xff);
+#else
+ /* Only allow supported frequencies 800Mhz and below */
+ freq = log2(freq_cap1 & freq_cap2 & 0x3f);
+#endif
+
+ /* Set the Calulcated link frequency */
+ pci_write_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_FREQ, freq);
+ pci_write_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_FREQ, freq);
+
+ /* Get the width capabilities */
+ width_cap1 = pci_read_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_WIDTH);
+ width_cap2 = pci_read_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_WIDTH);
+
+ /* Calculate node1's input width */
+ ln_width1 = link_width_to_pow2[width_cap1 & 7];
+ ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
+ if (ln_width1 > ln_width2) {
+ ln_width1 = ln_width2;
+ }
+ width = pow2_to_link_width[ln_width1];
+ /* Calculate node1's output width */
+ ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
+ ln_width2 = link_width_to_pow2[width_cap2 & 7];
+ if (ln_width1 > ln_width2) {
+ ln_width1 = ln_width2;
+ }
+ width |= pow2_to_link_width[ln_width1] << 4;
+
+ /* Set node1's widths */
+ pci_write_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
+
+ /* Set node2's widths */
+ width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
+ pci_write_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
+}
+
static void fill_row(u8 node, u8 row, u32 value)
{
#if 0
@@ -346,6 +358,7 @@ static u8 setup_smp(void)
}
/* We found 2 nodes so far */
+ optimize_connection(0, ACROSS, 7, ACROSS);
setup_node(0, cpus); /* Node 1 is there. Setup Node 0 correctly */
setup_remote_node(1, cpus); /* Setup the routes on the remote node */
rename_temp_node(1); /* Rename Node 7 to Node 1 */
@@ -444,17 +457,6 @@ static unsigned detect_mp_capabilities(unsigned cpus)
#endif
-/* this is a shrunken cpuid. */
-
-static unsigned int cpuid(unsigned int op)
-{
- unsigned int ret;
-
- asm volatile ( "cpuid" : "=a" (ret) : "a" (op));
-
- return ret;
-}
-
static void coherent_ht_finalize(unsigned cpus)
{
int node;
@@ -469,7 +471,7 @@ static void coherent_ht_finalize(unsigned cpus)
#if 1
print_debug("coherent_ht_finalize\r\n");
#endif
- rev_a0=((cpuid(1)&0xffff)==0x0f10);
+ rev_a0= is_cpu_rev_a0();
for (node=0; node<cpus; node++) {
u32 val;
@@ -479,7 +481,11 @@ static void coherent_ht_finalize(unsigned cpus)
pci_write_config32(NODE_HT(node),0x60,val);
val=pci_read_config32(NODE_HT(node), 0x68);
+#if 1
+ val |= 0x00008000;
+#else
val |= 0x0f00c800; // 0x00008000->0f00c800 BY LYH
+#endif
pci_write_config32(NODE_HT(node),0x68,val);
if (rev_a0) {
@@ -508,7 +514,7 @@ static int setup_coherent_ht_domain(void)
#endif
coherent_ht_finalize(cpus);
- /* this should probably go away again. */
+ /* FIXME this should probably go away again. */
coherent_ht_mainboard(cpus);
return reset_needed;
}
diff --git a/src/northbridge/amd/amdk8/cpu_rev.c b/src/northbridge/amd/amdk8/cpu_rev.c
new file mode 100644
index 0000000000..51f235905e
--- /dev/null
+++ b/src/northbridge/amd/amdk8/cpu_rev.c
@@ -0,0 +1,25 @@
+/* this is a shrunken cpuid. */
+
+static unsigned int cpuid(unsigned int op)
+{
+ unsigned int ret;
+ unsigned dummy2,dummy3,dummy4;
+
+ asm volatile (
+ "cpuid"
+ : "=a" (ret), "=b" (dummy2), "=c" (dummy3), "=d" (dummy4)
+ : "a" (op)
+ );
+
+ return ret;
+}
+
+static int is_cpu_rev_a0(void)
+{
+ return (cpuid(1) & 0xffff) == 0x0f10;
+}
+
+static int is_cpu_pre_c0(void)
+{
+ return (cpuid(1) & 0xffef) < 0x0f48;
+}
diff --git a/src/northbridge/amd/amdk8/misc_control.c b/src/northbridge/amd/amdk8/misc_control.c
index 639e34fbaf..045f5cef06 100644
--- a/src/northbridge/amd/amdk8/misc_control.c
+++ b/src/northbridge/amd/amdk8/misc_control.c
@@ -8,6 +8,7 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
+#include "./cpu_rev.c"
static void misc_control_init(struct device *dev)
{
@@ -17,7 +18,48 @@ static void misc_control_init(struct device *dev)
cmd = pci_read_config32(dev, 0x44);
cmd |= (1<<6) | (1<<25);
pci_write_config32(dev, 0x44, cmd );
+ if (is_cpu_pre_c0()) {
+ /* errata 58 */
+ cmd = pci_read_config32(dev, 0x80);
+ cmd &= ~(1<<0);
+ pci_write_config32(dev, 0x80, cmd );
+ cmd = pci_read_config32(dev, 0x84);
+ cmd &= ~(1<<24);
+ cmd &= ~(1<<8);
+ pci_write_config32(dev, 0x84, cmd );
+ /* errata 66 */
+ cmd = pci_read_config32(dev, 0x70);
+ cmd &= ~(1<<0);
+ cmd |= (1<<1);
+ pci_write_config32(dev, 0x70, cmd );
+ cmd = pci_read_config32(dev, 0x7c);
+ cmd &= ~(3<<4);
+ pci_write_config32(dev, 0x7c, cmd );
+ }
+ else {
+ /* errata 98 */
+#if 0
+ cmd = pci_read_config32(dev, 0xd4);
+ if(cmd != 0x04e20707) {
+ cmd = 0x04e20707;
+ pci_write_config32(dev, 0xd4, cmd );
+ hard_reset();
+ }
+#endif
+ cmd = 0x04e20707;
+ pci_write_config32(dev, 0xd4, cmd );
+ }
+#if 1
+ cmd = pci_read_config32(dev, 0xdc);
+ if((cmd & 0x0000ff00) != 0x02500) {
+ cmd &= 0xffff00ff;
+ cmd |= 0x00002500;
+ pci_write_config32(dev, 0xdc, cmd );
+ printk_debug("resetting cpu\n");
+ hard_reset();
+ }
+#endif
printk_debug("done.\n");
}
diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c
index 7bcb1567ba..13845c5a70 100644
--- a/src/northbridge/amd/amdk8/northbridge.c
+++ b/src/northbridge/amd/amdk8/northbridge.c
@@ -475,6 +475,6 @@ static void enumerate(struct chip *chip)
}
struct chip_control northbridge_amd_amdk8_control = {
- .enumerate = enumerate,
.name = "AMD K8 Northbridge",
+ .enumerate = enumerate,
};
diff --git a/src/northbridge/amd/amdk8/raminit.c b/src/northbridge/amd/amdk8/raminit.c
index 802e4318b4..437ef2655d 100644
--- a/src/northbridge/amd/amdk8/raminit.c
+++ b/src/northbridge/amd/amdk8/raminit.c
@@ -124,6 +124,9 @@
#define DCH_MEMCLK_EN3 (1 << 29)
/* Function 3 */
+#define MCA_NB_CONFIG 0x44
+#define MNC_ECC_EN (1 << 22)
+#define MNC_CHIPKILL_EN (1 << 23)
#define SCRUB_CONTROL 0x58
#define SCRUB_NONE 0
#define SCRUB_40ns 1
@@ -1127,23 +1130,6 @@ static void spd_set_ram_size(const struct mem_controller *ctrl)
}
}
-//BY LYH //Fill next base reg with right value
-static void fill_last(unsigned long node_id,unsigned long base)
-{
- unsigned i;
- unsigned base_reg;
- base &=0xffff0000;
- device_t device;
- for(device = PCI_DEV(0, 0x18, 1); device <= PCI_DEV(0, 0x1f, 1); device
-+= PCI_DEV(0, 1, 0)) {
- for(i=node_id+1;i<=7;i++) {
- base_reg=0x40+(i<<3);
- pci_write_config32(device,base_reg,base);
- }
- }
-}
-//BY LYH END
-
static void route_dram_accesses(const struct mem_controller *ctrl,
unsigned long base_k, unsigned long limit_k)
{
@@ -1177,7 +1163,12 @@ static void set_top_mem(unsigned tom_k)
{
/* Error if I don't have memory */
if (!tom_k) {
- die("No memory");
+ set_bios_reset();
+ print_debug("No memory - reset");
+ /* enable cf9 */
+ pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+ /* reset */
+ outb(0x0e, 0x0cf9);
}
#if 1
@@ -1204,15 +1195,102 @@ static void set_top_mem(unsigned tom_k)
wrmsr(TOP_MEM, msr);
}
-static void order_dimms(const struct mem_controller *ctrl)
+static unsigned long interleave_chip_selects(const struct mem_controller *ctrl)
{
- unsigned long tom, tom_k, base_k;
- unsigned node_id;
+ /* 35 - 25 */
+ static const uint32_t csbase_low[] = {
+ /* 32MB */ (1 << (13 - 4)),
+ /* 64MB */ (1 << (14 - 4)),
+ /* 128MB */ (1 << (14 - 4)),
+ /* 256MB */ (1 << (15 - 4)),
+ /* 512MB */ (1 << (15 - 4)),
+ /* 1GB */ (1 << (16 - 4)),
+ /* 2GB */ (1 << (16 - 4)),
+ };
+ uint32_t csbase_inc;
+ int chip_selects, index;
+ int bits;
+ int dual_channel;
+ unsigned common_size;
+ uint32_t csbase, csmask;
+
+ /* See if all of the memory chip selects are the same size
+ * and if so count them.
+ */
+ chip_selects = 0;
+ common_size = 0;
+ for(index = 0; index < 8; index++) {
+ unsigned size;
+ uint32_t value;
+
+ value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
+
+ /* Is it enabled? */
+ if (!(value & 1)) {
+ continue;
+ }
+ chip_selects++;
+ size = value >> 21;
+ if (common_size == 0) {
+ common_size = size;
+ }
+ /* The size differed fail */
+ if (common_size != size) {
+ return 0;
+ }
+ }
+ /* Chip selects can only be interleaved when there is
+ * more than one and their is a power of two of them.
+ */
+ bits = log2(chip_selects);
+ if (((1 << bits) != chip_selects) || (bits < 1) || (bits > 3)) {
+ return 0;
+
+ }
+ /* Also we run out of address mask bits if we try and interleave 8 4GB dimms */
+ if ((bits == 3) && (common_size == (1 << (32 - 3)))) {
+ print_debug("8 4GB chip selects cannot be interleaved\r\n");
+ return 0;
+ }
+ /* Find the bits of csbase that we need to interleave on */
+ if (is_dual_channel(ctrl)) {
+ csbase_inc = csbase_low[log2(common_size) - 1] << 1;
+ } else {
+ csbase_inc = csbase_low[log2(common_size)];
+ }
+ /* Compute the initial values for csbase and csbask.
+ * In csbase just set the enable bit and the base to zero.
+ * In csmask set the mask bits for the size and page level interleave.
+ */
+ csbase = 0 | 1;
+ csmask = (((common_size << bits) - 1) << 21);
+ csmask |= 0xfe00 & ~((csbase_inc << bits) - csbase_inc);
+ for(index = 0; index < 8; index++) {
+ uint32_t value;
+
+ value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
+ /* Is it enabled? */
+ if (!(value & 1)) {
+ continue;
+ }
+ pci_write_config32(ctrl->f2, DRAM_CSBASE + (index << 2), csbase);
+ pci_write_config32(ctrl->f2, DRAM_CSMASK + (index << 2), csmask);
+ csbase += csbase_inc;
+ }
+
+#if 1
+ print_debug("Interleaved\r\n");
+#endif
+ /* Return the memory size in K */
+ return common_size << (15 + bits);
+}
- /* Compute the memory base address address */
- base_k = 0;
+static unsigned long order_chip_selects(const struct mem_controller *ctrl)
+{
+ unsigned long tom;
+
/* Remember which registers we have used in the high 8 bits of tom */
- tom = base_k >> 15;
+ tom = 0;
for(;;) {
/* Find the largest remaining canidate */
unsigned index, canidate;
@@ -1270,8 +1348,19 @@ static void order_dimms(const struct mem_controller *ctrl)
pci_write_config32(ctrl->f2, DRAM_CSMASK + (canidate << 2), csmask);
}
- tom_k = (tom & ~0xff000000) << 15;
+ /* Return the memory size in K */
+ return (tom & ~0xff000000) << 15;
+}
+
+static void order_dimms(const struct mem_controller *ctrl)
+{
+ unsigned long tom, tom_k, base_k;
+ unsigned node_id;
+ tom_k = interleave_chip_selects(ctrl);
+ if (!tom_k) {
+ tom_k = order_chip_selects(ctrl);
+ }
/* Compute the memory base address */
base_k = 0;
for(node_id = 0; node_id < ctrl->node_id; node_id++) {
@@ -1287,18 +1376,13 @@ static void order_dimms(const struct mem_controller *ctrl)
}
tom_k += base_k;
#if 0
- print_debug("tom: ");
- print_debug_hex32(tom);
- print_debug(" base_k: ");
+ print_debug("base_k: ");
print_debug_hex32(base_k);
print_debug(" tom_k: ");
print_debug_hex32(tom_k);
print_debug("\r\n");
#endif
route_dram_accesses(ctrl, base_k, tom_k);
-//BY LYH
- fill_last(ctrl->node_id, tom_k<<2);
-//BY LYH END
set_top_mem(tom_k);
}
@@ -2063,6 +2147,10 @@ static void set_read_preamble(const struct mem_controller *ctrl, const struct me
/* 166Mhz, 7.5ns */
rdpreamble = ((7 << 1)+1);
}
+ else if (divisor == ((5 << 1)+0)) {
+ /* 200Mhz, 7ns */
+ rdpreamble = ((7 << 1)+0);
+ }
}
else {
int slots;
@@ -2175,6 +2263,8 @@ static void spd_set_dram_timing(const struct mem_controller *ctrl, const struct
{
int dimms;
int i;
+ int rc;
+
init_Tref(ctrl, param);
for(i = 0; (i < 4) && ctrl->channel0[i]; i++) {
int rc;
@@ -2247,13 +2337,16 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
print_debug_hex32(dcl);
print_debug("\r\n");
#endif
-#warning "FIXME set the ECC type to perform"
-#warning "FIXME initialize the scrub registers"
-#if 1
if (dcl & DCL_DimmEccEn) {
+ uint32_t mnc;
print_debug("ECC enabled\r\n");
+ mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
+ mnc |= MNC_ECC_EN;
+ if (dcl & DCL_128BitEn) {
+ mnc |= MNC_CHIPKILL_EN;
+ }
+ pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
}
-#endif
dcl |= DCL_DisDqsHys;
pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
dcl &= ~DCL_DisDqsHys;
@@ -2280,29 +2373,148 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
} else {
print_debug(" done\r\n");
}
-#if 0
if (dcl & DCL_DimmEccEn) {
print_debug("Clearing memory: ");
- loops = 0;
- dcl &= ~DCL_MemClrStatus;
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+ if (!is_cpu_pre_c0()) {
+ /* Wait until the automatic ram scrubber is finished */
+ dcl &= ~(DCL_MemClrStatus | DCL_DramEnable);
+ pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+ do {
+ dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
+ } while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) );
+ }
+ uint32_t base, last_scrub_k, scrub_k;
+ uint32_t cnt,zstart,zend;
+ msr_t msr,msr_201;
+
+ /* First make certain the scrubber is disabled */
+ pci_write_config32(ctrl[i].f3, SCRUB_CONTROL,
+ (SCRUB_NONE << 16) | (SCRUB_NONE << 8) | (SCRUB_NONE << 0));
+
+ /* load the start and end for the memory block to clear */
+ msr_201 = rdmsr(0x201);
+ zstart = pci_read_config32(ctrl[0].f1, 0x40 + (i*8));
+ zend = pci_read_config32(ctrl[0].f1, 0x44 + (i*8));
+ zstart >>= 16;
+ zend >>=16;
+#if 1
+ print_debug("addr ");
+ print_debug_hex32(zstart);
+ print_debug("-");
+ print_debug_hex32(zend);
+ print_debug("\r\n");
+#endif
- do {
- dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- loops += 1;
- if ((loops & 1023) == 0) {
- print_debug(" ");
- print_debug_hex32(loops);
- }
- } while(((dcl & DCL_MemClrStatus) == 0) && (loops < TIMEOUT_LOOPS));
- if (loops >= TIMEOUT_LOOPS) {
- print_debug("failed\r\n");
- } else {
- print_debug("done\r\n");
+ /* Disable fixed mtrrs */
+ msr = rdmsr(MTRRdefType_MSR);
+ msr.lo &= ~(1<<10);
+ wrmsr(MTRRdefType_MSR, msr);
+
+ /* turn on the wrap 32 disable */
+ msr = rdmsr(0xc0010015);
+ msr.lo |= (1<<17);
+ wrmsr(0xc0010015,msr);
+
+ for(;zstart<zend;zstart+=4) {
+
+ /* test for the last 64 meg of 4 gig space */
+ if(zstart == 0x0fc)
+ continue;
+
+ /* disable cache */
+ __asm__ volatile(
+ "movl %%cr0, %0\n\t"
+ "orl $0x40000000, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (cnt)
+ );
+
+ /* Set the variable mtrrs to write combine */
+ msr.lo = 1 + ((zstart&0x0ff)<<24);
+ msr.hi = (zstart&0x0ff00)>>8;
+ wrmsr(0x200,msr);
+
+ /* Set the limit to 64 meg of ram */
+ msr.hi = 0x000000ff;
+ msr.lo = 0xfc000800;
+ wrmsr(0x201,msr);
+
+ /* enable cache */
+ __asm__ volatile(
+ "movl %%cr0, %0\n\t"
+ "andl $0x9fffffff, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (cnt)
+ );
+ /* Set fs base address */
+ msr.lo = (zstart&0xff) << 24;
+ msr.hi = (zstart&0xff00) >> 8;
+ wrmsr(0xc0000100,msr);
+
+ print_debug_char((zstart > 0x0ff)?'+':'-');
+
+ /* clear memory 64meg */
+ __asm__ volatile(
+ "1: \n\t"
+ "movl %0, %%fs:(%1)\n\t"
+ "addl $4,%1\n\t"
+ "subl $1,%2\n\t"
+ "jnz 1b\n\t"
+ :
+ : "a" (0), "D" (0), "c" (0x01000000)
+ );
}
- pci_write_config32(ctrl[i].f3, SCRUB_ADDR_LOW, 0);
- pci_write_config32(ctrl[i].f3, SCRUB_ADDR_HIGH, 0);
+
+ /* disable cache */
+ __asm__ volatile(
+ "movl %%cr0, %0\n\t"
+ "orl $0x40000000, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (cnt)
+ );
+
+ /* restore msr registers */
+ msr = rdmsr(MTRRdefType_MSR);
+ msr.lo |= 0x0400;
+ wrmsr(MTRRdefType_MSR, msr);
+
+ /* Restore the variable mtrrs */
+ msr.lo = 6;
+ msr.hi = 0;
+ wrmsr(0x200,msr);
+ wrmsr(0x201,msr_201);
+
+ /* Set fs base to 0 */
+ msr.lo = 0;
+ msr.hi = 0;
+ wrmsr(0xc0000100,msr);
+
+ /* enable cache */
+ __asm__ volatile(
+ "movl %%cr0, %0\n\t"
+ "andl $0x9fffffff, %0\n\t"
+ "movl %0, %%cr0\n\t"
+ :"=r" (cnt)
+ );
+
+ /* turn off the wrap 32 disable */
+ msr = rdmsr(0xc0010015);
+ msr.lo &= ~(1<<17);
+ wrmsr(0xc0010015,msr);
+
+ /* Find the Srub base address for this cpu */
+ base = pci_read_config32(ctrl[i].f1, 0x40 + (ctrl[i].node_id << 3));
+ base &= 0xffff0000;
+
+ /* Set the scrub base address registers */
+ pci_write_config32(ctrl[i].f3, SCRUB_ADDR_LOW, base << 8);
+ pci_write_config32(ctrl[i].f3, SCRUB_ADDR_HIGH, base >> 24);
+
+ /* Enable scrubbing at the lowest possible rate */
+ pci_write_config32(ctrl[i].f3, SCRUB_CONTROL,
+ (SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_84ms << 0));
+
+ print_debug("done\r\n");
}
-#endif
}
}
diff --git a/src/northbridge/via/vt8601/northbridge.c b/src/northbridge/via/vt8601/northbridge.c
index 3b655cbdb5..5f5e5d9dd8 100644
--- a/src/northbridge/via/vt8601/northbridge.c
+++ b/src/northbridge/via/vt8601/northbridge.c
@@ -38,21 +38,21 @@ struct mem_range *sizeram(void)
idx++;
}
for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) {
- unsigned char reg;
- reg = pci_read_config8(dev, ramregs[i]);
- /* these are ENDING addresses, not sizes.
- * if there is memory in this slot, then reg will be > rambits.
- * So we just take the max, that gives us total.
- * We take the highest one to cover for once and future linuxbios
- * bugs. We warn about bugs.
- */
- if (reg > rambits)
- rambits = reg;
- if (reg < rambits)
- printk_err("ERROR! register 0x%x is not set!\n",
- ramregs[i]);
+ unsigned char reg;
+ reg = pci_read_config8(dev, ramregs[i]);
+ /* these are ENDING addresses, not sizes.
+ * if there is memory in this slot, then reg will be > rambits.
+ * So we just take the max, that gives us total.
+ * We take the highest one to cover for once and future linuxbios
+ * bugs. We warn about bugs.
+ */
+ if (reg > rambits)
+ rambits = reg;
+ if (reg < rambits)
+ printk_err("ERROR! register 0x%x is not set!\n",
+ ramregs[i]);
}
-
+
printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024);
mem[0].sizek = rambits*8*1024;
#if 1
@@ -77,48 +77,46 @@ static void enumerate(struct chip *chip)
* slower than normal, ethernet drops packets).
* Apparently these registers govern some sort of bus master behavior.
*/
-static void
-random_fixup() {
- device_t pcidev = dev_find_slot(0, 0);
+static void random_fixup() {
+ device_t pcidev = dev_find_slot(0, 0);
- printk_spew("VT8601 random fixup ...\n");
- if (pcidev) {
- pci_write_config8(pcidev, 0x70, 0xc0);
- pci_write_config8(pcidev, 0x71, 0x88);
- pci_write_config8(pcidev, 0x72, 0xec);
- pci_write_config8(pcidev, 0x73, 0x0c);
- pci_write_config8(pcidev, 0x74, 0x0e);
- pci_write_config8(pcidev, 0x75, 0x81);
- pci_write_config8(pcidev, 0x76, 0x52);
- }
+ printk_spew("VT8601 random fixup ...\n");
+ if (pcidev) {
+ pci_write_config8(pcidev, 0x70, 0xc0);
+ pci_write_config8(pcidev, 0x71, 0x88);
+ pci_write_config8(pcidev, 0x72, 0xec);
+ pci_write_config8(pcidev, 0x73, 0x0c);
+ pci_write_config8(pcidev, 0x74, 0x0e);
+ pci_write_config8(pcidev, 0x75, 0x81);
+ pci_write_config8(pcidev, 0x76, 0x52);
+ }
}
-static void
-northbridge_init(struct chip *chip, enum chip_pass pass)
+static void northbridge_init(struct chip *chip, enum chip_pass pass)
{
- struct northbridge_via_vt8601_config *conf =
- (struct northbridge_via_vt8601_config *)chip->chip_info;
-
- switch (pass) {
- case CONF_PASS_PRE_PCI:
- break;
+ struct northbridge_via_vt8601_config *conf =
+ (struct northbridge_via_vt8601_config *)chip->chip_info;
- case CONF_PASS_POST_PCI:
- break;
-
- case CONF_PASS_PRE_BOOT:
- random_fixup();
- break;
-
- default:
- /* nothing yet */
- break;
- }
+ switch (pass) {
+ case CONF_PASS_PRE_PCI:
+ break;
+
+ case CONF_PASS_POST_PCI:
+ break;
+
+ case CONF_PASS_PRE_BOOT:
+ random_fixup();
+ break;
+
+ default:
+ /* nothing yet */
+ break;
+ }
}
struct chip_control northbridge_via_vt8601_control = {
.enumerate = enumerate,
- enable: northbridge_init,
- .name = "VIA vt8601 Northbridge",
+ .enable = northbridge_init,
+ .name = "VIA vt8601 Northbridge",
};
diff --git a/src/pc80/vgabios.c b/src/pc80/vgabios.c
index 05e3ce33ed..9aebf1d35c 100644
--- a/src/pc80/vgabios.c
+++ b/src/pc80/vgabios.c
@@ -66,86 +66,86 @@
/* The address arguments to this function are PHYSICAL ADDRESSES */
static void real_mode_switch_call_vga(unsigned long devfn)
{
- __asm__ __volatile__
- (
- // paranoia -- does ecx get saved? not sure. This is
- // the easiest safe thing to do.
- "pushal\n"
- /* save the stack */
- "mov %esp, __stack\n"
- "jmp 1f\n"
- "__stack: .long 0\n"
- "1:\n"
- /* get devfn into %ecx */
- "movl %esp, %ebp\n"
- "movl 8(%ebp), %ecx\n"
- /* This configures CS properly for real mode. */
- " ljmp $0x28, $__rms_16bit\n"
- "__rms_16bit: \n"
- ".code16 \n" /* 16 bit code from here on... */
-
- /* Load the segment registers w/ properly configured segment
- * descriptors. They will retain these configurations (limits,
- * writability, etc.) once protected mode is turned off. */
- " mov $0x30, %ax \n"
- " mov %ax, %ds \n"
- " mov %ax, %es \n"
- " mov %ax, %fs \n"
- " mov %ax, %gs \n"
- " mov %ax, %ss \n"
-
- /* Turn off protection (bit 0 in CR0) */
- " movl %cr0, %eax \n"
- " andl $0xFFFFFFFE, %eax \n"
- " movl %eax, %cr0 \n"
-
- /* Now really going into real mode */
- " ljmp $0, $__rms_real \n"
- "__rms_real: \n"
-
- // put the stack at the end of page zero.
- // that way we can easily share it between real and protected,
- // since the 16-bit ESP at segment 0 will work for any case.
- /* Setup a stack */
- " mov $0x0, %ax \n"
- " mov %ax, %ss \n"
- " movl $0x1000, %eax \n"
- " movl %eax, %esp \n"
- /* debugging for RGM */
- " mov $0x11, %al \n"
- " outb %al, $0x80\n"
-
- /* Dump zeros in the other segregs */
- " xor %ax, %ax \n"
- " mov %ax, %ds \n"
- " mov %ax, %es \n"
- " mov %ax, %fs \n"
- " mov %ax, %gs \n"
- " mov %cx, %ax \n"
- " .byte 0x9a, 0x03, 0, 0, 0xc0 \n"
- " movb $0x55, %al\noutb %al, $0x80\n"
- /* if we got here, just about done.
- * Need to get back to protected mode */
- "movl %cr0, %eax\n"
- // "andl $0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */
- // "orl $0x60000001, %eax\n" /* CD, NW, PE = 1 */
- "orl $0x0000001, %eax\n" /* PE = 1 */
- "movl %eax, %cr0\n"
- /* Now that we are in protected mode jump to a 32 bit code segment. */
- "data32 ljmp $0x10, $vgarestart\n"
- "vgarestart:\n"
- ".code32\n"
- " movw $0x18, %ax \n"
- " mov %ax, %ds \n"
- " mov %ax, %es \n"
- " mov %ax, %fs \n"
- " mov %ax, %gs \n"
- " mov %ax, %ss \n"
- ".globl vga_exit\n"
- "vga_exit:\n"
- " mov __stack, %esp\n"
- " popal\n"
- );
+ __asm__ __volatile__
+ (
+ // paranoia -- does ecx get saved? not sure. This is
+ // the easiest safe thing to do.
+ "pushal\n"
+ /* save the stack */
+ "mov %esp, __stack\n"
+ "jmp 1f\n"
+ "__stack: .long 0\n"
+ "1:\n"
+ /* get devfn into %ecx */
+ "movl %esp, %ebp\n"
+ "movl 8(%ebp), %ecx\n"
+ /* This configures CS properly for real mode. */
+ " ljmp $0x28, $__rms_16bit\n"
+ "__rms_16bit: \n"
+ ".code16 \n" /* 16 bit code from here on... */
+
+ /* Load the segment registers w/ properly configured segment
+ * descriptors. They will retain these configurations (limits,
+ * writability, etc.) once protected mode is turned off. */
+ " mov $0x30, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ " mov %ax, %ss \n"
+
+ /* Turn off protection (bit 0 in CR0) */
+ " movl %cr0, %eax \n"
+ " andl $0xFFFFFFFE, %eax \n"
+ " movl %eax, %cr0 \n"
+
+ /* Now really going into real mode */
+ " ljmp $0, $__rms_real \n"
+ "__rms_real: \n"
+
+ // put the stack at the end of page zero.
+ // that way we can easily share it between real and protected,
+ // since the 16-bit ESP at segment 0 will work for any case.
+ /* Setup a stack */
+ " mov $0x0, %ax \n"
+ " mov %ax, %ss \n"
+ " movl $0x1000, %eax \n"
+ " movl %eax, %esp \n"
+ /* debugging for RGM */
+ " mov $0x11, %al \n"
+ " outb %al, $0x80\n"
+
+ /* Dump zeros in the other segregs */
+ " xor %ax, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ " mov %cx, %ax \n"
+ " .byte 0x9a, 0x03, 0, 0, 0xc0 \n"
+ " movb $0x55, %al\noutb %al, $0x80\n"
+ /* if we got here, just about done.
+ * Need to get back to protected mode */
+ "movl %cr0, %eax\n"
+ // "andl $0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */
+ // "orl $0x60000001, %eax\n" /* CD, NW, PE = 1 */
+ "orl $0x0000001, %eax\n" /* PE = 1 */
+ "movl %eax, %cr0\n"
+ /* Now that we are in protected mode jump to a 32 bit code segment. */
+ "data32 ljmp $0x10, $vgarestart\n"
+ "vgarestart:\n"
+ ".code32\n"
+ " movw $0x18, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ " mov %ax, %ss \n"
+ ".globl vga_exit\n"
+ "vga_exit:\n"
+ " mov __stack, %esp\n"
+ " popal\n"
+ );
}
__asm__ (".text\n""real_mode_switch_end:\n");
extern char real_mode_switch_end[];
@@ -153,53 +153,53 @@ extern char real_mode_switch_end[];
void
do_vgabios(void)
{
- struct pci_dev *dev;
- unsigned long busdevfn;
- unsigned int rom = 0;
- unsigned char *buf;
- unsigned int size = 64*1024;
- int i;
-
- for (i=0x400; i<0x500; i++) {
- printk_debug("%02x%c", *(unsigned char *)i, i%16==15 ? '\n' : ' ');
- *(unsigned char *) i = 0;
- }
-
- for (i=0x400; i<0x500; i++) {
- printk_debug("%02x%c", *(unsigned char *)i, i%16==15 ? '\n' : ' ');
- }
-
- dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL);
-
- if (! dev) {
- printk_debug("NO VGA FOUND\n");
- return;
- }
- printk_debug("found VGA: vid=%x, did=%x\n", dev->vendor, dev->device);
-
+ struct pci_dev *dev;
+ unsigned long busdevfn;
+ unsigned int rom = 0;
+ unsigned char *buf;
+ unsigned int size = 64*1024;
+ int i;
+
+ for (i=0x400; i<0x500; i++) {
+ printk_debug("%02x%c", *(unsigned char *)i, i%16==15 ? '\n' : ' ');
+ *(unsigned char *) i = 0;
+ }
+
+ for (i=0x400; i<0x500; i++) {
+ printk_debug("%02x%c", *(unsigned char *)i, i%16==15 ? '\n' : ' ');
+ }
+
+ dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL);
+
+ if (! dev) {
+ printk_debug("NO VGA FOUND\n");
+ return;
+ }
+ printk_debug("found VGA: vid=%x, did=%x\n", dev->vendor, dev->device);
+
#ifdef VGABIOS_START
- // Use VGA BIOS blob at specified address
- rom = VGABIOS_START;
+ // Use VGA BIOS blob at specified address
+ rom = VGABIOS_START;
#else
- pci_read_config32(dev, PCI_ROM_ADDRESS, &rom);
- // paranoia
- rom = 0xf0000000;
- pci_write_config32(dev, PCI_ROM_ADDRESS, rom|1);
- printk_debug("rom base, size: %x\n", rom);
+ pci_read_config32(dev, PCI_ROM_ADDRESS, &rom);
+ // paranoia
+ rom = 0xf0000000;
+ pci_write_config32(dev, PCI_ROM_ADDRESS, rom|1);
+ printk_debug("rom base, size: %x\n", rom);
#endif
- buf = (unsigned char *) rom;
- if ((buf[0] == 0x55) && (buf[1] = 0xaa)) {
- memcpy((void *) 0xc0000, buf, size);
-
- for(i = 0; i < 16; i++)
- printk_debug("0x%x ", buf[i]);
- // check signature here later!
- busdevfn = (dev->bus->secondary << 8) | dev->devfn;
- real_mode_switch_call_vga(busdevfn);
- } else
- printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
+ buf = (unsigned char *) rom;
+ if ((buf[0] == 0x55) && (buf[1] = 0xaa)) {
+ memcpy((void *) 0xc0000, buf, size);
+
+ for(i = 0; i < 16; i++)
+ printk_debug("0x%x ", buf[i]);
+ // check signature here later!
+ busdevfn = (dev->bus->secondary << 8) | dev->devfn;
+ real_mode_switch_call_vga(busdevfn);
+ } else
+ printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
#ifndef VGABIOS_START
- pci_write_config32(dev, PCI_ROM_ADDRESS, 0);
+ pci_write_config32(dev, PCI_ROM_ADDRESS, 0);
#endif
}
@@ -209,7 +209,7 @@ do_vgabios(void)
// to the BIOS.
// no longer. Dammit. We have to respond to these.
struct realidt {
- unsigned short offset, cs;
+ unsigned short offset, cs;
};
// from a handy writeup that andrey found.
@@ -228,15 +228,15 @@ struct realidt {
// have to do address fixup in this little stub, and calls are absolute
// so the handler is relocatable.
void handler(void) {
- __asm__ __volatile__ (
- ".code16\n"
- "idthandle:\n"
- " pushal\n"
- " movb $0, %al\n"
- " ljmp $0, $callbiosint16\n"
- "end_idthandle:\n"
- ".code32\n"
- );
+ __asm__ __volatile__ (
+ ".code16\n"
+ "idthandle:\n"
+ " pushal\n"
+ " movb $0, %al\n"
+ " ljmp $0, $callbiosint16\n"
+ "end_idthandle:\n"
+ ".code32\n"
+ );
}
@@ -247,79 +247,79 @@ void handler(void) {
// REFERENCE parameters. In this way, we can easily get
// returns back to the INTx caller (i.e. vgabios)
void callbiosint(void) {
- __asm__ __volatile__ (
- ".code16\n"
- "callbiosint16:\n"
- // clean up the int #. To save space we put it in the lower
- // byte. But the top 24 bits are junk.
- "andl $0xff, %eax\n"
- // this push does two things:
- // - put the INT # on the stack as a parameter
- // - provides us with a temp for the %cr0 mods.
- "pushl %eax\n"
- "movl %cr0, %eax\n"
- //"andl $0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */
- //"orl $0x60000001, %eax\n" /* CD, NW, PE = 1 */
- "orl $0x00000001, %eax\n" /* PE = 1 */
- "movl %eax, %cr0\n"
- /* Now that we are in protected mode jump to a 32 bit code segment. */
- "data32 ljmp $0x10, $biosprotect\n"
- "biosprotect:\n"
- ".code32\n"
- " movw $0x18, %ax \n"
- " mov %ax, %ds \n"
- " mov %ax, %es \n"
- " mov %ax, %fs \n"
- " mov %ax, %gs \n"
- " mov %ax, %ss \n"
- " call biosint \n"
- // back to real mode ...
- " ljmp $0x28, $__rms_16bit\n"
- "__rms_16bit: \n"
- ".code16 \n" /* 16 bit code from here on... */
-
- /* Load the segment registers w/ properly configured segment
- * descriptors. They will retain these configurations (limits,
- * writability, etc.) once protected mode is turned off. */
- " mov $0x30, %ax \n"
- " mov %ax, %ds \n"
- " mov %ax, %es \n"
- " mov %ax, %fs \n"
- " mov %ax, %gs \n"
- " mov %ax, %ss \n"
-
- /* Turn off protection (bit 0 in CR0) */
- " movl %cr0, %eax \n"
- " andl $0xFFFFFFFE, %eax \n"
- " movl %eax, %cr0 \n"
-
- /* Now really going into real mode */
- " ljmp $0, $__rms_real \n"
- "__rms_real: \n"
-
- /* Setup a stack */
- " mov $0x0, %ax \n"
- " mov %ax, %ss \n"
- /* ebugging for RGM */
- " mov $0x11, %al \n"
- " outb %al, $0x80\n"
- " xor %ax, %ax \n"
- " mov %ax, %ds \n"
- " mov %ax, %es \n"
- " mov %ax, %fs \n"
- " mov %ax, %gs \n"
- // pop the INT # that you pushed earlier
- " popl %eax\n"
- " popal\n"
- " iret\n"
- ".code32\n"
- );
+ __asm__ __volatile__ (
+ ".code16\n"
+ "callbiosint16:\n"
+ // clean up the int #. To save space we put it in the lower
+ // byte. But the top 24 bits are junk.
+ "andl $0xff, %eax\n"
+ // this push does two things:
+ // - put the INT # on the stack as a parameter
+ // - provides us with a temp for the %cr0 mods.
+ "pushl %eax\n"
+ "movl %cr0, %eax\n"
+ //"andl $0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */
+ //"orl $0x60000001, %eax\n" /* CD, NW, PE = 1 */
+ "orl $0x00000001, %eax\n" /* PE = 1 */
+ "movl %eax, %cr0\n"
+ /* Now that we are in protected mode jump to a 32 bit code segment. */
+ "data32 ljmp $0x10, $biosprotect\n"
+ "biosprotect:\n"
+ ".code32\n"
+ " movw $0x18, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ " mov %ax, %ss \n"
+ " call biosint \n"
+ // back to real mode ...
+ " ljmp $0x28, $__rms_16bit\n"
+ "__rms_16bit: \n"
+ ".code16 \n" /* 16 bit code from here on... */
+
+ /* Load the segment registers w/ properly configured segment
+ * descriptors. They will retain these configurations (limits,
+ * writability, etc.) once protected mode is turned off. */
+ " mov $0x30, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ " mov %ax, %ss \n"
+
+ /* Turn off protection (bit 0 in CR0) */
+ " movl %cr0, %eax \n"
+ " andl $0xFFFFFFFE, %eax \n"
+ " movl %eax, %cr0 \n"
+
+ /* Now really going into real mode */
+ " ljmp $0, $__rms_real \n"
+ "__rms_real: \n"
+
+ /* Setup a stack */
+ " mov $0x0, %ax \n"
+ " mov %ax, %ss \n"
+ /* ebugging for RGM */
+ " mov $0x11, %al \n"
+ " outb %al, $0x80\n"
+ " xor %ax, %ax \n"
+ " mov %ax, %ds \n"
+ " mov %ax, %es \n"
+ " mov %ax, %fs \n"
+ " mov %ax, %gs \n"
+ // pop the INT # that you pushed earlier
+ " popl %eax\n"
+ " popal\n"
+ " iret\n"
+ ".code32\n"
+ );
}
enum {
- PCIBIOS = 0x1a,
- MEMSIZE = 0x12
+ PCIBIOS = 0x1a,
+ MEMSIZE = 0x12
};
int
pcibios(
@@ -350,116 +350,116 @@ biosint(
unsigned long cs_ip,
unsigned short stackflags
) {
- unsigned long ip;
- unsigned long cs;
- unsigned long flags;
- int ret = -1;
-
- ip = cs_ip & 0xffff;
- cs = cs_ip >> 16;
- flags = stackflags;
-
- printk_debug("biosint: # 0x%lx, eax 0x%lx ebx 0x%lx ecx 0x%lx edx 0x%lx\n",
- intnumber, eax, ebx, ecx, edx);
- printk_debug("biosint: ebp 0x%lx esp 0x%lx edi 0x%lx esi 0x%lx\n", ebp, esp, edi, esi);
- printk_debug("biosint: ip 0x%x cs 0x%x flags 0x%x\n", ip, cs, flags);
- // cases in a good compiler are just as good as your own tables.
- switch (intnumber) {
- case 0 ... 15:
- // These are not BIOS service, but the CPU-generated exceptions
- printk_info("biosint: Oops, exception %u\n", intnumber);
- if (esp < 0x1000) {
- printk_debug("Stack contents: ");
- while (esp < 0x1000) {
- printk_debug("0x%04x ", *(unsigned short *) esp);
- esp += 2;
- }
- printk_debug("\n");
- }
- printk_debug("biosint: Bailing out\n");
- // "longjmp"
- vga_exit();
- break;
-
- case PCIBIOS:
- ret = pcibios( &edi, &esi, &ebp, &esp,
- &ebx, &edx, &ecx, &eax, &flags);
- break;
- case MEMSIZE:
- // who cares.
- eax = 64 * 1024;
- ret = 0;
- break;
- default:
- printk_info(__FUNCTION__ ": Unsupport int #0x%x\n",
- intnumber);
- break;
- }
- if (ret)
- flags |= 1; // carry flags
- else
- flags &= ~1;
- stackflags = flags;
- return ret;
+ unsigned long ip;
+ unsigned long cs;
+ unsigned long flags;
+ int ret = -1;
+
+ ip = cs_ip & 0xffff;
+ cs = cs_ip >> 16;
+ flags = stackflags;
+
+ printk_debug("biosint: # 0x%lx, eax 0x%lx ebx 0x%lx ecx 0x%lx edx 0x%lx\n",
+ intnumber, eax, ebx, ecx, edx);
+ printk_debug("biosint: ebp 0x%lx esp 0x%lx edi 0x%lx esi 0x%lx\n", ebp, esp, edi, esi);
+ printk_debug("biosint: ip 0x%x cs 0x%x flags 0x%x\n", ip, cs, flags);
+ // cases in a good compiler are just as good as your own tables.
+ switch (intnumber) {
+ case 0 ... 15:
+ // These are not BIOS service, but the CPU-generated exceptions
+ printk_info("biosint: Oops, exception %u\n", intnumber);
+ if (esp < 0x1000) {
+ printk_debug("Stack contents: ");
+ while (esp < 0x1000) {
+ printk_debug("0x%04x ", *(unsigned short *) esp);
+ esp += 2;
+ }
+ printk_debug("\n");
+ }
+ printk_debug("biosint: Bailing out\n");
+ // "longjmp"
+ vga_exit();
+ break;
+
+ case PCIBIOS:
+ ret = pcibios( &edi, &esi, &ebp, &esp,
+ &ebx, &edx, &ecx, &eax, &flags);
+ break;
+ case MEMSIZE:
+ // who cares.
+ eax = 64 * 1024;
+ ret = 0;
+ break;
+ default:
+ printk_info(__FUNCTION__ ": Unsupport int #0x%x\n",
+ intnumber);
+ break;
+ }
+ if (ret)
+ flags |= 1; // carry flags
+ else
+ flags &= ~1;
+ stackflags = flags;
+ return ret;
}
-void
-setup_realmode_idt(void) {
- extern unsigned char idthandle, end_idthandle;
- int i;
- struct realidt *idts = (struct realidt *) 0;
- int codesize = &end_idthandle - &idthandle;
- unsigned char *intbyte, *codeptr;
-
- // for each int, we create a customized little handler
- // that just pushes %ax, puts the int # in %al,
- // then calls the common interrupt handler.
- // this necessitated because intel didn't know much about
- // architecture when they did the 8086 (it shows)
- // (hmm do they know anymore even now :-)
- // obviously you can see I don't really care about memory
- // efficiency. If I did I would probe back through the stack
- // and get it that way. But that's really disgusting.
- for (i = 0; i < 256; i++) {
- idts[i].cs = 0;
- codeptr = (char*) 4096 + i * codesize;
- idts[i].offset = (unsigned) codeptr;
- memcpy(codeptr, &idthandle, codesize);
- intbyte = codeptr + 3;
- *intbyte = i;
- }
-
- // fixed entry points
-
- // VGA BIOSes tend to hardcode f000:f065 as the previous handler of
- // int10.
- // calling convention here is the same as INTs, we can reuse
- // the int entry code.
- codeptr = (char*) 0xff065;
- memcpy(codeptr, &idthandle, codesize);
- intbyte = codeptr + 3;
- *intbyte = 0x42; /* int42 is the relocated int10 */
+void setup_realmode_idt(void)
+{
+ extern unsigned char idthandle, end_idthandle;
+ int i;
+ struct realidt *idts = (struct realidt *) 0;
+ int codesize = &end_idthandle - &idthandle;
+ unsigned char *intbyte, *codeptr;
+
+ // for each int, we create a customized little handler
+ // that just pushes %ax, puts the int # in %al,
+ // then calls the common interrupt handler.
+ // this necessitated because intel didn't know much about
+ // architecture when they did the 8086 (it shows)
+ // (hmm do they know anymore even now :-)
+ // obviously you can see I don't really care about memory
+ // efficiency. If I did I would probe back through the stack
+ // and get it that way. But that's really disgusting.
+ for (i = 0; i < 256; i++) {
+ idts[i].cs = 0;
+ codeptr = (char*) 4096 + i * codesize;
+ idts[i].offset = (unsigned) codeptr;
+ memcpy(codeptr, &idthandle, codesize);
+ intbyte = codeptr + 3;
+ *intbyte = i;
+ }
+
+ // fixed entry points
+
+ // VGA BIOSes tend to hardcode f000:f065 as the previous handler of
+ // int10.
+ // calling convention here is the same as INTs, we can reuse
+ // the int entry code.
+ codeptr = (char*) 0xff065;
+ memcpy(codeptr, &idthandle, codesize);
+ intbyte = codeptr + 3;
+ *intbyte = 0x42; /* int42 is the relocated int10 */
}
enum {
- CHECK = 0xb001,
- FINDDEV = 0xb102,
- READCONFBYTE = 0xb108,
- READCONFWORD = 0xb109,
- READCONFDWORD = 0xb10a,
- WRITECONFBYTE = 0xb10b,
- WRITECONFWORD = 0xb10c,
- WRITECONFDWORD = 0xb10d
+ CHECK = 0xb001,
+ FINDDEV = 0xb102,
+ READCONFBYTE = 0xb108,
+ READCONFWORD = 0xb109,
+ READCONFDWORD = 0xb10a,
+ WRITECONFBYTE = 0xb10b,
+ WRITECONFWORD = 0xb10c,
+ WRITECONFDWORD = 0xb10d
};
// errors go in AH. Just set these up so that word assigns
// will work. KISS.
enum {
- PCIBIOS_NODEV = 0x8600,
- PCIBIOS_BADREG = 0x8700
+ PCIBIOS_NODEV = 0x8600,
+ PCIBIOS_BADREG = 0x8700
};
int
@@ -474,145 +474,144 @@ pcibios(
unsigned long *peax,
unsigned long *pflags
) {
- unsigned long edi = *pedi;
- unsigned long esi = *pesi;
- unsigned long ebp = *pebp;
- unsigned long esp = *pesp;
- unsigned long ebx = *pebx;
- unsigned long edx = *pedx;
- unsigned long ecx = *pecx;
- unsigned long eax = *peax;
- unsigned long flags = *pflags;
- unsigned short func = (unsigned short) eax;
- int retval = 0;
- unsigned short devid, vendorid, devfn;
- short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */
- unsigned char bus;
- struct pci_dev *dev;
-
- switch(func) {
- case CHECK:
- *pedx = 0x4350;
- *pecx = 0x2049;
- retval = 0;
- break;
- case FINDDEV:
- {
- devid = *pecx;
- vendorid = *pedx;
- devindex = *pesi;
- dev = 0;
- while ((dev = pci_find_device(vendorid, devid, dev))) {
- if (devindex <= 0)
- break;
- devindex--;
- }
- if (dev) {
- unsigned short busdevfn;
- *peax = 0;
- // busnum is an unsigned char;
- // devfn is an int, so we mask it off.
- busdevfn = (dev->bus->secondary << 8)
- | (dev->devfn & 0xff);
- printk_debug("0x%x: return 0x%x\n", func, busdevfn);
- *pebx = busdevfn;
- retval = 0;
- } else {
- *peax = PCIBIOS_NODEV;
- retval = -1;
- }
- }
- break;
- case READCONFDWORD:
- case READCONFWORD:
- case READCONFBYTE:
- case WRITECONFDWORD:
- case WRITECONFWORD:
- case WRITECONFBYTE:
- {
- unsigned long dword;
- unsigned short word;
- unsigned char byte;
- unsigned char reg;
-
- devfn = *pebx & 0xff;
- bus = *pebx >> 8;
- reg = *pedi;
- dev = pci_find_slot(bus, devfn);
- if (! dev) {
- printk_debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
- // idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
- *peax = PCIBIOS_BADREG;
- retval = -1;
- }
- switch(func) {
- case READCONFBYTE:
- byte = pci_read_config8(dev, reg);
- *pecx = byte;
- break;
- case READCONFWORD:
- word = pci_read_config16(dev, reg);
- *pecx = word;
- break;
- case READCONFDWORD:
- dword = pci_read_config32(dev, reg);
- *pecx = dword;
+ unsigned long edi = *pedi;
+ unsigned long esi = *pesi;
+ unsigned long ebp = *pebp;
+ unsigned long esp = *pesp;
+ unsigned long ebx = *pebx;
+ unsigned long edx = *pedx;
+ unsigned long ecx = *pecx;
+ unsigned long eax = *peax;
+ unsigned long flags = *pflags;
+ unsigned short func = (unsigned short) eax;
+ int retval = 0;
+ unsigned short devid, vendorid, devfn;
+ short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */
+ unsigned char bus;
+ struct pci_dev *dev;
+
+ switch(func) {
+ case CHECK:
+ *pedx = 0x4350;
+ *pecx = 0x2049;
+ retval = 0;
+ break;
+ case FINDDEV:
+ {
+ devid = *pecx;
+ vendorid = *pedx;
+ devindex = *pesi;
+ dev = 0;
+ while ((dev = pci_find_device(vendorid, devid, dev))) {
+ if (devindex <= 0)
+ break;
+ devindex--;
+ }
+ if (dev) {
+ unsigned short busdevfn;
+ *peax = 0;
+ // busnum is an unsigned char;
+ // devfn is an int, so we mask it off.
+ busdevfn = (dev->bus->secondary << 8)
+ | (dev->devfn & 0xff);
+ printk_debug("0x%x: return 0x%x\n", func, busdevfn);
+ *pebx = busdevfn;
+ retval = 0;
+ } else {
+ *peax = PCIBIOS_NODEV;
+ retval = -1;
+ }
+ }
break;
- case WRITECONFBYTE:
- byte = *pecx;
- write_config8(dev, reg, byte);
- break;
- case WRITECONFWORD:
- word = *pecx;
- write_config16(dev, reg, word);
- break;
- case WRITECONFDWORD:
- word = *pecx;
- write_config32(dev, reg, dword);
+ case READCONFDWORD:
+ case READCONFWORD:
+ case READCONFBYTE:
+ case WRITECONFDWORD:
+ case WRITECONFWORD:
+ case WRITECONFBYTE:
+ {
+ unsigned long dword;
+ unsigned short word;
+ unsigned char byte;
+ unsigned char reg;
+
+ devfn = *pebx & 0xff;
+ bus = *pebx >> 8;
+ reg = *pedi;
+ dev = pci_find_slot(bus, devfn);
+ if (! dev) {
+ printk_debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
+ // idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
+ *peax = PCIBIOS_BADREG;
+ retval = -1;
+ }
+ switch(func) {
+ case READCONFBYTE:
+ byte = pci_read_config8(dev, reg);
+ *pecx = byte;
+ break;
+ case READCONFWORD:
+ word = pci_read_config16(dev, reg);
+ *pecx = word;
+ break;
+ case READCONFDWORD:
+ dword = pci_read_config32(dev, reg);
+ *pecx = dword;
+ break;
+ case WRITECONFBYTE:
+ byte = *pecx;
+ write_config8(dev, reg, byte);
+ break;
+ case WRITECONFWORD:
+ word = *pecx;
+ write_config16(dev, reg, word);
+ break;
+ case WRITECONFDWORD:
+ word = *pecx;
+ write_config32(dev, reg, dword);
+ break;
+ }
+
+ if (retval)
+ retval = PCIBIOS_BADREG;
+ printk_debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%lx\n", func, bus, devfn, reg, *pecx);
+ *peax = 0;
+ retval = 0;
+ }
break;
- }
-
- if (retval)
- retval = PCIBIOS_BADREG;
- printk_debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%lx\n", func, bus, devfn, reg, *pecx);
- *peax = 0;
- retval = 0;
- }
- break;
- default:
- printk_err("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
- break;
- }
-
- return retval;
+ default:
+ printk_err("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
+ break;
+ }
+
+ return retval;
}
-static void
-vga_init(struct chip *chip, enum chip_pass pass)
+static void vga_init(struct chip *chip, enum chip_pass pass)
{
- struct pc80_vgabios_config *conf =
- (struct pc80_vgabios_config *)chip->chip_info;
-
- switch (pass) {
- case CONF_PASS_PRE_BOOT:
-
- break;
-
- default:
- /* nothing yet */
- break;
- }
+ struct pc80_vgabios_config *conf =
+ (struct pc80_vgabios_config *)chip->chip_info;
+
+ switch (pass) {
+ case CONF_PASS_PRE_BOOT:
+
+ break;
+
+ default:
+ /* nothing yet */
+ break;
+ }
}
static void enumerate(struct chip *chip)
{
- /* don't really need to do anything */
+ /* don't really need to do anything */
}
struct chip_control southbridge_via_vt8231_control = {
- .enumerate = enumerate,
- enable: vga_init,
- name: "Legacy VGA bios"
+ .enumerate = enumerate,
+ .enable = vga_init,
+ .name = "Legacy VGA bios"
};
diff --git a/src/pc80/vgachip.h b/src/pc80/vgachip.h
index 02124b3df3..d43788cd66 100644
--- a/src/pc80/vgachip.h
+++ b/src/pc80/vgachip.h
@@ -4,7 +4,7 @@
extern struct chip_control pc80_vgabios_control;
struct pc80_vgabios_config {
- int nothing;
+ int nothing;
};
#endif /* _PC80_VGABIOS */
diff --git a/src/southbridge/amd/amd8111/Config.lb b/src/southbridge/amd/amd8111/Config.lb
index f8f38a9964..904b0995b5 100644
--- a/src/southbridge/amd/amd8111/Config.lb
+++ b/src/southbridge/amd/amd8111/Config.lb
@@ -1,5 +1,9 @@
+config amd8111.h
+driver amd8111.o
driver amd8111_usb.o
driver amd8111_lpc.o
driver amd8111_ide.o
driver amd8111_acpi.o
driver amd8111_usb2.o
+#driver amd8111_ac97.o
+#driver amd8111_nic.o
diff --git a/src/southbridge/amd/amd8111/amd8111.c b/src/southbridge/amd/amd8111/amd8111.c
new file mode 100644
index 0000000000..8dde5f13c6
--- /dev/null
+++ b/src/southbridge/amd/amd8111/amd8111.c
@@ -0,0 +1,56 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/chip.h>
+#include "amd8111.h"
+
+void amd8111_enable(device_t dev)
+{
+ device_t lpc_dev;
+ device_t bus_dev;
+ unsigned index;
+ uint16_t reg_old, reg;
+
+ /* See if we are on the behind the amd8111 pci bridge */
+ bus_dev = dev->bus->dev;
+ if ((bus_dev->vendor == PCI_VENDOR_ID_AMD) &&
+ (bus_dev->device == PCI_DEVICE_ID_AMD_8111_PCI)) {
+ unsigned devfn;
+ devfn = bus_dev->path.u.pci.devfn + (1 << 3);
+ lpc_dev = dev_find_slot(bus_dev->bus->secondary, devfn);
+ index = ((dev->path.u.pci.devfn & ~7) >> 3) + 8;
+ } else {
+ unsigned devfn;
+ devfn = (dev->path.u.pci.devfn) & ~7;
+ 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)) {
+ 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
+ }
+}
+
+struct chip_control southbridge_amd_amd8111_control = {
+ .name = "AMD 8111",
+ .enable_dev = amd8111_enable,
+};
diff --git a/src/southbridge/amd/amd8111/amd8111.h b/src/southbridge/amd/amd8111/amd8111.h
new file mode 100644
index 0000000000..10e152954f
--- /dev/null
+++ b/src/southbridge/amd/amd8111/amd8111.h
@@ -0,0 +1,12 @@
+#ifndef AMD8111_H
+#define AMD8111_H
+
+struct southbridge_amd_amd8111_config
+{
+};
+struct chip_control;
+extern struct chip_control southbridge_amd_amd8111_control;
+
+void amd8111_enable(device_t dev);
+
+#endif /* AMD8111_H */
diff --git a/src/southbridge/amd/amd8111/amd8111_ac97.c b/src/southbridge/amd/amd8111/amd8111_ac97.c
new file mode 100644
index 0000000000..63a0e1264e
--- /dev/null
+++ b/src/southbridge/amd/amd8111/amd8111_ac97.c
@@ -0,0 +1,41 @@
+/*
+ * (C) 2003 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "amd8111.h"
+
+
+static struct device_operations ac97audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = amd8111_enable,
+ .init = 0,
+ .scan_bus = 0,
+};
+
+static struct pci_driver ac97audio_driver __pci_driver = {
+ .ops = &ac97audio_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x746D,
+};
+
+
+static struct device_operations ac97modem_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = amd8111_enable,
+ .init = 0,
+ .scan_bus = 0,
+};
+
+static struct pci_driver ac97modem_driver __pci_driver = {
+ .ops = &ac97modem_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x746E,
+};
diff --git a/src/southbridge/amd/amd8111/amd8111_acpi.c b/src/southbridge/amd/amd8111/amd8111_acpi.c
index 5fa6fdce29..3a5a594f57 100644
--- a/src/southbridge/amd/amd8111/amd8111_acpi.c
+++ b/src/southbridge/amd/amd8111/amd8111_acpi.c
@@ -3,11 +3,23 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include "amd8111.h"
+
+#define PREVIOUS_POWER_STATE 0x43
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+
+#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
static void acpi_init(struct device *dev)
{
uint8_t byte;
uint16_t word;
+ int on;
#if 0
printk_debug("ACPI: disabling NMI watchdog.. ");
@@ -35,6 +47,15 @@ static void acpi_init(struct device *dev)
pci_write_config_dword(dev, 0x60, 0x06800000);
printk_debug("done.\n");
#endif
+ on = MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ get_option(&on, "power_on_after_fail");
+ byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
+ byte &= ~0x40;
+ if (!on) {
+ byte |= 0x40;
+ }
+ pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
+ printk_info("set power %s after power fail\n", on?"on":"off");
}
@@ -42,8 +63,9 @@ static struct device_operations acpi_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
- .init = acpi_init,
- .scan_bus = 0,
+ .init = acpi_init,
+ .scan_bus = 0,
+ .enable = amd8111_enable,
};
static struct pci_driver acpi_driver __pci_driver = {
diff --git a/src/southbridge/amd/amd8111/amd8111_early_smbus.c b/src/southbridge/amd/amd8111/amd8111_early_smbus.c
index e0aaa05ff4..b9f142dc8e 100644
--- a/src/southbridge/amd/amd8111/amd8111_early_smbus.c
+++ b/src/southbridge/amd/amd8111/amd8111_early_smbus.c
@@ -21,6 +21,8 @@ static void enable_smbus(void)
pci_write_config32(dev, 0x58, SMBUS_IO_BASE | 1);
enable = pci_read_config8(dev, 0x41);
pci_write_config8(dev, 0x41, enable | (1 << 7));
+ /* clear any lingering errors, so the transaction will run */
+ outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
}
@@ -40,8 +42,12 @@ static int smbus_wait_until_ready(void)
if ((val & 0x800) == 0) {
break;
}
+ if(loops == (SMBUS_TIMEOUT / 2)) {
+ outw(inw(SMBUS_IO_BASE + SMBGSTATUS),
+ SMBUS_IO_BASE + SMBGSTATUS);
+ }
} while(--loops);
- return loops?0:-1;
+ return loops?0:-2;
}
static int smbus_wait_until_done(void)
@@ -57,7 +63,7 @@ static int smbus_wait_until_done(void)
break;
}
} while(--loops);
- return loops?0:-1;
+ return loops?0:-3;
}
static int smbus_read_byte(unsigned device, unsigned address)
@@ -67,7 +73,7 @@ static int smbus_read_byte(unsigned device, unsigned address)
unsigned char byte;
if (smbus_wait_until_ready() < 0) {
- return -1;
+ return -2;
}
/* setup transaction */
@@ -93,7 +99,7 @@ static int smbus_read_byte(unsigned device, unsigned address)
/* poll for transaction completion */
if (smbus_wait_until_done() < 0) {
- return -1;
+ return -3;
}
global_status_register = inw(SMBUS_IO_BASE + SMBGSTATUS);
diff --git a/src/southbridge/amd/amd8111/amd8111_ide.c b/src/southbridge/amd/amd8111/amd8111_ide.c
index 11f795b0bb..4502bb3c45 100644
--- a/src/southbridge/amd/amd8111/amd8111_ide.c
+++ b/src/southbridge/amd/amd8111/amd8111_ide.c
@@ -3,6 +3,7 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
+#include "amd8111.h"
static void ide_init(struct device *dev)
{
diff --git a/src/southbridge/amd/amd8111/amd8111_lpc.c b/src/southbridge/amd/amd8111/amd8111_lpc.c
index b0c1672f5d..437ed2e877 100644
--- a/src/southbridge/amd/amd8111/amd8111_lpc.c
+++ b/src/southbridge/amd/amd8111/amd8111_lpc.c
@@ -6,6 +6,8 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
+#include <device/chip.h>
+#include "amd8111.h"
struct ioapicreg {
@@ -87,7 +89,6 @@ static void setup_ioapic(void)
static void lpc_init(struct device *dev)
{
uint8_t byte;
- uint16_t word;
int pwr_on=-1;
printk_debug("lpc_init\n");
@@ -100,14 +101,7 @@ static void lpc_init(struct device *dev)
/* posted memory write enable */
byte = pci_read_config8(dev, 0x46);
- pci_write_config8(dev, 0x46, byte | (1<<0));
-
-//BY LYH
- /* Disable AC97 and Ethernet */
- word = pci_read_config16(dev, 0x48);
- pci_write_config16(dev, 0x48, word & ~((1<<5)|(1<<6)|(1<<9)));
-//BY LYH END
-
+ pci_write_config8(dev, 0x46, byte | (1<<0));
/* power after power fail */
byte = pci_read_config8(dev, 0x43);
@@ -118,6 +112,10 @@ static void lpc_init(struct device *dev)
}
pci_write_config8(dev, 0x43, byte);
+ /* Enable Port 92 fast reset */
+ byte = pci_read_config8(dev, 0x41);
+ byte |= (1 << 5);
+ pci_write_config8(dev, 0x41, byte);
}
@@ -159,6 +157,7 @@ static struct device_operations lpc_ops = {
.enable_resources = pci_dev_enable_resources,
.init = lpc_init,
.scan_bus = walk_static_devices,
+ .enable = amd8111_enable,
};
static struct pci_driver lpc_driver __pci_driver = {
@@ -166,3 +165,4 @@ 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_nic.c b/src/southbridge/amd/amd8111/amd8111_nic.c
new file mode 100644
index 0000000000..b3792086a5
--- /dev/null
+++ b/src/southbridge/amd/amd8111/amd8111_nic.c
@@ -0,0 +1,25 @@
+/*
+ * (C) 2003 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "amd8111.h"
+
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = amd8111_enable,
+ .init = 0,
+ .scan_bus = 0,
+};
+
+static struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7462,
+};
diff --git a/src/southbridge/amd/amd8111/amd8111_usb.c b/src/southbridge/amd/amd8111/amd8111_usb.c
index cfef06dee2..46cfabbcda 100644
--- a/src/southbridge/amd/amd8111/amd8111_usb.c
+++ b/src/southbridge/amd/amd8111/amd8111_usb.c
@@ -3,6 +3,7 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
+#include "amd8111.h"
static void usb_init(struct device *dev)
{
@@ -25,6 +26,7 @@ static struct device_operations usb_ops = {
.enable_resources = pci_dev_enable_resources,
.init = usb_init,
.scan_bus = 0,
+ .enable = amd8111_enable,
};
static struct pci_driver usb_driver __pci_driver = {
diff --git a/src/southbridge/amd/amd8111/amd8111_usb2.c b/src/southbridge/amd/amd8111/amd8111_usb2.c
index 924e0e6109..15ed69b0f1 100644
--- a/src/southbridge/amd/amd8111/amd8111_usb2.c
+++ b/src/southbridge/amd/amd8111/amd8111_usb2.c
@@ -7,6 +7,7 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
+#include "amd8111.h"
static void usb2_init(struct device *dev)
{
@@ -23,17 +24,17 @@ static void usb2_init(struct device *dev)
}
-static struct device_operations usb_ops = {
+static struct device_operations usb2_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = usb2_init,
.scan_bus = 0,
+ .enable = amd8111_enable,
};
static struct pci_driver usb2_driver __pci_driver = {
- .ops = &usb_ops,
+ .ops = &usb2_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_USB2,
};
-
diff --git a/src/southbridge/amd/amd8131/amd8131_bridge.c b/src/southbridge/amd/amd8131/amd8131_bridge.c
index dccf962fbd..9d28de4f32 100644
--- a/src/southbridge/amd/amd8131/amd8131_bridge.c
+++ b/src/southbridge/amd/amd8131/amd8131_bridge.c
@@ -29,6 +29,17 @@ static void pcix_init(device_t dev)
word = pci_read_config16(dev, 0xe8);
word = 0x0404;
pci_write_config16(dev, 0xe8, word);
+
+ /* Set discard unrequested prefetch data */
+ word = pci_read_config16(dev, 0x4c);
+ word |= 1;
+ pci_write_config16(dev, 0x4c, word);
+
+ /* Set split transaction limits */
+ word = pci_read_config16(dev, 0xa8);
+ pci_write_config16(dev, 0xaa, word);
+ word = pci_read_config16(dev, 0xac);
+ pci_write_config16(dev, 0xae, word);
return;
}
@@ -58,14 +69,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 = {
diff --git a/src/southbridge/via/vt8231/chip.h b/src/southbridge/via/vt8231/chip.h
index 0ae3b98c63..fe3d332675 100644
--- a/src/southbridge/via/vt8231/chip.h
+++ b/src/southbridge/via/vt8231/chip.h
@@ -9,13 +9,13 @@ struct southbridge_via_vt8231_config {
/* I am putting in IDE as an example but obviously this needs
* to be more complete!
*/
- int enable_ide;
- /* enables of functions of devices */
- int enable_usb;
- int enable_native_ide;
- int enable_com_ports;
- int enable_keyboard;
- int enable_nvram;
+ int enable_ide;
+ /* enables of functions of devices */
+ int enable_usb;
+ int enable_native_ide;
+ int enable_com_ports;
+ int enable_keyboard;
+ int enable_nvram;
};
#endif /* _SOUTHBRIDGE_VIA_VT8231 */
diff --git a/src/southbridge/via/vt8231/vt8231.c b/src/southbridge/via/vt8231/vt8231.c
index 470ab5acf1..ea1f488f3e 100644
--- a/src/southbridge/via/vt8231/vt8231.c
+++ b/src/southbridge/via/vt8231/vt8231.c
@@ -11,101 +11,94 @@
void pc_keyboard_init(void);
-void
-hard_reset() {
- printk_err("NO HARD RESET ON VT8231! FIX ME!\n");
+void hard_reset(void)
+{
+ printk_err("NO HARD RESET ON VT8231! FIX ME!\n");
}
+
static void usb_on(int enable)
{
-
- unsigned char regval;
-
- /* Base 8231 controller */
- device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, \
- PCI_DEVICE_ID_VIA_8231, 0);
- /* USB controller 1 */
- device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, \
- PCI_DEVICE_ID_VIA_82C586_2, 0);
- /* USB controller 2 */
- device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, \
- PCI_DEVICE_ID_VIA_82C586_2, \
- dev2);
-
- /* enable USB1 */
- if(dev2) {
- if (enable) {
- pci_write_config8(dev2, 0x3c, 0x05);
- pci_write_config8(dev2, 0x04, 0x07);
- } else {
- pci_write_config8(dev2, 0x3c, 0x00);
- pci_write_config8(dev2, 0x04, 0x00);
- }
- }
-
- if(dev0) {
- regval = pci_read_config8(dev0, 0x50);
- if (enable)
- regval &= ~(0x10);
- else
- regval |= 0x10;
- pci_write_config8(dev0, 0x50, regval);
- }
-
- /* enable USB2 */
- if(dev3) {
- if (enable) {
- pci_write_config8(dev3, 0x3c, 0x05);
- pci_write_config8(dev3, 0x04, 0x07);
- } else {
- pci_write_config8(dev3, 0x3c, 0x00);
- pci_write_config8(dev3, 0x04, 0x00);
- }
- }
-
- if(dev0) {
- regval = pci_read_config8(dev0, 0x50);
- if (enable)
- regval &= ~(0x20);
- else
- regval |= 0x20;
- pci_write_config8(dev0, 0x50, regval);
- }
-
+ unsigned char regval;
+
+ /* Base 8231 controller */
+ device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
+ /* USB controller 1 */
+ device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
+ /* USB controller 2 */
+ device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev2);
+
+ /* enable USB1 */
+ if(dev2) {
+ if (enable) {
+ pci_write_config8(dev2, 0x3c, 0x05);
+ pci_write_config8(dev2, 0x04, 0x07);
+ } else {
+ pci_write_config8(dev2, 0x3c, 0x00);
+ pci_write_config8(dev2, 0x04, 0x00);
+ }
+ }
+
+ if(dev0) {
+ regval = pci_read_config8(dev0, 0x50);
+ if (enable)
+ regval &= ~(0x10);
+ else
+ regval |= 0x10;
+ pci_write_config8(dev0, 0x50, regval);
+ }
+
+ /* enable USB2 */
+ if(dev3) {
+ if (enable) {
+ pci_write_config8(dev3, 0x3c, 0x05);
+ pci_write_config8(dev3, 0x04, 0x07);
+ } else {
+ pci_write_config8(dev3, 0x3c, 0x00);
+ pci_write_config8(dev3, 0x04, 0x00);
+ }
+ }
+
+ if(dev0) {
+ regval = pci_read_config8(dev0, 0x50);
+ if (enable)
+ regval &= ~(0x20);
+ else
+ regval |= 0x20;
+ pci_write_config8(dev0, 0x50, regval);
+ }
}
-static void keyboard_on()
+static void keyboard_on(void)
{
- unsigned char regval;
-
- /* Base 8231 controller */
- device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, \
- PCI_DEVICE_ID_VIA_8231, 0);
-
- /* kevinh/Ispiri - update entire function to use
- new pci_write_config8 */
-
- if (dev0) {
- regval = pci_read_config8(dev0, 0x51);
- regval |= 0x0f;
- pci_write_config8(dev0, 0x51, regval);
- }
- pc_keyboard_init();
+ unsigned char regval;
+
+ /* Base 8231 controller */
+ device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
+
+ /* kevinh/Ispiri - update entire function to use
+ new pci_write_config8 */
+ if (dev0) {
+ regval = pci_read_config8(dev0, 0x51);
+ regval |= 0x0f;
+ pci_write_config8(dev0, 0x51, regval);
+ }
+ pc_keyboard_init();
}
-static void nvram_on()
+static void nvram_on(void)
{
- /*
- * the VIA 8231 South has a very different nvram setup than the
- * piix4e ...
- * turn on ProMedia nvram.
- * TO DO: use the PciWriteByte function here.
- */
-
- /*
- * kevinh/Ispiri - I don't think this is the correct address/value
- * intel_conf_writeb(0x80008841, 0xFF);
- */
+ /*
+ * the VIA 8231 South has a very different nvram setup than the
+ * piix4e ...
+ * turn on ProMedia nvram.
+ * TO DO: use the PciWriteByte function here.
+ */
+
+ /*
+ * kevinh/Ispiri - I don't think this is the correct address/value
+ * intel_conf_writeb(0x80008841, 0xFF);
+ */
}
@@ -115,22 +108,22 @@ static void nvram_on()
*/
static void ethernet_fixup()
{
- device_t edev;
- uint8_t byte;
-
- printk_info("Ethernet fixup\n");
-
- edev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_7, 0);
- if (edev) {
- printk_debug("Configuring VIA LAN\n");
-
- /* We don't need stepping - though the device supports it */
- byte = pci_read_config8(edev, PCI_COMMAND);
- byte &= ~PCI_COMMAND_WAIT;
- pci_write_config8(edev, PCI_COMMAND, byte);
- } else {
- printk_debug("VIA LAN not found\n");
- }
+ device_t edev;
+ uint8_t byte;
+
+ printk_info("Ethernet fixup\n");
+
+ edev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_7, 0);
+ if (edev) {
+ printk_debug("Configuring VIA LAN\n");
+
+ /* We don't need stepping - though the device supports it */
+ byte = pci_read_config8(edev, PCI_COMMAND);
+ byte &= ~PCI_COMMAND_WAIT;
+ pci_write_config8(edev, PCI_COMMAND, byte);
+ } else {
+ printk_debug("VIA LAN not found\n");
+ }
}
@@ -145,13 +138,14 @@ static void ethernet_fixup()
* (e.g. device_t). This needs to get fixed. We need low-level pci scans
* in the C code.
*/
-static void vt8231_pci_enable(struct southbridge_via_vt8231_config *conf) {
- /*
- unsigned long busdevfn = 0x8000;
- if (conf->enable_ide) {
- printk_debug("%s: enabling IDE function\n", __FUNCTION__);
- }
- */
+static void vt8231_pci_enable(struct southbridge_via_vt8231_config *conf)
+{
+ /*
+ unsigned long busdevfn = 0x8000;
+ if (conf->enable_ide) {
+ printk_debug("%s: enabling IDE function\n", __FUNCTION__);
+ }
+ */
}
/* PIRQ init
@@ -170,7 +164,7 @@ static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 };
*/
static void pci_routing_fixup(void)
{
- device_t dev;
+ device_t dev;
dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
printk_info("%s: dev is %p\n", __FUNCTION__, dev);
@@ -204,260 +198,258 @@ static void pci_routing_fixup(void)
void
-dump_south(void){
- device_t dev0;
- dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
- int i,j;
-
- for(i = 0; i < 256; i += 16) {
- printk_debug("0x%x: ", i);
- for(j = 0; j < 16; j++) {
- printk_debug("%02x ", pci_read_config8(dev0, i+j));
- }
- printk_debug("\n");
- }
+dump_south(void)
+{
+ device_t dev0;
+ dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
+ int i,j;
+
+ for(i = 0; i < 256; i += 16) {
+ printk_debug("0x%x: ", i);
+ for(j = 0; j < 16; j++) {
+ printk_debug("%02x ", pci_read_config8(dev0, i+j));
+ }
+ printk_debug("\n");
+ }
}
static void vt8231_init(struct southbridge_via_vt8231_config *conf)
{
- unsigned char enables;
- device_t dev0;
- device_t dev1;
- device_t devpwr;
-
- // to do: use the pcibios_find function here, instead of
- // hard coding the devfn.
- // done - kevinh/Ispiri
- printk_debug("vt8231 init\n");
- /* Base 8231 controller */
- dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
- /* IDE controller */
- dev1 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, \
- 0);
- /* Power management controller */
- devpwr = dev_find_device(PCI_VENDOR_ID_VIA, \
- PCI_DEVICE_ID_VIA_8231_4, 0);
-
- // enable the internal I/O decode
- enables = pci_read_config8(dev0, 0x6C);
- enables |= 0x80;
- pci_write_config8(dev0, 0x6C, enables);
-
- // Map 4MB of FLASH into the address space
- pci_write_config8(dev0, 0x41, 0x7f);
-
- // Set bit 6 of 0x40, because Award does it (IO recovery time)
- // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
- // interrupts can be properly marked as level triggered.
- enables = pci_read_config8(dev0, 0x40);
- pci_write_config8(dev0, 0x40, enables);
-
- // Set 0x42 to 0xf0 to match Award bios
- enables = pci_read_config8(dev0, 0x42);
- enables |= 0xf0;
- pci_write_config8(dev0, 0x42, enables);
-
- // Set bit 3 of 0x4a, to match award (dummy pci request)
- enables = pci_read_config8(dev0, 0x4a);
- enables |= 0x08;
- pci_write_config8(dev0, 0x4a, enables);
-
- // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
- enables = pci_read_config8(dev0, 0x4f);
- enables |= 0x08;
- pci_write_config8(dev0, 0x4f, enables);
-
- // Set 0x58 to 0x03 to match Award
- pci_write_config8(dev0, 0x58, 0x03);
-
- // enable the ethernet/RTC
- if(dev0) {
- enables = pci_read_config8(dev0, 0x51);
- enables |= 0x18;
- pci_write_config8(dev0, 0x51, enables);
- }
-
-
- // enable com1 and com2.
- if (conf->enable_com_ports) {
- enables = pci_read_config8(dev0, 0x6e);
-
- /* 0x80 is enable com port b, 0x10 is to make it com2, 0x8
- * is enable com port a as com1 kevinh/Ispiri - Old code
- * thought 0x01 would make it com1, that was wrong enables =
- * 0x80 | 0x10 | 0x8 ; pci_write_config8(dev0, 0x6e,
- * enables); // note: this is also a redo of some port of
- * assembly, but we want everything up.
- */
-
- /* set com1 to 115 kbaud not clear how to do this yet.
- * forget it; done in assembly.
- */
-
- }
- // enable IDE, since Linux won't do it.
- // First do some more things to devfn (17,0)
- // note: this should already be cleared, according to the book.
- enables = pci_read_config8(dev0, 0x50);
- printk_debug("IDE enable in reg. 50 is 0x%x\n", enables);
- enables &= ~8; // need manifest constant here!
- printk_debug("set IDE reg. 50 to 0x%x\n", enables);
- pci_write_config8(dev0, 0x50, enables);
-
- // set default interrupt values (IDE)
- enables = pci_read_config8(dev0, 0x4c);
- printk_debug("IRQs in reg. 4c are 0x%x\n", enables & 0xf);
- // clear out whatever was there.
- enables &= ~0xf;
- enables |= 4;
- printk_debug("setting reg. 4c to 0x%x\n", enables);
- pci_write_config8(dev0, 0x4c, enables);
-
- // set up the serial port interrupts.
- // com2 to 3, com1 to 4
- pci_write_config8(dev0, 0x46, 0x04);
- pci_write_config8(dev0, 0x47, 0x03);
- pci_write_config8(dev0, 0x6e, 0x98);
- //
- // Power management setup
- //
- // Set ACPI base address to IO 0x4000
- pci_write_config32(devpwr, 0x48, 0x4001);
-
- // Enable ACPI access (and setup like award)
- pci_write_config8(devpwr, 0x41, 0x84);
-
- // Set hardware monitor base address to IO 0x6000
- pci_write_config32(devpwr, 0x70, 0x6001);
-
- // Enable hardware monitor (and setup like award)
- pci_write_config8(devpwr, 0x74, 0x01);
-
- // set IO base address to 0x5000
- pci_write_config32(devpwr, 0x90, 0x5001);
-
- // Enable SMBus
- pci_write_config8(devpwr, 0xd2, 0x01);
-
- //
- // IDE setup
- //
- if (conf->enable_native_ide) {
- // Run the IDE controller in 'compatiblity mode - i.e. don't use PCI
- // interrupts. Using PCI ints confuses linux for some reason.
-
- printk_info("%s: enabling native IDE addresses\n", __FUNCTION__);
- enables = pci_read_config8(dev1, 0x42);
- printk_debug("enables in reg 0x42 0x%x\n", enables);
- enables &= ~0xc0; // compatability mode
- pci_write_config8(dev1, 0x42, enables);
- enables = pci_read_config8(dev1, 0x42);
- printk_debug("enables in reg 0x42 read back as 0x%x\n", enables);
- }
-
- enables = pci_read_config8(dev1, 0x40);
- printk_debug("enables in reg 0x40 0x%x\n", enables);
- enables |= 3;
- pci_write_config8(dev1, 0x40, enables);
- enables = pci_read_config8(dev1, 0x40);
- printk_debug("enables in reg 0x40 read back as 0x%x\n", enables);
-
- // Enable prefetch buffers
- enables = pci_read_config8(dev1, 0x41);
- enables |= 0xf0;
- pci_write_config8(dev1, 0x41, enables);
-
- // Lower thresholds (cause award does it)
- enables = pci_read_config8(dev1, 0x43);
- enables &= ~0x0f;
- enables |= 0x05;
- pci_write_config8(dev1, 0x43, enables);
-
- // PIO read prefetch counter (cause award does it)
- pci_write_config8(dev1, 0x44, 0x18);
-
- // Use memory read multiple
- pci_write_config8(dev1, 0x45, 0x1c);
-
- // address decoding.
- // we want "flexible", i.e. 1f0-1f7 etc. or native PCI
- // kevinh@ispiri.com - the standard linux drivers seem ass slow when
- // used in native mode - I've changed back to classic
- enables = pci_read_config8(dev1, 0x9);
- printk_debug("enables in reg 0x9 0x%x\n", enables);
- // by the book, set the low-order nibble to 0xa.
- if (conf->enable_native_ide) {
- enables &= ~0xf;
- // cf/cg silicon needs an 'f' here.
- enables |= 0xf;
- } else {
- enables &= ~0x5;
- }
-
- pci_write_config8(dev1, 0x9, enables);
- enables = pci_read_config8(dev1, 0x9);
- printk_debug("enables in reg 0x9 read back as 0x%x\n", enables);
-
- // standard bios sets master bit.
- enables = pci_read_config8(dev1, 0x4);
- printk_debug("command in reg 0x4 0x%x\n", enables);
- enables |= 7;
-
- // No need for stepping - kevinh@ispiri.com
- enables &= ~0x80;
-
- pci_write_config8(dev1, 0x4, enables);
- enables = pci_read_config8(dev1, 0x4);
- printk_debug("command in reg 0x4 reads back as 0x%x\n", enables);
-
- if (! conf->enable_native_ide) {
- // Use compatability mode - per award bios
- pci_write_config32(dev1, 0x10, 0x0);
- pci_write_config32(dev1, 0x14, 0x0);
- pci_write_config32(dev1, 0x18, 0x0);
- pci_write_config32(dev1, 0x1c, 0x0);
-
- // Force interrupts to use compat mode - just like Award bios
- pci_write_config8(dev1, 0x3d, 00);
- pci_write_config8(dev1, 0x3c, 0xff);
- }
-
-
- /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
- pci_write_config8(dev0, 0x40, 0x54);
- ethernet_fixup();
-
- // Start the rtc
- rtc_init(0);
+ unsigned char enables;
+ device_t dev0;
+ device_t dev1;
+ device_t devpwr;
+
+ // to do: use the pcibios_find function here, instead of
+ // hard coding the devfn.
+ // done - kevinh/Ispiri
+ printk_debug("vt8231 init\n");
+ /* Base 8231 controller */
+ dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
+ /* IDE controller */
+ dev1 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, 0);
+ /* Power management controller */
+ devpwr = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4, 0);
+
+ // enable the internal I/O decode
+ enables = pci_read_config8(dev0, 0x6C);
+ enables |= 0x80;
+ pci_write_config8(dev0, 0x6C, enables);
+
+ // Map 4MB of FLASH into the address space
+ pci_write_config8(dev0, 0x41, 0x7f);
+
+ // Set bit 6 of 0x40, because Award does it (IO recovery time)
+ // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
+ // interrupts can be properly marked as level triggered.
+ enables = pci_read_config8(dev0, 0x40);
+ pci_write_config8(dev0, 0x40, enables);
+
+ // Set 0x42 to 0xf0 to match Award bios
+ enables = pci_read_config8(dev0, 0x42);
+ enables |= 0xf0;
+ pci_write_config8(dev0, 0x42, enables);
+
+ // Set bit 3 of 0x4a, to match award (dummy pci request)
+ enables = pci_read_config8(dev0, 0x4a);
+ enables |= 0x08;
+ pci_write_config8(dev0, 0x4a, enables);
+
+ // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
+ enables = pci_read_config8(dev0, 0x4f);
+ enables |= 0x08;
+ pci_write_config8(dev0, 0x4f, enables);
+
+ // Set 0x58 to 0x03 to match Award
+ pci_write_config8(dev0, 0x58, 0x03);
+
+ // enable the ethernet/RTC
+ if(dev0) {
+ enables = pci_read_config8(dev0, 0x51);
+ enables |= 0x18;
+ pci_write_config8(dev0, 0x51, enables);
+ }
+
+
+ // enable com1 and com2.
+ if (conf->enable_com_ports) {
+ enables = pci_read_config8(dev0, 0x6e);
+
+ /* 0x80 is enable com port b, 0x10 is to make it com2, 0x8
+ * is enable com port a as com1 kevinh/Ispiri - Old code
+ * thought 0x01 would make it com1, that was wrong enables =
+ * 0x80 | 0x10 | 0x8 ; pci_write_config8(dev0, 0x6e,
+ * enables); // note: this is also a redo of some port of
+ * assembly, but we want everything up.
+ */
+
+ /* set com1 to 115 kbaud not clear how to do this yet.
+ * forget it; done in assembly.
+ */
+
+ }
+ // enable IDE, since Linux won't do it.
+ // First do some more things to devfn (17,0)
+ // note: this should already be cleared, according to the book.
+ enables = pci_read_config8(dev0, 0x50);
+ printk_debug("IDE enable in reg. 50 is 0x%x\n", enables);
+ enables &= ~8; // need manifest constant here!
+ printk_debug("set IDE reg. 50 to 0x%x\n", enables);
+ pci_write_config8(dev0, 0x50, enables);
+
+ // set default interrupt values (IDE)
+ enables = pci_read_config8(dev0, 0x4c);
+ printk_debug("IRQs in reg. 4c are 0x%x\n", enables & 0xf);
+ // clear out whatever was there.
+ enables &= ~0xf;
+ enables |= 4;
+ printk_debug("setting reg. 4c to 0x%x\n", enables);
+ pci_write_config8(dev0, 0x4c, enables);
+
+ // set up the serial port interrupts.
+ // com2 to 3, com1 to 4
+ pci_write_config8(dev0, 0x46, 0x04);
+ pci_write_config8(dev0, 0x47, 0x03);
+ pci_write_config8(dev0, 0x6e, 0x98);
+ //
+ // Power management setup
+ //
+ // Set ACPI base address to IO 0x4000
+ pci_write_config32(devpwr, 0x48, 0x4001);
+
+ // Enable ACPI access (and setup like award)
+ pci_write_config8(devpwr, 0x41, 0x84);
+
+ // Set hardware monitor base address to IO 0x6000
+ pci_write_config32(devpwr, 0x70, 0x6001);
+
+ // Enable hardware monitor (and setup like award)
+ pci_write_config8(devpwr, 0x74, 0x01);
+
+ // set IO base address to 0x5000
+ pci_write_config32(devpwr, 0x90, 0x5001);
+
+ // Enable SMBus
+ pci_write_config8(devpwr, 0xd2, 0x01);
+
+ //
+ // IDE setup
+ //
+ if (conf->enable_native_ide) {
+ // Run the IDE controller in 'compatiblity mode - i.e. don't use PCI
+ // interrupts. Using PCI ints confuses linux for some reason.
+
+ printk_info("%s: enabling native IDE addresses\n", __FUNCTION__);
+ enables = pci_read_config8(dev1, 0x42);
+ printk_debug("enables in reg 0x42 0x%x\n", enables);
+ enables &= ~0xc0; // compatability mode
+ pci_write_config8(dev1, 0x42, enables);
+ enables = pci_read_config8(dev1, 0x42);
+ printk_debug("enables in reg 0x42 read back as 0x%x\n", enables);
+ }
+
+ enables = pci_read_config8(dev1, 0x40);
+ printk_debug("enables in reg 0x40 0x%x\n", enables);
+ enables |= 3;
+ pci_write_config8(dev1, 0x40, enables);
+ enables = pci_read_config8(dev1, 0x40);
+ printk_debug("enables in reg 0x40 read back as 0x%x\n", enables);
+
+ // Enable prefetch buffers
+ enables = pci_read_config8(dev1, 0x41);
+ enables |= 0xf0;
+ pci_write_config8(dev1, 0x41, enables);
+
+ // Lower thresholds (cause award does it)
+ enables = pci_read_config8(dev1, 0x43);
+ enables &= ~0x0f;
+ enables |= 0x05;
+ pci_write_config8(dev1, 0x43, enables);
+
+ // PIO read prefetch counter (cause award does it)
+ pci_write_config8(dev1, 0x44, 0x18);
+
+ // Use memory read multiple
+ pci_write_config8(dev1, 0x45, 0x1c);
+
+ // address decoding.
+ // we want "flexible", i.e. 1f0-1f7 etc. or native PCI
+ // kevinh@ispiri.com - the standard linux drivers seem ass slow when
+ // used in native mode - I've changed back to classic
+ enables = pci_read_config8(dev1, 0x9);
+ printk_debug("enables in reg 0x9 0x%x\n", enables);
+ // by the book, set the low-order nibble to 0xa.
+ if (conf->enable_native_ide) {
+ enables &= ~0xf;
+ // cf/cg silicon needs an 'f' here.
+ enables |= 0xf;
+ } else {
+ enables &= ~0x5;
+ }
+
+ pci_write_config8(dev1, 0x9, enables);
+ enables = pci_read_config8(dev1, 0x9);
+ printk_debug("enables in reg 0x9 read back as 0x%x\n", enables);
+
+ // standard bios sets master bit.
+ enables = pci_read_config8(dev1, 0x4);
+ printk_debug("command in reg 0x4 0x%x\n", enables);
+ enables |= 7;
+
+ // No need for stepping - kevinh@ispiri.com
+ enables &= ~0x80;
+
+ pci_write_config8(dev1, 0x4, enables);
+ enables = pci_read_config8(dev1, 0x4);
+ printk_debug("command in reg 0x4 reads back as 0x%x\n", enables);
+
+ if (! conf->enable_native_ide) {
+ // Use compatability mode - per award bios
+ pci_write_config32(dev1, 0x10, 0x0);
+ pci_write_config32(dev1, 0x14, 0x0);
+ pci_write_config32(dev1, 0x18, 0x0);
+ pci_write_config32(dev1, 0x1c, 0x0);
+
+ // Force interrupts to use compat mode - just like Award bios
+ pci_write_config8(dev1, 0x3d, 00);
+ pci_write_config8(dev1, 0x3c, 0xff);
+ }
+
+
+ /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
+ pci_write_config8(dev0, 0x40, 0x54);
+ ethernet_fixup();
+
+ // Start the rtc
+ rtc_init(0);
}
-static void
-southbridge_init(struct chip *chip, enum chip_pass pass)
+static void southbridge_init(struct chip *chip, enum chip_pass pass)
{
- struct southbridge_via_vt8231_config *conf =
- (struct southbridge_via_vt8231_config *)chip->chip_info;
-
- switch (pass) {
- case CONF_PASS_PRE_PCI:
- vt8231_pci_enable(conf);
- break;
-
- case CONF_PASS_POST_PCI:
- vt8231_init(conf);
- printk_err("FUCK! ROUTING FIXUP!\n");
- pci_routing_fixup();
-
- break;
- case CONF_PASS_PRE_BOOT:
- pci_routing_fixup();
- dump_south();
- break;
-
- default:
- /* nothing yet */
- break;
- }
+ struct southbridge_via_vt8231_config *conf =
+ (struct southbridge_via_vt8231_config *)chip->chip_info;
+
+ switch (pass) {
+ case CONF_PASS_PRE_PCI:
+ vt8231_pci_enable(conf);
+ break;
+
+ case CONF_PASS_POST_PCI:
+ vt8231_init(conf);
+ printk_err("FUCK! ROUTING FIXUP!\n");
+ pci_routing_fixup();
+
+ break;
+ case CONF_PASS_PRE_BOOT:
+ pci_routing_fixup();
+ dump_south();
+ break;
+
+ default:
+ /* nothing yet */
+ break;
+ }
}
static void enumerate(struct chip *chip)
@@ -468,7 +460,7 @@ static void enumerate(struct chip *chip)
}
struct chip_control southbridge_via_vt8231_control = {
- .enumerate = enumerate,
- enable: southbridge_init,
- name: "VIA vt8231"
+ .enumerate = enumerate,
+ .enable = southbridge_init,
+ .name = "VIA vt8231"
};
diff --git a/src/southbridge/via/vt8231/vt8231_early_serial.c b/src/southbridge/via/vt8231/vt8231_early_serial.c
index ca7831df42..1bfffed7f5 100644
--- a/src/southbridge/via/vt8231/vt8231_early_serial.c
+++ b/src/southbridge/via/vt8231/vt8231_early_serial.c
@@ -8,20 +8,20 @@
#define SIO_BASE 0x3f0
#define SIO_DATA SIO_BASE+1
-static void
-vt8231_writesuper(uint8_t reg, uint8_t val) {
- outb(reg, SIO_BASE);
- outb(val, SIO_DATA);
+static void vt8231_writesuper(uint8_t reg, uint8_t val)
+{
+ outb(reg, SIO_BASE);
+ outb(val, SIO_DATA);
}
-static void
-vt8231_writesiobyte(uint16_t reg, uint8_t val) {
- outb(val, reg);
+static void vt8231_writesiobyte(uint16_t reg, uint8_t val)
+{
+ outb(val, reg);
}
-static void
-vt8231_writesioword(uint16_t reg, uint16_t val) {
- outw(val, reg);
+static void vt8231_writesioword(uint16_t reg, uint16_t val)
+{
+ outw(val, reg);
}
@@ -29,48 +29,47 @@ vt8231_writesioword(uint16_t reg, uint16_t val) {
mainboard
*/
-static void
-enable_vt8231_serial(void) {
- unsigned long x;
- uint8_t c;
- device_t dev;
- outb(6, 0x80);
- dev = pci_locate_device(PCI_ID(0x1106,0x8231), 0);
-
- if (dev == PCI_DEV_INVALID) {
- outb(7, 0x80);
- die("Serial controller not found\r\n");
- }
-
- /* first, you have to enable the superio and superio config.
- put a 6 reg 80
- */
- c = pci_read_config8(dev, 0x50);
- c |= 6;
- pci_write_config8(dev, 0x50, c);
- outb(2, 0x80);
- // now go ahead and set up com1.
- // set address
- vt8231_writesuper(0xf4, 0xfe);
- // enable serial out
- vt8231_writesuper(0xf2, 7);
- // That's it for the sio stuff.
- // movl $SUPERIOCONFIG, %eax
- // movb $9, %dl
- // PCI_WRITE_CONFIG_BYTE
- // set up reg to set baud rate.
- vt8231_writesiobyte(0x3fb, 0x80);
- // Set 115 kb
- vt8231_writesioword(0x3f8, 1);
- // Set 9.6 kb
- // WRITESIOWORD(0x3f8, 12)
- // now set no parity, one stop, 8 bits
- vt8231_writesiobyte(0x3fb, 3);
- // now turn on RTS, DRT
- vt8231_writesiobyte(0x3fc, 3);
- // Enable interrupts
- vt8231_writesiobyte(0x3f9, 0xf);
- // should be done. Dump a char for fun.
- vt8231_writesiobyte(0x3f8, 48);
-
+static void enable_vt8231_serial(void)
+{
+ unsigned long x;
+ uint8_t c;
+ device_t dev;
+ outb(6, 0x80);
+ dev = pci_locate_device(PCI_ID(0x1106,0x8231), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ outb(7, 0x80);
+ die("Serial controller not found\r\n");
+ }
+
+ /* first, you have to enable the superio and superio config.
+ put a 6 reg 80
+ */
+ c = pci_read_config8(dev, 0x50);
+ c |= 6;
+ pci_write_config8(dev, 0x50, c);
+ outb(2, 0x80);
+ // now go ahead and set up com1.
+ // set address
+ vt8231_writesuper(0xf4, 0xfe);
+ // enable serial out
+ vt8231_writesuper(0xf2, 7);
+ // That's it for the sio stuff.
+ // movl $SUPERIOCONFIG, %eax
+ // movb $9, %dl
+ // PCI_WRITE_CONFIG_BYTE
+ // set up reg to set baud rate.
+ vt8231_writesiobyte(0x3fb, 0x80);
+ // Set 115 kb
+ vt8231_writesioword(0x3f8, 1);
+ // Set 9.6 kb
+ // WRITESIOWORD(0x3f8, 12)
+ // now set no parity, one stop, 8 bits
+ vt8231_writesiobyte(0x3fb, 3);
+ // now turn on RTS, DRT
+ vt8231_writesiobyte(0x3fc, 3);
+ // Enable interrupts
+ vt8231_writesiobyte(0x3f9, 0xf);
+ // should be done. Dump a char for fun.
+ vt8231_writesiobyte(0x3f8, 48);
}
diff --git a/src/southbridge/via/vt8231/vt8231_early_smbus.c b/src/southbridge/via/vt8231/vt8231_early_smbus.c
index 49b942cb23..e419d59b63 100644
--- a/src/southbridge/via/vt8231/vt8231_early_smbus.c
+++ b/src/southbridge/via/vt8231/vt8231_early_smbus.c
@@ -24,115 +24,115 @@
static void enable_smbus(void)
{
- device_t dev;
- unsigned char c;
- /* Power management controller */
- dev = pci_locate_device(PCI_ID(0x1106,0x8235), 0);
-
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\r\n");
- }
-
- // set IO base address to SMBUS_IO_BASE
- pci_write_config32(dev, 0x90, SMBUS_IO_BASE|1);
-
- // Enable SMBus
- c = pci_read_config8(dev, 0xd2);
- c |= 5;
- pci_write_config8(dev, 0xd2, c);
-
- /* make it work for I/O ...
- */
- dev = pci_locate_device(PCI_ID(0x1106,0x8231), 0);
- c = pci_read_config8(dev, 4);
- c |= 1;
- pci_write_config8(dev, 4, c);
- print_err_hex8(c);
- print_err(" is the comm register\n");
-
- print_debug("SMBus controller enabled\r\n");
+ device_t dev;
+ unsigned char c;
+ /* Power management controller */
+ dev = pci_locate_device(PCI_ID(0x1106,0x8235), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\r\n");
+ }
+
+ // set IO base address to SMBUS_IO_BASE
+ pci_write_config32(dev, 0x90, SMBUS_IO_BASE|1);
+
+ // Enable SMBus
+ c = pci_read_config8(dev, 0xd2);
+ c |= 5;
+ pci_write_config8(dev, 0xd2, c);
+
+ /* make it work for I/O ...
+ */
+ dev = pci_locate_device(PCI_ID(0x1106,0x8231), 0);
+ c = pci_read_config8(dev, 4);
+ c |= 1;
+ pci_write_config8(dev, 4, c);
+ print_err_hex8(c);
+ print_err(" is the comm register\n");
+
+ print_debug("SMBus controller enabled\r\n");
}
static inline void smbus_delay(void)
{
- outb(0x80, 0x80);
+ outb(0x80, 0x80);
}
static int smbus_wait_until_ready(void)
{
unsigned char c;
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- c = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- while((c & 1) == 1) {
- print_err("c is ");
- print_err_hex8(c);
- print_err("\n");
- c = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- /* nop */
- }
-
- } while(--loops);
- return loops?0:-1;
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ c = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ while((c & 1) == 1) {
+ print_err("c is ");
+ print_err_hex8(c);
+ print_err("\n");
+ c = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ /* nop */
+ }
+
+ } while(--loops);
+ return loops?0:-1;
}
void smbus_reset(void)
{
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
-
- smbus_wait_until_ready();
- print_err("After reset status ");
- print_err_hex8( inb(SMBUS_IO_BASE + SMBHSTSTAT));
- print_err("\n");
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+
+ smbus_wait_until_ready();
+ print_err("After reset status ");
+ print_err_hex8( inb(SMBUS_IO_BASE + SMBHSTSTAT));
+ print_err("\n");
}
static int smbus_wait_until_done(void)
{
- unsigned long loops;
- unsigned char byte;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
+ unsigned long loops;
+ unsigned char byte;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
- byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if (byte & 1)
- break;
-
- } while(--loops);
- return loops?0:-1;
+ byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if (byte & 1)
+ break;
+
+ } while(--loops);
+ return loops?0:-1;
}
static void smbus_print_error(unsigned char host_status_register)
{
- print_err("smbus_error: ");
- print_err_hex8(host_status_register);
- print_err("\n");
- if (host_status_register & (1 << 4)) {
- print_err("Interrup/SMI# was Failed Bus Transaction\n");
- }
- if (host_status_register & (1 << 3)) {
- print_err("Bus Error\n");
- }
- if (host_status_register & (1 << 2)) {
- print_err("Device Error\n");
- }
- if (host_status_register & (1 << 1)) {
- print_err("Interrupt/SMI# was Successful Completion\n");
- }
- if (host_status_register & (1 << 0)) {
- print_err("Host Busy\n");
- }
+ print_err("smbus_error: ");
+ print_err_hex8(host_status_register);
+ print_err("\n");
+ if (host_status_register & (1 << 4)) {
+ print_err("Interrup/SMI# was Failed Bus Transaction\n");
+ }
+ if (host_status_register & (1 << 3)) {
+ print_err("Bus Error\n");
+ }
+ if (host_status_register & (1 << 2)) {
+ print_err("Device Error\n");
+ }
+ if (host_status_register & (1 << 1)) {
+ print_err("Interrupt/SMI# was Successful Completion\n");
+ }
+ if (host_status_register & (1 << 0)) {
+ print_err("Host Busy\n");
+ }
}
@@ -141,39 +141,39 @@ static void smbus_print_error(unsigned char host_status_register)
static unsigned char smbus_read_byte(unsigned char devAdr,
unsigned char bIndex)
{
- unsigned short i;
- unsigned char bData;
- unsigned char sts = 0;
-
- /* clear host status */
- outb(0xff, SMBUS_IO_BASE);
-
- /* check SMBUS ready */
- for ( i = 0; i < 0xFFFF; i++ )
- if ( (inb(SMBUS_IO_BASE) & 0x01) == 0 )
- break;
-
- /* set host command */
- outb(bIndex, SMBUS_IO_BASE+3);
-
- /* set slave address */
- outb(devAdr | 0x01, SMBUS_IO_BASE+4);
-
- /* start */
- outb(0x48, SMBUS_IO_BASE+2);
-
- /* SMBUS Wait Ready */
- for ( i = 0; i < 0xFFFF; i++ )
- if ( ((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0 )
- break;
- if ((sts & ~3) != 0) {
- smbus_print_error(sts);
- return 0;
- }
- bData=inb(SMBUS_IO_BASE+5);
-
- return bData;
-
+ unsigned short i;
+ unsigned char bData;
+ unsigned char sts = 0;
+
+ /* clear host status */
+ outb(0xff, SMBUS_IO_BASE);
+
+ /* check SMBUS ready */
+ for ( i = 0; i < 0xFFFF; i++ )
+ if ( (inb(SMBUS_IO_BASE) & 0x01) == 0 )
+ break;
+
+ /* set host command */
+ outb(bIndex, SMBUS_IO_BASE+3);
+
+ /* set slave address */
+ outb(devAdr | 0x01, SMBUS_IO_BASE+4);
+
+ /* start */
+ outb(0x48, SMBUS_IO_BASE+2);
+
+ /* SMBUS Wait Ready */
+ for ( i = 0; i < 0xFFFF; i++ )
+ if ( ((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0 )
+ break;
+ if ((sts & ~3) != 0) {
+ smbus_print_error(sts);
+ return 0;
+ }
+ bData=inb(SMBUS_IO_BASE+5);
+
+ return bData;
+
}
/* for reference, here is the fancier version which we will use at some
@@ -182,48 +182,48 @@ static unsigned char smbus_read_byte(unsigned char devAdr,
# if 0
int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
{
- unsigned char host_status_register;
- unsigned char byte;
-
- reset();
-
- smbus_wait_until_ready();
-
- /* setup transaction */
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2),
- SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* clear the data byte...*/
- outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* start the command */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
- SMBUS_IO_BASE + SMBHSTCTL);
-
- /* poll for transaction completion */
- smbus_wait_until_done();
-
- host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* Ignore the In Use Status... */
- host_status_register &= ~(1 << 6);
-
- /* read results of transaction */
- byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
- smbus_print_error(byte);
-
- *result = byte;
- return host_status_register != 0x02;
+ unsigned char host_status_register;
+ unsigned char byte;
+
+ reset();
+
+ smbus_wait_until_ready();
+
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2),
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* clear the data byte...*/
+ outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ smbus_wait_until_done();
+
+ host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* Ignore the In Use Status... */
+ host_status_register &= ~(1 << 6);
+
+ /* read results of transaction */
+ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+ smbus_print_error(byte);
+
+ *result = byte;
+ return host_status_register != 0x02;
}
diff --git a/src/superio/NSC/pc87360/chip.h b/src/superio/NSC/pc87360/chip.h
index 24bf65061f..55787566fc 100644
--- a/src/superio/NSC/pc87360/chip.h
+++ b/src/superio/NSC/pc87360/chip.h
@@ -14,7 +14,7 @@
extern struct chip_control superio_NSC_pc87360_control;
struct superio_NSC_pc87360_config {
- struct com_ports com1;
- struct lpt_ports lpt;
- int port;
+ struct com_ports com1;
+ struct lpt_ports lpt;
+ int port;
};
diff --git a/src/superio/NSC/pc87360/superio.c b/src/superio/NSC/pc87360/superio.c
index 0ec41c3346..8765eb35cc 100644
--- a/src/superio/NSC/pc87360/superio.c
+++ b/src/superio/NSC/pc87360/superio.c
@@ -305,7 +305,16 @@ static void enumerate(struct chip *chip)
resource->base = conf->com1.irq;
resource->flags = IORESOURCE_IRQ | IORESOURCE_FIXED | IORESOURCE_SET;
}
-
+
+ /* Process the hard codes for the keyboard controller */
+ path.u.pnp.device = KBC_DEVICE;
+ dev = alloc_find_dev(dev, &path);
+ resource = get_resource(dev, 0x60);
+ resource->base = 0x60;
+ resource->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_SET;
+ resource = get_resource(dev, 0x62);
+ resource->base = 0x64;
+ resource->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_SET;
}
struct chip_control superio_NSC_pc87360_control = {