summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config/Options.lb13
-rw-r--r--src/devices/device_util.c26
-rw-r--r--src/devices/emulator/biosemu.c7
-rw-r--r--src/devices/hypertransport.c28
-rw-r--r--src/devices/pci_device.c1
-rw-r--r--src/devices/root_device.c6
-rw-r--r--src/include/device/device.h2
-rw-r--r--src/include/device/pci_ids.h20
-rw-r--r--src/mainboard/tyan/s2891/Config.lb287
-rw-r--r--src/mainboard/tyan/s2891/Options.lb236
-rw-r--r--src/mainboard/tyan/s2891/auto.c164
-rw-r--r--src/mainboard/tyan/s2891/chip.h6
-rw-r--r--src/mainboard/tyan/s2891/cmos.layout98
-rw-r--r--src/mainboard/tyan/s2891/failover.c104
-rw-r--r--src/mainboard/tyan/s2891/irq_tables.c35
-rw-r--r--src/mainboard/tyan/s2891/mainboard.c12
-rw-r--r--src/mainboard/tyan/s2891/mptable.c252
-rw-r--r--src/mainboard/tyan/s2891/resourcemap.c273
-rw-r--r--src/mainboard/tyan/s2895/Config.lb318
-rw-r--r--src/mainboard/tyan/s2895/Options.lb237
-rw-r--r--src/mainboard/tyan/s2895/auto.c223
-rw-r--r--src/mainboard/tyan/s2895/chip.h6
-rw-r--r--src/mainboard/tyan/s2895/cmos.layout98
-rw-r--r--src/mainboard/tyan/s2895/failover.c118
-rw-r--r--src/mainboard/tyan/s2895/irq_tables.c39
-rw-r--r--src/mainboard/tyan/s2895/mainboard.c12
-rw-r--r--src/mainboard/tyan/s2895/mptable.c298
-rw-r--r--src/mainboard/tyan/s2895/resourcemap.c267
-rw-r--r--src/northbridge/amd/amdk8/early_ht.c25
-rw-r--r--src/northbridge/amd/amdk8/incoherent_ht.c111
-rw-r--r--src/northbridge/amd/amdk8/setup_resource_map.c196
-rw-r--r--src/southbridge/nvidia/ck804/Config.lb14
-rw-r--r--src/southbridge/nvidia/ck804/chip.h18
-rw-r--r--src/southbridge/nvidia/ck804/ck804.c197
-rw-r--r--src/southbridge/nvidia/ck804/ck804.h8
-rw-r--r--src/southbridge/nvidia/ck804/ck804_ac97.c53
-rw-r--r--src/southbridge/nvidia/ck804/ck804_early_setup.c345
-rw-r--r--src/southbridge/nvidia/ck804/ck804_early_setup_ss.h206
-rw-r--r--src/southbridge/nvidia/ck804/ck804_early_smbus.c34
-rw-r--r--src/southbridge/nvidia/ck804/ck804_enable_rom.c19
-rw-r--r--src/southbridge/nvidia/ck804/ck804_ht.c35
-rw-r--r--src/southbridge/nvidia/ck804/ck804_ide.c78
-rw-r--r--src/southbridge/nvidia/ck804/ck804_lpc.c411
-rw-r--r--src/southbridge/nvidia/ck804/ck804_nic.c115
-rw-r--r--src/southbridge/nvidia/ck804/ck804_pci.c64
-rw-r--r--src/southbridge/nvidia/ck804/ck804_pcie.c46
-rw-r--r--src/southbridge/nvidia/ck804/ck804_reset.c40
-rw-r--r--src/southbridge/nvidia/ck804/ck804_sata.c176
-rw-r--r--src/southbridge/nvidia/ck804/ck804_smbus.c102
-rw-r--r--src/southbridge/nvidia/ck804/ck804_smbus.h202
-rw-r--r--src/southbridge/nvidia/ck804/ck804_usb.c36
-rw-r--r--src/southbridge/nvidia/ck804/ck804_usb2.c44
-rw-r--r--src/southbridge/nvidia/ck804/id.inc16
-rw-r--r--src/southbridge/nvidia/ck804/id.lds6
-rw-r--r--src/southbridge/nvidia/ck804/romstrap.inc42
-rw-r--r--src/southbridge/nvidia/ck804/romstrap.lds6
-rw-r--r--src/superio/smsc/lpc47b397/Config.lb2
-rw-r--r--src/superio/smsc/lpc47b397/chip.h17
-rw-r--r--src/superio/smsc/lpc47b397/lpc47b397.h7
-rw-r--r--src/superio/smsc/lpc47b397/lpc47b397_early_gpio.c25
-rw-r--r--src/superio/smsc/lpc47b397/lpc47b397_early_serial.c20
-rw-r--r--src/superio/smsc/lpc47b397/superio.c244
62 files changed, 6104 insertions, 42 deletions
diff --git a/src/config/Options.lb b/src/config/Options.lb
index fb8e2efc1e..35a3151b52 100644
--- a/src/config/Options.lb
+++ b/src/config/Options.lb
@@ -763,12 +763,19 @@ define AGP_APERTURE_SIZE
comment "AGP graphics virtual memory aperture size"
end
+define CK804_DEVN_BASE
+ default 1
+ export always
+ comment "CK804 device count from 0 or 1"
+end
+
define CONFIG_PCI_ROM_RUN
- default 0
- export always
- comment "Init PCI device option rom"
+ default 0
+ export always
+ comment "Init PCI device option rom"
end
+
###############################################
# Board specific options
###############################################
diff --git a/src/devices/device_util.c b/src/devices/device_util.c
index ff2d90ce6e..a19a878b47 100644
--- a/src/devices/device_util.c
+++ b/src/devices/device_util.c
@@ -64,6 +64,29 @@ struct device *dev_find_slot(unsigned int bus, unsigned int devfn)
return result;
}
+/**
+ * @brief Given a smbus bus and a device number, find the device structure
+ *
+ * @param bus The bus number
+ * @param addr a device number
+ * @return pointer to the device structure
+ */
+struct device *dev_find_slot_on_smbus(unsigned int bus, unsigned int addr)
+{
+ struct device *dev, *result;
+
+ result = 0;
+ for (dev = all_devices; dev; dev = dev->next) {
+ if ((dev->path.type == DEVICE_PATH_I2C) &&
+ (dev->bus->secondary == bus) &&
+ (dev->path.u.i2c.device == addr)) {
+ result = dev;
+ break;
+ }
+ }
+ return result;
+}
+
/** Find a device of a given vendor and type
* @param vendor Vendor ID (e.g. 0x8086 for Intel)
* @param device Device ID
@@ -125,7 +148,8 @@ const char *dev_path(device_t dev)
dev->path.u.pnp.port, dev->path.u.pnp.device);
break;
case DEVICE_PATH_I2C:
- sprintf(buffer, "I2C: %02x",
+ sprintf(buffer, "I2C: %02x:%02x",
+ dev->bus->secondary,
dev->path.u.i2c.device);
break;
case DEVICE_PATH_APIC:
diff --git a/src/devices/emulator/biosemu.c b/src/devices/emulator/biosemu.c
index 59785fb229..85f10c648f 100644
--- a/src/devices/emulator/biosemu.c
+++ b/src/devices/emulator/biosemu.c
@@ -113,7 +113,7 @@ void do_int(int num)
{
int ret = 0;
- printk_debug("int%x vector at %x\n", num, getIntVect(num));
+// printk_debug("int%x vector at %x\n", num, getIntVect(num));
switch (num) {
#ifndef _PC
@@ -154,6 +154,7 @@ void do_int(int num)
ret = run_bios_int(num);
}
+#if 0
#define SYS_BIOS 0xf0000
/*
* here we are really paranoid about faking a "real"
@@ -270,7 +271,7 @@ void reset_int_vect(void)
MEM_WW(0x6D << 2, 0xf065);
MEM_WW((0x6D << 2) + 2, SYS_BIOS >> 4);
}
-
+#endif
void run_bios(struct device * dev, unsigned long addr)
{
#if 1
@@ -322,7 +323,7 @@ void run_bios(struct device * dev, unsigned long addr)
pushw(X86_SS);
pushw(X86_SP + 2);
- //X86EMU_trace_on();
+// X86EMU_trace_on();
X86EMU_exec();
#endif
diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c
index de5d132263..7bc1c215b8 100644
--- a/src/devices/hypertransport.c
+++ b/src/devices/hypertransport.c
@@ -200,6 +200,16 @@ static void ht_collapse_early_enumeration(struct bus *bus)
continue;
}
+#if 0
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+#endif
+
dummy.vendor = id & 0xffff;
dummy.device = (id >> 16) & 0xffff;
dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE);
@@ -312,8 +322,17 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
/* Update the Unitid of the current device */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
flags &= ~0x1f; /* mask out base Unit ID */
- flags |= next_unitid & 0x1f;
- pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
+#if CK804_DEVN_BASE==0
+ if(id == 0x005e10de) {
+ next_unitid = 0;
+ }
+ else {
+#endif
+ flags |= next_unitid & 0x1f;
+ pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
+#if CK804_DEVN_BASE==0
+ }
+#endif
/* Update the Unitd id in the device structure */
static_count = 1;
@@ -354,6 +373,11 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
dev_path(dev),
dev->vendor, dev->device,
(dev->enabled? "enabled": "disabled"), next_unitid);
+#if CK804_DEVN_BASE==0
+ if(id == 0x005e10de) {
+ break; // CK804 can not change unitid, so it only can be alone in the link
+ }
+#endif
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c
index 0ad4e55915..3f9a1cadae 100644
--- a/src/devices/pci_device.c
+++ b/src/devices/pci_device.c
@@ -832,6 +832,7 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devf
dev_path(dev));
dev->enabled = 0;
}
+ continue;
}
}
/* Read the rest of the pci configuration information */
diff --git a/src/devices/root_device.c b/src/devices/root_device.c
index 91c706e4b6..2bb4f0afe8 100644
--- a/src/devices/root_device.c
+++ b/src/devices/root_device.c
@@ -74,6 +74,7 @@ void root_dev_set_resources(device_t root)
* @param max Maximum bus number currently used before scanning.
* @return Largest bus number used after scanning.
*/
+static int smbus_max = 0;
unsigned int scan_static_bus(device_t root, unsigned int max)
{
device_t child;
@@ -82,6 +83,11 @@ unsigned int scan_static_bus(device_t root, unsigned int max)
printk_spew("%s for %s\n", __func__, dev_path(root));
for (link = 0; link < root->links; link++) {
+ /* for smbus bus enumerate */
+ child = root->link[link].children;
+ if(child && child->path.type == DEVICE_PATH_I2C) {
+ root->link[link].secondary = ++smbus_max;
+ }
for (child = root->link[link].children; child; child = child->sibling) {
if (child->chip_ops && child->chip_ops->enable_dev) {
child->chip_ops->enable_dev(child);
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 75e1189e03..be93f554fa 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -117,6 +117,8 @@ 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);
+device_t dev_find_slot_on_smbus (unsigned int bus, unsigned int addr);
+
/* Rounding for boundaries.
* Due to some chip bugs, go ahead and roung IO to 16
diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h
index 1e84629ce4..c0ccdd0fcd 100644
--- a/src/include/device/pci_ids.h
+++ b/src/include/device/pci_ids.h
@@ -417,8 +417,8 @@
#define PCI_DEVICE_ID_AMD_8111_IDE 0x7469
#define PCI_DEVICE_ID_AMD_8111_SMB 0x746a
#define PCI_DEVICE_ID_AMD_8111_ACPI 0x746b
+#define PCI_DEVICE_ID_AMD_8111_NIC 0x7462
-#define PCI_DEVICE_ID_AMD_8111_NIC 0x7462
#define PCI_DEVICE_ID_AMD_8111_USB2 0x7463
#define PCI_DEVICE_ID_AMD_8131_PCIX 0x7450
#define PCI_DEVICE_ID_AMD_8131_IOAPIC 0x7451
@@ -919,6 +919,24 @@
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202
#define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC 0x0203
+#define PCI_DEVICE_ID_NVIDIA_CK804_HT 0x005e
+#define PCI_DEVICE_ID_NVIDIA_CK804_LPC 0x0050
+#define PCI_DEVICE_ID_NVIDIA_CK804_PRO 0x0051
+#define PCI_DEVICE_ID_NVIDIA_CK804_SLAVE 0x00d3
+#define PCI_DEVICE_ID_NVIDIA_CK804_SM 0x0052
+#define PCI_DEVICE_ID_NVIDIA_CK804_ACPI 0x0052
+#define PCI_DEVICE_ID_NVIDIA_CK804_USB 0x005a
+#define PCI_DEVICE_ID_NVIDIA_CK804_USB2 0x005b
+#define PCI_DEVICE_ID_NVIDIA_CK804_NIC 0x0056
+#define PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE 0x0057
+#define PCI_DEVICE_ID_NVIDIA_CK804_ACI 0x0059
+#define PCI_DEVICE_ID_NVIDIA_CK804_MCI 0x0058
+#define PCI_DEVICE_ID_NVIDIA_CK804_IDE 0x0053
+#define PCI_DEVICE_ID_NVIDIA_CK804_SATA0 0x0054
+#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1 0x0055
+#define PCI_DEVICE_ID_NVIDIA_CK804_PCI 0x005c
+#define PCI_DEVICE_ID_NVIDIA_CK804_PCI_E 0x005d
+
#define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849
#define PCI_DEVICE_ID_IMS_TT128 0x9128
diff --git a/src/mainboard/tyan/s2891/Config.lb b/src/mainboard/tyan/s2891/Config.lb
new file mode 100644
index 0000000000..71d4f9341c
--- /dev/null
+++ b/src/mainboard/tyan/s2891/Config.lb
@@ -0,0 +1,287 @@
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+ default ROM_SECTION_SIZE = FALLBACK_SIZE
+ default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+ default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE )
+ default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+default CONFIG_ROM_STREAM = 1
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=65536
+default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+arch i386 end
+
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+
+#dir /drivers/ati/ragexl
+
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE object irq_tables.o end
+#object reset.o
+##
+## Romcc output
+##
+makerule ./failover.E
+ depends "$(MAINBOARD)/failover.c ./romcc"
+ action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+ depends "$(MAINBOARD)/failover.c ./romcc"
+ action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E
+ depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+ action "./romcc -E -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+makerule ./auto.inc
+ depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+ action "./romcc -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE
+ mainboardinit cpu/x86/16bit/reset16.inc
+ ldscript /cpu/x86/16bit/reset16.lds
+else
+ mainboardinit cpu/x86/32bit/reset32.inc
+ ldscript /cpu/x86/32bit/reset32.lds
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit southbridge/nvidia/ck804/id.inc
+ldscript /southbridge/nvidia/ck804/id.lds
+
+##
+## ROMSTRAP table for CK804
+##
+if USE_FALLBACK_IMAGE
+ mainboardinit southbridge/nvidia/ck804/romstrap.inc
+ ldscript /southbridge/nvidia/ck804/romstrap.lds
+end
+
+###
+### This is the early phase of linuxBIOS startup
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+ ldscript /arch/i386/lib/failover.lds
+ mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit cpu/x86/sse/enable_sse.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/sse/disable_sse.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+##
+## Include the secondary Configuration files
+##
+if CONFIG_CHIP_NAME
+ config chip.h
+end
+
+
+# sample config for tyan/s2891
+chip northbridge/amd/amdk8/root_complex
+ device apic_cluster 0 on
+ chip cpu/amd/socket_940
+ device apic 0 on end
+ end
+ end
+
+ device pci_domain 0 on
+ chip northbridge/amd/amdk8 #mc0
+ device pci 18.0 on # northbridge
+ # devices on link 0, link 0 == LDT 0
+ chip southbridge/nvidia/ck804
+ device pci 0.0 on end # HT
+ device pci 1.0 on # LPC
+ chip superio/winbond/w83627hf
+ device pnp 2e.0 on # Floppy
+ io 0x60 = 0x3f0
+ irq 0x70 = 6
+ drq 0x74 = 2
+ end
+ device pnp 2e.1 off # Parallel Port
+ io 0x60 = 0x378
+ irq 0x70 = 7
+ end
+ device pnp 2e.2 on # Com1
+ io 0x60 = 0x3f8
+ irq 0x70 = 4
+ end
+ device pnp 2e.3 on # Com2
+ io 0x60 = 0x2f8
+ irq 0x70 = 3
+ end
+ device pnp 2e.5 on # Keyboard
+ io 0x60 = 0x60
+ io 0x62 = 0x64
+ irq 0x70 = 1
+ irq 0x72 = 12
+ end
+ device pnp 2e.6 off # CIR
+ io 0x60 = 0x100
+ end
+ device pnp 2e.7 off # GAME_MIDI_GIPO1
+ io 0x60 = 0x220
+ io 0x62 = 0x300
+ irq 0x70 = 9
+ end
+ device pnp 2e.8 off end # GPIO2
+ device pnp 2e.9 off end # GPIO3
+ device pnp 2e.a off end # ACPI
+ device pnp 2e.b on # HW Monitor
+ io 0x60 = 0x290
+ irq 0x70 = 5
+ end
+ end
+ end
+ device pci 1.1 on # SM 0
+ chip drivers/generic/generic #dimm 0-0-0
+ device i2c 50 on end
+ end
+ chip drivers/generic/generic #dimm 0-0-1
+ device i2c 51 on end
+ end
+ chip drivers/generic/generic #dimm 0-1-0
+ device i2c 52 on end
+ end
+ chip drivers/generic/generic #dimm 0-1-1
+ device i2c 53 on end
+ end
+ chip drivers/generic/generic #dimm 1-0-0
+ device i2c 54 on end
+ end
+ chip drivers/generic/generic #dimm 1-0-1
+ device i2c 55 on end
+ end
+ chip drivers/generic/generic #dimm 1-1-0
+ device i2c 56 on end
+ end
+ chip drivers/generic/generic #dimm 1-1-1
+ device i2c 57 on end
+ end
+ end # SM
+ device pci 1.1 on # SM 1
+ chip drivers/i2c/adm1027 # ADT7463A CPU0 temp, SYS FAN 2/3/4
+ device i2c 2d on end
+ end
+ chip drivers/i2c/adm1027 # ADT7463A CPU1 temp, CPU0/1 FAN , SYS FAN 1/5
+ device i2c 2e on end
+ end
+ chip drivers/generic/generic # Winbond HWM 0x54 CPU0/1 VRM temp, SYSFAN 6/7, SB FAN
+ device i2c 2a on end
+ end
+ chip drivers/generic/generic # Winbond HWM 0x92
+ device i2c 49 on end
+ end
+ chip drivers/generic/generic # Winbond HWM 0x94
+ device i2c 4a on end
+ end
+ end #SM
+ device pci 2.0 on end # USB 1.1
+ device pci 2.1 on end # USB 2
+ device pci 4.0 off end # ACI
+ device pci 4.1 off end # MCI
+ device pci 6.0 on end # IDE
+ device pci 7.0 on end # SATA 1
+ device pci 8.0 on end # SATA 0
+ device pci 9.0 on # PCI
+ # chip drivers/ati/ragexl
+ chip drivers/pci/onboard
+ device pci 7.0 on end
+ register "rom_address" = "0xfff80000"
+ end
+ end
+ device pci a.0 off end # NIC
+ device pci b.0 off end # PCI E 3
+ device pci c.0 off end # PCI E 2
+ device pci d.0 on end # PCI E 1
+ device pci e.0 on end # PCI E 0
+ register "ide0_enable" = "1"
+ register "ide1_enable" = "1"
+ register "sata0_enable" = "1"
+ register "sata1_enable" = "1"
+ end
+ end # device pci 18.0
+ device pci 18.0 on end # Link 1
+ device pci 18.0 on
+ # devices on link 2, link 2 == LDT 2
+ chip southbridge/amd/amd8131
+ # the on/off keyword is mandatory
+ device pci 0.0 on end
+ device pci 0.1 on end
+ device pci 1.0 on
+ chip drivers/pci/onboard
+ device pci 9.0 on end
+ device pci 9.1 on end
+ end
+ end
+ device pci 1.1 on end
+ end
+ end # device pci 18.0
+ device pci 18.1 on end
+ device pci 18.2 on end
+ device pci 18.3 on end
+ end #mc0
+
+ end # pci_domain
+
+end # root_complex
diff --git a/src/mainboard/tyan/s2891/Options.lb b/src/mainboard/tyan/s2891/Options.lb
new file mode 100644
index 0000000000..75deaf69a7
--- /dev/null
+++ b/src/mainboard/tyan/s2891/Options.lb
@@ -0,0 +1,236 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses HARD_RESET_BUS
+uses HARD_RESET_DEVICE
+uses HARD_RESET_FUNCTION
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_MAX_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses _RAMBASE
+uses CONFIG_GDB_STUB
+uses CROSS_COMPILE
+uses CC
+uses HOSTCC
+uses OBJCOPY
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_SERIAL8250
+uses CONFIG_CONSOLE_BTEXT
+uses HAVE_INIT_TIMER
+uses CONFIG_GDB_STUB
+uses CONFIG_CHIP_NAME
+uses CONFIG_CONSOLE_VGA
+uses CONFIG_PCI_ROM_RUN
+
+uses CK804_DEVN_BASE
+
+## ROM_SIZE is the size of boot ROM that this board will use.
+#512K bytes
+default ROM_SIZE=524288
+
+##
+## FALLBACK_SIZE is the amount of the ROM the complete fallback image will use
+##
+default FALLBACK_SIZE=131072
+
+###
+### Build options
+###
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+default HARD_RESET_BUS=1
+default HARD_RESET_DEVICE=4
+default HARD_RESET_FUNCTION=0
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=11
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=2
+
+#CK804 setting
+
+default CK804_DEVN_BASE=0
+
+#BTEXT Console
+#default CONFIG_CONSOLE_BTEXT=1
+
+#VGA Console
+default CONFIG_CONSOLE_VGA=1
+default CONFIG_PCI_ROM_RUN=1
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="Tyan"
+default MAINBOARD_VENDOR="s2891"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2891
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 16K heap
+##
+default HEAP_SIZE=0x4000
+
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00004000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM = 1
+
+###
+### Defaults of options that you may want to override in the target config file
+###
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## Disable the gdb stub by default
+##
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG 1 system is unusable
+## ALERT 2 action must be taken immediately
+## CRIT 3 critical conditions
+## ERR 4 error conditions
+## WARNING 5 warning conditions
+## NOTICE 6 normal but significant condition
+## INFO 7 informational
+## DEBUG 8 debug-level messages
+## SPEW 9 Way too many details
+
+## Request this level of debugging output
+default DEFAULT_CONSOLE_LOGLEVEL=8
+## At a maximum only compile in this level of debugging
+default MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+### End Options.lb
+end
diff --git a/src/mainboard/tyan/s2891/auto.c b/src/mainboard/tyan/s2891/auto.c
new file mode 100644
index 0000000000..d0ee70ba2b
--- /dev/null
+++ b/src/mainboard/tyan/s2891/auto.c
@@ -0,0 +1,164 @@
+#define ASSEMBLY 1
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+
+#include "northbridge/amd/amdk8/cpu_rev.c"
+#define K8_HT_FREQ_1G_SUPPORT 0
+#include "northbridge/amd/amdk8/incoherent_ht.c"
+#include "southbridge/nvidia/ck804/ck804_early_smbus.c"
+#include "northbridge/amd/amdk8/raminit.h"
+#include "cpu/amd/model_fxx/apic_timer.c"
+#include "lib/delay.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+#include "northbridge/amd/amdk8/debug.c"
+#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
+
+#include "cpu/amd/mtrr/amd_earlymtrr.c"
+#include "cpu/x86/bist.h"
+
+#include "northbridge/amd/amdk8/setup_resource_map.c"
+
+#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+
+static void hard_reset(void)
+{
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+static void soft_reset(void)
+{
+ set_bios_reset();
+#if 1
+ /* link reset */
+ outb(0x02, 0x0cf9);
+ outb(0x06, 0x0cf9);
+#endif
+}
+
+static void memreset_setup(void)
+{
+}
+
+static void memreset(int controllers, const struct mem_controller *ctrl)
+{
+}
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+ /* nothing to do */
+}
+
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+ return smbus_read_byte(device, address);
+}
+
+#define K8_4RANK_DIMM_SUPPORT 1
+
+#include "northbridge/amd/amdk8/raminit.c"
+#include "northbridge/amd/amdk8/coherent_ht.c"
+#include "sdram/generic_sdram.c"
+
+ /* tyan does not want the default */
+#include "resourcemap.c"
+
+#define FIRST_CPU 1
+#define SECOND_CPU 1
+#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
+
+#define CK804_NUM 1
+#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
+#include "southbridge/nvidia/ck804/ck804_early_setup.c"
+
+static void main(unsigned long bist)
+{
+ static const struct mem_controller cpu[] = {
+#if FIRST_CPU
+ {
+ .node_id = 0,
+ .f0 = PCI_DEV(0, 0x18, 0),
+ .f1 = PCI_DEV(0, 0x18, 1),
+ .f2 = PCI_DEV(0, 0x18, 2),
+ .f3 = PCI_DEV(0, 0x18, 3),
+ .channel0 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 },
+ .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 },
+ },
+#endif
+#if SECOND_CPU
+ {
+ .node_id = 1,
+ .f0 = PCI_DEV(0, 0x19, 0),
+ .f1 = PCI_DEV(0, 0x19, 1),
+ .f2 = PCI_DEV(0, 0x19, 2),
+ .f3 = PCI_DEV(0, 0x19, 3),
+ .channel0 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 },
+ .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 },
+ },
+#endif
+ };
+
+ int needs_reset;
+ unsigned nodeid;
+
+ if (bist == 0) {
+ /* Skip this if there was a built in self test failure */
+ amd_early_mtrr_init();
+
+ enable_lapic();
+ init_timer();
+
+ nodeid = lapicid();
+ if (cpu_init_detected(nodeid)) {
+ asm volatile ("jmp __cpu_reset");
+ }
+ distinguish_cpu_resets(nodeid);
+
+
+ if (!boot_cpu()
+ ) {
+ stop_this_cpu();
+ }
+ }
+
+ w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE);
+ uart_init();
+ console_init();
+
+ /* Halt if there was a built in self test failure */
+ report_bist_failure(bist);
+
+ setup_s2891_resource_map();
+
+ needs_reset = setup_coherent_ht_domain();
+
+ needs_reset |= ht_setup_chains_x();
+
+ needs_reset |= ck804_early_setup_x();
+
+ if (needs_reset) {
+ print_info("ht reset -\r\n");
+ soft_reset();
+ }
+
+ enable_smbus();
+
+ memreset_setup();
+ sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
+
+
+}
diff --git a/src/mainboard/tyan/s2891/chip.h b/src/mainboard/tyan/s2891/chip.h
new file mode 100644
index 0000000000..71a5bb9e8d
--- /dev/null
+++ b/src/mainboard/tyan/s2891/chip.h
@@ -0,0 +1,6 @@
+extern struct chip_operations mainboard_tyan_s2891_ops;
+
+struct mainboard_tyan_s2891_config {
+ int fixup_scsi;
+ int fixup_vga;
+};
diff --git a/src/mainboard/tyan/s2891/cmos.layout b/src/mainboard/tyan/s2891/cmos.layout
new file mode 100644
index 0000000000..c1f3d75316
--- /dev/null
+++ b/src/mainboard/tyan/s2891/cmos.layout
@@ -0,0 +1,98 @@
+entries
+
+#start-bit length config config-ID name
+#0 8 r 0 seconds
+#8 8 r 0 alarm_seconds
+#16 8 r 0 minutes
+#24 8 r 0 alarm_minutes
+#32 8 r 0 hours
+#40 8 r 0 alarm_hours
+#48 8 r 0 day_of_week
+#56 8 r 0 day_of_month
+#64 8 r 0 month
+#72 8 r 0 year
+#80 4 r 0 rate_select
+#84 3 r 0 REF_Clock
+#87 1 r 0 UIP
+#88 1 r 0 auto_switch_DST
+#89 1 r 0 24_hour_mode
+#90 1 r 0 binary_values_enable
+#91 1 r 0 square-wave_out_enable
+#92 1 r 0 update_finished_enable
+#93 1 r 0 alarm_interrupt_enable
+#94 1 r 0 periodic_interrupt_enable
+#95 1 r 0 disable_clock_updates
+#96 288 r 0 temporary_filler
+0 384 r 0 reserved_memory
+384 1 e 4 boot_option
+385 1 e 4 last_boot
+386 1 e 1 ECC_memory
+388 4 r 0 reboot_bits
+392 3 e 5 baud_rate
+395 1 e 1 hw_scrubber
+396 1 e 1 interleave_chip_selects
+397 2 e 8 max_mem_clock
+399 1 e 2 dual_core
+400 1 e 1 power_on_after_fail
+412 4 e 6 debug_level
+416 4 e 7 boot_first
+420 4 e 7 boot_second
+424 4 e 7 boot_third
+428 4 h 0 boot_index
+432 8 h 0 boot_countdown
+440 4 e 9 slow_cpu
+444 1 e 1 nmi
+445 1 e 1 iommu
+728 256 h 0 user_data
+984 16 h 0 check_sum
+# Reserve the extended AMD configuration registers
+1000 24 r 0 reserved_memory
+
+
+
+enumerations
+
+#ID value text
+1 0 Disable
+1 1 Enable
+2 0 Enable
+2 1 Disable
+4 0 Fallback
+4 1 Normal
+5 0 115200
+5 1 57600
+5 2 38400
+5 3 19200
+5 4 9600
+5 5 4800
+5 6 2400
+5 7 1200
+6 6 Notice
+6 7 Info
+6 8 Debug
+6 9 Spew
+7 0 Network
+7 1 HDD
+7 2 Floppy
+7 8 Fallback_Network
+7 9 Fallback_HDD
+7 10 Fallback_Floppy
+#7 3 ROM
+8 0 200Mhz
+8 1 166Mhz
+8 2 133Mhz
+8 3 100Mhz
+9 0 off
+9 1 87.5%
+9 2 75.0%
+9 3 62.5%
+9 4 50.0%
+9 5 37.5%
+9 6 25.0%
+9 7 12.5%
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/tyan/s2891/failover.c b/src/mainboard/tyan/s2891/failover.c
new file mode 100644
index 0000000000..fb092e7203
--- /dev/null
+++ b/src/mainboard/tyan/s2891/failover.c
@@ -0,0 +1,104 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/mc146818rtc_early.c"
+
+#include "southbridge/nvidia/ck804/ck804_enable_rom.c"
+#include "northbridge/amd/amdk8/early_ht.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+
+static void sio_setup(void)
+{
+
+ unsigned value;
+ uint32_t dword;
+ uint8_t byte;
+
+ byte = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b);
+ byte |= 0x20;
+ pci_write_config8(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b, byte);
+
+ dword = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0);
+ dword |= (1<<0) | (1<<1);
+ pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0, dword);
+
+#if 1
+ dword = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa4);
+ dword |= (1<<16);
+ pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa4, dword);
+
+#endif
+
+}
+
+
+static unsigned long main(unsigned long bist)
+{
+ unsigned nodeid;
+ /* Make cerain my local apic is useable */
+ enable_lapic();
+
+ nodeid = lapicid();
+ /* Is this a cpu only reset? */
+ if (cpu_init_detected(nodeid)) {
+ if (last_boot_normal()) {
+ goto normal_image;
+ } else {
+ goto cpu_reset;
+ }
+ }
+
+ /* Is this a secondary cpu? */
+ if (!boot_cpu()) {
+ if (last_boot_normal()) {
+ goto normal_image;
+ } else {
+ goto fallback_image;
+ }
+ }
+
+ /* Nothing special needs to be done to find bus 0 */
+ /* Allow the HT devices to be found */
+
+ enumerate_ht_chain();
+
+ sio_setup();
+
+ /* Setup the ck804 */
+ ck804_enable_rom();
+
+ /* Is this a deliberate reset by the bios */
+ if (bios_reset_detected() && last_boot_normal()) {
+ goto normal_image;
+ }
+ /* This is the primary cpu how should I boot? */
+ else if (do_normal_boot()) {
+ goto normal_image;
+ }
+ else {
+ goto fallback_image;
+ }
+ normal_image:
+ asm volatile ("jmp __normal_image"
+ : /* outputs */
+ : "a" (bist) /* inputs */
+ : /* clobbers */
+ );
+ cpu_reset:
+#if 0
+ //CPU reset will reset memtroller ???
+ asm volatile ("jmp __cpu_reset"
+ : /* outputs */
+ : "a"(bist) /* inputs */
+ : /* clobbers */
+ );
+#endif
+
+ fallback_image:
+ return bist;
+}
diff --git a/src/mainboard/tyan/s2891/irq_tables.c b/src/mainboard/tyan/s2891/irq_tables.c
new file mode 100644
index 0000000000..8a00214c18
--- /dev/null
+++ b/src/mainboard/tyan/s2891/irq_tables.c
@@ -0,0 +1,35 @@
+/* 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*11, /* there can be total 11 devices on the bus */
+ 1, /* Where the interrupt router lies (bus) */
+ ((CK804_DEVN_BASE+9)<<3)|0, /* Where the interrupt router lies (dev) */
+ 0, /* IRQs devoted exclusively to PCI usage */
+ 0x10de, /* Vendor */
+ 0x005c, /* Device */
+ 0, /* Crap (miniport) */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+ 0x5a, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
+ {
+ {1,((CK804_DEVN_BASE+9)<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0},
+ {0x5,(1<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0},
+ {0x5,(4<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x0, 0},
+ {0x5,(3<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x1, 0},
+ {0x5,(6<<3)|0, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x2, 0},
+ {0x4,(8<<3)|0, {{0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}}, 0x3, 0},
+ {0x4,(7<<3)|0, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x4, 0},
+ {0x6,(0x0a<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x5, 0},
+ {0x4,(9<<3)|0, {{0x1, 0xdef8}, {2, 0xdef8}, {0, 0}, {0, 0}}, 0, 0},
+ {0x6,(0x0b<<3)|0, {{0x2, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0},
+ {0x6,(0x0c<<3)|0, {{0x4, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0},
+ }
+};
diff --git a/src/mainboard/tyan/s2891/mainboard.c b/src/mainboard/tyan/s2891/mainboard.c
new file mode 100644
index 0000000000..a547abfd66
--- /dev/null
+++ b/src/mainboard/tyan/s2891/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "chip.h"
+
+#if CONFIG_CHIP_NAME == 1
+struct chip_operations mainboard_tyan_s2891_ops = {
+ CHIP_NAME("Tyan s2891 mainboard")
+};
+#endif
diff --git a/src/mainboard/tyan/s2891/mptable.c b/src/mainboard/tyan/s2891/mptable.c
new file mode 100644
index 0000000000..9aa2f336b8
--- /dev/null
+++ b/src/mainboard/tyan/s2891/mptable.c
@@ -0,0 +1,252 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+ static const char sig[4] = "PCMP";
+ static const char oem[8] = "TYAN ";
+ static const char productid[12] = "S2891 ";
+ struct mp_config_table *mc;
+
+ unsigned char bus_num;
+ unsigned char bus_isa;
+ unsigned char bus_ck804_0; //1
+ unsigned char bus_ck804_1; //2
+ unsigned char bus_ck804_2; //3
+ unsigned char bus_ck804_3; //4
+ unsigned char bus_ck804_4; //5
+ unsigned char bus_ck804_5; //6
+ unsigned char bus_8131_0; //7
+ unsigned char bus_8131_1; //8
+ unsigned char bus_8131_2; //9
+ unsigned apicid_base;
+ unsigned apicid_ck804;
+ unsigned apicid_8131_1;
+ unsigned apicid_8131_2;
+
+ mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+ memset(mc, 0, sizeof(*mc));
+
+ memcpy(mc->mpc_signature, sig, sizeof(sig));
+ mc->mpc_length = sizeof(*mc); /* initially just the header */
+ mc->mpc_spec = 0x04;
+ mc->mpc_checksum = 0; /* not yet computed */
+ memcpy(mc->mpc_oem, oem, sizeof(oem));
+ memcpy(mc->mpc_productid, productid, sizeof(productid));
+ mc->mpc_oemptr = 0;
+ mc->mpc_oemsize = 0;
+ mc->mpc_entry_count = 0; /* No entries yet... */
+ mc->mpc_lapic = LAPIC_ADDR;
+ mc->mpe_length = 0;
+ mc->mpe_checksum = 0;
+ mc->reserved = 0;
+
+ smp_write_processors(mc);
+
+ {
+ device_t dev;
+
+
+ /* CK804 */
+ bus_ck804_0 = 1;
+ dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0));
+ if (dev) {
+ bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_ck804_4++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09);
+
+ bus_ck804_1 = 2;
+ bus_ck804_4 = 3;
+
+ }
+ dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0));
+ if (dev) {
+ bus_ck804_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_ck804_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_ck804_5++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n",CK804_DEVN_BASE + 0x0d);
+
+ bus_ck804_5 = bus_ck804_4+1;
+ }
+
+ dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0));
+ if (dev) {
+ bus_ck804_5 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_8131_0 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_8131_0++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n",CK804_DEVN_BASE + 0x0e);
+
+ bus_8131_0 = bus_ck804_5+1;
+ }
+
+ /* 8131-1 */
+ dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x01,0));
+ if (dev) {
+ bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_8131_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_8131_2++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI %02x:01.0, using defaults\n", bus_8131_0);
+
+ bus_8131_1 = bus_8131_0+1;
+ bus_8131_2 = bus_8131_0+2;
+ }
+ /* 8131-2 */
+ dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x02,0));
+ if (dev) {
+ bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_isa++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI %02x:02.0, using defaults\n", bus_8131_0);
+
+ bus_8131_2 = bus_8131_1+1;
+ bus_isa = bus_8131_1+2;
+ }
+
+ }
+
+
+
+/*Bus: Bus ID Type*/
+ /* define bus and isa numbers */
+ for(bus_num = 0; bus_num < bus_isa; bus_num++) {
+ smp_write_bus(mc, bus_num, "PCI ");
+ }
+ smp_write_bus(mc, bus_isa, "ISA ");
+
+/*I/O APICs: APIC ID Version State Address*/
+ apicid_base = CONFIG_MAX_CPUS;
+ apicid_ck804 = apicid_base;
+ apicid_8131_1 = apicid_base+1;
+ apicid_8131_2 = apicid_base+2;
+// smp_write_ioapic(mc, 2, 0x11, 0xfec00000);
+ {
+ device_t dev;
+ struct resource *res;
+ uint32_t dword;
+
+ dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE+ 0x1,0));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_1);
+ if (res) {
+ smp_write_ioapic(mc, apicid_ck804, 0x11, res->base);
+ }
+
+
+ dword = 0x0000d218;
+ pci_write_config32(dev, 0x7c, dword);
+
+ dword = 0x8d001a00;
+
+
+ pci_write_config32(dev, 0x80, dword);
+
+ dword = 0x00000072;
+
+ pci_write_config32(dev, 0x84, dword);
+
+ }
+
+ dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x1,1));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base);
+ }
+ }
+ dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x2,1));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base);
+ }
+ }
+
+ }
+
+/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#
+*/ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_ck804, 0x0);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_ck804, 0x1);
+ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_ck804, 0x2);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_ck804, 0x3);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_ck804, 0x4);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_ck804, 0x6);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_ck804, 0x7);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_ck804, 0x8);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_ck804, 0xc);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_ck804, 0xd);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_ck804, 0xe);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_ck804, 0xf);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x16);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x17);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x14);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x15);
+
+#if 1
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); //
+#endif
+
+#if 1
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x12); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x13); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x10); //
+#endif
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (7<<2)|0, apicid_ck804, 0x13); //
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x1);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x0); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, apicid_8131_1, 0x1);//
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, apicid_8131_1, 0x2);//
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, apicid_8131_1, 0x3);//
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, apicid_8131_1, 0x2); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|1, apicid_8131_1, 0x3);//
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|2, apicid_8131_1, 0x0);//
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|3, apicid_8131_1, 0x1);//
+
+
+/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
+ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0);
+ smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1);
+ /* There is no extension information... */
+
+ /* Compute the checksums */
+ mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+ mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+ printk_debug("Wrote the mp table end at: %p - %p\n",
+ mc, smp_next_mpe_entry(mc));
+ return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+ void *v;
+ v = smp_write_floating_table(addr);
+ return (unsigned long)smp_write_config_table(v);
+}
diff --git a/src/mainboard/tyan/s2891/resourcemap.c b/src/mainboard/tyan/s2891/resourcemap.c
new file mode 100644
index 0000000000..c55d95bb99
--- /dev/null
+++ b/src/mainboard/tyan/s2891/resourcemap.c
@@ -0,0 +1,273 @@
+/*
+ * Tyan S2891 needs a different resource map
+ *
+ */
+
+static void setup_s2891_resource_map(void)
+{
+ static const unsigned int register_values[] = {
+#if 1
+ /* Careful set limit registers before base registers which contain the enables */
+ /* DRAM Limit i Registers
+ * F1:0x44 i = 0
+ * F1:0x4C i = 1
+ * F1:0x54 i = 2
+ * F1:0x5C i = 3
+ * F1:0x64 i = 4
+ * F1:0x6C i = 5
+ * F1:0x74 i = 6
+ * F1:0x7C i = 7
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 7: 3] Reserved
+ * [10: 8] Interleave select
+ * specifies the values of A[14:12] to use with interleave enable.
+ * [15:11] Reserved
+ * [31:16] DRAM Limit Address i Bits 39-24
+ * This field defines the upper address bits of a 40 bit address
+ * that define the end of the DRAM region.
+ */
+ PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
+ PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
+ PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
+ PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
+ PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
+ PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
+ PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
+ /* DRAM Base i Registers
+ * F1:0x40 i = 0
+ * F1:0x48 i = 1
+ * F1:0x50 i = 2
+ * F1:0x58 i = 3
+ * F1:0x60 i = 4
+ * F1:0x68 i = 5
+ * F1:0x70 i = 6
+ * F1:0x78 i = 7
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 7: 2] Reserved
+ * [10: 8] Interleave Enable
+ * 000 = No interleave
+ * 001 = Interleave on A[12] (2 nodes)
+ * 010 = reserved
+ * 011 = Interleave on A[12] and A[14] (4 nodes)
+ * 100 = reserved
+ * 101 = reserved
+ * 110 = reserved
+ * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
+ * [15:11] Reserved
+ * [13:16] DRAM Base Address i Bits 39-24
+ * This field defines the upper address bits of a 40-bit address
+ * that define the start of the DRAM region.
+ */
+ PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
+#endif
+#if 1
+
+ /* Memory-Mapped I/O Limit i Registers
+ * F1:0x84 i = 0
+ * F1:0x8C i = 1
+ * F1:0x94 i = 2
+ * F1:0x9C i = 3
+ * F1:0xA4 i = 4
+ * F1:0xAC i = 5
+ * F1:0xB4 i = 6
+ * F1:0xBC i = 7
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 3: 3] Reserved
+ * [ 5: 4] Destination Link ID
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 = Reserved
+ * [ 6: 6] Reserved
+ * [ 7: 7] Non-Posted
+ * 0 = CPU writes may be posted
+ * 1 = CPU writes must be non-posted
+ * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
+ * This field defines the upp adddress bits of a 40-bit address that
+ * defines the end of a memory-mapped I/O region n
+ */
+ PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000,
+// PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff00,
+
+ /* Memory-Mapped I/O Base i Registers
+ * F1:0x80 i = 0
+ * F1:0x88 i = 1
+ * F1:0x90 i = 2
+ * F1:0x98 i = 3
+ * F1:0xA0 i = 4
+ * F1:0xA8 i = 5
+ * F1:0xB0 i = 6
+ * F1:0xB8 i = 7
+ * [ 0: 0] Read Enable
+ * 0 = Reads disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes disabled
+ * 1 = Writes Enabled
+ * [ 2: 2] Cpu Disable
+ * 0 = Cpu can use this I/O range
+ * 1 = Cpu requests do not use this I/O range
+ * [ 3: 3] Lock
+ * 0 = base/limit registers i are read/write
+ * 1 = base/limit registers i are read-only
+ * [ 7: 4] Reserved
+ * [31: 8] Memory-Mapped I/O Base Address i (39-16)
+ * This field defines the upper address bits of a 40bit address
+ * that defines the start of memory-mapped I/O region i
+ */
+ PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000,
+// PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003,
+#endif
+#if 1
+
+ /* PCI I/O Limit i Registers
+ * F1:0xC4 i = 0
+ * F1:0xCC i = 1
+ * F1:0xD4 i = 2
+ * F1:0xDC i = 3
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 3: 3] Reserved
+ * [ 5: 4] Destination Link ID
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 = reserved
+ * [11: 6] Reserved
+ * [24:12] PCI I/O Limit Address i
+ * This field defines the end of PCI I/O region n
+ * [31:25] Reserved
+ */
+ PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff000,
+ PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000,
+
+ /* PCI I/O Base i Registers
+ * F1:0xC0 i = 0
+ * F1:0xC8 i = 1
+ * F1:0xD0 i = 2
+ * F1:0xD8 i = 3
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 3: 2] Reserved
+ * [ 4: 4] VGA Enable
+ * 0 = VGA matches Disabled
+ * 1 = matches all address < 64K and where A[9:0] is in the
+ * range 3B0-3BB or 3C0-3DF independen of the base & limit registers
+ * [ 5: 5] ISA Enable
+ * 0 = ISA matches Disabled
+ * 1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
+ * from matching agains this base/limit pair
+ * [11: 6] Reserved
+ * [24:12] PCI I/O Base i
+ * This field defines the start of PCI I/O region n
+ * [31:25] Reserved
+ */
+ PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000033,
+ PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000,
+#endif
+ /* Config Base and Limit i Registers
+ * F1:0xE0 i = 0
+ * F1:0xE4 i = 1
+ * F1:0xE8 i = 2
+ * F1:0xEC i = 3
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 2: 2] Device Number Compare Enable
+ * 0 = The ranges are based on bus number
+ * 1 = The ranges are ranges of devices on bus 0
+ * [ 3: 3] Reserved
+ * [ 6: 4] Destination Node
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 7: 7] Reserved
+ * [ 9: 8] Destination Link
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 - Reserved
+ * [15:10] Reserved
+ * [23:16] Bus Number Base i
+ * This field defines the lowest bus number in configuration region i
+ * [31:24] Bus Number Limit i
+ * This field defines the highest bus number in configuration region i
+ */
+#if 1
+// PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x07000003,
+// PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x7f080203,
+ PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000,
+#endif
+
+ };
+
+ int max;
+ max = sizeof(register_values)/sizeof(register_values[0]);
+ setup_resource_map(register_values, max);
+}
+
diff --git a/src/mainboard/tyan/s2895/Config.lb b/src/mainboard/tyan/s2895/Config.lb
new file mode 100644
index 0000000000..5a7cb14e9a
--- /dev/null
+++ b/src/mainboard/tyan/s2895/Config.lb
@@ -0,0 +1,318 @@
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+ default ROM_SECTION_SIZE = FALLBACK_SIZE
+ default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+ default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE )
+ default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+default CONFIG_ROM_STREAM = 1
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=65536
+default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+arch i386 end
+
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE object irq_tables.o end
+#object reset.o
+
+##
+## Romcc output
+##
+makerule ./failover.E
+ depends "$(MAINBOARD)/failover.c ./romcc"
+ action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+ depends "$(MAINBOARD)/failover.c ./romcc"
+ action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E
+ depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+ action "./romcc -E -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+makerule ./auto.inc
+ depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+ action "./romcc -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE
+ mainboardinit cpu/x86/16bit/reset16.inc
+ ldscript /cpu/x86/16bit/reset16.lds
+else
+ mainboardinit cpu/x86/32bit/reset32.inc
+ ldscript /cpu/x86/32bit/reset32.lds
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit southbridge/nvidia/ck804/id.inc
+ldscript /southbridge/nvidia/ck804/id.lds
+
+##
+## ROMSTRAP table for CK804
+##
+if USE_FALLBACK_IMAGE
+ mainboardinit southbridge/nvidia/ck804/romstrap.inc
+ ldscript /southbridge/nvidia/ck804/romstrap.lds
+end
+
+###
+### This is the early phase of linuxBIOS startup
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+ ldscript /arch/i386/lib/failover.lds
+ mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit cpu/x86/sse/enable_sse.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/sse/disable_sse.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+##
+## Include the secondary Configuration files
+##
+if CONFIG_CHIP_NAME
+ config chip.h
+end
+
+# sample config for tyan/s2895
+chip northbridge/amd/amdk8/root_complex
+ device apic_cluster 0 on
+ chip cpu/amd/socket_940
+ device apic 0 on end
+ end
+ end
+ device pci_domain 0 on
+ chip northbridge/amd/amdk8 #mc0
+ device pci 18.0 on
+ # devices on link 0, link 0 == LDT 0
+ chip southbridge/nvidia/ck804
+ device pci 0.0 on end # HT
+ device pci 1.0 on # LPC
+ chip superio/smsc/lpc47b397
+ device pnp 2e.0 on # Floppy
+ io 0x60 = 0x3f0
+ irq 0x70 = 6
+ drq 0x74 = 2
+ end
+ device pnp 2e.3 off # Parallel Port
+ io 0x60 = 0x378
+ irq 0x70 = 7
+ end
+ device pnp 2e.4 on # Com1
+ io 0x60 = 0x3f8
+ irq 0x70 = 4
+ end
+ device pnp 2e.5 off # Com2
+ io 0x60 = 0x2f8
+ irq 0x70 = 3
+ end
+ device pnp 2e.7 on # Keyboard
+ io 0x60 = 0x60
+ io 0x62 = 0x64
+ irq 0x70 = 1
+ irq 0x72 = 12
+ end
+ device pnp 2e.8 on # HW Monitor
+ io 0x60 = 0x290
+ chip drivers/generic/generic # LM95221 CPU temp
+ device i2c 2b on end
+ end
+ chip drivers/generic/generic # EMCT03
+ device i2c 54 on end
+ end
+ end
+ device pnp 2e.a on # RT
+ io 0x60 = 0x400
+ end
+ end
+ end
+ device pci 1.1 on # SM 0
+ chip drivers/generic/generic #dimm 0-0-0
+ device i2c 50 on end
+ end
+ chip drivers/generic/generic #dimm 0-0-1
+ device i2c 51 on end
+ end
+ chip drivers/generic/generic #dimm 0-1-0
+ device i2c 52 on end
+ end
+ chip drivers/generic/generic #dimm 0-1-1
+ device i2c 53 on end
+ end
+ chip drivers/generic/generic #dimm 1-0-0
+ device i2c 54 on end
+ end
+ chip drivers/generic/generic #dimm 1-0-1
+ device i2c 55 on end
+ end
+ chip drivers/generic/generic #dimm 1-1-0
+ device i2c 56 on end
+ end
+ chip drivers/generic/generic #dimm 1-1-1
+ device i2c 57 on end
+ end
+ end # SM
+ device pci 1.1 on # SM 1
+#PCI device smbus address will depend on addon pci device, do we need to scan_smbus_bus?
+# chip drivers/generic/generic #PCIXA Slot1
+# device i2c 50 on end
+# end
+# chip drivers/generic/generic #PCIXB Slot1
+# device i2c 51 on end
+# end
+# chip drivers/generic/generic #PCIXB Slot2
+# device i2c 52 on end
+# end
+# chip drivers/generic/generic #PCI Slot1
+# device i2c 53 on end
+# end
+# chip drivers/generic/generic #Master CK804 PCI-E
+# device i2c 54 on end
+# end
+# chip drivers/generic/generic #Slave CK804 PCI-E
+# device i2c 55 on end
+# end
+ chip drivers/generic/generic #MAC EEPROM
+ device i2c 51 on end
+ end
+
+ end # SM
+ device pci 2.0 on end # USB 1.1
+ device pci 2.1 on end # USB 2
+ device pci 4.0 on end # ACI
+ device pci 4.1 off end # MCI
+ device pci 6.0 on end # IDE
+ device pci 7.0 on end # SATA 1
+ device pci 8.0 on end # SATA 0
+ device pci 9.0 on end # PCI
+ device pci a.0 on end # NIC
+ device pci b.0 off end # PCI E 3
+ device pci c.0 off end # PCI E 2
+ device pci d.0 off end # PCI E 1
+ device pci e.0 on end # PCI E 0
+ register "ide0_enable" = "1"
+ register "ide1_enable" = "1"
+ register "sata0_enable" = "1"
+ register "sata1_enable" = "1"
+# register "nic_rom_address" = "0xfff80000" # 64k
+# register "raid_rom_address" = "0xfff90000"
+ register "mac_eeprom_smbus" = "3" # 1: smbus under 2e.8, 2: SM0 3: SM1
+ register "mac_eeprom_addr" = "0x51"
+ end
+ end # device pci 18.0
+ device pci 18.0 on end # Link 1
+ device pci 18.0 on
+ # devices on link 2, link 2 == LDT 2
+ chip southbridge/amd/amd8131
+ # the on/off keyword is mandatory
+ device pci 0.0 on end
+ device pci 0.1 on end
+ device pci 1.0 on
+ chip drivers/pci/onboard
+ device pci 6.0 on end # lsi scsi
+ device pci 6.1 on end
+ end
+ end
+ device pci 1.1 on end
+ end
+ end # device pci 18.0
+ device pci 18.1 on end
+ device pci 18.2 on end
+ device pci 18.3 on end
+ end # mc0
+
+ chip northbridge/amd/amdk8
+ device pci 19.0 on # northbridge
+ # devices on link 0, link 0 == LDT 0
+ chip southbridge/nvidia/ck804
+ device pci 0.0 on end # HT
+ device pci 1.0 on end # LPC
+ device pci 1.1 off end # SM
+ device pci 2.0 off end # USB 1.1
+ device pci 2.1 off end # USB 2
+ device pci 4.0 off end # ACI
+ device pci 4.1 off end # MCI
+ device pci 6.0 off end # IDE
+ device pci 7.0 off end # SATA 1
+ device pci 8.0 off end # SATA 0
+ device pci 9.0 off end # PCI
+ device pci a.0 on end # NIC
+ device pci b.0 off end # PCI E 3
+ device pci c.0 off end # PCI E 2
+ device pci d.0 off end # PCI E 1
+ device pci e.0 on end # PCI E 0
+# register "nic_rom_address" = "0xfff80000" # 64k
+ register "mac_eeprom_smbus" = "3"
+ register "mac_eeprom_addr" = "0x51"
+ end
+ end # device pci 19.0
+
+ device pci 19.0 on end
+ device pci 19.0 on end
+ device pci 19.1 on end
+ device pci 19.2 on end
+ device pci 19.3 on end
+ end
+ end # PCI domain
+
+end #root_complex
diff --git a/src/mainboard/tyan/s2895/Options.lb b/src/mainboard/tyan/s2895/Options.lb
new file mode 100644
index 0000000000..545dbe9f42
--- /dev/null
+++ b/src/mainboard/tyan/s2895/Options.lb
@@ -0,0 +1,237 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses HARD_RESET_BUS
+uses HARD_RESET_DEVICE
+uses HARD_RESET_FUNCTION
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_MAX_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses _RAMBASE
+uses CONFIG_GDB_STUB
+uses CROSS_COMPILE
+uses CC
+uses HOSTCC
+uses OBJCOPY
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_SERIAL8250
+uses HAVE_INIT_TIMER
+uses CONFIG_GDB_STUB
+uses CONFIG_CHIP_NAME
+uses CONFIG_CONSOLE_VGA
+uses CONFIG_PCI_ROM_RUN
+
+uses CK804_DEVN_BASE
+
+## ROM_SIZE is the size of boot ROM that this board will use.
+#512K bytes
+default ROM_SIZE=524288
+
+#1M bytes
+#default ROM_SIZE=1048576
+
+##
+## FALLBACK_SIZE is the amount of the ROM the complete fallback image will use
+##
+default FALLBACK_SIZE=131072
+
+###
+### Build options
+###
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+default HARD_RESET_BUS=1
+default HARD_RESET_DEVICE=4
+default HARD_RESET_FUNCTION=0
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=11
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=2
+
+#CHIP_NAME ?
+#default CONFIG_CHIP_NAME=1
+
+#CK804 setting
+default CK804_DEVN_BASE=0
+
+#VGA
+default CONFIG_CONSOLE_VGA=1
+default CONFIG_PCI_ROM_RUN=1
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="Tyan"
+default MAINBOARD_VENDOR="s2895"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2895
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 16K heap
+##
+default HEAP_SIZE=0x4000
+
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00004000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM = 1
+
+###
+### Defaults of options that you may want to override in the target config file
+###
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## Disable the gdb stub by default
+##
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG 1 system is unusable
+## ALERT 2 action must be taken immediately
+## CRIT 3 critical conditions
+## ERR 4 error conditions
+## WARNING 5 warning conditions
+## NOTICE 6 normal but significant condition
+## INFO 7 informational
+## DEBUG 8 debug-level messages
+## SPEW 9 Way too many details
+
+## Request this level of debugging output
+default DEFAULT_CONSOLE_LOGLEVEL=7
+## At a maximum only compile in this level of debugging
+default MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+### End Options.lb
+end
diff --git a/src/mainboard/tyan/s2895/auto.c b/src/mainboard/tyan/s2895/auto.c
new file mode 100644
index 0000000000..209f284d58
--- /dev/null
+++ b/src/mainboard/tyan/s2895/auto.c
@@ -0,0 +1,223 @@
+#define ASSEMBLY 1
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include <arch/cpu.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+
+#include "northbridge/amd/amdk8/cpu_rev.c"
+#define K8_HT_FREQ_1G_SUPPORT 1
+#include "northbridge/amd/amdk8/incoherent_ht.c"
+#include "southbridge/nvidia/ck804/ck804_early_smbus.c"
+#include "northbridge/amd/amdk8/raminit.h"
+#include "cpu/amd/model_fxx/apic_timer.c"
+#include "lib/delay.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+#include "northbridge/amd/amdk8/debug.c"
+#include "cpu/amd/model_fxx/model_fxx_msr.h"
+#include "superio/smsc/lpc47b397/lpc47b397_early_serial.c"
+
+#include "cpu/amd/mtrr/amd_earlymtrr.c"
+#include "cpu/x86/bist.h"
+
+#include "superio/smsc/lpc47b397/lpc47b397_early_gpio.c"
+
+#include "northbridge/amd/amdk8/setup_resource_map.c"
+
+#define SERIAL_DEV PNP_DEV(0x2e, LPC47B397_SP1)
+
+static void hard_reset(void)
+{
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+static void soft_reset(void)
+{
+ set_bios_reset();
+#if 1
+ /* link reset */
+ outb(0x02, 0x0cf9);
+ outb(0x06, 0x0cf9);
+#endif
+}
+
+static void memreset_setup(void)
+{
+}
+
+static void memreset(int controllers, const struct mem_controller *ctrl)
+{
+}
+
+#define SUPERIO_GPIO_DEV PNP_DEV(0x2e, LPC47B397_RT)
+
+#define SUPERIO_GPIO_IO_BASE 0x400
+
+static void sio_gpio_setup(void){
+
+ unsigned value;
+
+#if 1
+ /*Enable onboard scsi*/
+ lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x2c, (1<<7)|(0<<2)|(0<<1)|(0<<0)); // GP21, offset 0x2c, DISABLE_SCSI_L
+ value = lpc47b397_gpio_offset_in(SUPERIO_GPIO_IO_BASE, 0x4c);
+ lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x4c, (value|(1<<1)));
+#endif
+
+}
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+ /* nothing to do */
+}
+
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+ return smbus_read_byte(device, address);
+}
+
+#define K8_4RANK_DIMM_SUPPORT 1
+
+#include "northbridge/amd/amdk8/raminit.c"
+#if 0
+ #define ENABLE_APIC_EXT_ID 1
+ #define APIC_ID_OFFSET 0x10
+ #define LIFT_BSP_APIC_ID 0
+#else
+ #define ENABLE_APIC_EXT_ID 0
+#endif
+#include "northbridge/amd/amdk8/coherent_ht.c"
+#include "sdram/generic_sdram.c"
+
+/* tyan does not want the default */
+#include "resourcemap.c"
+
+#define FIRST_CPU 1
+#define SECOND_CPU 1
+#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
+
+#define CK804_NUM 2
+#define CK804B_BUSN 0xc
+#define CK804_USE_NIC 1
+#define CK804_USE_ACI 1
+#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
+
+//set GPIO to input mode
+#define CK804_MB_SETUP \
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 5, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* M9,GPIO6, PCIXB2_PRSNT1_L*/ \
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+15, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* M8,GPIO16, PCIXB2_PRSNT2_L*/ \
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+44, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* P5,GPIO45, PCIXA_PRSNT1_L*/ \
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 7, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* M5,GPIO8, PCIXA_PRSNT2_L*/ \
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+16, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* K4,GPIO17, PCIXB_PRSNT1_L*/ \
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+45, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* P7,GPIO46, PCIXB_PRSNT2_L*/
+
+#include "southbridge/nvidia/ck804/ck804_early_setup.c"
+
+
+static void main(unsigned long bist)
+{
+ static const struct mem_controller cpu[] = {
+#if FIRST_CPU
+ {
+ .node_id = 0,
+ .f0 = PCI_DEV(0, 0x18, 0),
+ .f1 = PCI_DEV(0, 0x18, 1),
+ .f2 = PCI_DEV(0, 0x18, 2),
+ .f3 = PCI_DEV(0, 0x18, 3),
+ .channel0 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 },
+ .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 },
+ },
+#endif
+#if SECOND_CPU
+ {
+ .node_id = 1,
+ .f0 = PCI_DEV(0, 0x19, 0),
+ .f1 = PCI_DEV(0, 0x19, 1),
+ .f2 = PCI_DEV(0, 0x19, 2),
+ .f3 = PCI_DEV(0, 0x19, 3),
+ .channel0 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 },
+ .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 },
+ },
+#endif
+ };
+
+ int needs_reset;
+ unsigned nodeid;
+
+ if (bist == 0) {
+ /* Skip this if there was a built in self test failure */
+ amd_early_mtrr_init();
+
+ nodeid = lapicid();;
+ #if ENABLE_APIC_EXT_ID == 1
+ enable_apic_ext_id(nodeid);
+ #endif
+
+ enable_lapic();
+ init_timer();
+
+
+ #if ENABLE_APIC_EXT_ID == 1
+ #if LIFT_BSP_APIC_ID == 0
+ if(nodeid != 0)
+ #endif
+ lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10
+
+ #endif
+
+ if (cpu_init_detected(nodeid)) {
+ asm volatile ("jmp __cpu_reset");
+ }
+ distinguish_cpu_resets(nodeid);
+
+
+ if (!boot_cpu()
+ ) {
+ stop_this_cpu(); // it will stop all cores except core0 of cpu0
+ }
+ }
+
+
+ lpc47b397_enable_serial(SERIAL_DEV, TTYS0_BASE);
+ uart_init();
+ console_init();
+
+ /* Halt if there was a built in self test failure */
+ report_bist_failure(bist);
+
+ sio_gpio_setup();
+
+ setup_s2895_resource_map();
+
+ needs_reset = setup_coherent_ht_domain();
+
+ needs_reset |= ht_setup_chains_x();
+
+ needs_reset |= ck804_early_setup_x();
+
+ if (needs_reset) {
+ print_info("ht reset -\r\n");
+ soft_reset();
+ }
+
+
+ enable_smbus();
+
+ memreset_setup();
+ sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
+
+
+}
diff --git a/src/mainboard/tyan/s2895/chip.h b/src/mainboard/tyan/s2895/chip.h
new file mode 100644
index 0000000000..350f4a6369
--- /dev/null
+++ b/src/mainboard/tyan/s2895/chip.h
@@ -0,0 +1,6 @@
+extern struct chip_operations mainboard_tyan_s2895_ops;
+
+struct mainboard_tyan_s2895_config {
+// int fixup_scsi;
+// int fixup_vga;
+};
diff --git a/src/mainboard/tyan/s2895/cmos.layout b/src/mainboard/tyan/s2895/cmos.layout
new file mode 100644
index 0000000000..c1f3d75316
--- /dev/null
+++ b/src/mainboard/tyan/s2895/cmos.layout
@@ -0,0 +1,98 @@
+entries
+
+#start-bit length config config-ID name
+#0 8 r 0 seconds
+#8 8 r 0 alarm_seconds
+#16 8 r 0 minutes
+#24 8 r 0 alarm_minutes
+#32 8 r 0 hours
+#40 8 r 0 alarm_hours
+#48 8 r 0 day_of_week
+#56 8 r 0 day_of_month
+#64 8 r 0 month
+#72 8 r 0 year
+#80 4 r 0 rate_select
+#84 3 r 0 REF_Clock
+#87 1 r 0 UIP
+#88 1 r 0 auto_switch_DST
+#89 1 r 0 24_hour_mode
+#90 1 r 0 binary_values_enable
+#91 1 r 0 square-wave_out_enable
+#92 1 r 0 update_finished_enable
+#93 1 r 0 alarm_interrupt_enable
+#94 1 r 0 periodic_interrupt_enable
+#95 1 r 0 disable_clock_updates
+#96 288 r 0 temporary_filler
+0 384 r 0 reserved_memory
+384 1 e 4 boot_option
+385 1 e 4 last_boot
+386 1 e 1 ECC_memory
+388 4 r 0 reboot_bits
+392 3 e 5 baud_rate
+395 1 e 1 hw_scrubber
+396 1 e 1 interleave_chip_selects
+397 2 e 8 max_mem_clock
+399 1 e 2 dual_core
+400 1 e 1 power_on_after_fail
+412 4 e 6 debug_level
+416 4 e 7 boot_first
+420 4 e 7 boot_second
+424 4 e 7 boot_third
+428 4 h 0 boot_index
+432 8 h 0 boot_countdown
+440 4 e 9 slow_cpu
+444 1 e 1 nmi
+445 1 e 1 iommu
+728 256 h 0 user_data
+984 16 h 0 check_sum
+# Reserve the extended AMD configuration registers
+1000 24 r 0 reserved_memory
+
+
+
+enumerations
+
+#ID value text
+1 0 Disable
+1 1 Enable
+2 0 Enable
+2 1 Disable
+4 0 Fallback
+4 1 Normal
+5 0 115200
+5 1 57600
+5 2 38400
+5 3 19200
+5 4 9600
+5 5 4800
+5 6 2400
+5 7 1200
+6 6 Notice
+6 7 Info
+6 8 Debug
+6 9 Spew
+7 0 Network
+7 1 HDD
+7 2 Floppy
+7 8 Fallback_Network
+7 9 Fallback_HDD
+7 10 Fallback_Floppy
+#7 3 ROM
+8 0 200Mhz
+8 1 166Mhz
+8 2 133Mhz
+8 3 100Mhz
+9 0 off
+9 1 87.5%
+9 2 75.0%
+9 3 62.5%
+9 4 50.0%
+9 5 37.5%
+9 6 25.0%
+9 7 12.5%
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/tyan/s2895/failover.c b/src/mainboard/tyan/s2895/failover.c
new file mode 100644
index 0000000000..a70264ec2f
--- /dev/null
+++ b/src/mainboard/tyan/s2895/failover.c
@@ -0,0 +1,118 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+
+#include <device/pnp_def.h>
+
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/mc146818rtc_early.c"
+
+#include "southbridge/nvidia/ck804/ck804_enable_rom.c"
+#include "northbridge/amd/amdk8/early_ht.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+
+#include "superio/smsc/lpc47b397/lpc47b397_early_serial.c"
+#include "superio/smsc/lpc47b397/lpc47b397_early_gpio.c"
+
+#define SUPERIO_GPIO_DEV PNP_DEV(0x2e, LPC47B397_RT)
+
+#define SUPERIO_GPIO_IO_BASE 0x400
+
+static void sio_setup(void)
+{
+
+ unsigned value;
+ uint32_t dword;
+ uint8_t byte;
+
+ pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1, 0), 0xac, 0x047f0400);
+
+ byte = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b);
+ byte |= 0x20;
+ pci_write_config8(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b, byte);
+
+ dword = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0);
+ dword |= (1<<29)|(1<<0);
+ pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0, dword);
+
+#if 1
+ lpc47b397_enable_serial(SUPERIO_GPIO_DEV, SUPERIO_GPIO_IO_BASE);
+
+ value = lpc47b397_gpio_offset_in(SUPERIO_GPIO_IO_BASE, 0x77);
+ value &= 0xbf;
+ lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x77, value);
+#endif
+
+}
+
+
+
+static unsigned long main(unsigned long bist)
+{
+ unsigned nodeid;
+ /* Make cerain my local apic is useable */
+// enable_lapic();
+
+ nodeid = lapicid();;
+ /* Is this a cpu only reset? */
+ if (cpu_init_detected(nodeid)) {
+ if (last_boot_normal()) {
+ goto normal_image;
+ } else {
+ goto cpu_reset;
+ }
+ }
+
+ /* Is this a secondary cpu? */
+ if (!boot_cpu()) {
+ if (last_boot_normal()) {
+ goto normal_image;
+ } else {
+ goto fallback_image;
+ }
+ }
+
+ /* Nothing special needs to be done to find bus 0 */
+ /* Allow the HT devices to be found */
+
+ enumerate_ht_chain();
+
+ sio_setup();
+
+ /* Setup the ck804 */
+ ck804_enable_rom();
+
+ /* Is this a deliberate reset by the bios */
+ if (bios_reset_detected() && last_boot_normal()) {
+ goto normal_image;
+ }
+ /* This is the primary cpu how should I boot? */
+ else if (do_normal_boot()) {
+ goto normal_image;
+ }
+ else {
+ goto fallback_image;
+ }
+ normal_image:
+ asm volatile ("jmp __normal_image"
+ : /* outputs */
+ : "a" (bist) /* inputs */
+ : /* clobbers */
+ );
+ cpu_reset:
+#if 0
+ //CPU reset will reset memtroller ???
+ asm volatile ("jmp __cpu_reset"
+ : /* outputs */
+ : "a"(bist) /* inputs */
+ : /* clobbers */
+ );
+#endif
+
+ fallback_image:
+ return bist;
+}
diff --git a/src/mainboard/tyan/s2895/irq_tables.c b/src/mainboard/tyan/s2895/irq_tables.c
new file mode 100644
index 0000000000..8fe7516dca
--- /dev/null
+++ b/src/mainboard/tyan/s2895/irq_tables.c
@@ -0,0 +1,39 @@
+/* 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*11, /* there can be total 11 devices on the bus */
+ 1, /* Where the interrupt router lies (bus) */
+ ((CK804_DEVN_BASE+9)<<3)|0, /* Where the interrupt router lies (dev) */
+ 0, /* IRQs devoted exclusively to PCI usage */
+ 0x10de, /* Vendor */
+ 0x005c, /* Device */
+ 0, /* Crap (miniport) */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+#if CK804_DEVN_BASE==0
+ 0x31, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
+#else
+ 0x19,
+#endif
+ {
+ {1,((CK804_DEVN_BASE+9)<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0},
+ {0x4,(1<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0},
+ {0x7,((CK804_DEVN_BASE+9)<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x0, 0},
+ {0x5,(3<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x1, 0},
+ {0x5,(6<<3)|0, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x2, 0},
+ {0x4,(8<<3)|0, {{0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}}, 0x3, 0},
+ {0x4,(7<<3)|0, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x4, 0},
+ {0x6,(0x0a<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x5, 0},
+ {0x4,(9<<3)|0, {{0x1, 0xdef8}, {2, 0xdef8}, {0, 0}, {0, 0}}, 0, 0},
+ {0x6,(0x0b<<3)|0, {{0x2, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0},
+ {0x6,(0x0c<<3)|0, {{0x4, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0},
+ }
+};
diff --git a/src/mainboard/tyan/s2895/mainboard.c b/src/mainboard/tyan/s2895/mainboard.c
new file mode 100644
index 0000000000..044be53d61
--- /dev/null
+++ b/src/mainboard/tyan/s2895/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "chip.h"
+
+#if CONFIG_CHIP_NAME == 1
+struct chip_operations mainboard_tyan_s2895_ops = {
+ CHIP_NAME("Tyan s2895 mainboard")
+};
+#endif
diff --git a/src/mainboard/tyan/s2895/mptable.c b/src/mainboard/tyan/s2895/mptable.c
new file mode 100644
index 0000000000..61ab3f26a8
--- /dev/null
+++ b/src/mainboard/tyan/s2895/mptable.c
@@ -0,0 +1,298 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+ static const char sig[4] = "PCMP";
+ static const char oem[8] = "TYAN ";
+ static const char productid[12] = "S2895 ";
+ struct mp_config_table *mc;
+
+ unsigned char bus_num;
+ unsigned char bus_isa;
+ unsigned char bus_ck804_0; //1
+ unsigned char bus_ck804_1; //2
+ unsigned char bus_ck804_2; //3
+ unsigned char bus_ck804_3; //4
+ unsigned char bus_ck804_4; //5
+ unsigned char bus_ck804_5; //6
+ unsigned char bus_8131_0; //7
+ unsigned char bus_8131_1; //8
+ unsigned char bus_8131_2; //9
+ unsigned char bus_ck804b_0;//a
+ unsigned char bus_ck804b_1;//b
+ unsigned char bus_ck804b_2;//c
+ unsigned char bus_ck804b_3;//d
+ unsigned char bus_ck804b_4;//e
+ unsigned char bus_ck804b_5;//f
+ unsigned apicid_base;
+ unsigned apicid_ck804;
+ unsigned apicid_8131_1;
+ unsigned apicid_8131_2;
+ unsigned apicid_ck804b;
+
+
+ mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+ memset(mc, 0, sizeof(*mc));
+
+ memcpy(mc->mpc_signature, sig, sizeof(sig));
+ mc->mpc_length = sizeof(*mc); /* initially just the header */
+ mc->mpc_spec = 0x04;
+ mc->mpc_checksum = 0; /* not yet computed */
+ memcpy(mc->mpc_oem, oem, sizeof(oem));
+ memcpy(mc->mpc_productid, productid, sizeof(productid));
+ mc->mpc_oemptr = 0;
+ mc->mpc_oemsize = 0;
+ mc->mpc_entry_count = 0; /* No entries yet... */
+ mc->mpc_lapic = LAPIC_ADDR;
+ mc->mpe_length = 0;
+ mc->mpe_checksum = 0;
+ mc->reserved = 0;
+
+ smp_write_processors(mc);
+
+ {
+ device_t dev;
+
+
+ /* CK804 */
+ bus_ck804_0 = 1;
+ dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0));
+ if (dev) {
+ bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_ck804_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_ck804_5++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09);
+
+ bus_ck804_1 = 2;
+ bus_ck804_5 = 3;
+
+ }
+
+ dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0));
+ if (dev) {
+ bus_ck804_5 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_8131_0 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_8131_0++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n",CK804_DEVN_BASE + 0x0e);
+
+ bus_8131_0 = bus_ck804_5+1;
+ }
+
+ /* 8131-1 */
+ dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x01,0));
+ if (dev) {
+ bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_8131_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_8131_2++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI %02x:01.0, using defaults\n", bus_8131_0);
+
+ bus_8131_1 = bus_8131_0+1;
+ bus_8131_2 = bus_8131_0+2;
+ }
+ /* 8131-2 */
+ dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x02,0));
+ if (dev) {
+ bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_ck804b_0 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_ck804b_0++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI %02x:02.0, using defaults\n", bus_8131_0);
+
+ bus_8131_2 = bus_8131_1+1;
+ bus_ck804b_0 = bus_8131_1+2;
+ }
+
+ /* CK804b */
+
+ dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0));
+ if (dev) {
+ bus_ck804b_5 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_isa++;
+ }
+ else {
+ printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x0e);
+#if 1
+ bus_ck804b_5 = bus_ck804b_0+1;
+#endif
+
+ bus_isa = bus_ck804b_5+1;
+ }
+
+ }
+
+
+
+/*Bus: Bus ID Type*/
+ /* define bus and isa numbers */
+ for(bus_num = 0; bus_num < bus_isa; bus_num++) {
+ smp_write_bus(mc, bus_num, "PCI ");
+ }
+ smp_write_bus(mc, bus_isa, "ISA ");
+
+/*I/O APICs: APIC ID Version State Address*/
+ apicid_base = CONFIG_MAX_CPUS;
+ apicid_ck804 = apicid_base;
+ apicid_8131_1 = apicid_base+1;
+ apicid_8131_2 = apicid_base+2;
+ apicid_ck804b = apicid_base+3;
+// smp_write_ioapic(mc, 2, 0x11, 0xfec00000);
+ {
+ device_t dev;
+ struct resource *res;
+ uint32_t dword;
+
+ dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE+ 0x1,0));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_1);
+ if (res) {
+ smp_write_ioapic(mc, apicid_ck804, 0x11, res->base);
+ }
+
+ dword = 0x0120d218;
+ pci_write_config32(dev, 0x7c, dword);
+
+ dword = 0x00001a00;
+ pci_write_config32(dev, 0x80, dword);
+
+ dword = 0x00080d72;
+ pci_write_config32(dev, 0x84, dword);
+
+ }
+
+ dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x1,1));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base);
+ }
+ }
+ dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x2,1));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base);
+ }
+ }
+
+ dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x1,0));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_1);
+ if (res) {
+ smp_write_ioapic(mc, apicid_ck804b, 0x11, res->base);
+ }
+
+ dword = 0x0000d218;
+ pci_write_config32(dev, 0x7c, dword);
+
+ dword = 0x00000000;
+ pci_write_config32(dev, 0x80, dword);
+
+ dword = 0x00000d00;
+ pci_write_config32(dev, 0x84, dword);
+
+ }
+
+ }
+
+/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#
+*/ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_ck804, 0x0);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_ck804, 0x1);
+ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_ck804, 0x2);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_ck804, 0x3);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_ck804, 0x4);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_ck804, 0x6);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_ck804, 0x7);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_ck804, 0x8);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_ck804, 0xc);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_ck804, 0xd);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_ck804, 0xe);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_ck804, 0xf);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x16);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x17);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+4)<<2)|0, apicid_ck804, 0x14);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x11);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x12);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +0x0a)<<2)|0, apicid_ck804, 0x15);
+
+#if 1
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); //
+#endif
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x05<<2)|0, apicid_ck804, 0x13); //
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); //
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_0, ((CK804_DEVN_BASE+0x0a)<<2)|0, apicid_ck804b, 0x15);//
+
+#if 1
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|0, apicid_ck804b, 0x12);//
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|1, apicid_ck804b, 0x13); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|2, apicid_ck804b, 0x10); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|3, apicid_ck804b, 0x11); //
+#endif
+
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|0, apicid_8131_2, 0x0); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|1, apicid_8131_2, 0x1);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|2, apicid_8131_2, 0x2); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|3, apicid_8131_2, 0x3); //
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x1); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x2);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|2, apicid_8131_2, 0x3);//
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|3, apicid_8131_2, 0x0);//
+
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, apicid_8131_2, 0x2); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, apicid_8131_2, 0x3);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, apicid_8131_1, 0x0); //
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|1, apicid_8131_1, 0x1);//
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|2, apicid_8131_1, 0x2);//
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|3, apicid_8131_1, 0x3);//
+
+/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
+ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0);
+ smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1);
+ /* There is no extension information... */
+
+ /* Compute the checksums */
+ mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+ mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+ printk_debug("Wrote the mp table end at: %p - %p\n",
+ mc, smp_next_mpe_entry(mc));
+ return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+ void *v;
+ v = smp_write_floating_table(addr);
+ return (unsigned long)smp_write_config_table(v);
+}
diff --git a/src/mainboard/tyan/s2895/resourcemap.c b/src/mainboard/tyan/s2895/resourcemap.c
new file mode 100644
index 0000000000..f35252c085
--- /dev/null
+++ b/src/mainboard/tyan/s2895/resourcemap.c
@@ -0,0 +1,267 @@
+/*
+ * Tyan S2895 needs a different resource map
+ *
+ */
+
+static void setup_s2895_resource_map(void)
+{
+ static const unsigned int register_values[] = {
+ /* Careful set limit registers before base registers which contain the enables */
+ /* DRAM Limit i Registers
+ * F1:0x44 i = 0
+ * F1:0x4C i = 1
+ * F1:0x54 i = 2
+ * F1:0x5C i = 3
+ * F1:0x64 i = 4
+ * F1:0x6C i = 5
+ * F1:0x74 i = 6
+ * F1:0x7C i = 7
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 7: 3] Reserved
+ * [10: 8] Interleave select
+ * specifies the values of A[14:12] to use with interleave enable.
+ * [15:11] Reserved
+ * [31:16] DRAM Limit Address i Bits 39-24
+ * This field defines the upper address bits of a 40 bit address
+ * that define the end of the DRAM region.
+ */
+ PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
+ PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
+ PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
+ PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
+ PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
+ PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
+ PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
+
+ /* DRAM Base i Registers
+ * F1:0x40 i = 0
+ * F1:0x48 i = 1
+ * F1:0x50 i = 2
+ * F1:0x58 i = 3
+ * F1:0x60 i = 4
+ * F1:0x68 i = 5
+ * F1:0x70 i = 6
+ * F1:0x78 i = 7
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 7: 2] Reserved
+ * [10: 8] Interleave Enable
+ * 000 = No interleave
+ * 001 = Interleave on A[12] (2 nodes)
+ * 010 = reserved
+ * 011 = Interleave on A[12] and A[14] (4 nodes)
+ * 100 = reserved
+ * 101 = reserved
+ * 110 = reserved
+ * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
+ * [15:11] Reserved
+ * [13:16] DRAM Base Address i Bits 39-24
+ * This field defines the upper address bits of a 40-bit address
+ * that define the start of the DRAM region.
+ */
+ PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
+
+ /* Memory-Mapped I/O Limit i Registers
+ * F1:0x84 i = 0
+ * F1:0x8C i = 1
+ * F1:0x94 i = 2
+ * F1:0x9C i = 3
+ * F1:0xA4 i = 4
+ * F1:0xAC i = 5
+ * F1:0xB4 i = 6
+ * F1:0xBC i = 7
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 3: 3] Reserved
+ * [ 5: 4] Destination Link ID
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 = Reserved
+ * [ 6: 6] Reserved
+ * [ 7: 7] Non-Posted
+ * 0 = CPU writes may be posted
+ * 1 = CPU writes must be non-posted
+ * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
+ * This field defines the upp adddress bits of a 40-bit address that
+ * defines the end of a memory-mapped I/O region n
+ */
+ PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000,
+// PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff00,
+
+ /* Memory-Mapped I/O Base i Registers
+ * F1:0x80 i = 0
+ * F1:0x88 i = 1
+ * F1:0x90 i = 2
+ * F1:0x98 i = 3
+ * F1:0xA0 i = 4
+ * F1:0xA8 i = 5
+ * F1:0xB0 i = 6
+ * F1:0xB8 i = 7
+ * [ 0: 0] Read Enable
+ * 0 = Reads disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes disabled
+ * 1 = Writes Enabled
+ * [ 2: 2] Cpu Disable
+ * 0 = Cpu can use this I/O range
+ * 1 = Cpu requests do not use this I/O range
+ * [ 3: 3] Lock
+ * 0 = base/limit registers i are read/write
+ * 1 = base/limit registers i are read-only
+ * [ 7: 4] Reserved
+ * [31: 8] Memory-Mapped I/O Base Address i (39-16)
+ * This field defines the upper address bits of a 40bit address
+ * that defines the start of memory-mapped I/O region i
+ */
+ PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000,
+// PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003,
+
+ /* PCI I/O Limit i Registers
+ * F1:0xC4 i = 0
+ * F1:0xCC i = 1
+ * F1:0xD4 i = 2
+ * F1:0xDC i = 3
+ * [ 2: 0] Destination Node ID
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 3: 3] Reserved
+ * [ 5: 4] Destination Link ID
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 = reserved
+ * [11: 6] Reserved
+ * [24:12] PCI I/O Limit Address i
+ * This field defines the end of PCI I/O region n
+ * [31:25] Reserved
+ */
+ PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x00007000,
+ PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x01fff001,
+ PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000,
+
+ /* PCI I/O Base i Registers
+ * F1:0xC0 i = 0
+ * F1:0xC8 i = 1
+ * F1:0xD0 i = 2
+ * F1:0xD8 i = 3
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 3: 2] Reserved
+ * [ 4: 4] VGA Enable
+ * 0 = VGA matches Disabled
+ * 1 = matches all address < 64K and where A[9:0] is in the
+ * range 3B0-3BB or 3C0-3DF independen of the base & limit registers
+ * [ 5: 5] ISA Enable
+ * 0 = ISA matches Disabled
+ * 1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
+ * from matching agains this base/limit pair
+ * [11: 6] Reserved
+ * [24:12] PCI I/O Base i
+ * This field defines the start of PCI I/O region n
+ * [31:25] Reserved
+ */
+ PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000033,
+ PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00008033,
+ PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000,
+
+ /* Config Base and Limit i Registers
+ * F1:0xE0 i = 0
+ * F1:0xE4 i = 1
+ * F1:0xE8 i = 2
+ * F1:0xEC i = 3
+ * [ 0: 0] Read Enable
+ * 0 = Reads Disabled
+ * 1 = Reads Enabled
+ * [ 1: 1] Write Enable
+ * 0 = Writes Disabled
+ * 1 = Writes Enabled
+ * [ 2: 2] Device Number Compare Enable
+ * 0 = The ranges are based on bus number
+ * 1 = The ranges are ranges of devices on bus 0
+ * [ 3: 3] Reserved
+ * [ 6: 4] Destination Node
+ * 000 = Node 0
+ * 001 = Node 1
+ * 010 = Node 2
+ * 011 = Node 3
+ * 100 = Node 4
+ * 101 = Node 5
+ * 110 = Node 6
+ * 111 = Node 7
+ * [ 7: 7] Reserved
+ * [ 9: 8] Destination Link
+ * 00 = Link 0
+ * 01 = Link 1
+ * 10 = Link 2
+ * 11 - Reserved
+ * [15:10] Reserved
+ * [23:16] Bus Number Base i
+ * This field defines the lowest bus number in configuration region i
+ * [31:24] Bus Number Limit i
+ * This field defines the highest bus number in configuration region i
+ */
+ PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x07000003,
+ PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x7f080203,
+ PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0xff800013,
+ PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000,
+
+ };
+
+ int max;
+ max = sizeof(register_values)/sizeof(register_values[0]);
+ setup_resource_map(register_values, max);
+}
+
diff --git a/src/northbridge/amd/amdk8/early_ht.c b/src/northbridge/amd/amdk8/early_ht.c
index af9453492b..ab9d4592dd 100644
--- a/src/northbridge/amd/amdk8/early_ht.c
+++ b/src/northbridge/amd/amdk8/early_ht.c
@@ -7,6 +7,7 @@ static int enumerate_ht_chain(void)
*/
unsigned next_unitid, last_unitid;
int reset_needed = 0;
+
next_unitid = 1;
do {
uint32_t id;
@@ -16,18 +17,25 @@ static int enumerate_ht_chain(void)
id = pci_read_config32(PCI_DEV(0,0,0), PCI_VENDOR_ID);
/* If the chain is enumerated quit */
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0x0000))
- {
+ (((id >> 16) & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0x0000)) {
break;
}
+
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+
hdr_type = pci_read_config8(PCI_DEV(0,0,0), PCI_HEADER_TYPE);
pos = 0;
hdr_type &= 0x7f;
if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
- (hdr_type == PCI_HEADER_TYPE_BRIDGE))
- {
+ (hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
pos = pci_read_config8(PCI_DEV(0,0,0), PCI_CAPABILITY_LIST);
}
while(pos != 0) {
@@ -38,17 +46,22 @@ static int enumerate_ht_chain(void)
flags = pci_read_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS);
if ((flags >> 13) == 0) {
unsigned count;
+
flags &= ~0x1f;
flags |= next_unitid & 0x1f;
count = (flags >> 5) & 0x1f;
+
pci_write_config16(PCI_DEV(0, 0, 0), pos + PCI_CAP_FLAGS, flags);
+
next_unitid += count;
break;
}
}
pos = pci_read_config8(PCI_DEV(0, 0, 0), pos + PCI_CAP_LIST_NEXT);
}
- } while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
+ } while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
+
+
return reset_needed;
}
diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c
index ee7e5dc66d..d76a3e8731 100644
--- a/src/northbridge/amd/amdk8/incoherent_ht.c
+++ b/src/northbridge/amd/amdk8/incoherent_ht.c
@@ -6,9 +6,15 @@
#include <device/pci_ids.h>
#include <device/hypertransport_def.h>
+#ifndef K8_HT_FREQ_1G_SUPPORT
+ #define K8_HT_FREQ_1G_SUPPORT 0
+#endif
+
static inline void print_linkn_in (const char *strval, uint8_t byteval)
{
+#if 0
print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
+#endif
}
static uint8_t ht_lookup_slave_capability(device_t dev)
@@ -70,6 +76,15 @@ static void ht_collapse_previous_enumeration(uint8_t bus)
(id == 0x0000ffff) || (id == 0xffff0000)) {
continue;
}
+#if 0
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+#endif
pos = ht_lookup_slave_capability(dev);
if (!pos) {
@@ -97,15 +112,20 @@ static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos)
/* AMD 8131 Errata 48 */
if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
freq_cap &= ~(1 << HT_FREQ_800Mhz);
- }
+ return freq_cap;
+ }
+
/* AMD 8151 Errata 23 */
if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
freq_cap &= ~(1 << HT_FREQ_800Mhz);
- }
+ return freq_cap;
+ }
+
/* AMD K8 Unsupported 1Ghz? */
if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
- freq_cap &= ~(1 << HT_FREQ_1000Mhz);
+ freq_cap &= ~(1 << HT_FREQ_1000Mhz);
}
+
return freq_cap;
}
@@ -208,7 +228,7 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
* non Coherent links the appropriate bus registers for the
* links needs to be programed to point at bus 0.
*/
- unsigned next_unitid, last_unitid;
+ uint8_t next_unitid, last_unitid;
int reset_needed;
unsigned uoffs;
@@ -221,7 +241,8 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
do {
uint32_t id;
uint8_t pos;
- uint16_t flags, count;
+ uint16_t flags;
+ uint8_t count;
unsigned offs;
device_t dev = PCI_DEV(0, 0, 0);
@@ -240,6 +261,12 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
print_err("HT link capability not found\r\n");
break;
}
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+ if(id != 0x005e10de) {
+#endif
/* Update the Unitid of the current device */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
@@ -248,24 +275,35 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
dev = PCI_DEV(0, next_unitid, 0);
+#if CK804_DEVN_BASE==0
+ }
+ else {
+ dev = PCI_DEV(0, 0, 0);
+ }
+#endif
/* Compute the number of unitids consumed */
count = (flags >> 5) & 0x1f;
next_unitid += count;
-
+
/* get ht direction */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ??
-
+
offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
/* Setup the Hypertransport link */
reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
- /* Remeber the location of the last device */
- udev = dev;
- upos = pos;
- uoffs = (offs != PCI_HT_SLAVE0_OFFS) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
+#if CK804_DEVN_BASE==0
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+ /* Remeber the location of the last device */
+ udev = dev;
+ upos = pos;
+ uoffs = (offs != PCI_HT_SLAVE0_OFFS) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
return reset_needed;
@@ -273,7 +311,7 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
{
- unsigned next_unitid, last_unitid;
+ uint8_t next_unitid, last_unitid;
unsigned uoffs;
int reset_needed=0;
@@ -283,13 +321,15 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
do {
uint32_t id;
uint8_t pos;
- uint16_t flags, count;
+ uint16_t flags;
+ uint8_t count;
unsigned offs;
device_t dev = PCI_DEV(bus, 0, 0);
last_unitid = next_unitid;
id = pci_read_config32(dev, PCI_VENDOR_ID);
+
/* If the chain is enumerated quit */
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
@@ -299,34 +339,53 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
pos = ht_lookup_slave_capability(dev);
if (!pos) {
- print_err("HT link capability not found\r\n");
+ print_err(" HT link capability not found\r\n");
break;
}
- /* Update the Unitid of the current device */
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
- flags &= ~0x1f; /* mask out the bse Unit ID */
- flags |= next_unitid & 0x1f;
- pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+ if(id != 0x005e10de) {
+#endif
+
+ /* Update the Unitid of the current device */
+ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
+ flags &= ~0x1f; /* mask out the bse Unit ID */
+ flags |= next_unitid & 0x1f;
+ pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
- dev = PCI_DEV(bus, next_unitid, 0);
+ dev = PCI_DEV(bus, next_unitid, 0);
+#if CK804_DEVN_BASE==0
+ }
+ else {
+ dev = PCI_DEV(bus, 0, 0);
+ }
+#endif
/* Compute the number of unitids consumed */
count = (flags >> 5) & 0x1f;
next_unitid += count;
/* get ht direction */
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ??
+ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ??
offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
-
+
/* Setup the Hypertransport link */
reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
- /* Remeber the location of the last device */
- udev = dev;
- upos = pos;
- uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
+#if CK804_DEVN_BASE==0
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+
+ /* Remeber the location of the last device */
+ udev = dev;
+ upos = pos;
+ uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
return reset_needed;
diff --git a/src/northbridge/amd/amdk8/setup_resource_map.c b/src/northbridge/amd/amdk8/setup_resource_map.c
new file mode 100644
index 0000000000..74bbfdf646
--- /dev/null
+++ b/src/northbridge/amd/amdk8/setup_resource_map.c
@@ -0,0 +1,196 @@
+#define RES_DEBUG 0
+
+#define RES_PCI_IO 0x10
+#define RES_PORT_IO_8 0x22
+#define RES_PORT_IO_32 0x20
+#define RES_MEM_IO 0x30
+
+static void setup_resource_map_x(const unsigned int *register_values, int max)
+{
+ int i;
+
+#if RES_DEBUG
+ print_debug("setting up resource map ex....");
+
+#endif
+
+#if RES_DEBUG
+ print_debug("\r\n");
+#endif
+ for(i = 0; i < max; i += 4) {
+#if RES_DEBUG
+ print_debug_hex16(i/4);
+ print_debug(": ");
+ print_debug_hex8(register_values[i]);
+ print_debug(" ");
+ print_debug_hex32(register_values[i+1]);
+ print_debug(" <- & ");
+ print_debug_hex32(register_values[i+2]);
+ print_debug(" | ");
+ print_debug_hex32(register_values[i+3]);
+ print_debug("\r\n");
+#endif
+ switch (register_values[i]) {
+ case RES_PCI_IO: //PCI
+ {
+ device_t dev;
+ unsigned where;
+ unsigned long reg;
+ dev = register_values[i+1] & ~0xff;
+ where = register_values[i+1] & 0xff;
+ reg = pci_read_config32(dev, where);
+ reg &= register_values[i+2];
+ reg |= register_values[i+3];
+ pci_write_config32(dev, where, reg);
+ }
+ break;
+ case RES_PORT_IO_8: // io 8
+ {
+ unsigned where;
+ unsigned reg;
+ where = register_values[i+1];
+ reg = inb(where);
+ reg &= register_values[i+2];
+ reg |= register_values[i+3];
+ outb(reg, where);
+ }
+ break;
+ case RES_PORT_IO_32: //io32
+ {
+ unsigned where;
+ unsigned long reg;
+ where = register_values[i+1];
+ reg = inl(where);
+ reg &= register_values[i+2];
+ reg |= register_values[i+3];
+ outl(reg, where);
+ }
+ break;
+#if 0
+ case RES_MEM_IO: //mem
+ {
+ unsigned where;
+ unsigned long reg;
+ where = register_values[i+1];
+ reg = read32(where);
+ reg &= register_values[i+2];
+ reg |= register_values[i+3];
+ write32( where, reg);
+ }
+ break;
+#endif
+
+ } // switch
+
+
+ }
+
+#if RES_DEBUG
+ print_debug("done.\r\n");
+#endif
+}
+
+
+static void setup_iob_resource_map(const unsigned int *register_values, int max)
+{
+ int i;
+
+ for(i = 0; i < max; i += 3) {
+ unsigned where;
+ unsigned reg;
+
+ where = register_values[i];
+#if 0
+ udelay(2000);
+ print_debug_hex16(where);
+#endif
+ reg = inb(where);
+#if 0
+ print_debug("=");
+ print_debug_hex8(reg);
+#endif
+
+ reg &= register_values[i+1];
+ reg |= register_values[i+2];
+#if 0
+ print_debug(" <- ");
+ print_debug_hex8(reg);
+#endif
+ outb(reg, where);
+#if 0
+
+ print_debug(" -> ");
+ reg = inb(where);
+ print_debug_hex8(reg);
+ print_debug("\r\n");
+#endif
+ }
+}
+
+static void setup_io_resource_map(const unsigned int *register_values, int max)
+{
+ int i;
+
+ for(i = 0; i < max; i += 3) {
+ unsigned where;
+ unsigned long reg;
+
+ where = register_values[i];
+#if 0
+ udelay(2000);
+ print_debug_hex16(where);
+#endif
+
+ reg = inl(where);
+#if 0
+ udelay(2000);
+ print_debug("=");
+ print_debug_hex32(reg);
+#endif
+ reg &= register_values[i+1];
+ reg |= register_values[i+2];
+
+#if 0
+ udelay(2000);
+ print_debug(" <- ");
+ print_debug_hex32(reg);
+#endif
+ outl(reg, where);
+#if 0
+ udelay(2000);
+ print_debug(" -> ");
+ reg = inl(where);
+ print_debug_hex32(reg);
+ print_debug("\r\n");
+#endif
+ }
+}
+
+#if 0
+static void setup_mem_resource_map(const unsigned int *register_values, int max)
+{
+ int i;
+
+ for(i = 0; i < max; i += 3) {
+ unsigned where;
+ unsigned long reg;
+#if 0
+ print_debug_hex32(register_values[i]);
+ print_debug(" <-");
+ print_debug_hex32(register_values[i+2]);
+#endif
+ where = register_values[i];
+ reg = read32(where);
+ reg &= register_values[i+1];
+ reg |= register_values[i+2];
+ write32( where, reg);
+#if 0
+ print_debug(" RB ");
+ reg = read32(where);
+ print_debug_hex32(reg);
+ print_debug("\r\n");
+#endif
+ }
+}
+#endif
+
diff --git a/src/southbridge/nvidia/ck804/Config.lb b/src/southbridge/nvidia/ck804/Config.lb
new file mode 100644
index 0000000000..a4562192ae
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/Config.lb
@@ -0,0 +1,14 @@
+config chip.h
+driver ck804.o
+driver ck804_usb.o
+driver ck804_lpc.o
+driver ck804_smbus.o
+driver ck804_ide.o
+driver ck804_sata.o
+driver ck804_usb2.o
+driver ck804_ac97.o
+driver ck804_nic.o
+driver ck804_pci.o
+driver ck804_pcie.o
+driver ck804_ht.o
+object ck804_reset.o
diff --git a/src/southbridge/nvidia/ck804/chip.h b/src/southbridge/nvidia/ck804/chip.h
new file mode 100644
index 0000000000..a9b18fb021
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/chip.h
@@ -0,0 +1,18 @@
+#ifndef CK804_CHIP_H
+#define CK804_CHIP_H
+
+struct southbridge_nvidia_ck804_config
+{
+ unsigned int ide0_enable : 1;
+ unsigned int ide1_enable : 1;
+ unsigned int sata0_enable : 1;
+ unsigned int sata1_enable : 1;
+ unsigned long nic_rom_address;
+ unsigned long raid_rom_address;
+ unsigned int mac_eeprom_smbus;
+ unsigned int mac_eeprom_addr;
+};
+struct chip_operations;
+extern struct chip_operations southbridge_nvidia_ck804_ops;
+
+#endif /* CK804_CHIP_H */
diff --git a/src/southbridge/nvidia/ck804/ck804.c b/src/southbridge/nvidia/ck804/ck804.c
new file mode 100644
index 0000000000..a4b77c3596
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+
+#include <console/console.h>
+
+#include <arch/io.h>
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static uint32_t final_reg;
+
+static device_t find_lpc_dev( device_t dev, unsigned devfn)
+{
+
+ device_t lpc_dev;
+
+ lpc_dev = dev_find_slot(dev->bus->secondary, devfn);
+
+ if ( !lpc_dev ) return lpc_dev;
+
+ if ((lpc_dev->vendor != PCI_VENDOR_ID_NVIDIA) || (
+ (lpc_dev->device != PCI_DEVICE_ID_NVIDIA_CK804_LPC) &&
+ (lpc_dev->device != PCI_DEVICE_ID_NVIDIA_CK804_PRO) &&
+ (lpc_dev->device != PCI_DEVICE_ID_NVIDIA_CK804_SLAVE)) ) {
+ uint32_t id;
+ id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
+ if ( (id != (PCI_VENDOR_ID_NVIDIA | (PCI_DEVICE_ID_NVIDIA_CK804_LPC << 16))) &&
+ (id != (PCI_VENDOR_ID_NVIDIA | (PCI_DEVICE_ID_NVIDIA_CK804_PRO << 16))) &&
+ (id != (PCI_VENDOR_ID_NVIDIA | (PCI_DEVICE_ID_NVIDIA_CK804_SLAVE << 16)))
+ ) {
+ lpc_dev = 0;
+ }
+ }
+
+ return lpc_dev;
+}
+
+void ck804_enable(device_t dev)
+{
+ device_t lpc_dev;
+ unsigned index = 0;
+ unsigned index2 = 0;
+ uint32_t reg_old, reg;
+ uint8_t byte;
+ unsigned deviceid;
+ unsigned vendorid;
+
+ struct southbridge_nvidia_ck804_config *conf;
+ conf = dev->chip_info;
+
+ unsigned devfn;
+
+ if(dev->device==0x0000) {
+ vendorid = pci_read_config32(dev, PCI_VENDOR_ID);
+ deviceid = (vendorid>>16) & 0xffff;
+// vendorid &= 0xffff;
+ } else {
+// vendorid = dev->vendor;
+ deviceid = dev->device;
+ }
+
+ devfn = (dev->path.u.pci.devfn) & ~7;
+ switch(deviceid) {
+ case PCI_DEVICE_ID_NVIDIA_CK804_SM:
+ index = 16;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_USB:
+ devfn -= (1<<3);
+ index = 8;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_USB2:
+ devfn -= (1<<3);
+ index = 20;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_NIC:
+ devfn -= (9<<3);
+ index = 10;
+ dev->rom_address = conf->nic_rom_address;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE:
+ devfn -= (9<<3);
+ index = 10;
+ dev->rom_address = conf->nic_rom_address;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_ACI:
+ devfn -= (3<<3);
+ index = 12;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_MCI:
+ devfn -= (3<<3);
+ index = 13;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_IDE:
+ devfn -= (5<<3);
+ index = 14;
+ dev->rom_address = conf->raid_rom_address;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_SATA0:
+ devfn -= (6<<3);
+ index = 22;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_SATA1:
+ devfn -= (7<<3);
+ index = 18;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_PCI:
+ devfn -= (8<<3);
+ index = 15;
+ break;
+ case PCI_DEVICE_ID_NVIDIA_CK804_PCI_E:
+ devfn -= (0xa<<3);
+ index2 = 19;
+ break;
+ default:
+ index = 0;
+ }
+
+ if(index2!=0) {
+ int i;
+ for(i=0;i<4;i++) {
+ lpc_dev = find_lpc_dev(dev, devfn - (i<<3));
+ if(!lpc_dev) continue;
+ index2 -= i;
+ break;
+ }
+
+ if ( lpc_dev ) {
+ reg_old = reg = pci_read_config32(lpc_dev, 0xe4);
+
+ if (!dev->enabled) {
+ reg |= (1<<index2);
+ }
+
+ if (reg != reg_old) {
+ pci_write_config32(lpc_dev, 0xe4, reg);
+ }
+ }
+
+ index2 = 0;
+ return;
+ }
+
+
+ lpc_dev = find_lpc_dev(dev, devfn);
+
+ if ( !lpc_dev ) return;
+
+ if ( index == 0) {
+
+ final_reg = pci_read_config32(lpc_dev, 0xe8);
+ final_reg &= ~((1<<16)|(1<<8)|(1<<20)|(1<<10)|(1<<12)|(1<<13)|(1<<14)|(1<<22)|(1<<18)|(1<<15));
+ pci_write_config32(lpc_dev, 0xe8, final_reg);
+
+#if 1
+ reg_old = reg = pci_read_config32(lpc_dev, 0xe4);
+ reg |= (1<<20);
+ if (reg != reg_old) {
+ pci_write_config32(lpc_dev, 0xe4, reg);
+ }
+#endif
+
+ byte = pci_read_config8(lpc_dev, 0x74);
+ byte |= ((1<<1));
+ pci_write_config8(dev, 0x74, byte);
+
+ byte = pci_read_config8(lpc_dev, 0xdd);
+ byte |= ((1<<0)|(1<<3));
+ pci_write_config8(dev, 0xdd, byte);
+
+ return;
+
+ }
+
+ if (!dev->enabled) {
+ final_reg |= (1 << index);
+ }
+
+ if(index == 10 ) {
+ reg_old = pci_read_config32(lpc_dev, 0xe8);
+ if (final_reg != reg_old) {
+ pci_write_config32(lpc_dev, 0xe8, final_reg);
+ }
+
+ }
+
+}
+
+struct chip_operations southbridge_nvidia_ck804_ops = {
+ CHIP_NAME("Nvidia ck804")
+ .enable_dev = ck804_enable,
+};
diff --git a/src/southbridge/nvidia/ck804/ck804.h b/src/southbridge/nvidia/ck804/ck804.h
new file mode 100644
index 0000000000..cad4e42d63
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804.h
@@ -0,0 +1,8 @@
+#ifndef CK804_H
+#define CK804_H
+
+#include "chip.h"
+
+void ck804_enable(device_t dev);
+
+#endif /* CK804_H */
diff --git a/src/southbridge/nvidia/ck804/ck804_ac97.c b/src/southbridge/nvidia/ck804/ck804_ac97.c
new file mode 100644
index 0000000000..36a7d3f17a
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_ac97.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+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 = ck804_enable,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver ac97audio_driver __pci_driver = {
+ .ops = &ac97audio_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_ACI,
+};
+
+
+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 = ck804_enable,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver ac97modem_driver __pci_driver = {
+ .ops = &ac97modem_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_MCI,
+};
diff --git a/src/southbridge/nvidia/ck804/ck804_early_setup.c b/src/southbridge/nvidia/ck804/ck804_early_setup.c
new file mode 100644
index 0000000000..0d300bbd21
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_early_setup.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
+{
+ uint32_t dword, dword_old;
+ uint8_t link_type;
+
+ dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
+ link_type = dword & 0xff;
+
+ dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x90 + (linkn * 0x20) );
+
+ if ( (link_type & 0x7) == linkt ) {
+ dword = val;
+ }
+
+ if (dword != dword_old) {
+ pci_write_config32(PCI_DEV(0,0x18+node,0), 0x90 + (linkn * 0x20), dword);
+ return 1;
+ }
+
+ return 0;
+}
+static int set_ht_link_ck804(uint8_t ht_c_num)
+{
+ int reset_needed;
+ uint8_t i;
+
+ reset_needed = 0;
+
+ for (i = 0; i < ht_c_num; i++) {
+ uint32_t reg;
+ uint8_t nodeid, linkn;
+ uint8_t busn;
+ unsigned val;
+
+ reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
+ if((reg & 3) != 3) continue;
+
+ nodeid = ((reg & 0xf0)>>4);
+ linkn = ((reg & 0xf00)>>8);
+ busn = (reg & 0xff0000)>>16;
+
+ reg = pci_read_config32( PCI_DEV(busn, 1, 0), PCI_VENDOR_ID);
+ if ( (reg & 0xffff) == 0x10de ) {
+ val = 0x01610169;
+ reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
+ }
+ }
+
+ return reset_needed;
+}
+
+
+static void setup_ss_table(unsigned index, unsigned where, unsigned control, const unsigned int *register_values, int max)
+{
+ int i;
+
+ unsigned val;
+
+ val = inl(control);
+ val &= 0xfffffffe;
+ outl(val, control);
+
+ outl(0, index);
+
+ for(i = 0; i < max; i++) {
+ unsigned long reg;
+ reg = register_values[i];
+ outl(reg, where);
+ }
+ val = inl(control);
+ val |= 1;
+ outl(val, control);
+
+}
+
+#define ANACTRL_IO_BASE 0x7000
+#define ANACTRL_REG_POS 0x68
+
+
+#define SYSCTRL_IO_BASE 0x6000
+#define SYSCTRL_REG_POS 0x64
+
+/*
+ 16 1 1 2 :0
+ 8 8 2 2 :1
+ 8 8 4 :2
+ 8 4 4 4 :3
+ 16 4 :4
+*/
+
+#ifndef CK804_PCI_E_X
+ #define CK804_PCI_E_X 4
+#endif
+
+#if CK804_NUM > 1
+ #define CK804B_ANACTRL_IO_BASE (ANACTRL_IO_BASE+0x8000)
+ #define CK804B_SYSCTRL_IO_BASE (SYSCTRL_IO_BASE+0x8000)
+
+ #ifndef CK804B_BUSN
+ #define CK804B_BUSN 0x80
+ #endif
+
+ #ifndef CK804B_PCI_E_X
+ #define CK804B_PCI_E_X 4
+ #endif
+#endif
+
+#ifndef CK804_USE_NIC
+ #define CK804_USE_NIC 0
+#endif
+
+#ifndef CK804_USE_ACI
+ #define CK804_USE_ACI 0
+#endif
+
+#define CK804_CHIP_REV 3
+
+static void ck804_early_set_port(void)
+{
+
+ static const unsigned int ctrl_devport_conf[] = {
+ PCI_ADDR(0, (CK804_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), ANACTRL_IO_BASE,
+#if CK804_NUM > 1
+ PCI_ADDR(CK804B_BUSN, (CK804_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), CK804B_ANACTRL_IO_BASE,
+#endif
+
+ PCI_ADDR(0, (CK804_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), SYSCTRL_IO_BASE,
+#if CK804_NUM > 1
+ PCI_ADDR(CK804B_BUSN, (CK804_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), CK804B_SYSCTRL_IO_BASE,
+#endif
+ };
+
+ setup_resource_map(ctrl_devport_conf, sizeof(ctrl_devport_conf)/sizeof(ctrl_devport_conf[0]));
+
+}
+
+static void ck804_early_clear_port(void)
+{
+
+ static const unsigned int ctrl_devport_conf_clear[] = {
+ PCI_ADDR(0, (CK804_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), 0,
+#if CK804_NUM > 1
+ PCI_ADDR(CK804B_BUSN, (CK804_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), 0,
+#endif
+
+ PCI_ADDR(0, (CK804_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), 0,
+#if CK804_NUM > 1
+ PCI_ADDR(CK804B_BUSN, (CK804_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), 0,
+#endif
+ };
+
+ setup_resource_map(ctrl_devport_conf_clear, sizeof(ctrl_devport_conf_clear)/sizeof(ctrl_devport_conf_clear[0]));
+
+}
+
+static void ck804_early_setup(void)
+{
+
+ static const unsigned int ctrl_conf[] = {
+
+
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+1 , 2, 0x8c), 0xffff0000, 0x00009880,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+1 , 2, 0x90), 0xffff000f, 0x000074a0,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+1 , 2, 0xa0), 0xfffff0ff, 0x00000a00,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+1 , 2, 0xac), 0xffffff00, 0x00000000,
+
+
+#if CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+1 , 2, 0x8c), 0xffff0000, 0x00009880,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+1 , 2, 0x90), 0xffff000f, 0x000074a0,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+1 , 2, 0xa0), 0xfffff0ff, 0x00000a00,
+#endif
+
+
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE , 0, 0x48), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE , 0, 0x74), 0xfffff00f, 0x000009d0,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE , 0, 0x8c), 0xffff0000, 0x0000007f,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE , 0, 0xcc), 0xfffffff8, 0x00000003,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE , 0, 0xd0), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE , 0, 0xd4), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE , 0, 0xd8), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE , 0, 0xdc), 0x7f000000, 0x00000000,
+
+
+#if CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE , 0, 0x48), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE , 0, 0x74), 0xfffff00f, 0x000009d0,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE , 0, 0x8c), 0xffff0000, 0x0000007f,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE , 0, 0xcc), 0xfffffff8, 0x00000003,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE , 0, 0xd0), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE , 0, 0xd4), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE , 0, 0xd8), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE , 0, 0xdc), 0x7f000000, 0x00000000,
+#endif
+
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+1 , 0, 0xf0), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0,CK804_DEVN_BASE+1,0,0xf8), 0xffffffcf, 0x00000010,
+
+#if CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+1 , 0, 0xf0), 0xfffffffd, 0x00000002,
+ RES_PCI_IO,PCI_ADDR(CK804B_BUSN,CK804_DEVN_BASE+1,0,0xf8), 0xffffffcf, 0x00000010,
+#endif
+
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+9 , 0, 0x40), 0xfff8ffff, 0x00030000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+9 , 0, 0x4c), 0xfe00ffff, 0x00440000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+9 , 0, 0x74), 0xffffffc0, 0x00000000,
+
+#if CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+9 , 0, 0x40), 0xfff8ffff, 0x00030000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+9 , 0, 0x4c), 0xfe00ffff, 0x00440000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+9 , 0, 0x74), 0xffffffc0, 0x00000000,
+#endif
+
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+1 , 0, 0x78), 0xc0ffffff, 0x19000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+1 , 0, 0xe0), 0xfffffeff, 0x00000100,
+
+
+
+#if CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+1 , 0, 0x78), 0xc0ffffff, 0x20000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN,CK804_DEVN_BASE+1,0,0xe0), 0xfffffeff, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+1 , 0, 0xe8), 0xffffff00, 0x000000ff,
+#endif
+
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x74, ~(0xffff), 0x0f008,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x78, ~((0xff)|(0xff<<16)), (0x41<<16)|(0x32),
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x7c, ~(0xff<<16), (0xa0<<16),
+
+#if CK804_NUM > 1
+
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
+
+#endif
+
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
+#if CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
+#endif
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x04, ~((0x3ff<<0)|(0x3ff<<10)), (0x21<<0)|(0x22<<10),
+#if CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x04, ~((0x3ff<<0)|(0x3ff<<10)), (0x21<<0)|(0x22<<10),
+#endif
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c<<10)|0x1b,
+#if CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c<<10)|0x1b,
+#endif
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, ~(1<<3), 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, ~((7<<4)|(1<<8)), (CK804_PCI_E_X<<4)|(1<<8),
+#if CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0xcc, ~((7<<4)|(1<<8)), (CK804B_PCI_E_X<<4)|(1<<8),
+#endif
+
+
+
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 8, ~(0xff), ((0<<4)|(0<<2)|(0<<0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 9, ~(0xff), ((0<<4)|(1<<2)|(1<<0)),
+#if CK804_USE_NIC == 1
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE+0xa , 0, 0xf8), 0xffffffbf, 0x00000040,
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+19, ~(0xff), ((0<<4)|(1<<2)|(0<<0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 3, ~(0xff), ((0<<4)|(1<<2)|(0<<0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 3, ~(0xff), ((0<<4)|(1<<2)|(1<<0)),
+#endif
+
+#if CK804_USE_ACI == 1
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+0x0d, ~(0xff), ((0<<4)|(2<<2)|(0<<0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+0x1a, ~(0xff), ((0<<4)|(2<<2)|(0<<0)),
+#endif
+
+#if CK804_NUM > 1
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 0, ~(3<<2), (0<<2),
+#endif
+
+
+#if CK804_NUM > 1
+ #if CK804_USE_NIC == 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804_DEVN_BASE+0xa , 0, 0xf8), 0xffffffbf, 0x00000040,
+ RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0+19, ~(0xff), ((0<<4)|(1<<2)|(0<<0)),
+ RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0+ 3, ~(0xff), ((0<<4)|(1<<2)|(0<<0)),
+ RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0+ 3, ~(0xff), ((0<<4)|(1<<2)|(1<<0)),
+ #endif
+#endif
+
+
+
+#ifdef CK804_MB_SETUP
+ CK804_MB_SETUP
+#endif
+
+ };
+
+
+
+ setup_resource_map_x(ctrl_conf, sizeof(ctrl_conf)/sizeof(ctrl_conf[0]));
+
+ setup_ss_table(ANACTRL_IO_BASE+0x40, ANACTRL_IO_BASE+0x44, ANACTRL_IO_BASE+0x48, pcie_ss_tbl, 64);
+ setup_ss_table(ANACTRL_IO_BASE+0xb0, ANACTRL_IO_BASE+0xb4, ANACTRL_IO_BASE+0xb8, sata_ss_tbl, 64);
+ setup_ss_table(ANACTRL_IO_BASE+0xc0, ANACTRL_IO_BASE+0xc4, ANACTRL_IO_BASE+0xc8, cpu_ss_tbl, 64);
+
+#if CK804_NUM > 1
+ setup_ss_table(CK804B_ANACTRL_IO_BASE+0x40, CK804B_ANACTRL_IO_BASE+0x44, CK804B_ANACTRL_IO_BASE+0x48, pcie_ss_tbl,64);
+ setup_ss_table(CK804B_ANACTRL_IO_BASE+0xb0, CK804B_ANACTRL_IO_BASE+0xb4, CK804B_ANACTRL_IO_BASE+0xb8, sata_ss_tbl,64);
+ setup_ss_table(CK804B_ANACTRL_IO_BASE+0xc0, CK804B_ANACTRL_IO_BASE+0xc4, CK804B_ANACTRL_IO_BASE+0xc8, cpu_ss_tbl,64);
+#endif
+
+#if 0
+ dump_io_resources(ANACTRL_IO_BASE);
+ dump_io_resources(SYSCTRL_IO_BASE);
+#endif
+
+}
+
+static int ck804_early_setup_x(void)
+{
+ ck804_early_set_port();
+ ck804_early_setup();
+ ck804_early_clear_port();
+ return set_ht_link_ck804(4);
+}
diff --git a/src/southbridge/nvidia/ck804/ck804_early_setup_ss.h b/src/southbridge/nvidia/ck804/ck804_early_setup_ss.h
new file mode 100644
index 0000000000..0ab7939f3a
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_early_setup_ss.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+
+static const unsigned int pcie_ss_tbl[] = {
+ 0x0C504103f,
+ 0x0C504103f,
+ 0x0C504103f,
+ 0x0C5042040,
+ 0x0C5042040,
+ 0x0C5042040,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C504a048,
+ 0x0C504a048,
+ 0x0C504b049,
+ 0x0C504b049,
+ 0x0C504a048,
+ 0x0C504a048,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5042040,
+ 0x0C5042040,
+};
+static const unsigned int sata_ss_tbl[] = {
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9044042,
+};
+
+static const unsigned int cpu_ss_tbl[] = {
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+};
+
+
diff --git a/src/southbridge/nvidia/ck804/ck804_early_smbus.c b/src/southbridge/nvidia/ck804/ck804_early_smbus.c
new file mode 100644
index 0000000000..29f97d0ecf
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_early_smbus.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+
+#include "ck804_smbus.h"
+
+#define SMBUS_IO_BASE 0x1000
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ dev = pci_locate_device(PCI_ID(0x10de, 0x0052), 0);
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\r\n");
+ }
+
+ print_debug("SMBus controller enabled\r\n");
+ /* set smbus iobase */
+ pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+ /* Set smbus iospace enable */
+ pci_write_config16(dev, 0x4, 0x01);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+static int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val);
+}
diff --git a/src/southbridge/nvidia/ck804/ck804_enable_rom.c b/src/southbridge/nvidia/ck804/ck804_enable_rom.c
new file mode 100644
index 0000000000..48ce689358
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_enable_rom.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+
+static void ck804_enable_rom(void)
+{
+ unsigned char byte;
+ device_t addr;
+
+ /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */
+ /* Locate the ck804 LPC */
+ addr = PCI_DEV(0, (CK804_DEVN_BASE+1), 0);
+
+ /* Set the 4MB enable bit bit */
+ byte = pci_read_config8(addr, 0x88);
+ byte |= 0x80;
+ pci_write_config8(addr, 0x88, byte);
+}
diff --git a/src/southbridge/nvidia/ck804/ck804_ht.c b/src/southbridge/nvidia/ck804/ck804_ht.c
new file mode 100644
index 0000000000..d8a82a3e34
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_ht.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations ht_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver ht_driver __pci_driver = {
+ .ops = &ht_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_HT,
+};
+
diff --git a/src/southbridge/nvidia/ck804/ck804_ide.c b/src/southbridge/nvidia/ck804/ck804_ide.c
new file mode 100644
index 0000000000..f927f2a7cc
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_ide.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void ide_init(struct device *dev)
+{
+ struct southbridge_nvidia_ck804_config *conf;
+ /* Enable ide devices so the linux ide driver will work */
+ uint32_t dword;
+ uint16_t word;
+ uint8_t byte;
+ conf = dev->chip_info;
+
+ word = pci_read_config16(dev, 0x50);
+ /* Ensure prefetch is disabled */
+ word &= ~((1 << 15) | (1 << 13));
+ if (conf->ide1_enable) {
+ /* Enable secondary ide interface */
+ word |= (1<<0);
+ printk_debug("IDE1 \t");
+ }
+ if (conf->ide0_enable) {
+ /* Enable primary ide interface */
+ word |= (1<<1);
+ printk_debug("IDE0\n");
+ }
+
+ word |= (1<<12);
+ word |= (1<<14);
+
+ pci_write_config16(dev, 0x50, word);
+
+
+ byte = 0x20 ; // Latency: 64-->32
+ pci_write_config8(dev, 0xd, byte);
+
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 12;
+ pci_write_config32(dev, 0xf8, dword);
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);
+#endif
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+// .enable = ck804_enable,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_IDE,
+};
+
diff --git a/src/southbridge/nvidia/ck804/ck804_lpc.c b/src/southbridge/nvidia/ck804/ck804_lpc.c
new file mode 100644
index 0000000000..ea37b241d5
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_lpc.c
@@ -0,0 +1,411 @@
+/*
+ * (C) 2003 Linux Networx, SuSE Linux AG
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include "ck804.h"
+
+#define CK804_CHIP_REV 2
+
+#define NMI_OFF 0
+
+struct ioapicreg {
+ unsigned int reg;
+ unsigned int value_low, value_high;
+};
+
+static struct ioapicreg ioapicregvalues[] = {
+#define ALL (0xff << 24)
+#define NONE (0)
+#define DISABLED (1 << 16)
+#define ENABLED (0 << 16)
+#define TRIGGER_EDGE (0 << 15)
+#define TRIGGER_LEVEL (1 << 15)
+#define POLARITY_HIGH (0 << 13)
+#define POLARITY_LOW (1 << 13)
+#define PHYSICAL_DEST (0 << 11)
+#define LOGICAL_DEST (1 << 11)
+#define ExtINT (7 << 8)
+#define NMI (4 << 8)
+#define SMI (2 << 8)
+#define INT (1 << 8)
+ /* IO-APIC virtual wire mode configuration */
+ /* mask, trigger, polarity, destination, delivery, vector */
+ { 0, ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT, NONE},
+ { 1, DISABLED, NONE},
+ { 2, DISABLED, NONE},
+ { 3, DISABLED, NONE},
+ { 4, DISABLED, NONE},
+ { 5, DISABLED, NONE},
+ { 6, DISABLED, NONE},
+ { 7, DISABLED, NONE},
+ { 8, DISABLED, NONE},
+ { 9, DISABLED, NONE},
+ { 10, DISABLED, NONE},
+ { 11, DISABLED, NONE},
+ { 12, DISABLED, NONE},
+ { 13, DISABLED, NONE},
+ { 14, DISABLED, NONE},
+ { 15, DISABLED, NONE},
+ { 16, DISABLED, NONE},
+ { 17, DISABLED, NONE},
+ { 18, DISABLED, NONE},
+ { 19, DISABLED, NONE},
+ { 20, DISABLED, NONE},
+ { 21, DISABLED, NONE},
+ { 22, DISABLED, NONE},
+ { 23, DISABLED, NONE},
+ /* Be careful and don't write past the end... */
+};
+
+static void setup_ioapic(unsigned long ioapic_base)
+{
+ int i;
+ unsigned long value_low, value_high;
+// unsigned long ioapic_base = 0xfec00000;
+ volatile unsigned long *l;
+ struct ioapicreg *a = ioapicregvalues;
+
+ l = (unsigned long *) ioapic_base;
+
+ for (i = 0; i < sizeof(ioapicregvalues) / sizeof(ioapicregvalues[0]);
+ i++, a++) {
+ l[0] = (a->reg * 2) + 0x10;
+ l[4] = a->value_low;
+ value_low = l[4];
+ l[0] = (a->reg *2) + 0x11;
+ l[4] = a->value_high;
+ value_high = l[4];
+ if ((i==0) && (value_low == 0xffffffff)) {
+ printk_warning("IO APIC not responding.\n");
+ return;
+ }
+ printk_spew("for IRQ, reg 0x%08x value 0x%08x 0x%08x\n",
+ a->reg, a->value_low, a->value_high);
+ }
+}
+
+// 0x7a or e3
+#define PREVIOUS_POWER_STATE 0x7A
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+#define SLOW_CPU_OFF 0
+#define SLOW_CPU__ON 1
+
+#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+static void lpc_common_init(device_t dev)
+{
+ uint8_t byte;
+ uint32_t dword;
+
+ /* IO APIC initialization */
+ byte = pci_read_config8(dev, 0x74);
+ byte |= (1<<0); // enable APIC
+ pci_write_config8(dev, 0x74, byte);
+ dword = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14
+
+ setup_ioapic(dword);
+
+#if 1
+ dword = pci_read_config32(dev, 0xe4);
+ dword |= (1<<23);
+ pci_write_config32(dev, 0xe4, dword);
+#endif
+
+}
+
+static void lpc_slave_init(device_t dev)
+{
+ lpc_common_init(dev);
+}
+
+static void rom_dummy_write(device_t dev){
+ uint8_t old, new;
+ uint8_t *p;
+
+ old = pci_read_config8(dev, 0x88);
+ new = old | 0xc0;
+ if (new != old) {
+ pci_write_config8(dev, 0x88, new);
+ }
+ // enable write
+ old = pci_read_config8(dev, 0x6d);
+ new = old | 0x01;
+ if (new != old) {
+ pci_write_config8(dev, 0x6d, new);
+ }
+
+ /* dummy write */
+ p = (uint8_t *)0xffffffe0;
+ old = 0;
+ *p = old;
+ old = *p;
+
+ // disable write
+ old = pci_read_config8(dev, 0x6d);
+ new = old & 0xfe;
+ if (new != old) {
+ pci_write_config8(dev, 0x6d, new);
+
+ }
+
+}
+#if 0
+static void enable_hpet(struct device *dev)
+{
+ unsigned long hpet_address;
+
+ pci_write_config32(dev,0x44, 0xfed00001);
+ hpet_address=pci_read_config32(dev,0x44)& 0xfffffffe;
+ printk_debug("enabling HPET @0x%x\n", hpet_address);
+}
+#endif
+
+static void lpc_init(device_t dev)
+{
+ uint8_t byte;
+ uint8_t byte_old;
+ int on;
+ int nmi_option;
+
+ lpc_common_init(dev);
+
+#if CK804_CHIP_REV==1
+ if(dev->bus->secondary!=1) return;
+#endif
+
+#if 0
+ /* posted memory write enable */
+ byte = pci_read_config8(dev, 0x46);
+ pci_write_config8(dev, 0x46, byte | (1<<0));
+
+#endif
+ /* power after power fail */
+
+ 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");
+
+ /* Throttle the CPU speed down for testing */
+ on = SLOW_CPU_OFF;
+ get_option(&on, "slow_cpu");
+ if(on) {
+ uint16_t pm10_bar;
+ uint32_t dword;
+ pm10_bar = (pci_read_config16(dev, 0x60)&0xff00);
+ outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
+ dword = inl(pm10_bar + 0x10);
+ on = 8-on;
+ printk_debug("Throttling CPU %2d.%1.1d percent.\n",
+ (on*12)+(on>>1),(on&1)*5);
+ }
+
+#if 0
+// default is enabled
+ /* Enable Port 92 fast reset */
+ byte = pci_read_config8(dev, 0xe8);
+ byte |= ~(1 << 3);
+ pci_write_config8(dev, 0xe8, byte);
+#endif
+
+ /* Enable Error reporting */
+ /* Set up sync flood detected */
+ byte = pci_read_config8(dev, 0x47);
+ byte |= (1 << 1);
+ pci_write_config8(dev, 0x47, byte);
+
+ /* Set up NMI on errors */
+ byte = inb(0x70); // RTC70
+ byte_old = byte;
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* set NMI */
+ } else {
+ byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
+ }
+ if( byte != byte_old) {
+ outb(0x70, byte);
+ }
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+
+ /* Initialize the High Precision Event Timers */
+// enable_hpet(dev);
+
+ rom_dummy_write(dev);
+
+}
+
+static void ck804_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+ unsigned long index;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev); // We got one for APIC, or one more for TRAP
+
+ /* Get Resource for ACPI, SYSTEM_CONTROL, ANALOG_CONTROL */
+ for (index = 0x60; index <= 0x68; index+=4) { // We got another 3.
+ pci_get_resource(dev, index);
+ }
+ compact_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+}
+
+/**
+ * @brief Enable resources for children devices
+ *
+ * @param dev the device whos children's resources are to be enabled
+ *
+ * This function is call by the global enable_resources() indirectly via the
+ * device_operation::enable_resources() method of devices.
+ *
+ * Indirect mutual recursion:
+ * enable_childrens_resources() -> enable_resources()
+ * enable_resources() -> device_operation::enable_resources()
+ * device_operation::enable_resources() -> enable_children_resources()
+ */
+static void ck804_lpc_enable_childrens_resources(device_t dev)
+{
+ unsigned link;
+ uint32_t reg, reg_var[4];
+ int i;
+ int var_num = 0;
+
+ reg = pci_read_config32(dev, 0xa0);
+
+ for (link = 0; link < dev->links; link++) {
+ device_t child;
+ for (child = dev->link[link].children; child; child = child->sibling) {
+ enable_resources(child);
+ if(child->have_resources && (child->path.type == DEVICE_PATH_PNP)) {
+ for(i=0;i<child->resources;i++) {
+ struct resource *res;
+ unsigned long base, end; // don't need long long
+ res = &child->resource[i];
+ if(!(res->flags & IORESOURCE_IO)) continue;
+ base = res->base;
+ end = resource_end(res);
+ printk_debug("ck804 lpc decode:%s, base=0x%08x, end=0x%08x\r\n",dev_path(child),base, end);
+ switch(base) {
+ case 0x3f8: // COM1
+ reg |= (1<<0); break;
+ case 0x2f8: // COM2
+ reg |= (1<<1); break;
+ case 0x378: // Parallal 1
+ reg |= (1<<24); break;
+ case 0x3f0: // FD0
+ reg |= (1<<20); break;
+ case 0x220: // Aduio 0
+ reg |= (1<<8); break;
+ case 0x300: // Midi 0
+ reg |= (1<<12); break;
+ }
+ if( base == 0x290 || base >= 0x400) {
+ if(var_num>=4) continue; // only 4 var ; compact them ?
+ reg |= (1<<(28+var_num));
+ reg_var[var_num++] = (base & 0xffff)|((end & 0xffff)<<16);
+ }
+ }
+ }
+ }
+ }
+ pci_write_config32(dev, 0xa0, reg);
+ for(i=0;i<var_num;i++) {
+ pci_write_config32(dev, 0xa8 + i*4, reg_var[i]);
+ }
+
+
+}
+
+static void ck804_lpc_enable_resources(device_t dev)
+{
+ pci_dev_enable_resources(dev);
+ ck804_lpc_enable_childrens_resources(dev);
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = ck804_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = ck804_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+// .enable = ck804_enable,
+ .ops_pci = &lops_pci,
+};
+static struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_LPC,
+};
+
+static struct pci_driver lpc_driver_pro __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_PRO,
+};
+
+#if CK804_CHIP_REV == 1
+static struct pci_driver lpc_driver_slave __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SLAVE,
+};
+#else
+static struct device_operations lpc_slave_ops = {
+ .read_resources = ck804_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_slave_init,
+// .enable = ck804_enable,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver lpc_driver_slave __pci_driver = {
+ .ops = &lpc_slave_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SLAVE,
+};
+#endif
diff --git a/src/southbridge/nvidia/ck804/ck804_nic.c b/src/southbridge/nvidia/ck804/ck804_nic.c
new file mode 100644
index 0000000000..19b69af465
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_nic.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/smbus.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "ck804.h"
+
+
+static void nic_init(struct device *dev)
+{
+ uint32_t dword, old;
+ uint32_t mac_h, mac_l;
+ int eeprom_valid = 0;
+ struct southbridge_nvidia_ck804_config *conf;
+
+ static uint32_t nic_index = 0;
+
+
+ old = dword = pci_read_config32(dev, 0x30);
+ dword &= ~(0xf);
+ dword |= 0xf;
+ if(old != dword) {
+ pci_write_config32(dev, 0x30 , dword);
+ }
+
+ conf = dev->chip_info;
+
+ if(conf->mac_eeprom_smbus != 0) {
+// read MAC address from EEPROM at first
+ struct device *dev_eeprom;
+ dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr);
+
+ if(dev_eeprom) {
+ // if that is valid we will use that
+ unsigned char dat[6];
+ int status;
+ int i;
+ for(i=0;i<6;i++) {
+ status = smbus_read_byte(dev_eeprom, i);
+ if(status < 0) break;
+ dat[i] = status & 0xff;
+ }
+ if(status >= 0) {
+ mac_l = 0;
+ for(i=3;i>=0;i--) {
+ mac_l <<= 8;
+ mac_l += dat[i];
+ }
+ if(mac_l != 0xffffffff) {
+ mac_l += nic_index;
+ mac_h = 0;
+ for(i=5;i>=4;i--) {
+ mac_h <<= 8;
+ mac_h += dat[i];
+ }
+ eeprom_valid = 1;
+ }
+ }
+ }
+ }
+// if that is invalid we will read that from romstrap
+ if(!eeprom_valid) {
+ unsigned long mac_pos;
+ mac_pos = 0xffffffd0; // refer to romstrap.inc and romstrap.lds
+ mac_l = readl(mac_pos) + nic_index;
+ mac_h = readl(mac_pos + 4);
+ }
+
+// set that into NIC
+ pci_write_config32(dev, 0xa8, mac_l);
+ pci_write_config32(dev, 0xac, mac_h);
+
+ nic_index++;
+
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);// it will init option rom
+#endif
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .scan_bus = 0,
+// .enable = ck804_enable,
+ .ops_pci = &lops_pci,
+};
+static struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC,
+};
+static struct pci_driver nic_bridge_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE,
+};
diff --git a/src/southbridge/nvidia/ck804/ck804_pci.c b/src/southbridge/nvidia/ck804/ck804_pci.c
new file mode 100644
index 0000000000..34e2e9c970
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_pci.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void pci_init(struct device *dev)
+{
+
+ uint32_t dword;
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* System error enable */
+ dword |= (1<<30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+#if 0
+ word = pci_read_config16(dev, 0x48);
+ word |= (1<<0); /* MRL2MRM */
+ word |= (1<<2); /* MR2MRM */
+ pci_write_config16(dev, 0x48, word);
+#endif
+
+#if 1
+ dword = pci_read_config32(dev, 0x4c);
+ dword |= 0x00440000; /*TABORT_SER_ENABLE Park Last Enable.*/
+ pci_write_config32(dev, 0x4c, dword);
+#endif
+
+ dword = dev_root.resource[1].base & (0xffff0000UL);
+ printk_debug("dev_root mem base = 0x%010Lx\n", dev_root.resource[1].base);
+
+ printk_debug("[0x50] <-- 0x%08x\n", dword);
+ pci_write_config32(dev, 0x50, dword); //TOM
+
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+// .enable = ck804_enable,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_PCI,
+};
+
diff --git a/src/southbridge/nvidia/ck804/ck804_pcie.c b/src/southbridge/nvidia/ck804/ck804_pcie.c
new file mode 100644
index 0000000000..3a2ec20a25
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_pcie.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void pcie_init(struct device *dev)
+{
+
+ /* Enable pci error detecting */
+ uint32_t dword;
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* System error enable */
+ dword |= (1<<30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations pcie_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pcie_init,
+ .scan_bus = pci_scan_bridge,
+// .enable = ck804_enable,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver pcie_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_PCI_E,
+};
+
diff --git a/src/southbridge/nvidia/ck804/ck804_reset.c b/src/southbridge/nvidia/ck804/ck804_reset.c
new file mode 100644
index 0000000000..bd1bc5378c
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_reset.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+
+#include <arch/io.h>
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+ (((BUS) & 0xFF) << 16) | \
+ (((DEV) & 0x1f) << 11) | \
+ (((FN) & 0x7) << 8))
+
+typedef unsigned device_t;
+
+static void pci_write_config32(device_t dev, unsigned where, unsigned value)
+{
+ unsigned addr;
+ addr = dev | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outl(value, 0xCFC);
+}
+
+static unsigned pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = dev | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inl(0xCFC);
+}
+
+#include "../../../northbridge/amd/amdk8/reset_test.c"
+
+void hard_reset(void)
+{
+ set_bios_reset();
+ /* Try rebooting through port 0xcf9 */
+ outb((0 <<3)|(0<<2)|(1<<1), 0xcf9);
+ outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
+
diff --git a/src/southbridge/nvidia/ck804/ck804_sata.c b/src/southbridge/nvidia/ck804/ck804_sata.c
new file mode 100644
index 0000000000..97744f6823
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_sata.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+
+static void sata_com_reset(struct device *dev, unsigned reset)
+// reset = 1 : reset
+// reset = 0 : clear
+{
+ uint32_t *base;
+ uint32_t dword;
+ int loop;
+
+ base = (uint32_t *) pci_read_config32(dev, 0x24);
+
+ printk_debug("base = %08x\r\n", base);
+
+ if(reset) {
+ *(base + 4) = 0xffffffff;
+ *(base + 0x44) = 0xffffffff;
+ }
+
+ dword = *(base +8);
+ dword &= ~(0xf);
+ dword |= reset;
+
+ *(base + 8) = dword;
+ *(base + 0x48) = dword;
+
+#if 0
+ udelay(1000);
+ dword &= ~(0xf);
+ *(base + 8) = dword;
+ *(base + 0x48) = dword;
+#endif
+
+
+
+ if(reset) return;
+
+ dword = *(base+ 0);
+ printk_debug("*(base+0)=%08x\r\n",dword);
+ if(dword == 0x113) {
+ loop = 200000;// 2
+ do {
+ dword = *(base + 4);
+ if((dword & 0x10000)!=0) break;
+ udelay(10);
+ } while (--loop>0);
+ printk_debug("loop=%d, *(base+4)=%08x\r\n",loop, dword);
+ }
+
+
+ dword = *(base+ 0x40);
+ printk_debug("*(base+0x40)=%08x\r\n",dword);
+ if(dword == 0x113) {
+ loop = 200000;//2
+ do {
+ dword = *(base + 0x44);
+ if((dword & 0x10000)!=0) break;
+ udelay(10);
+ } while (--loop>0);
+ printk_debug("loop=%d, *(base+0x44)=%08x\r\n",loop, dword);
+ }
+
+
+}
+
+static void sata_init(struct device *dev)
+{
+
+ uint32_t dword;
+
+ struct southbridge_nvidia_ck804_config *conf;
+ conf = dev->chip_info;
+
+ dword = pci_read_config32(dev, 0x50);
+ /* Ensure prefetch is disabled */
+ dword &= ~((1 << 15) | (1 << 13));
+ if (conf->sata1_enable) {
+ /* Enable secondary SATA interface */
+ dword |= (1<<0);
+ printk_debug("SATA S \t");
+ }
+ if (conf->sata0_enable) {
+ /* Enable primary SATA interface */
+ dword |= (1<<1);
+ printk_debug("SATA P \n");
+ }
+// write back
+ dword |= (1<<12);
+ dword |= (1<<14);
+
+#if 1
+// ADMA
+ dword |= (1<<16);
+ dword |= (1<<17);
+#endif
+
+#if 1
+//DO NOT relay OK and PAGE_FRNDLY_DTXFR_CNT.
+ dword &= ~(0x1f<<24);
+ dword |= (0x15<<24);
+#endif
+ pci_write_config32(dev, 0x50, dword);
+
+#if 1
+//SLUMBER_DURING_D3.
+ dword = pci_read_config32(dev, 0x7c);
+ dword &= ~(1<<4);
+ pci_write_config32(dev, 0x7c, dword);
+
+ dword = pci_read_config32(dev, 0xd0);
+ dword &= ~(0xff<<24);
+ dword |= (0x68<<24);
+ pci_write_config32(dev, 0xd0, dword);
+
+ dword = pci_read_config32(dev, 0xe0);
+ dword &= ~(0xff<<24);
+ dword |= (0x68<<24);
+ pci_write_config32(dev, 0xe0, dword);
+#endif
+
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 2;
+ pci_write_config32(dev, 0xf8, dword);
+
+#if 0
+ dword = pci_read_config32(dev, 0xac);
+ dword &= ~((1<<13)|(1<<14));
+ dword |= (1<<13)|(0<<14);
+ pci_write_config32(dev, 0xac, dword);
+
+ sata_com_reset(dev, 1); // for discover some s-atapi device
+#endif
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+// .enable = ck804_enable,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver sata0_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA0,
+};
+
+static struct pci_driver sata1_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA1,
+};
diff --git a/src/southbridge/nvidia/ck804/ck804_smbus.c b/src/southbridge/nvidia/ck804/ck804_smbus.c
new file mode 100644
index 0000000000..0fce134a1c
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_smbus.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include "ck804.h"
+#include "ck804_smbus.h"
+
+static int lsmbus_recv_byte(device_t dev)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.u.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+
+ return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.u.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+
+ return do_smbus_send_byte(res->base, device, val);
+}
+
+static int lsmbus_read_byte(device_t dev, uint8_t address)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.u.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.u.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link * 4));
+
+ return do_smbus_write_byte(res->base, device, address, val);
+}
+static struct smbus_bus_operations lops_smbus_bus = {
+ .recv_byte = lsmbus_recv_byte,
+ .send_byte = lsmbus_send_byte,
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+static struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+// .enable = ck804_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+static struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SM,
+};
+
diff --git a/src/southbridge/nvidia/ck804/ck804_smbus.h b/src/southbridge/nvidia/ck804/ck804_smbus.h
new file mode 100644
index 0000000000..079007836f
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_smbus.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x1
+#define SMBHSTPRTCL 0x0
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x2
+#define SMBHSTDAT0 0x4
+#define SMBHSTDAT1 0x5
+
+/* Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100*1000*10)
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ if ((val & 0x1f) == 0) {
+ break;
+ }
+ if(loops == (SMBUS_TIMEOUT / 2)) {
+ outb((val & 0x1f),smbus_io_base + SMBHSTSTAT);
+ }
+ } while(--loops);
+ return loops?0:-2;
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ if ( (val & 0xff) != 0) {
+ break;
+ }
+ } while(--loops);
+ return loops?0:-3;
+}
+static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+#if 0
+// Don't need, when you write to PRTCL, the status will be cleared automatically
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2;
+ }
+#endif
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
+ smbus_delay();
+ /* set the command/address... */
+ outb(0, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+ /* byte data recv */
+ outb(0x05, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ if (global_status_register != 0x80) { // lose check, otherwise it should be 0
+ return -1;
+ }
+ return byte;
+}
+static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
+{
+ unsigned global_status_register;
+
+#if 0
+// Don't need, when you write to PRTCL, the status will be cleared automatically
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2;
+ }
+#endif
+
+ outb(val, smbus_io_base + SMBHSTDAT0);
+ smbus_delay();
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ outb(0, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* set up for a byte data write */
+ outb(0x04, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
+
+ if (global_status_register != 0x80) {
+ return -1;
+ }
+ return 0;
+}
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+#if 0
+// Don't need, when you write to PRTCL, the status will be cleared automatically
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2;
+ }
+#endif
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
+ smbus_delay();
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+ /* byte data read */
+ outb(0x07, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ if (global_status_register != 0x80) { // lose check, otherwise it should be 0
+ return -1;
+ }
+ return byte;
+}
+
+
+static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
+{
+ unsigned global_status_register;
+
+#if 0
+// Don't need, when you write to PRTCL, the status will be cleared automatically
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2;
+ }
+#endif
+
+ outb(val, smbus_io_base + SMBHSTDAT0);
+ smbus_delay();
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* set up for a byte data write */
+ outb(0x06, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
+
+ if (global_status_register != 0x80) {
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/southbridge/nvidia/ck804/ck804_usb.c b/src/southbridge/nvidia/ck804/ck804_usb.c
new file mode 100644
index 0000000000..a839b7e338
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_usb.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+// .enable = ck804_enable,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver usb_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_USB,
+};
+
diff --git a/src/southbridge/nvidia/ck804/ck804_usb2.c b/src/southbridge/nvidia/ck804/ck804_usb2.c
new file mode 100644
index 0000000000..c3d83684b5
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/ck804_usb2.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void usb2_init(struct device *dev)
+{
+
+ uint32_t dword;
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 40;
+ pci_write_config32(dev, 0xf8, dword);
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+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,
+// .enable = ck804_enable,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver usb2_driver __pci_driver = {
+ .ops = &usb2_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_USB2,
+};
diff --git a/src/southbridge/nvidia/ck804/id.inc b/src/southbridge/nvidia/ck804/id.inc
new file mode 100644
index 0000000000..438065a5c0
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/id.inc
@@ -0,0 +1,16 @@
+
+ .section ".id", "a", @progbits
+
+ .globl __id_start
+__id_start:
+vendor:
+ .asciz MAINBOARD_VENDOR
+part:
+ .asciz MAINBOARD_PART_NUMBER
+.long __id_end + 0x80 - vendor /* Reverse offset to the vendor id */
+.long __id_end + 0x80 - part /* Reverse offset to the part number */
+.long PAYLOAD_SIZE + ROM_IMAGE_SIZE /* Size of this romimage */
+ .globl __id_end
+
+__id_end:
+.previous
diff --git a/src/southbridge/nvidia/ck804/id.lds b/src/southbridge/nvidia/ck804/id.lds
new file mode 100644
index 0000000000..947a2f0c03
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/id.lds
@@ -0,0 +1,6 @@
+SECTIONS {
+ . = (_ROMBASE + ROM_IMAGE_SIZE - 0x80) - (__id_end - __id_start);
+ .id (.): {
+ *(.id)
+ }
+}
diff --git a/src/southbridge/nvidia/ck804/romstrap.inc b/src/southbridge/nvidia/ck804/romstrap.inc
new file mode 100644
index 0000000000..1810f7793d
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/romstrap.inc
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2004 Tyan Computer
+ * by yhlu@tyan.com
+ */
+ .section ".romstrap", "a", @progbits
+
+
+ .globl __romstrap_start
+__romstrap_start:
+rstables:
+ .long 0x2b16d065
+ .long 0x0
+ .long 0x0
+ .long linkedlist
+
+linkedlist:
+ .long 0x0003001C // 10h
+ .long 0x08000000 // 14h
+ .long 0x00000000 // 18h
+ .long 0xFFFFFFFF // 1Ch
+
+ .long 0xFFFFFFFF // 20h
+ .long 0xFFFFFFFF // 24h
+ .long 0xFFFFFFFF // 28h
+ .long 0xFFFFFFFF // 2Ch
+
+ .long 0x81543266 // 30h, MAC address low 4 byte ---> keep it in 0xffffffd0
+ .long 0x000000E0 // 34h, MAC address high 4 byte
+
+ .long 0x002309CE // 38h, UUID low 4 byte
+ .long 0x00E08100 // 3Ch, UUID high 4 byte
+
+rspointers:
+ .long rstables // It will be 0xffffffe0
+ .long rstables
+ .long rstables
+ .long rstables
+
+ .globl __romstrap_end
+
+__romstrap_end:
+.previous
diff --git a/src/southbridge/nvidia/ck804/romstrap.lds b/src/southbridge/nvidia/ck804/romstrap.lds
new file mode 100644
index 0000000000..5b69024629
--- /dev/null
+++ b/src/southbridge/nvidia/ck804/romstrap.lds
@@ -0,0 +1,6 @@
+SECTIONS {
+ . = (_ROMBASE + ROM_IMAGE_SIZE - 0x10) - (__romstrap_end - __romstrap_start);
+ .romstrap (.): {
+ *(.romstrap)
+ }
+}
diff --git a/src/superio/smsc/lpc47b397/Config.lb b/src/superio/smsc/lpc47b397/Config.lb
new file mode 100644
index 0000000000..f62a567d61
--- /dev/null
+++ b/src/superio/smsc/lpc47b397/Config.lb
@@ -0,0 +1,2 @@
+config chip.h
+object superio.o
diff --git a/src/superio/smsc/lpc47b397/chip.h b/src/superio/smsc/lpc47b397/chip.h
new file mode 100644
index 0000000000..452cef51cf
--- /dev/null
+++ b/src/superio/smsc/lpc47b397/chip.h
@@ -0,0 +1,17 @@
+#ifndef SIO_COM1
+#define SIO_COM1_BASE 0x3F8
+#endif
+#ifndef SIO_COM2
+#define SIO_COM2_BASE 0x2F8
+#endif
+
+struct chip_operations;
+extern struct chip_operations superio_smsc_lpc47b397_ops;
+
+#include <pc80/keyboard.h>
+#include <uart8250.h>
+
+struct superio_smsc_lpc47b397_config {
+ struct uart8250 com1, com2;
+ struct pc_keyboard keyboard;
+};
diff --git a/src/superio/smsc/lpc47b397/lpc47b397.h b/src/superio/smsc/lpc47b397/lpc47b397.h
new file mode 100644
index 0000000000..193a971d8c
--- /dev/null
+++ b/src/superio/smsc/lpc47b397/lpc47b397.h
@@ -0,0 +1,7 @@
+#define LPC47B397_FDC 0 /* Floppy */
+#define LPC47B397_PP 3 /* Parallel Port */
+#define LPC47B397_SP1 4 /* Com1 */
+#define LPC47B397_SP2 5 /* Com2 */
+#define LPC47B397_KBC 7 /* Keyboard & Mouse */
+#define LPC47B397_HWM 8 /* HW Monitor */
+#define LPC47B397_RT 10 /* Runtime reg*/
diff --git a/src/superio/smsc/lpc47b397/lpc47b397_early_gpio.c b/src/superio/smsc/lpc47b397/lpc47b397_early_gpio.c
new file mode 100644
index 0000000000..6f27c74db1
--- /dev/null
+++ b/src/superio/smsc/lpc47b397/lpc47b397_early_gpio.c
@@ -0,0 +1,25 @@
+static void lpc47b397_gpio_offset_out(unsigned iobase, unsigned offset, unsigned value)
+{
+ outb(value,iobase+offset);
+}
+static unsigned lpc47b397_gpio_offset_in(unsigned iobase, unsigned offset)
+{
+ return inb(iobase+offset);
+}
+
+//for GP60-GP64, GP66-GP85
+#define LPC47B397_GPIO_CNTL_INDEX 0x70
+#define LPC47B397_GPIO_CNTL_DATA 0x71
+
+static void lpc47b397_gpio_index_out(unsigned iobase, unsigned index, unsigned value)
+{
+ outb(index,iobase+LPC47B397_GPIO_CNTL_INDEX);
+ outb(value, iobase+LPC47B397_GPIO_CNTL_DATA);
+}
+static unsigned lpc47b397_gpio_index_in(unsigned iobase, unsigned index)
+{
+ outb(index,iobase+LPC47B397_GPIO_CNTL_INDEX);
+ return inb(iobase+LPC47B397_GPIO_CNTL_DATA);
+}
+
+
diff --git a/src/superio/smsc/lpc47b397/lpc47b397_early_serial.c b/src/superio/smsc/lpc47b397/lpc47b397_early_serial.c
new file mode 100644
index 0000000000..2a3d3dbd31
--- /dev/null
+++ b/src/superio/smsc/lpc47b397/lpc47b397_early_serial.c
@@ -0,0 +1,20 @@
+#include <arch/romcc_io.h>
+#include "lpc47b397.h"
+
+static inline void pnp_enter_conf_state(device_t dev) {
+ unsigned port = dev>>8;
+ outb(0x55, port);
+}
+static void pnp_exit_conf_state(device_t dev) {
+ unsigned port = dev>>8;
+ outb(0xaa, port);
+}
+static void lpc47b397_enable_serial(device_t dev, unsigned iobase)
+{
+ pnp_enter_conf_state(dev);
+ pnp_set_logical_device(dev);
+ pnp_set_enable(dev, 0);
+ pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
+ pnp_set_enable(dev, 1);
+ pnp_exit_conf_state(dev);
+}
diff --git a/src/superio/smsc/lpc47b397/superio.c b/src/superio/smsc/lpc47b397/superio.c
new file mode 100644
index 0000000000..5a456099c8
--- /dev/null
+++ b/src/superio/smsc/lpc47b397/superio.c
@@ -0,0 +1,244 @@
+/* Copyright 2000 AG Electronics Ltd. */
+/* Copyright 2003-2004 Linux Networx */
+/* Copyright 2004 Tyan
+ */
+
+/* This code is distributed without warranty under the GPL v2 (see COPYING) */
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pnp.h>
+#include <console/console.h>
+#include <device/smbus.h>
+#include <string.h>
+#include <bitops.h>
+#include <uart8250.h>
+#include <pc80/keyboard.h>
+#include "chip.h"
+#include "lpc47b397.h"
+
+
+static void pnp_enter_conf_state(device_t dev) {
+ outb(0x55, dev->path.u.pnp.port);
+}
+static void pnp_exit_conf_state(device_t dev) {
+ outb(0xaa, dev->path.u.pnp.port);
+}
+
+static void pnp_write_index(unsigned long port_base, uint8_t reg, uint8_t value)
+{
+ outb(reg, port_base);
+ outb(value, port_base + 1);
+}
+
+static uint8_t pnp_read_index(unsigned long port_base, uint8_t reg)
+{
+ outb(reg, port_base);
+ return inb(port_base + 1);
+}
+
+static void enable_hwm_smbus(device_t dev) {
+ /* enable SensorBus register access */
+ uint8_t reg, value;
+ reg = 0xf0;
+ value = pnp_read_config(dev, reg);
+ value |= 0x01;
+ pnp_write_config(dev, reg, value);
+}
+#if 0
+static void dump_pnp_device(device_t dev)
+{
+ int i;
+ print_debug("\r\n");
+
+ for(i = 0; i <= 255; i++) {
+ uint8_t reg, val;
+ if ((i & 0x0f) == 0) {
+ print_debug_hex8(i);
+ print_debug_char(':');
+ }
+ reg = i;
+ if(i!=0xaa) {
+ val = pnp_read_config(dev, reg);
+ }
+ else {
+ val = 0xaa;
+ }
+ print_debug_char(' ');
+ print_debug_hex8(val);
+ if ((i & 0x0f) == 0x0f) {
+ print_debug("\r\n");
+ }
+ }
+}
+#endif
+
+
+static void lpc47b397_init(device_t dev)
+{
+ struct superio_smsc_lpc47b397_config *conf;
+ struct resource *res0, *res1;
+ if (!dev->enabled) {
+ return;
+ }
+ conf = dev->chip_info;
+ switch(dev->path.u.pnp.device) {
+ case LPC47B397_SP1:
+ res0 = find_resource(dev, PNP_IDX_IO0);
+ init_uart8250(res0->base, &conf->com1);
+ break;
+ case LPC47B397_SP2:
+ res0 = find_resource(dev, PNP_IDX_IO0);
+ init_uart8250(res0->base, &conf->com2);
+ break;
+ case LPC47B397_KBC:
+ res0 = find_resource(dev, PNP_IDX_IO0);
+ res1 = find_resource(dev, PNP_IDX_IO1);
+ init_pc_keyboard(res0->base, res1->base, &conf->keyboard);
+ break;
+ }
+
+}
+
+void lpc47b397_pnp_set_resources(device_t dev)
+{
+
+ pnp_enter_conf_state(dev);
+
+ pnp_set_resources(dev);
+
+#if 0
+ dump_pnp_device(dev);
+#endif
+
+ pnp_exit_conf_state(dev);
+
+}
+
+void lpc47b397_pnp_enable_resources(device_t dev)
+{
+
+ pnp_enter_conf_state(dev);
+
+ pnp_enable_resources(dev);
+
+ switch(dev->path.u.pnp.device) {
+ case LPC47B397_HWM:
+ printk_debug("lpc47b397 SensorBus Register Access enabled\r\n");
+ pnp_set_logical_device(dev);
+ enable_hwm_smbus(dev);
+ break;
+ }
+
+#if 0
+ dump_pnp_device(dev);
+#endif
+
+ pnp_exit_conf_state(dev);
+
+}
+
+void lpc47b397_pnp_enable(device_t dev)
+{
+
+ pnp_enter_conf_state(dev);
+
+ pnp_set_logical_device(dev);
+
+ if(dev->enabled) {
+ pnp_set_enable(dev, 1);
+ }
+ else {
+ pnp_set_enable(dev, 0);
+ }
+
+ pnp_exit_conf_state(dev);
+
+}
+
+static struct device_operations ops = {
+ .read_resources = pnp_read_resources,
+ .set_resources = lpc47b397_pnp_set_resources,
+ .enable_resources = lpc47b397_pnp_enable_resources,
+ .enable = lpc47b397_pnp_enable,
+ .init = lpc47b397_init,
+};
+
+
+#define HWM_INDEX 0
+#define HWM_DATA 1
+#define SB_INDEX 0x0b
+#define SB_DATA0 0x0c
+#define SB_DATA1 0x0d
+#define SB_DATA2 0x0e
+#define SB_DATA3 0x0f
+
+static int lsmbus_read_byte(device_t dev, uint8_t address)
+{
+ unsigned device;
+ struct resource *res;
+ int result;
+
+ device = dev->path.u.i2c.device;
+
+ res = find_resource(get_pbus_smbus(dev)->dev, PNP_IDX_IO0);
+
+ pnp_write_index(res->base+HWM_INDEX, 0, device); // why 0?
+
+ result = pnp_read_index(res->base+SB_INDEX, address); // we only read it one byte one time
+
+ return result;
+}
+
+static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+
+ device = dev->path.u.i2c.device;
+ res = find_resource(get_pbus_smbus(dev)->dev, PNP_IDX_IO0);
+
+ pnp_write_index(res->base+HWM_INDEX, 0, device); // why 0?
+
+ pnp_write_index(res->base+SB_INDEX, address, val); // we only write it one byte one time
+
+ return 0;
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+// .recv_byte = lsmbus_recv_byte,
+// .send_byte = lsmbus_send_byte,
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+static struct device_operations ops_hwm = {
+ .read_resources = pnp_read_resources,
+ .set_resources = lpc47b397_pnp_set_resources,
+ .enable_resources = lpc47b397_pnp_enable_resources,
+ .enable = lpc47b397_pnp_enable,
+ .init = lpc47b397_init,
+ .scan_bus = scan_static_bus,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static struct pnp_info pnp_dev_info[] = {
+ { &ops, LPC47B397_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
+ { &ops, LPC47B397_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
+ { &ops, LPC47B397_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+ { &ops, LPC47B397_SP2, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+ { &ops, LPC47B397_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, { 0x7ff, 0 }, { 0x7ff, 0x4}, },
+ { &ops_hwm, LPC47B397_HWM, PNP_IO0, { 0x7f0, 0 }, },
+ { &ops, LPC47B397_RT, PNP_IO0, { 0x780, 0 }, },
+};
+
+static void enable_dev(struct device *dev)
+{
+ pnp_enable_devices(dev, &pnp_ops,
+ sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info);
+}
+
+struct chip_operations superio_smsc_lpc47b397_ops = {
+ CHIP_NAME("smsc lpc47b397")
+ .enable_dev = enable_dev,
+};
+