From f3961e0491ae72fa53395a00ebcfa19c5ceea9c7 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Thu, 17 Jul 2003 22:53:27 +0000 Subject: [PATCH] add AMD Quartet target git-svn-id: svn://svn.coreboot.org/coreboot/trunk@980 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/mainboard/amd/quartet/Config.lb | 143 +++++++ src/mainboard/amd/quartet/auto.c | 511 ++++++++++++++++++++++++ src/mainboard/amd/quartet/cmos.layout | 74 ++++ src/mainboard/amd/quartet/failover.c | 23 ++ src/mainboard/amd/quartet/irq_tables.c | 31 ++ src/mainboard/amd/quartet/mainboard.c | 11 + src/mainboard/amd/quartet/mptable.c | 236 +++++++++++ src/mainboard/amd/quartet/resourcemap.c | 265 ++++++++++++ 8 files changed, 1294 insertions(+) create mode 100644 src/mainboard/amd/quartet/Config.lb create mode 100644 src/mainboard/amd/quartet/auto.c create mode 100644 src/mainboard/amd/quartet/cmos.layout create mode 100644 src/mainboard/amd/quartet/failover.c create mode 100644 src/mainboard/amd/quartet/irq_tables.c create mode 100644 src/mainboard/amd/quartet/mainboard.c create mode 100644 src/mainboard/amd/quartet/mptable.c create mode 100644 src/mainboard/amd/quartet/resourcemap.c diff --git a/src/mainboard/amd/quartet/Config.lb b/src/mainboard/amd/quartet/Config.lb new file mode 100644 index 0000000000..2601e5975e --- /dev/null +++ b/src/mainboard/amd/quartet/Config.lb @@ -0,0 +1,143 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses USE_NORMAL_IMAGE +uses AMD8111_DEV +# +# +### +### Set all of the defaults for an x86 architecture +### +# +# +### +### Build the objects we have code for in this directory. +### +##object mainboard.o +driver mainboard.o +object static_devices.o +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +# +arch i386 end +#cpu k8 end +# +### +### Build our 16 bit and 32 bit linuxBIOS entry code +### +mainboardinit cpu/i386/entry16.inc +mainboardinit cpu/i386/entry32.inc +ldscript /cpu/i386/entry16.lds +ldscript /cpu/i386/entry32.lds +# +### +### Build our reset vector (This is where linuxBIOS is entered) +### +if USE_FALLBACK_IMAGE + mainboardinit cpu/i386/reset16.inc + ldscript /cpu/i386/reset16.lds +else + print "NO FALLBACK USED!" +end + +if USE_NORMAL_IMAGE + mainboardinit cpu/i386/reset32.inc + ldscript /cpu/i386/reset32.lds +end +# +#### Should this be in the northbridge code? +mainboardinit arch/i386/lib/cpu_reset.inc +### +### Setup the serial port +### +#mainboardinit superiowinbond/w83627hf/setup_serial.inc +mainboardinit pc80/serial.inc +mainboardinit arch/i386/lib/console.inc +# +### +### Include an id string (For safe flashing) +### +mainboardinit arch/i386/lib/id.inc +ldscript /arch/i386/lib/id.lds +# +#### +#### This is the early phase of linuxBIOS startup +#### Things are delicate and we test to see if we should +#### failover to another image. +#### +#option MAX_REBOOT_CNT=2 +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds +end +# +### +### Setup our mtrrs +### +mainboardinit cpu/k8/earlymtrr.inc +# +# +### +### Only the bootstrap cpu makes it here. +### Failover if we need to +### +# +if USE_FALLBACK_IMAGE + mainboardinit southbridge/amd/amd8111/cmos_boot_failover.inc +end +# +#### +#### O.k. We aren't just an intermediary anymore! +#### +# +### +### When debugging disable the watchdog timer +### +##option MAXIMUM_CONSOLE_LOGLEVEL=7 +#default MAXIMUM_CONSOLE_LOGLEVEL=7 +#option DISABLE_WATCHDOG= (MAXIMUM_CONSOLE_LOGLEVEL >= 8) +#if DISABLE_WATCHDOG +# mainboardinit southbridgeamd/amd8111/disable_watchdog.inc +#end +# +if USE_FALLBACK_IMAGE mainboardinit arch/i386/lib/noop_failover.inc end +# +### +### Romcc output +### +#makerule ./failover.E dep "$(MAINBOARD)/failover.c" act "$(CPP) -I$(TOP)/src $(CPPFLAGS) $(MAINBOARD)/failover.c > ./failever.E" +#makerule ./failover.inc dep "./romcc ./failover.E" act "./romcc -O ./failover.E > failover.inc" +#mainboardinit .failover.inc +makerule ./auto.E + depends "$(MAINBOARD)/auto.c" + action "$(CPP) -I$(TOP)/src $(ROMCCPPFLAGS) $(CPPFLAGS) $(MAINBOARD)/auto.c > ./auto.E" +end +makerule ./auto.inc + depends "./romcc ./auto.E" + action "./romcc -O ./auto.E > auto.inc" +end +mainboardinit ./auto.inc +# +### +### Setup RAM +### +mainboardinit ram/ramtest.inc +mainboardinit southbridge/amd/amd8111/smbus.inc +mainboardinit sdram/generic_dump_spd.inc +# +### +### Include the secondary Configuration files +### +northbridge amd/amdk8 +end +southbridge amd/amd8111 +end +#mainboardinit archi386/smp/secondary.inc +superio NSC/pc87360 + register ".com1={1}, .com2={0}, .floppy=1, .lpt=1, .keyboard=1" +end +dir /pc80 +##dir /src/superio/winbond/w83627hf +cpu p5 end +cpu p6 end +cpu k7 end +cpu k8 end diff --git a/src/mainboard/amd/quartet/auto.c b/src/mainboard/amd/quartet/auto.c new file mode 100644 index 0000000000..8395e12d6f --- /dev/null +++ b/src/mainboard/amd/quartet/auto.c @@ -0,0 +1,511 @@ +#define ASSEMBLY 1 +#include +#include +#include "arch/romcc_io.h" +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "ram/ramtest.c" +#include "northbridge/amd/amdk8/early_ht.c" +#include "southbridge/amd/amd8111/amd8111_early_smbus.c" +#include "northbridge/amd/amdk8/raminit.h" + + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + device_t dev; + for(dev = PCI_DEV(0, 0, 0); + dev <= PCI_DEV(0, 0x1f, 0x7); + dev += PCI_DEV(0,0,1)) { + uint32_t id; + id = pci_read_config32(dev, PCI_VENDOR_ID); + if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0x0000)) { + continue; + } + print_debug_pci_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_pci_devices(void) +{ + device_t dev; + for(dev = PCI_DEV(0, 0, 0); + dev <= PCI_DEV(0, 0x1f, 0x7); + dev += PCI_DEV(0,0,1)) { + uint32_t id; + id = pci_read_config32(dev, PCI_VENDOR_ID); + if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0x0000)) { + continue; + } + dump_pci_device(dev); + } +} + +static void dump_spd_registers(const struct mem_controller *ctrl) +{ + int i; + print_debug("\r\n"); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl->channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl->channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + } +} + +#warning "FIXME move these delay functions somewhere more appropriate" +#warning "FIXME use the apic timer instead it needs no calibration on an Opteron it runs at 200Mhz" +static void print_clock_multiplier(void) +{ + msr_t msr; + print_debug("clock multipler: 0x"); + msr = rdmsr(0xc0010042); + print_debug_hex32(msr.lo & 0x3f); + print_debug(" = 0x"); + print_debug_hex32(((msr.lo & 0x3f) + 8) * 100); + print_debug("Mhz\r\n"); +} + +static unsigned usecs_to_ticks(unsigned usecs) +{ +#warning "FIXME make usecs_to_ticks work properly" +#if 1 + return usecs *2000; +#else + /* This can only be done if cpuid says fid changing is supported + * I need to look up the base frequency another way for other + * cpus. Is it worth dedicating a global register to this? + * Are the PET timers useable for this purpose? + */ + msr_t msr; + msr = rdmsr(0xc0010042); + return ((msr.lo & 0x3f) + 8) * 100 *usecs; +#endif +} + +static void init_apic_timer(void) +{ + volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000; + uint32_t start, end; + /* Set the apic timer to no interrupts and periodic mode */ + apic_reg[0x320 >> 2] = (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0); + /* Set the divider to 1, no divider */ + apic_reg[0x3e0 >> 2] = (1 << 3) | 3; + /* Set the initial counter to 0xffffffff */ + apic_reg[0x380 >> 2] = 0xffffffff; +} + +static void udelay(unsigned usecs) +{ +#if 1 + uint32_t start, ticks; + tsc_t tsc; + /* Calculate the number of ticks to run for */ + ticks = usecs_to_ticks(usecs); + /* Find the current time */ + tsc = rdtsc(); + start = tsc.lo; + do { + tsc = rdtsc(); + } while((tsc.lo - start) < ticks); +#else + volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000; + uint32_t start, value, ticks; + /* Calculate the number of ticks to run for */ + ticks = usecs * 200; + start = apic_reg[0x390 >> 2]; + do { + value = apic_reg[0x390 >> 2]; + } while((start - value) < ticks); +#endif +} + +static void mdelay(unsigned msecs) +{ + int i; + for(i = 0; i < msecs; i++) { + udelay(1000); + } +} + +static void delay(unsigned secs) +{ + int i; + for(i = 0; i < secs; i++) { + mdelay(1000); + } +} + + +static void memreset_setup(const struct mem_controller *ctrl) +{ + /* Set the memreset low */ + outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28); + /* Ensure the BIOS has control of the memory lines */ + outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29); +} + +static void memreset(const struct mem_controller *ctrl) +{ + udelay(800); + /* Set memreset_high */ + outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28); + udelay(50); +} + +/* + * generate_row is specific to board implementation + * + */ + + +static unsigned int generate_row(uint8_t node, uint8_t row, uint8_t maxnodes) +{ + /* Routing Table Node i + * + * F0: 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c + * i: 0, 1, 2, 3, 4, 5, 6, 7 + * + * [ 0: 3] Request Route + * [0] Route to this node + * [1] Route to Link 0 + * [2] Route to Link 1 + * [3] Route to Link 2 + * [11: 8] Response Route + * [0] Route to this node + * [1] Route to Link 0 + * [2] Route to Link 1 + * [3] Route to Link 2 + * [19:16] Broadcast route + * [0] Route to this node + * [1] Route to Link 0 + * [2] Route to Link 1 + * [3] Route to Link 2 + */ + + uint32_t ret=0x00010101; /* default row entry */ + + static const unsigned int rows_2p[2][2] = { + { 0x00030101, 0x00010202 }, + { 0x00010202, 0x00030101 } + }; + + static const unsigned int rows_4p[4][4] = { + { 0x00070101, 0x00010404, 0x00050202, 0x00010402 }, + { 0x00010808, 0x000b0101, 0x00010802, 0x00090202 }, + { 0x00090202, 0x00010802, 0x000b0101, 0x00010808 }, + { 0x00010402, 0x00050202, 0x00010404, 0x00070101 } + }; + + if (!(node>=maxnodes || row>=maxnodes)) { + if (maxnodes==2) + ret=rows_2p[node][row]; + if (maxnodes==4) + ret=rows_4p[node][row]; + } + + return ret; +} + + +#include "northbridge/amd/amdk8/raminit.c" +#include "northbridge/amd/amdk8/coherent_ht.c" +#include "sdram/generic_sdram.c" + +#include "resourcemap.c" /* quartet does not want the default */ + +#define NODE_ID 0x60 +#define HT_INIT_CONTROL 0x6c + +#define HTIC_ColdR_Detect (1<<4) +#define HTIC_BIOSR_Detect (1<<5) +#define HTIC_INIT_Detect (1<<6) + +static int boot_cpu(void) +{ + volatile unsigned long *local_apic; + unsigned long apic_id; + int bsp; + msr_t msr; + msr = rdmsr(0x1b); + bsp = !!(msr.lo & (1 << 8)); + if (bsp) { + print_debug("Bootstrap cpu\r\n"); + } + + return bsp; +} + +static int cpu_init_detected(void) +{ + unsigned long dcl; + int cpu_init; + + unsigned long htic; + + htic = pci_read_config32(PCI_DEV(0, 0x18, 0), HT_INIT_CONTROL); +#if 0 + print_debug("htic: "); + print_debug_hex32(htic); + print_debug("\r\n"); + + if (!(htic & HTIC_ColdR_Detect)) { + print_debug("Cold Reset.\r\n"); + } + if ((htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect)) { + print_debug("BIOS generated Reset.\r\n"); + } + if (htic & HTIC_INIT_Detect) { + print_debug("Init event.\r\n"); + } +#endif + cpu_init = (htic & HTIC_INIT_Detect); + if (cpu_init) { + print_debug("CPU INIT Detected.\r\n"); + } + return cpu_init; +} + + + +static void pnp_write_config(unsigned char port, unsigned char value, unsigned char reg) +{ + outb(reg, port); + outb(value, port +1); +} + +static unsigned char pnp_read_config(unsigned char port, unsigned char reg) +{ + outb(reg, port); + return inb(port +1); +} + +static void pnp_set_logical_device(unsigned char port, int device) +{ + pnp_write_config(port, device, 0x07); +} + +static void pnp_set_enable(unsigned char port, int enable) +{ + pnp_write_config(port, enable?0x1:0x0, 0x30); +} + +static int pnp_read_enable(unsigned char port) +{ + return !!pnp_read_config(port, 0x30); +} + +static void pnp_set_iobase0(unsigned char port, unsigned iobase) +{ + pnp_write_config(port, (iobase >> 8) & 0xff, 0x60); + pnp_write_config(port, iobase & 0xff, 0x61); +} + +static void pnp_set_iobase1(unsigned char port, unsigned iobase) +{ + pnp_write_config(port, (iobase >> 8) & 0xff, 0x62); + pnp_write_config(port, iobase & 0xff, 0x63); +} + +static void pnp_set_irq0(unsigned char port, unsigned irq) +{ + pnp_write_config(port, irq, 0x70); +} + +static void pnp_set_irq1(unsigned char port, unsigned irq) +{ + pnp_write_config(port, irq, 0x72); +} + +static void pnp_set_drq(unsigned char port, unsigned drq) +{ + pnp_write_config(port, drq & 0xff, 0x74); +} + +#define PC87360_FDC 0x00 +#define PC87360_PP 0x01 +#define PC87360_SP2 0x02 +#define PC87360_SP1 0x03 +#define PC87360_SWC 0x04 +#define PC87360_KBCM 0x05 +#define PC87360_KBCK 0x06 +#define PC87360_GPIO 0x07 +#define PC87360_ACB 0x08 +#define PC87360_FSCM 0x09 +#define PC87360_WDT 0x0A + +static void pc87360_enable_serial(void) +{ + pnp_set_logical_device(SIO_BASE, PC87360_SP1); + pnp_set_enable(SIO_BASE, 1); + pnp_set_iobase0(SIO_BASE, 0x3f8); +} + +static void main(void) +{ + /* + * GPIO28 of 8111 will control H0_MEMRESET_L + * GPIO29 of 8111 will control H1_MEMRESET_L + */ + + static const struct mem_controller cpu0 = { + .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 }, + }; + static const struct mem_controller cpu1 = { + .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 }, + }; + static const struct mem_controller cpu2 = { + .f0 = PCI_DEV(0, 0x1a, 0), + .f1 = PCI_DEV(0, 0x1a, 1), + .f2 = PCI_DEV(0, 0x1a, 2), + .f3 = PCI_DEV(0, 0x1a, 3), + .channel0 = { (0xa<<3)|8, (0xa<<3)|10, 0, 0 }, + .channel1 = { (0xa<<3)|9, (0xa<<3)|11, 0, 0 }, + }; + static const struct mem_controller cpu3 = { + .f0 = PCI_DEV(0, 0x1b, 0), + .f1 = PCI_DEV(0, 0x1b, 1), + .f2 = PCI_DEV(0, 0x1b, 2), + .f3 = PCI_DEV(0, 0x1b, 3), + .channel0 = { (0xa<<3)|12, (0xa<<3)|14, 0, 0 }, + .channel1 = { (0xa<<3)|13, (0xa<<3)|15, 0, 0 }, + }; + + + pc87360_enable_serial(); + uart_init(); + console_init(); + if (boot_cpu() && !cpu_init_detected()) { +#if 0 + init_apic_timer(); +#endif + setup_quartet_resource_map(); + setup_coherent_ht_domain(); + enumerate_ht_chain(); + print_pci_devices(); + enable_smbus(); +#if 0 + dump_spd_registers(&cpu0); +#endif + sdram_initialize(&cpu0); + +#if 1 + dump_pci_devices(); +#endif +#if 0 + dump_pci_device(PCI_DEV(0, 0x18, 2)); +#endif + + /* Check all of memory */ +#if 0 + msr_t msr; + msr = rdmsr(TOP_MEM); + print_debug("TOP_MEM: "); + print_debug_hex32(msr.hi); + print_debug_hex32(msr.lo); + print_debug("\r\n"); +#endif +#if 0 + ram_check(0x00000000, msr.lo); +#else +#if 1 + /* Check 16MB of memory */ + ram_check(0x00000000, 0x01000000); +#endif +#endif + } +} diff --git a/src/mainboard/amd/quartet/cmos.layout b/src/mainboard/amd/quartet/cmos.layout new file mode 100644 index 0000000000..5ba4c032c1 --- /dev/null +++ b/src/mainboard/amd/quartet/cmos.layout @@ -0,0 +1,74 @@ +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 +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 +1008 16 h 0 check_sum + +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 + +checksums + +checksum 392 1007 1008 + + diff --git a/src/mainboard/amd/quartet/failover.c b/src/mainboard/amd/quartet/failover.c new file mode 100644 index 0000000000..017b03862f --- /dev/null +++ b/src/mainboard/amd/quartet/failover.c @@ -0,0 +1,23 @@ +#define ASSEMBLY 1 +#include +#include +#include +#include "arch/romcc_io.h" +#include "pc80/mc146818rtc_early.c" +#include "southbridge/amd/amd8111/amd8111_enable_rom.c" +#include "northbridge/amd/amdk8/early_ht.c" + +static void main(void) +{ + /* Nothing special needs to be done to find bus 0 */ + /* Allow the HT devices to be found */ + enumerate_ht_chain(); + + /* Setup the 8111 */ + amd8111_enable_rom(); + + if (do_normal_boot()) { + /* Jump to the normal image */ + asm("jmp __normal_image"); + } +} diff --git a/src/mainboard/amd/quartet/irq_tables.c b/src/mainboard/amd/quartet/irq_tables.c new file mode 100644 index 0000000000..286905c26f --- /dev/null +++ b/src/mainboard/amd/quartet/irq_tables.c @@ -0,0 +1,31 @@ +/* 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 + +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, /* u32 signature */ + PIRQ_VERSION, /* u16 version */ + 32+16*7, /* there can be total 7 devices on the bus */ + 0, /* Where the interrupt router lies (bus) */ + (5<<3)|3, /* Where the interrupt router lies (dev) */ + 0xc20, /* IRQs devoted exclusively to PCI usage */ + 0x1022, /* Vendor */ + 0x746b, /* Device */ + 0, /* Crap (miniport) */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xdf, /* u8 checksum , mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x02, (5<<3)|0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}, {0x01, 0xdeb8}}, 0x02, 0x00}, + {0x02, (6<<3)|0, {{0x03, 0xdeb8}, {0x04, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0xdeb8}}, 0x03, 0x00}, + {0x02, (7<<3)|0, {{0x04, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}}, 0x04, 0x00}, + {0x02, (1<<3)|1, {{0x01, 0xdeb8}, {0x01, 0xdeb8}, {0x01, 0xdeb8}, {0x01, 0xdeb8}}, 0x00, 0x00}, + {0x00, (5<<3)|1, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}}, 0x00, 0x00}, + {0x00, (2<<3)|0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}}, 0x00, 0x00}, + {0xff, 0xff, {{0xff, 0xffff}, {0xff, 0xffff}, {0xff, 0xffff}, {0xff, 0xffff}}, 0xff, 0xff}, + } +}; diff --git a/src/mainboard/amd/quartet/mainboard.c b/src/mainboard/amd/quartet/mainboard.c new file mode 100644 index 0000000000..5690bd5afd --- /dev/null +++ b/src/mainboard/amd/quartet/mainboard.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include +#include + + +unsigned long initial_apicid[MAX_CPUS] = +{ + 0 +}; diff --git a/src/mainboard/amd/quartet/mptable.c b/src/mainboard/amd/quartet/mptable.c new file mode 100644 index 0000000000..847416eec5 --- /dev/null +++ b/src/mainboard/amd/quartet/mptable.c @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include + +void *smp_write_config_table(void *v, unsigned long * processor_map) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "AMD "; + static const char productid[12] = "QUARTET "; + struct mp_config_table *mc; + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_8131_1; + unsigned char bus_8131_2; + unsigned char bus_8111_1; + + 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, processor_map); + + { + struct pci_dev *dev; + uint32_t base; + /* 8111 */ + dev = dev_find_slot(0, PCI_DEVFN(0x03,0)); + if (dev) { + bus_8111_1 = 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 0:03.0, using defaults\n"); + + bus_8111_1 = 3; + bus_isa = 4; + } + /* 8131-1 */ + dev = dev_find_slot(0, PCI_DEVFN(0x01,0)); + if (dev) { + bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 0:01.0, using defaults\n"); + + bus_8131_1 = 1; + } + /* 8131-2 */ + dev = dev_find_slot(0, PCI_DEVFN(0x02,0)); + if (dev) { + bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 0:02.0, using defaults\n"); + + bus_8131_2 = 2; + } + } + + /* 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 "); + + /* IOAPIC handling */ + + smp_write_ioapic(mc, 2, 0x11, 0xfec00000); + { + struct pci_dev *dev; + uint32_t base; + /* 8131 apic 3 */ + dev = dev_find_slot(0, PCI_DEVFN(0x01,1)); + if (dev) { + base = pci_read_config32(dev, PCI_BASE_ADDRESS_0); + base &= PCI_BASE_ADDRESS_MEM_MASK; + smp_write_ioapic(mc, 0x03, 0x11, base); + } + /* 8131 apic 4 */ + dev = dev_find_slot(0, PCI_DEVFN(0x02,1)); + if (dev) { + base = pci_read_config32(dev, PCI_BASE_ADDRESS_0); + base &= PCI_BASE_ADDRESS_MEM_MASK; + smp_write_ioapic(mc, 0x04, 0x11, base); + } + } + + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x00, 0x02, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x01, 0x02, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x00, 0x02, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x03, 0x02, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x04, 0x02, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x05, 0x02, 0x05); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x06, 0x02, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x07, 0x02, 0x07); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x08, 0x02, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x09, 0x02, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0a, 0x02, 0x0a); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0b, 0x02, 0x0b); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0c, 0x02, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0d, 0x02, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0e, 0x02, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0f, 0x02, 0x0f); + + /* Standard local interrupt assignments */ + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x00, MP_APIC_ALL, 0x00); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x00, MP_APIC_ALL, 0x01); + + + /* AGP Slot */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + 0x03, (6<<2)|0, 0x02, 0x12); + + /* PCI Slot 1 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (1<<2)|0, 0x04, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (1<<2)|1, 0x04, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (1<<2)|2, 0x04, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (1<<2)|3, 0x04, 0x0); + + /* PCI Slot 2 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (2<<2)|0, 0x04, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (2<<2)|1, 0x04, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (2<<2)|2, 0x04, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (2<<2)|3, 0x04, 0x1); + + /* PCI Slot 3 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (1<<2)|0, 0x03, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (1<<2)|1, 0x03, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (1<<2)|2, 0x03, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (1<<2)|3, 0x03, 0x0); + + /* PCI Slot 4 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (2<<2)|0, 0x03, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (2<<2)|1, 0x03, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (2<<2)|2, 0x03, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (2<<2)|3, 0x03, 0x1); + + /* PCI Slot 5 */ +#warning "FIXME get the irqs right, it's just hacked to work for now" + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8111_1, (5<<2)|0, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8111_1, (5<<2)|1, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8111_1, (5<<2)|2, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8111_1, (5<<2)|3, 0x02, 0x10); + + /* PCI Slot 6 */ +#warning "FIXME get the irqs right, it's just hacked to work for now" + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8111_1, (4<<2)|0, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8111_1, (4<<2)|1, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8111_1, (4<<2)|2, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8111_1, (4<<2)|3, 0x02, 0x13); + + /* On board nics */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (3<<2)|0, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (4<<2)|0, 0x02, 0x13); + + /* 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, unsigned long *processor_map) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v, processor_map); +} + diff --git a/src/mainboard/amd/quartet/resourcemap.c b/src/mainboard/amd/quartet/resourcemap.c new file mode 100644 index 0000000000..bf1e388238 --- /dev/null +++ b/src/mainboard/amd/quartet/resourcemap.c @@ -0,0 +1,265 @@ +/* + * QUARTET needs a different default resource map. + * + */ + + +static void setup_quartet_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, 0x00f00000, + PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x01f00001, + PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x02f00002, + PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x03f00003, + 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, 0x00000003, + PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00100003, + PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00200003, + PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00300003, + PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00400000, + PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00400000, + PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00400000, + PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00400000, + + /* 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, 0x00ee1f20, + PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00f10f11, + PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00fbff11, + PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00fec020, + PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000b20, + PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00fed020, + PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00000000, + + /* 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, 0x00ec0003, + PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00ee2003, + PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00f40003, + PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00fec003, + PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000a03, + PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00fed003, + PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00000000, + + /* 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, 0x00002020, + PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00005011, + 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, 0x00003003, + 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, 0x07000203, + PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0xff080113, + PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0xffff0040, + PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0xffff0330, + }; + int max; + max = sizeof(register_values)/sizeof(register_values[0]); + setup_resource_map(register_values, max); +} +