summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYinghai Lu <yinghailu@gmail.com>2006-02-16 17:22:19 +0000
committerYinghai Lu <yinghailu@gmail.com>2006-02-16 17:22:19 +0000
commitafd34e61ace6476946f9f30af92e0f714c901013 (patch)
tree82e1e5673992e2150bb87de3f1d5b6ee955b2b36 /src
parent4d5865d3d48259f43a1d78af8107d46c7a3a73f3 (diff)
serverworks HT1000/HT2000, bcm5785/5780 support
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2176 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src')
-rw-r--r--src/drivers/i2c/i2cmux2/Config.lb2
-rw-r--r--src/drivers/i2c/i2cmux2/chip.h4
-rw-r--r--src/drivers/i2c/i2cmux2/i2cmux2.c43
-rw-r--r--src/mainboard/broadcom/blast/Config.lb300
-rw-r--r--src/mainboard/broadcom/blast/Options.lb262
-rw-r--r--src/mainboard/broadcom/blast/cache_as_ram_auto.c274
-rw-r--r--src/mainboard/broadcom/blast/chip.h6
-rw-r--r--src/mainboard/broadcom/blast/cmos.layout98
-rw-r--r--src/mainboard/broadcom/blast/get_bus_conf.c118
-rw-r--r--src/mainboard/broadcom/blast/irq_tables.c108
-rw-r--r--src/mainboard/broadcom/blast/mainboard.c12
-rw-r--r--src/mainboard/broadcom/blast/mptable.c192
-rw-r--r--src/mainboard/broadcom/blast/resourcemap.c265
-rw-r--r--src/southbridge/broadcom/bcm5780/Config.lb3
-rw-r--r--src/southbridge/broadcom/bcm5780/bcm5780_nic.c49
-rw-r--r--src/southbridge/broadcom/bcm5780/bcm5780_pcie.c46
-rw-r--r--src/southbridge/broadcom/bcm5780/bcm5780_pcix.c37
-rw-r--r--src/southbridge/broadcom/bcm5785/Config.lb8
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785.c80
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785.h8
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c193
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_early_smbus.c45
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_ide.c58
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_lpc.c137
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_reset.c41
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_sata.c78
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_sb_pci_main.c153
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_smbus.h184
-rw-r--r--src/southbridge/broadcom/bcm5785/bcm5785_usb.c49
-rw-r--r--src/southbridge/broadcom/bcm5785/chip.h14
-rw-r--r--src/superio/NSC/pc87417/pc87417_early_serial.c16
-rw-r--r--src/superio/NSC/pc87417/superio.c34
32 files changed, 2900 insertions, 17 deletions
diff --git a/src/drivers/i2c/i2cmux2/Config.lb b/src/drivers/i2c/i2cmux2/Config.lb
new file mode 100644
index 0000000000..a0d83bab2c
--- /dev/null
+++ b/src/drivers/i2c/i2cmux2/Config.lb
@@ -0,0 +1,2 @@
+config chip.h
+object i2cmux2.o
diff --git a/src/drivers/i2c/i2cmux2/chip.h b/src/drivers/i2c/i2cmux2/chip.h
new file mode 100644
index 0000000000..f6fd35f796
--- /dev/null
+++ b/src/drivers/i2c/i2cmux2/chip.h
@@ -0,0 +1,4 @@
+extern struct chip_operations drivers_i2c_i2cmux2_ops;
+
+struct drivers_i2c_i2cmux2_config {
+};
diff --git a/src/drivers/i2c/i2cmux2/i2cmux2.c b/src/drivers/i2c/i2cmux2/i2cmux2.c
new file mode 100644
index 0000000000..30656eafca
--- /dev/null
+++ b/src/drivers/i2c/i2cmux2/i2cmux2.c
@@ -0,0 +1,43 @@
+#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 <cpu/x86/msr.h>
+#include "chip.h"
+
+static void i2cmux2_set_link(device_t dev, unsigned int link)
+{
+ if (dev->enabled && dev->path.type == DEVICE_PATH_I2C)
+ {
+ if(ops_smbus_bus(get_pbus_smbus(dev))) {
+ smbus_send_byte(dev, link); // output value
+ }
+
+ }
+
+}
+static void i2cmux2_noop(device_t dummy)
+{
+}
+
+static struct device_operations i2cmux2_operations = {
+ .read_resources = i2cmux2_noop,
+ .set_resources = i2cmux2_noop,
+ .enable_resources = i2cmux2_noop,
+ .init = i2cmux2_noop,
+ .scan_bus = scan_static_bus,
+ .set_link = i2cmux2_set_link,
+};
+
+static void enable_dev(struct device *dev)
+{
+ if(dev->links>0)
+ dev->ops = &i2cmux2_operations;
+}
+
+struct chip_operations drivers_i2c_i2cmux2_ops = {
+ CHIP_NAME("i2cmux2")
+ .enable_dev = enable_dev,
+};
diff --git a/src/mainboard/broadcom/blast/Config.lb b/src/mainboard/broadcom/blast/Config.lb
new file mode 100644
index 0000000000..412afb4b7d
--- /dev/null
+++ b/src/mainboard/broadcom/blast/Config.lb
@@ -0,0 +1,300 @@
+##
+## 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)
+
+##
+## 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/si/3114
+
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE
+ object get_bus_conf.o
+ object irq_tables.o
+end
+
+#object reset.o
+
+if USE_DCACHE_RAM
+
+ if CONFIG_USE_INIT
+
+ makerule ./cache_as_ram_auto.o
+ depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+ action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o $@"
+ end
+
+ else
+
+ makerule ./cache_as_ram_auto.inc
+ depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+ action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@"
+ action "perl -e 's/.rodata/.rom.data/g' -pi $@"
+ action "perl -e 's/.text/.section .rom.text/g' -pi $@"
+ end
+
+ end
+
+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
+if USE_DCACHE_RAM
+ if CONFIG_USE_INIT
+ ldscript /cpu/x86/32bit/entry32.lds
+ end
+
+ if CONFIG_USE_INIT
+ ldscript /cpu/amd/car/cache_as_ram.lds
+ end
+end
+
+##
+## 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
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+if USE_DCACHE_RAM
+ ##
+ ## Setup Cache-As-Ram
+ ##
+ mainboardinit cpu/amd/car/cache_as_ram.inc
+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
+ if USE_DCACHE_RAM
+ ldscript /arch/i386/lib/failover.lds
+ else
+ ldscript /arch/i386/lib/failover.lds
+ mainboardinit ./failover.inc
+ end
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+if USE_DCACHE_RAM
+
+ if CONFIG_USE_INIT
+ initobject cache_as_ram_auto.o
+ else
+ mainboardinit ./cache_as_ram_auto.inc
+ end
+
+end
+
+##
+## Include the secondary Configuration files
+##
+if CONFIG_CHIP_NAME
+ config chip.h
+end
+
+# sample config for broadcom/blast
+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
+ device pci 18.0 on # northbridge
+ # devices on link 0
+ chip southbridge/broadcom/bcm5780 # HT2000
+ device pci 0.0 on end # PXB 1 0x0130
+ device pci 1.0 on # PXB 2 0x0130
+ device pci 4.0 on end # GB E 0x1668 vid = 0x14e4
+ device pci 4.1 on end # GB E 0x1669 vid = 0x14e4
+ end
+ device pci 2.0 on end # PCI E 1 #0x0132
+ device pci 3.0 on end # PCI E 2
+ device pci 4.0 on end # PCI E 3
+ device pci 5.0 on end # PCI E 4
+ end
+ chip southbridge/broadcom/bcm5785 # HT1000
+ device pci 0.0 on # HT PXB 0x0036
+ device pci d.0 on end # PPBX 0x0104
+ device pci e.0 on end # SATA 0x024a
+ end
+ device pci 1.0 on # Legacy pci main 0x0205
+ chip drivers/i2c/i2cmux2 # pca9554 smbus mux
+ device i2c 71 on end #0 pca9554 0
+ device i2c 71 on end #0 pca9554 1
+ device i2c 71 on end #0 pca9554 2
+ device i2c 71 on end #0 pca9554 3
+ device i2c 71 on end #0 pca9554 4
+ device i2c 71 on end #0 pca9554 5
+ device i2c 71 on #0 pca9554 6
+ 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
+ end
+ device i2c 71 on #1 pca9554 7
+ chip drivers/generic/generic #dimm 1-0-0
+ device i2c 50 on end
+ end
+ chip drivers/generic/generic #dimm 1-0-1
+ device i2c 51 on end
+ end
+ chip drivers/generic/generic #dimm 1-1-0
+ device i2c 52 on end
+ end
+ chip drivers/generic/generic #dimm 1-1-1
+ device i2c 53 on end
+ end
+ end
+ end
+
+ end
+ device pci 1.1 on end # IDE 0x0214
+ device pci 1.2 on # LPC 0x0234
+ chip superio/NSC/pc87417
+ device pnp 2e.0 off # 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 off # Com 2
+ io 0x60 = 0x2f8
+ irq 0x70 = 3
+ end
+ device pnp 2e.3 on # Com 1
+ io 0x60 = 0x3f8
+ irq 0x70 = 4
+ end
+ device pnp 2e.4 off end # SWC
+ device pnp 2e.5 off end # Mouse
+ device pnp 2e.6 on # Keyboard
+ io 0x60 = 0x60
+ io 0x62 = 0x64
+ irq 0x70 = 1
+ end
+ device pnp 2e.7 off end # GPIO
+ device pnp 2e.f off end # XBUS
+ device pnp 2e.10 on #RTC
+ io 0x60 = 0x70
+ io 0x62 = 0x72
+ end
+ end
+ end
+ device pci 1.3 on end # WDTimer 0x0238
+ device pci 1.4 on end # XIOAPIC0 0x0235
+ device pci 1.5 on end # XIOAPIC1
+ device pci 1.6 on end # XIOAPIC2
+ device pci 2.0 on end # USB 0x0223
+ device pci 2.1 on end # USB
+ device pci 2.2 on end # USB
+ #when HT_CHAIN_END_UNITID_BASE (0,1) < HT_CHAIN_UNITID_BASE (6,,,,),
+ chip drivers/pci/onboard
+ device pci 4.0 on end # it is in bcm5785_0 bus, but the device id can not be changed even unitid is changed, fake one to get the rom_address
+ # if HT_CHAIN_END_UNITID_BASE=0, it is 5, if HT_CHAIN_END_UNITID_BASE=1, it is 4
+ register "rom_address" = "0xfff80000"
+ end
+ end
+ #when HT_CHAIN_END_UNITID_BASE > HT_CHAIN_UNITID_BASE (6, ,,,,)
+# chip drivers/pci/onboard
+# device pci 0.0 on end # fake, will be disabled
+# end
+# chip drivers/pci/onboard
+# device pci 5.0 on end # it is in bcm5785_0 bus, but the device id can not be changed even unitid is changed
+# register "rom_address" = "0xfff80000"
+# end
+
+
+ end # device pci 18.0
+
+ device pci 18.0 on end
+ device pci 18.0 on end
+ device pci 18.1 on end
+ device pci 18.2 on end
+ device pci 18.3 on end
+ end
+
+
+ end #pci_domain
+# chip drivers/generic/debug
+# device pnp 0.0 off end # chip name
+# device pnp 0.1 on end # pci_regs_all
+# device pnp 0.2 off end # mem
+# device pnp 0.3 off end # cpuid
+# device pnp 0.4 off end # smbus_regs_all
+# device pnp 0.5 off end # dual core msr
+# device pnp 0.6 off end # cache size
+# device pnp 0.7 off end # tsc
+# end
+
+end
+
diff --git a/src/mainboard/broadcom/blast/Options.lb b/src/mainboard/broadcom/blast/Options.lb
new file mode 100644
index 0000000000..02bb6eb035
--- /dev/null
+++ b/src/mainboard/broadcom/blast/Options.lb
@@ -0,0 +1,262 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses HAVE_ACPI_TABLES
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_MAX_CPUS
+uses CONFIG_MAX_PHYSICAL_CPUS
+uses CONFIG_LOGICAL_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 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_GDB_STUB
+uses CROSS_COMPILE
+uses CC
+uses HOSTCC
+uses OBJCOPY
+uses CONFIG_CHIP_NAME
+uses CONFIG_CONSOLE_VGA
+uses CONFIG_PCI_ROM_RUN
+uses K8_HW_MEM_HOLE_SIZEK
+uses HT_CHAIN_UNITID_BASE
+uses HT_CHAIN_END_UNITID_BASE
+uses K8_SB_HT_CHAIN_ON_BUS0
+
+uses USE_DCACHE_RAM
+uses DCACHE_RAM_BASE
+uses DCACHE_RAM_SIZE
+uses CONFIG_USE_INIT
+
+uses SB_HT_CHAIN_UNITID_OFFSET_ONLY
+
+###
+### Build options
+###
+
+##
+## ROM_SIZE is the size of boot ROM that this board will use.
+##
+default ROM_SIZE=524288
+
+##
+## FALLBACK_SIZE is the amount of the ROM the complete fallback image will use
+##
+#default FALLBACK_SIZE=131072
+#256K
+default FALLBACK_SIZE=0x40000
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+##
+## 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=4
+default CONFIG_MAX_PHYSICAL_CPUS=2
+default CONFIG_LOGICAL_CPUS=1
+
+#CHIP_NAME ?
+default CONFIG_CHIP_NAME=1
+
+#1G memory hole
+default K8_HW_MEM_HOLE_SIZEK=0x100000
+
+#VGA Console
+#default CONFIG_CONSOLE_VGA=1
+#default CONFIG_PCI_ROM_RUN=1
+
+#HT Unit ID offset
+default HT_CHAIN_UNITID_BASE=0x6
+
+#real SB Unit ID
+default HT_CHAIN_END_UNITID_BASE=0x1
+
+#make the SB HT chain on bus 0
+default K8_SB_HT_CHAIN_ON_BUS0=1
+
+##
+## enable CACHE_AS_RAM specifics
+##
+default USE_DCACHE_RAM=1
+default DCACHE_RAM_BASE=0xcf000
+default DCACHE_RAM_SIZE=0x1000
+default CONFIG_USE_INIT=0
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="blast"
+default MAINBOARD_VENDOR="Broadcom"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x161f
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x3050
+
+
+###
+### 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/broadcom/blast/cache_as_ram_auto.c b/src/mainboard/broadcom/blast/cache_as_ram_auto.c
new file mode 100644
index 0000000000..37c1fd79dc
--- /dev/null
+++ b/src/mainboard/broadcom/blast/cache_as_ram_auto.c
@@ -0,0 +1,274 @@
+#define ASSEMBLY 1
+#define __ROMCC__
+
+
+//#define K8_SCAN_PCI_BUS 1
+
+#define K8_4RANK_DIMM_SUPPORT 1
+
+#if CONFIG_LOGICAL_CPUS==1
+#define SET_NB_CFG_54 1
+#endif
+
+#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"
+
+#if 0
+static void post_code(uint8_t value) {
+#if 0
+ int i;
+ for(i=0;i<0x80000;i++) {
+ outb(value, 0x80);
+ }
+#endif
+}
+#endif
+
+#include <cpu/amd/model_fxx_rev.h>
+#include "northbridge/amd/amdk8/incoherent_ht.c"
+#include "southbridge/broadcom/bcm5785/bcm5785_early_smbus.c"
+#include "northbridge/amd/amdk8/raminit.h"
+#include "cpu/amd/model_fxx/apic_timer.c"
+#include "lib/delay.c"
+
+#if CONFIG_USE_INIT == 0
+#include "lib/memcpy.c"
+#endif
+
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+#include "northbridge/amd/amdk8/debug.c"
+#include "superio/NSC/pc87417/pc87417_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, PC87417_SP1)
+#define RTC_DEV PNP_DEV(0x2e, PC87417_RTC)
+
+#include "southbridge/broadcom/bcm5785/bcm5785_early_setup.c"
+
+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)
+{
+#define SMBUS_HUB 0x71
+ int ret,i;
+ unsigned device=(ctrl->channel0[0])>>8;
+ smbus_send_byte(SMBUS_HUB, device);
+}
+#if 0
+static inline void change_i2c_mux(unsigned device)
+{
+#define SMBUS_HUB 0x71
+ int ret;
+ print_debug("change_i2c_mux i="); print_debug_hex8(device); print_debug("\r\n");
+ ret = smbus_send_byte(SMBUS_HUB, device);
+ print_debug("change_i2c_mux ret="); print_debug_hex32(ret); print_debug("\r\n");
+}
+#endif
+
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+ return smbus_read_byte(device, address);
+}
+
+#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"
+
+#include "cpu/amd/dualcore/dualcore.c"
+
+#define RC0 (6<<8)
+#define RC1 (7<<8)
+
+#define DIMM0 0x50
+#define DIMM1 0x51
+#define DIMM2 0x52
+#define DIMM3 0x53
+
+#include "cpu/amd/car/copy_and_run.c"
+#include "cpu/amd/car/post_cache_as_ram.c"
+
+#include "cpu/amd/model_fxx/init_cpus.c"
+
+
+#if USE_FALLBACK_IMAGE == 1
+
+#include "northbridge/amd/amdk8/early_ht.c"
+
+void failover_process(unsigned long bist, unsigned long cpu_init_detectedx)
+{
+
+
+ /* Is this a cpu only reset? Is this a secondary cpu? */
+ if ((cpu_init_detectedx) || (!boot_cpu())) {
+ if (last_boot_normal()) { // RTC already inited
+ 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();
+
+ bcm5785_enable_rom();
+
+ bcm5785_enable_lpc();
+
+ //enable RTC
+ pc87417_enable_dev(RTC_DEV);
+
+ /* Is this a deliberate reset by the bios */
+// post_code(0x22);
+ 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:
+// post_code(0x23);
+ __asm__ volatile ("jmp __normal_image"
+ : /* outputs */
+ : "a" (bist), "b" (cpu_init_detectedx) /* inputs */
+ );
+
+ fallback_image:
+// post_code(0x25);
+ ;
+}
+#endif /* USE_FALLBACK_IMAGE == 1 */
+
+void real_main(unsigned long bist, unsigned long cpu_init_detectedx);
+
+void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+{
+
+#if USE_FALLBACK_IMAGE == 1
+ failover_process(bist, cpu_init_detectedx);
+#endif
+ real_main(bist, cpu_init_detectedx);
+
+}
+
+void real_main(unsigned long bist, unsigned long cpu_init_detectedx)
+{
+ static const uint16_t spd_addr[] = {
+ RC0|DIMM0, RC0|DIMM2, 0, 0,
+ RC0|DIMM1, RC0|DIMM3, 0, 0,
+#if CONFIG_MAX_PHYSICAL_CPUS > 1
+ RC1|DIMM0, RC1|DIMM2, 0, 0,
+ RC1|DIMM1, RC1|DIMM3, 0, 0,
+#endif
+ };
+
+ int needs_reset;
+ unsigned cpu_reset = 0;
+ unsigned bsp_apicid = 0;
+
+ struct mem_controller ctrl[8];
+ unsigned nodes;
+
+ if (bist == 0) {
+ bsp_apicid = init_cpus(cpu_init_detectedx);
+ }
+// post_code(0x32);
+
+ pc87417_enable_serial(SERIAL_DEV, TTYS0_BASE);
+// post_code(0x33);
+
+ uart_init();
+// post_code(0x34);
+
+ console_init();
+
+ /* Halt if there was a built in self test failure */
+ report_bist_failure(bist);
+
+ print_debug("bsp_apicid="); print_debug_hex8(bsp_apicid); print_debug("\r\n");
+
+ setup_blast_resource_map();
+
+#if 0
+ dump_pci_device(PCI_DEV(0, 0x18, 0));
+ dump_pci_device(PCI_DEV(0, 0x19, 0));
+#endif
+
+ needs_reset = setup_coherent_ht_domain();
+
+#if CONFIG_LOGICAL_CPUS==1
+ // It is said that we should start core1 after all core0 launched
+ wait_all_core0_started();
+ start_other_cores();
+#endif
+ wait_all_aps_started(bsp_apicid);
+
+ needs_reset |= ht_setup_chains_x();
+
+ bcm5785_early_setup();
+
+ if (needs_reset) {
+ print_info("ht reset -\r\n");
+ soft_reset();
+ }
+
+ allow_all_aps_stop(bsp_apicid);
+
+ nodes = get_nodes();
+ //It's the time to set ctrl now;
+ fill_mem_ctrl(nodes, ctrl, spd_addr);
+
+ enable_smbus();
+
+#if 0
+ int i;
+ for(i=4;i<8;i++) {
+ change_i2c_mux(i);
+ dump_smbus_registers();
+ }
+#endif
+
+ memreset_setup();
+
+// init_timer();
+
+ sdram_initialize(nodes, ctrl);
+
+#if 0
+ print_pci_devices();
+#endif
+
+#if 0
+ dump_pci_devices();
+#endif
+
+ post_cache_as_ram(cpu_reset);
+
+}
diff --git a/src/mainboard/broadcom/blast/chip.h b/src/mainboard/broadcom/blast/chip.h
new file mode 100644
index 0000000000..dbc442a184
--- /dev/null
+++ b/src/mainboard/broadcom/blast/chip.h
@@ -0,0 +1,6 @@
+extern struct chip_operations mainboard_broadcom_blast_ops;
+
+struct mainboard_broadcom_blast_config {
+// int fixup_scsi;
+// int fixup_vga;
+};
diff --git a/src/mainboard/broadcom/blast/cmos.layout b/src/mainboard/broadcom/blast/cmos.layout
new file mode 100644
index 0000000000..c1f3d75316
--- /dev/null
+++ b/src/mainboard/broadcom/blast/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/broadcom/blast/get_bus_conf.c b/src/mainboard/broadcom/blast/get_bus_conf.c
new file mode 100644
index 0000000000..44a9fc018e
--- /dev/null
+++ b/src/mainboard/broadcom/blast/get_bus_conf.c
@@ -0,0 +1,118 @@
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <string.h>
+#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#endif
+
+unsigned sblk;
+unsigned pci1234[] =
+{ //Here you only need to set value in pci1234 for HT-IO that could be installed or not
+ //You may need to preset pci1234 for HTIO board, please refer to src/northbridge/amd/amdk8/get_sblk_pci1234.c for detail
+ 0x0000ff0,
+// 0x0000ff0,
+// 0x0000ff0,
+// 0x0000ff0,
+// 0x0000ff0,
+// 0x0000ff0,
+// 0x0000ff0,
+// 0x0000ff0
+};
+unsigned hc_possible_num;
+unsigned sbdn;
+unsigned hcdn[] =
+{ //HT Chain device num, actually it is unit id base of every ht device in chain, assume every chain only have 4 ht device at most
+ 0x20202020,
+// 0x20202020,
+// 0x20202020,
+// 0x20202020,
+// 0x20202020,
+// 0x20202020,
+// 0x20202020,
+// 0x20202020,
+};
+
+// Global variables for MB layouts and these will be shared by irqtable mptable and acpi_tables
+//busnum is default
+unsigned char bus_isa = 10;
+unsigned char bus_bcm5780[7];
+unsigned char bus_bcm5785_0 = 1;
+unsigned char bus_bcm5785_1 = 8;
+unsigned char bus_bcm5785_1_1 = 9;
+unsigned apicid_bcm5785[3];
+
+unsigned sbdn2;
+
+extern void get_sblk_pci1234(void);
+
+static unsigned get_bus_conf_done = 0;
+
+void get_bus_conf(void)
+{
+
+ unsigned apicid_base;
+
+ device_t dev;
+ int i;
+
+ if(get_bus_conf_done==1) return; //do it only once
+
+ get_bus_conf_done = 1;
+
+ hc_possible_num = sizeof(pci1234)/sizeof(pci1234[0]);
+
+ get_sblk_pci1234();
+
+ sbdn = (hcdn[0] >> 8) & 0xff;
+ sbdn2 = hcdn[0] & 0xff; // bcm5780
+
+ bus_bcm5785_0 = (pci1234[0] >> 16) & 0xff;
+ bus_bcm5780[0] = bus_bcm5785_0;
+
+ /* bcm5785 */
+ dev = dev_find_slot(bus_bcm5785_0, PCI_DEVFN(sbdn,0));
+ if (dev) {
+ bus_bcm5785_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+ dev = dev_find_slot(bus_bcm5785_1, PCI_DEVFN(0x0d,0));
+ if(dev) {
+ bus_bcm5785_1_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+#if HT_CHAIN_END_UNITID_BASE >= HT_CHAIN_UNITID_BASE
+ bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_isa++;
+// printk_debug("bus_isa=%d\n",bus_isa);
+#endif
+ }
+ }
+ else {
+ printk_debug("ERROR - could not find PCI %02x:07.0, using defaults\n", bus_bcm5785_0);
+ }
+
+ /* bcm5780 */
+ for(i = 1; i < 7; i++) {
+ dev = dev_find_slot(bus_bcm5780[0], PCI_DEVFN(sbdn2 + i - 1,0));
+ if(dev) {
+ bus_bcm5780[i] = pci_read_config8(dev, PCI_SECONDARY_BUS);
+#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
+ bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+ bus_isa++;
+// printk_debug("bus_isa=%d\n",bus_isa);
+#endif
+
+ }
+ else {
+ printk_debug("ERROR - could not find PCI %02x:01.0, using defaults\n", bus_bcm5780[i]);
+ }
+ }
+
+
+/*I/O APICs: APIC ID Version State Address*/
+#if CONFIG_LOGICAL_CPUS==1
+ apicid_base = get_apicid_base(3);
+#else
+ apicid_base = CONFIG_MAX_PHYSICAL_CPUS;
+#endif
+ for(i=0;i<3;i++)
+ apicid_bcm5785[i] = apicid_base+i;
+}
diff --git a/src/mainboard/broadcom/blast/irq_tables.c b/src/mainboard/broadcom/blast/irq_tables.c
new file mode 100644
index 0000000000..6695a900aa
--- /dev/null
+++ b/src/mainboard/broadcom/blast/irq_tables.c
@@ -0,0 +1,108 @@
+/* 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 <console/console.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+#include <arch/pirq_routing.h>
+
+extern unsigned pci1234[];
+extern unsigned sbdn;
+extern unsigned hcdn[];
+
+static void write_pirq_info(struct irq_info *pirq_info, uint8_t bus, uint8_t devfn, uint8_t link0, uint16_t bitmap0,
+ uint8_t link1, uint16_t bitmap1, uint8_t link2, uint16_t bitmap2,uint8_t link3, uint16_t bitmap3,
+ uint8_t slot, uint8_t rfu)
+{
+ pirq_info->bus = bus;
+ pirq_info->devfn = devfn;
+
+ pirq_info->irq[0].link = link0;
+ pirq_info->irq[0].bitmap = bitmap0;
+ pirq_info->irq[1].link = link1;
+ pirq_info->irq[1].bitmap = bitmap1;
+ pirq_info->irq[2].link = link2;
+ pirq_info->irq[2].bitmap = bitmap2;
+ pirq_info->irq[3].link = link3;
+ pirq_info->irq[3].bitmap = bitmap3;
+
+ pirq_info->slot = slot;
+ pirq_info->rfu = rfu;
+}
+
+extern unsigned char bus_isa;
+extern unsigned char bus_bcm5780[7];
+extern unsigned char bus_bcm5785_0;
+extern unsigned char bus_bcm5785_1;
+extern unsigned apicid_bcm5785[3];
+
+extern unsigned sbdn2;
+
+extern void get_bus_conf(void);
+
+unsigned long write_pirq_routing_table(unsigned long addr)
+{
+
+ struct irq_routing_table *pirq;
+ struct irq_info *pirq_info;
+ unsigned slot_num;
+ uint8_t *v;
+
+ uint8_t sum=0;
+ int i;
+
+ get_bus_conf();
+
+ /* Align the table to be 16 byte aligned. */
+ addr += 15;
+ addr &= ~15;
+
+ /* This table must be betweeen 0xf0000 & 0x100000 */
+ printk_info("Writing IRQ routing tables to 0x%x...", addr);
+
+ pirq = (void *)(addr);
+ v = (uint8_t *)(addr);
+
+ pirq->signature = PIRQ_SIGNATURE;
+ pirq->version = PIRQ_VERSION;
+
+ pirq->rtr_bus = bus_bcm5785_0;
+ pirq->rtr_devfn = (sbdn<<3)|0;
+
+ pirq->exclusive_irqs = 0;
+
+ pirq->rtr_vendor = 0x1166;
+ pirq->rtr_device = 0x0036;
+
+ pirq->miniport_data = 0;
+
+ memset(pirq->rfu, 0, sizeof(pirq->rfu));
+
+ get_bus_conf(); // it will find out all bus num and apic that share with mptable.c and mptable.c and acpi_tables.c
+
+ pirq_info = (void *) ( &pirq->checksum + 1);
+ slot_num = 0;
+//pci bridge
+ write_pirq_info(pirq_info, bus_bcm5785_0, (sbdn<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0);
+ pirq_info++; slot_num++;
+
+ pirq->size = 32 + 16 * slot_num;
+
+ for (i = 0; i < pirq->size; i++)
+ sum += v[i];
+
+ sum = pirq->checksum - sum;
+
+ if (sum != pirq->checksum) {
+ pirq->checksum = sum;
+ }
+
+ printk_info("done.\n");
+
+ return (unsigned long) pirq_info;
+
+}
diff --git a/src/mainboard/broadcom/blast/mainboard.c b/src/mainboard/broadcom/blast/mainboard.c
new file mode 100644
index 0000000000..a5350cdaac
--- /dev/null
+++ b/src/mainboard/broadcom/blast/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_broadcom_blast_ops = {
+ CHIP_NAME("Broadcom blast mainboard")
+};
+#endif
diff --git a/src/mainboard/broadcom/blast/mptable.c b/src/mainboard/broadcom/blast/mptable.c
new file mode 100644
index 0000000000..77dc75db73
--- /dev/null
+++ b/src/mainboard/broadcom/blast/mptable.c
@@ -0,0 +1,192 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <arch/io.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#endif
+
+extern unsigned pci1234[];
+extern unsigned sbdn;
+extern unsigned hcdn[];
+
+extern unsigned char bus_isa;
+extern unsigned char bus_bcm5780[7];
+extern unsigned char bus_bcm5785_0;
+extern unsigned char bus_bcm5785_1;
+extern unsigned char bus_bcm5785_1_1;
+extern unsigned apicid_bcm5785[3];
+
+extern unsigned sbdn2;
+
+extern void get_bus_conf(void);
+
+void *smp_write_config_table(void *v)
+{
+ static const char sig[4] = "PCMP";
+ static const char oem[8] = "BROADCOM";
+ static const char productid[12] = "BLAST ";
+ struct mp_config_table *mc;
+
+ unsigned char bus_num;
+ int i;
+
+ 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);
+
+ get_bus_conf();
+
+/*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*/
+ {
+ device_t dev = 0;
+ int i;
+ struct resource *res;
+ for(i=0; i<3; i++) {
+ dev = dev_find_device(0x1166, 0x0235, dev);
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, apicid_bcm5785[i], 0x11, res->base);
+ }
+ }
+ }
+
+ }
+
+/*I/O 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, apicid_bcm5785[0], 0x0);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_bcm5785[0], 0x1);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_bcm5785[0], 0x2);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_bcm5785[0], 0x3);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_bcm5785[0], 0x4);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x5, apicid_bcm5785[0], 0x5);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_bcm5785[0], 0x6);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_bcm5785[0], 0x7);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_bcm5785[0], 0x8);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x9, apicid_bcm5785[0], 0x9);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_bcm5785[0], 0xc);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_bcm5785[0], 0xd);
+
+//IDE
+ outb(0x02, 0xc00); outb(0x0e, 0xc01);
+
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_bcm5785_0, ((1+sbdn)<<2)|1, apicid_bcm5785[0], 0xe); // IDE
+
+//SATA
+ outb(0x07, 0xc00); outb(0x0f, 0xc01);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_1, (0x0e<<2)|0, apicid_bcm5785[0], 0xf);
+
+//USB
+ outb(0x01, 0xc00); outb(0x0a, 0xc01);
+ for(i=0;i<3;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_0, ((2+sbdn)<<2)|i, apicid_bcm5785[0], 0xa); //
+ }
+
+
+
+ /* enable int */
+ /* why here? must get the BAR and PCI command bit 1 set before enable it ....*/
+ {
+ device_t dev;
+ dev = dev_find_device(0x1166, 0x0205, 0);
+ if(dev) {
+ uint32_t dword;
+ dword = pci_read_config32(dev, 0x6c);
+ dword |= (1<<4); // enable interrupts
+ pci_write_config32(dev, 0x6c, dword);
+
+ }
+
+ }
+
+//First pci-x slot (on bcm5785) under bus_bcm5785_1:d.0
+ for(i=0;i<4;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_1_1, (4<<2)|i, apicid_bcm5785[1], 2 + (0+i)%4); //
+ }
+
+
+//pci slot (on bcm5785)
+ for(i=0;i<4;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_0, (4<<2)|i, apicid_bcm5785[1], i%2); //
+ }
+
+
+//onboard ati
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_0, (5<<2)|0, apicid_bcm5785[1], 0x1);
+
+//PCI-X on bcm5780
+ for(i=0;i<4;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[1], (4<<2)|i, apicid_bcm5785[1], 6 + (0+i)%4); //
+ }
+
+ for(i=0;i<4;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[1], (5<<2)|i, apicid_bcm5785[1], 6 + (1+i)%4); //
+ }
+
+//onboard Broadcom
+ for(i=0;i<2;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[2], (4<<2)|i, apicid_bcm5785[1], 0xa + (0+i)%4); //
+ }
+
+
+// First PCI-E x8
+ for(i=0;i<4;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[5], (0<<2)|i, apicid_bcm5785[1], 0xe); //
+ }
+
+
+// Second PCI-E x8
+ for(i=0;i<4;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[3], (0<<2)|i, apicid_bcm5785[1], 0xc); //
+ }
+
+
+// Third PCI-E x1
+ for(i=0;i<4;i++) {
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[4], (0<<2)|i, apicid_bcm5785[1], 0xd); //
+ }
+
+/*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/broadcom/blast/resourcemap.c b/src/mainboard/broadcom/blast/resourcemap.c
new file mode 100644
index 0000000000..308b15d6e7
--- /dev/null
+++ b/src/mainboard/broadcom/blast/resourcemap.c
@@ -0,0 +1,265 @@
+/*
+ * broadcom blast needs a different resource map
+ *
+ */
+
+static void setup_blast_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, 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, 0x00000003,
+ PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000,
+ 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 regin i
+ */
+ PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x08000003,
+ PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000,
+ PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
+ 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/southbridge/broadcom/bcm5780/Config.lb b/src/southbridge/broadcom/bcm5780/Config.lb
new file mode 100644
index 0000000000..69153ef75d
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5780/Config.lb
@@ -0,0 +1,3 @@
+driver bcm5780_nic.o
+driver bcm5780_pcix.o
+driver bcm5780_pcie.o
diff --git a/src/southbridge/broadcom/bcm5780/bcm5780_nic.c b/src/southbridge/broadcom/bcm5780/bcm5780_nic.c
new file mode 100644
index 0000000000..8033f4d5c4
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5780/bcm5780_nic.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+
+static void nic_init(struct device *dev)
+{
+
+#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,
+ .ops_pci = &lops_pci,
+};
+static struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_BROADCOM,
+ .device = PCI_DEVICE_ID_BROADCOM_BCM5780_NIC,
+};
+static struct pci_driver nic1_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_BROADCOM,
+ .device = PCI_DEVICE_ID_BROADCOM_BCM5780_NIC1,
+};
diff --git a/src/southbridge/broadcom/bcm5780/bcm5780_pcie.c b/src/southbridge/broadcom/bcm5780/bcm5780_pcie.c
new file mode 100644
index 0000000000..24691775de
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5780/bcm5780_pcie.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.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,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = &lops_pci,
+
+};
+
+static struct pci_driver pcie_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5780_PCIE,
+};
+
diff --git a/src/southbridge/broadcom/bcm5780/bcm5780_pcix.c b/src/southbridge/broadcom/bcm5780/bcm5780_pcix.c
new file mode 100644
index 0000000000..d8f1c246ce
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5780/bcm5780_pcix.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.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_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = 0 ,
+ .scan_bus = pci_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = &lops_pci,
+
+};
+
+static struct pci_driver ht_driver __pci_driver = {
+ .ops = &ht_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5780_PXB,
+};
+
diff --git a/src/southbridge/broadcom/bcm5785/Config.lb b/src/southbridge/broadcom/bcm5785/Config.lb
new file mode 100644
index 0000000000..7cbc0667df
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/Config.lb
@@ -0,0 +1,8 @@
+config chip.h
+driver bcm5785.o
+driver bcm5785_usb.o
+driver bcm5785_lpc.o
+driver bcm5785_sb_pci_main.o
+driver bcm5785_ide.o
+driver bcm5785_sata.o
+object bcm5785_reset.o
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785.c b/src/southbridge/broadcom/bcm5785/bcm5785.c
new file mode 100644
index 0000000000..ebb7e8e729
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "bcm5785.h"
+
+void bcm5785_enable(device_t dev)
+{
+ device_t sb_pci_main_dev;
+ device_t bus_dev;
+ unsigned index;
+ unsigned reg_old, reg;
+
+ /* See if we are on the behind the pcix bridge */
+ bus_dev = dev->bus->dev;
+ if ((bus_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
+ (bus_dev->device == 0x0036 )) // device under PCI-X Bridge
+ {
+ unsigned devfn;
+ devfn = bus_dev->path.u.pci.devfn + (1 << 3);
+ sb_pci_main_dev = dev_find_slot(bus_dev->bus->secondary, devfn);
+// index = ((dev->path.u.pci.devfn & ~7) >> 3) + 8;
+ } else if ((bus_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
+ (bus_dev->device == 0x0104)) // device under PCI Bridge( under PCI-X )
+ {
+ unsigned devfn;
+ devfn = bus_dev->bus->dev->path.u.pci.devfn + (1 << 3);
+ sb_pci_main_dev = dev_find_slot(bus_dev->bus->dev->bus->secondary, devfn);
+// index = ((dev->path.u.pci.devfn & ~7) >> 3) + 8;
+ }
+ else { // same bus
+ unsigned devfn;
+ uint32_t id;
+ devfn = (dev->path.u.pci.devfn) & ~7;
+ if( dev->vendor == PCI_VENDOR_ID_SERVERWORKS ) {
+ if(dev->device == 0x0036) //PCI-X Bridge
+ { devfn += (1<<3); }
+ else if(dev->device == 0x0223) // USB
+ { devfn -= (1<<3); }
+ }
+ sb_pci_main_dev = dev_find_slot(dev->bus->secondary, devfn);
+// index = dev->path.u.pci.devfn & 7;
+ }
+ if (!sb_pci_main_dev) {
+ return;
+ }
+
+ // get index now
+#if 0
+ if (index < 16) {
+ reg = reg_old = pci_read_config16(sb_pci_main_dev, 0x48);
+ reg &= ~(1 << index);
+ if (dev->enabled) {
+ reg |= (1 << index);
+ }
+ if (reg != reg_old) {
+ pci_write_config16(sb_pci_main_dev, 0x48, reg);
+ }
+ }
+ else if (index == 16) {
+ reg = reg_old = pci_read_config8(sb_pci_main_dev, 0x47);
+ reg &= ~(1 << 7);
+ if (!dev->enabled) {
+ reg |= (1 << 7);
+ }
+ if (reg != reg_old) {
+ pci_write_config8(sb_pci_main_dev, 0x47, reg);
+ }
+ }
+#endif
+}
+
+struct chip_operations southbridge_broadcom_bcm5785_ops = {
+ CHIP_NAME("Serverworks bcm5785")
+ .enable_dev = bcm5785_enable,
+};
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785.h b/src/southbridge/broadcom/bcm5785/bcm5785.h
new file mode 100644
index 0000000000..5f7f94f5e2
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785.h
@@ -0,0 +1,8 @@
+#ifndef BCM5785_H
+#define BCM5785_H
+
+#include "chip.h"
+
+void bcm5785_enable(device_t dev);
+
+#endif /* BCM5785_H */
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c b/src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c
new file mode 100644
index 0000000000..ab94327481
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+
+#if USE_FALLBACK_IMAGE == 1
+
+static void bcm5785_enable_rom(void)
+{
+ unsigned char byte;
+ uint32_t dword;
+ uint16_t word;
+ device_t addr;
+
+ /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */
+ /* Locate the BCM 5785 SB PCI Main */
+ addr = pci_locate_device(PCI_ID(0x1166, 0x0205), 0); // 0x0201?
+
+ /* Set the 4MB enable bit bit */
+ byte = pci_read_config8(addr, 0x41);
+ byte |= 0x0e;
+ pci_write_config8(addr, 0x41, byte);
+}
+
+static void bcm5785_enable_lpc(void)
+{
+
+ uint8_t byte;
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
+
+ /* LPC Control 0 */
+ byte = pci_read_config8(dev, 0x44);
+ /* Serial 0 */
+ byte |= (1<<6);
+ pci_write_config8(dev, 0x44, byte);
+
+ /* LPC Control 4 */
+ byte = pci_read_config8(dev, 0x48);
+ /* superio port 0x2e/4e enable */
+ byte |=(1<<1)|(1<<0);
+ pci_write_config8(dev, 0x48, byte);
+}
+#endif /* USE_FALLBACK_IMAGE == 1 */
+
+
+static void bcm5785_enable_wdt_port_cf9(void)
+{
+ device_t dev;
+ uint32_t dword;
+ uint32_t dword_old;
+
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
+
+ dword_old = pci_read_config32(dev, 0x4c);
+ dword = dword_old | (1<<4); //enable Timer Func
+ if(dword != dword_old ) {
+ pci_write_config32(dev, 0x4c, dword);
+ }
+
+ dword_old = pci_read_config32(dev, 0x6c);
+ dword = dword_old | (1<<9); //unhide Timer Func in pci space
+ if(dword != dword_old ) {
+ pci_write_config32(dev, 0x6c, dword);
+ }
+
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0238), 0);
+
+ /* enable cf9 */
+ pci_write_config8(dev, 0x40, (1<<2));
+}
+
+static void hard_reset(void)
+{
+ bcm5785_enable_wdt_port_cf9();
+
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+static void soft_reset(void)
+{
+ bcm5785_enable_wdt_port_cf9();
+
+ set_bios_reset();
+#if 1
+ /* link reset */
+// outb(0x02, 0x0cf9);
+ outb(0x06, 0x0cf9);
+#endif
+}
+
+
+
+static void bcm5785_enable_msg(void)
+{
+ device_t dev;
+ uint32_t dword;
+ uint32_t dword_old;
+ uint8_t byte;
+
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
+
+ byte = pci_read_config8(dev, 0x42);
+ byte = (1<<1); //enable a20
+ pci_write_config8(dev, 0x42, byte);
+
+ dword_old = pci_read_config32(dev, 0x6c);
+ // bit 5: enable A20 Message
+ // bit 4: enable interrupt messages
+ // bit 3: enable reset init message
+ // bit 2: enable keyboard init message
+ // bit 1: enable upsteam messages
+ // bit 0: enable shutdowm message to init generation
+ dword = dword_old | (1<<5) | (1<<3) | (1<<2) | (1<<1) | (1<<0); // bit 1 and bit 4 must be set, otherwise interrupt msg will not be delivered to the processor
+ if(dword != dword_old ) {
+ pci_write_config32(dev, 0x6c, dword);
+ }
+
+}
+
+static void bcm5785_early_setup(void)
+{
+ uint8_t byte;
+ uint16_t word;
+ uint32_t dword;
+ device_t dev;
+
+//F0
+ // enable device on bcm5785 at first
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
+ dword = pci_read_config32(dev, 0x64);
+ dword |= (1<<15) | (1<<11) | (1<<3); // ioapci enable
+ dword |= (1<<8); // USB enable
+ dword |= /* (1<<27)|*/(1<<14); // IDE enable
+ pci_write_config32(dev, 0x64, dword);
+
+ byte = pci_read_config8(dev, 0x84);
+ byte |= (1<<0); // SATA enable
+ pci_write_config8(dev, 0x84, byte);
+
+// wdt and cf9 for later in linuxbios_ram to call hard_reset
+ bcm5785_enable_wdt_port_cf9();
+
+ bcm5785_enable_msg();
+
+
+#if 1
+// IDE related
+ //F0
+ byte = pci_read_config8(dev, 0x4e);
+ byte |= (1<<4); //enable IDE ext regs
+ pci_write_config8(dev, 0x4e, byte);
+
+ //F1
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0214), 0);
+ byte = pci_read_config8(dev, 0x48);
+ byte &= ~1; // disable pri channel
+ pci_write_config8(dev, 0x48, byte);
+ pci_write_config8(dev, 0xb0, 0x01);
+ pci_write_config8(dev, 0xb2, 0x02);
+ byte = pci_read_config8(dev, 0x06);
+ byte |= (1<<4); // so b0, b2 can not be changed from now
+ pci_write_config8(dev, 0x06, byte);
+ byte = pci_read_config8(dev, 0x49);
+ byte |= 1; // enable second channel
+ pci_write_config8(dev, 0x49, byte);
+#endif
+
+//F2
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
+
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1<<3)|(1<<2); // LPC Retry, LPC to PCI DMA enable
+ pci_write_config8(dev, 0x40, byte);
+
+ pci_write_config32(dev, 0x60, 0x0000ffff); // LPC Memory hole start and end
+
+#if 1
+// USB related
+ pci_write_config8(dev, 0x90, 0x40);
+ pci_write_config8(dev, 0x92, 0x06);
+ pci_write_config8(dev, 0x9c, 0x7c); //PHY timinig register
+ pci_write_config8(dev, 0xa4, 0x02); //mask reg - low/full speed func
+ pci_write_config8(dev, 0xa5, 0x02); //mask reg - low/full speed func
+ pci_write_config8(dev, 0xa6, 0x00); //mask reg - high speed func
+ pci_write_config8(dev, 0xb4, 0x40);
+#endif
+}
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_early_smbus.c b/src/southbridge/broadcom/bcm5785/bcm5785_early_smbus.c
new file mode 100644
index 0000000000..b6a2fe506e
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_early_smbus.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+
+#include "bcm5785_smbus.h"
+
+#define SMBUS_IO_BASE 0x1000
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0); // 0x0201?
+
+ 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, 0x90, SMBUS_IO_BASE | 1);
+ /* Set smbus iospace enable */
+ pci_write_config8(dev, 0xd2, 0x03);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+static int smbus_recv_byte(unsigned device)
+{
+ return do_smbus_recv_byte(SMBUS_IO_BASE, device);
+}
+
+static int smbus_send_byte(unsigned device, unsigned char val)
+{
+ return do_smbus_send_byte(SMBUS_IO_BASE, device, val);
+}
+
+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/broadcom/bcm5785/bcm5785_ide.c b/src/southbridge/broadcom/bcm5785/bcm5785_ide.c
new file mode 100644
index 0000000000..b3cc493f5b
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_ide.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "bcm5785.h"
+
+static void bcm5785_ide_read_resources(device_t dev)
+{
+ struct resource *res;
+ unsigned long index;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ /* BAR */
+ pci_get_resource(dev, 0x64);
+
+ compact_resources(dev);
+}
+
+static void ide_init(struct device *dev)
+{
+ uint16_t word;
+
+
+}
+
+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 = bcm5785_ide_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+// .enable = bcm5785_enable,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_IDE,
+};
+
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c b/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c
new file mode 100644
index 0000000000..5c061dbe86
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.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 "bcm5785.h"
+
+static void lpc_init(device_t dev)
+{
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+
+}
+
+static void bcm5785_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);
+
+ /* 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 bcm5785_lpc_enable_childrens_resources(device_t dev)
+{
+ unsigned link;
+ uint32_t reg;
+ int i;
+ int var_num = 0;
+
+ reg = pci_read_config8(dev, 0x44);
+
+ 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("bcm5785lpc decode:%s, base=0x%08x, end=0x%08x\r\n",dev_path(child),base, end);
+ switch(base) {
+ case 0x60: //KBC
+ case 0x64:
+ reg |= (1<<29);
+ case 0x3f8: // COM1
+ reg |= (1<<6); break;
+ case 0x2f8: // COM2
+ reg |= (1<<7); break;
+ case 0x378: // Parallal 1
+ reg |= (1<<0); break;
+ case 0x3f0: // FD0
+ reg |= (1<<26); break;
+ case 0x220: // Aduio 0
+ reg |= (1<<14); break;
+ case 0x300: // Midi 0
+ reg |= (1<<18); break;
+ }
+ }
+ }
+ }
+ }
+ pci_write_config32(dev, 0x44, reg);
+
+
+}
+
+static void bcm5785_lpc_enable_resources(device_t dev)
+{
+ pci_dev_enable_resources(dev);
+ bcm5785_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 = bcm5785_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = bcm5785_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+// .enable = bcm5785_enable,
+ .ops_pci = &lops_pci,
+};
+static struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_LPC,
+};
+
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_reset.c b/src/southbridge/broadcom/bcm5785/bcm5785_reset.c
new file mode 100644
index 0000000000..b6fc5926b3
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_reset.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+
+#include <arch/io.h>
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+ (((BUS) & 0xFFF) << 20) | \
+ (((DEV) & 0x1F) << 15) | \
+ (((FN) & 0x7) << 12))
+
+typedef unsigned device_t;
+
+static void pci_write_config32(device_t dev, unsigned where, unsigned value)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outl(value, 0xCFC);
+}
+
+static unsigned pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = (dev>>4) | 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 */
+ /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
+ outb((0 <<3)|(0<<2)|(1<<1), 0xcf9);
+ outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
+
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_sata.c b/src/southbridge/broadcom/bcm5785/bcm5785_sata.c
new file mode 100644
index 0000000000..470bc47c73
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_sata.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.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 <arch/io.h>
+#include "bcm5785.h"
+
+
+static void sata_init(struct device *dev)
+{
+
+ uint8_t byte;
+
+ uint8_t *base;
+ uint8_t *mmio;
+ struct resource *res;
+ int i;
+
+ if(!(dev->path.u.pci.devfn & 7)) { // only set it in Func0
+ byte = pci_read_config8(dev, 0x78);
+ byte |= (1<<7);
+ pci_write_config8(dev, 0x78, byte);
+
+ res = find_resource(dev, 0x24);
+ base = res->base;
+ //init PHY
+
+ printk_debug("init PHY...\n");
+ for(i=0; i<4; i++) {
+ mmio = base + 0x100 * i;
+ byte = readb(mmio + 0x40);
+ printk_debug("port %d PHY status = %02x\r\n", i, byte);
+ if(byte & 0x4) {// bit 2 is set
+ byte = readb(mmio+0x48);
+ writeb(byte | 1, mmio + 0x48);
+ writeb(byte & (~1), mmio + 0x48);
+ byte = readb(mmio + 0x40);
+ printk_debug("after reset port %d PHY status = %02x\r\n", i, 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 sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+// .enable = bcm5785_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_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_SATA,
+};
+
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_sb_pci_main.c b/src/southbridge/broadcom/bcm5785/bcm5785_sb_pci_main.c
new file mode 100644
index 0000000000..5db13d636d
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_sb_pci_main.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.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 <device/smbus.h>
+#include "bcm5785.h"
+#include "bcm5785_smbus.h"
+
+#define NMI_OFF 0
+
+static void sb_init(device_t dev)
+{
+ uint8_t byte;
+ uint8_t byte_old;
+ int nmi_option;
+
+ uint32_t dword;
+
+ /* 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);
+ }
+
+
+}
+
+static void bcm5785_sb_read_resources(device_t dev)
+{
+ struct resource *res;
+ unsigned long index;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ /* Get Resource for SMBUS */
+ pci_get_resource(dev, 0x90);
+
+ 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;
+
+}
+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, 0x90);
+
+ 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, 0x90);
+
+ 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, 0x90);
+
+ 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, 0x90);
+
+ 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, 0x2c,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations sb_ops = {
+ .read_resources = bcm5785_sb_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sb_init,
+ .scan_bus = scan_static_bus,
+// .enable = bcm5785_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+static struct pci_driver sb_driver __pci_driver = {
+ .ops = &sb_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_SB_PCI_MAIN,
+};
+
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_smbus.h b/src/southbridge/broadcom/bcm5785/bcm5785_smbus.h
new file mode 100644
index 0000000000..5f2f7717a0
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_smbus.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBSLVSTAT 0x1
+#define SMBHSTCTRL 0x2
+#define SMBHSTCMD 0x3
+#define SMBHSTADDR 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBHSTBLKDAT 0x7
+
+#define SMBSLVCTRL 0x8
+#define SMBSLVCMD_SHADOW 0x9
+#define SMBSLVEVT 0xa
+#define SMBSLVDAT 0xc
+
+
+/* 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;
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f;
+ if (val == 0) { // ready now
+ return 0;
+ }
+ outb(val, smbus_io_base + SMBHSTSTAT);
+ } while(--loops);
+ return -2; // time out
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f; // mask off reserved bits
+ if ( val & 0x1c) {
+ return -5; // error
+ }
+ if ( val == 0x02) {
+ outb(val, smbus_io_base + SMBHSTSTAT); // clear status
+ return 0; //
+ }
+ } while(--loops);
+ return -3; // timeout
+}
+
+static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
+{
+ uint8_t byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; // not ready
+ }
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; // Clear [4:2]
+ byte |= (1<<2) | (1<<6); // Byte data read/write command, start the command
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; // timeout or error
+ }
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTCMD);
+
+ return byte;
+
+}
+static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
+{
+ uint8_t byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; // not ready
+ }
+
+ /* set the command... */
+ outb(val, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|0 , smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; // Clear [4:2]
+ byte |= (1<<2) | (1<<6); // Byte data read/write command, start the command
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; // timeout or error
+ }
+
+ return 0;
+
+}
+
+
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+ uint8_t byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; // not ready
+ }
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; // Clear [4:2]
+ byte |= (1<<3) | (1<<6); // Byte data read/write command, start the command
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; // timeout or error
+ }
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ return byte;
+}
+static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
+{
+ uint8_t byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; // not ready
+ }
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|0 , smbus_io_base + SMBHSTADDR);
+
+ /* output value */
+ outb(val, smbus_io_base + SMBHSTDAT0);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; // Clear [4:2]
+ byte |= (1<<3) | (1<<6); // Byte data read/write command, start the command
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; // timeout or error
+ }
+
+ return 0;
+
+}
+
+
diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_usb.c b/src/southbridge/broadcom/bcm5785/bcm5785_usb.c
new file mode 100644
index 0000000000..d9ce41aa1e
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/bcm5785_usb.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2005 AMD
+ * by yinghai.lu@amd.com
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "bcm5785.h"
+
+static void usb_init(struct device *dev)
+{
+ uint32_t dword;
+
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<2)|(1<<1)|(1<<0);
+ pci_write_config32(dev, 0x04, dword);
+
+ pci_write_config8(dev, 0x41, 0x00); // Serversworks said
+
+}
+
+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 = usb_init,
+// .enable = bcm5785_enable,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver usb_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_USB,
+};
+
diff --git a/src/southbridge/broadcom/bcm5785/chip.h b/src/southbridge/broadcom/bcm5785/chip.h
new file mode 100644
index 0000000000..4aa2ce3217
--- /dev/null
+++ b/src/southbridge/broadcom/bcm5785/chip.h
@@ -0,0 +1,14 @@
+#ifndef BCM5785_CHIP_H
+#define BCM5785_CHIP_H
+
+struct southbridge_broadcom_bcm5785_config
+{
+ unsigned int ide0_enable : 1;
+ unsigned int ide1_enable : 1;
+ unsigned int sata0_enable : 1;
+ unsigned int sata1_enable : 1;
+};
+struct chip_operations;
+extern struct chip_operations southbridge_broadcom_bcm5785_ops;
+
+#endif /* BCM5785_CHIP_H */
diff --git a/src/superio/NSC/pc87417/pc87417_early_serial.c b/src/superio/NSC/pc87417/pc87417_early_serial.c
new file mode 100644
index 0000000000..cb91d21296
--- /dev/null
+++ b/src/superio/NSC/pc87417/pc87417_early_serial.c
@@ -0,0 +1,16 @@
+#include <arch/romcc_io.h>
+#include "pc87417.h"
+
+
+static void pc87417_enable_serial(device_t dev, unsigned iobase)
+{
+ pnp_set_logical_device(dev);
+ pnp_set_enable(dev, 0);
+ pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
+ pnp_set_enable(dev, 1);
+}
+static void pc87417_enable_dev(device_t dev)
+{
+ pnp_set_logical_device(dev);
+ pnp_set_enable(dev, 1);
+}
diff --git a/src/superio/NSC/pc87417/superio.c b/src/superio/NSC/pc87417/superio.c
index 2e75f82cd5..f7e5115e72 100644
--- a/src/superio/NSC/pc87417/superio.c
+++ b/src/superio/NSC/pc87417/superio.c
@@ -1,5 +1,7 @@
/* Copyright 2000 AG Electronics Ltd. */
/* Copyright 2003-2004 Linux Networx */
+/* Copyright 2005 Tyan */
+/* By yhlu */
/* This code is distributed without warranty under the GPL v2 (see COPYING) */
#include <arch/io.h>
@@ -8,10 +10,11 @@
#include <console/console.h>
#include <string.h>
#include <bitops.h>
+#include <uart8250.h>
+#include <pc80/keyboard.h>
#include "chip.h"
#include "pc87417.h"
-
static void init(device_t dev)
{
struct superio_NSC_pc87417_config *conf;
@@ -49,29 +52,26 @@ static struct device_operations ops = {
};
static struct pnp_info pnp_dev_info[] = {
- { &ops, PC87417_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07fa, 0}, },
- { &ops, PC87417_SP2, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
- { &ops, PC87417_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
- { &ops, PC87417_SWC, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 | PNP_IRQ0,
- { 0xfff0, 0 }, { 0xfffc, 0 }, { 0xfffc, 0 }, { 0xfff8, 0 } },
- { &ops, PC87417_KBCM, PNP_IRQ0 },
- { &ops, PC87417_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7f8, 0 }, { 0x7f8, 0x4}, },
- { &ops, PC87417_GPIO, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } },
- { &ops, PC87417_WDT, PNP_IO0 | PNP_IRQ0, { 0xfff0, 0 } },
- { &ops, PC87417_FMC, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } },
- { &ops, PC87417_XBUS, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } },
- { &ops, PC87417_RTC, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0xfffe, 0 }, { 0xfffe, 0 } },
- { &ops, PC87417_MHC, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0xffe0, 0 }, { 0xffe0, 0 } },
+ { &ops, PC87417_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07fa, 0}, },
+ { &ops, PC87417_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x04f8, 0}, },
+ { &ops, PC87417_SP2, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0 | PNP_DRQ1, { 0x7f8, 0 }, },
+ { &ops, PC87417_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+ { &ops, PC87417_SWC, PNP_IO0 | PNP_IRQ0, { 0xfff0, 0 }, },
+ { &ops, PC87417_KBCM, PNP_IRQ0 },
+ { &ops, PC87417_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7f8, 0 }, { 0x7f8, 0x4}, },
+ { &ops, PC87417_GPIO, PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
+ { &ops, PC87417_XBUS, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } },
+ { &ops, PC87417_RTC, PNP_IO0 | PNP_IO1, { 0xfffe, 0 }, {0xfffe, 0x4} },
};
static void enable_dev(struct device *dev)
{
- pnp_enable_devices(dev, &ops,
- sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info);
+ pnp_enable_devices(dev, &pnp_ops,
+ sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info);
}
struct chip_operations superio_NSC_pc87417_ops = {
- CHIP_NAME("NSC 87417")
+ CHIP_NAME("NSC pc87417")
.enable_dev = enable_dev,
};