From b980e39c81a1eed2dc3e2d1a939320292b36885c Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Thu, 28 Aug 2003 17:23:15 +0000 Subject: [PATCH] add first bunch of newisys khepri files. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1090 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/mainboard/newisys/khepri/Config.lb | 168 +++++++++++++++ src/mainboard/newisys/khepri/auto.c | 239 ++++++++++++++++++++++ src/mainboard/newisys/khepri/chip.h | 5 + src/mainboard/newisys/khepri/cmos.layout | 74 +++++++ src/mainboard/newisys/khepri/failover.c | 38 ++++ src/mainboard/newisys/khepri/irq_tables.c | 43 ++++ src/mainboard/newisys/khepri/mainboard.c | 35 ++++ src/mainboard/newisys/khepri/mptable.c | 236 +++++++++++++++++++++ 8 files changed, 838 insertions(+) create mode 100644 src/mainboard/newisys/khepri/Config.lb create mode 100644 src/mainboard/newisys/khepri/auto.c create mode 100644 src/mainboard/newisys/khepri/chip.h create mode 100644 src/mainboard/newisys/khepri/cmos.layout create mode 100644 src/mainboard/newisys/khepri/failover.c create mode 100644 src/mainboard/newisys/khepri/irq_tables.c create mode 100644 src/mainboard/newisys/khepri/mainboard.c create mode 100644 src/mainboard/newisys/khepri/mptable.c diff --git a/src/mainboard/newisys/khepri/Config.lb b/src/mainboard/newisys/khepri/Config.lb new file mode 100644 index 0000000000..db31552135 --- /dev/null +++ b/src/mainboard/newisys/khepri/Config.lb @@ -0,0 +1,168 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses USE_NORMAL_IMAGE +uses AMD8111_DEV +uses MAINBOARD +uses ARCH +uses ENABLE_IOMMU +# +# +### +### 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 +# +### +### 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 ./failover.inc +# mainboardinit southbridge/amd/amd8111/cmos_boot_failover.inc +end + +# +# +### +### Setup the serial port +### +#mainboardinit superiowinbond/w83627hf/setup_serial.inc +mainboardinit pc80/serial.inc +mainboardinit arch/i386/lib/console.inc +# +#### +#### 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 ./failover.E + depends "$(MAINBOARD)/failover.c" + action "$(CPP) -I$(TOP)/src $(ROMCCPPFLAGS) $(CPPFLAGS) $(MAINBOARD)/failover.c > ./failover.E" +end + +makerule ./failover.inc + depends "./romcc ./failover.E" + action "./romcc -O -o failover.inc --label-prefix=failover ./failover.E"end + +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 -mcpu=k8 -O ./auto.E > auto.inc" +end +mainboardinit cpu/k8/enable_mmx_sse.inc +mainboardinit ./auto.inc +mainboardinit cpu/k8/disable_mmx_sse.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 "amd8111" +end +southbridge amd/amd8131 "amd8131" +end +#mainboardinit archi386/smp/secondary.inc +superio NSC/pc87360 + register "com1" = "{1}" + register "lpt" = "{1}" +end +dir /pc80 +##dir /src/superio/winbond/w83627hf +#dir /cpu/k8 +cpu k8 "cpu0" + register "up" = "{.chip = &amd8111, .ht_width=8, .ht_speed=200}" +end + +cpu k8 "cpu1" +end + +option ENABLE_IOMMU=1 diff --git a/src/mainboard/newisys/khepri/auto.c b/src/mainboard/newisys/khepri/auto.c new file mode 100644 index 0000000000..ca19245293 --- /dev/null +++ b/src/mainboard/newisys/khepri/auto.c @@ -0,0 +1,239 @@ +#define ASSEMBLY 1 +#define MAXIMUM_CONSOLE_LOGLEVEL 9 +#define DEFAULT_CONSOLE_LOGLEVEL 9 + +#include +#include +#include +#include +#include +#include +#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" +#include "cpu/k8/apic_timer.c" +#include "lib/delay.c" +#include "cpu/p6/boot_cpu.c" +#include "northbridge/amd/amdk8/reset_test.c" +#include "debug.c" + +static void memreset_setup(void) +{ + /* Set the memreset low */ + outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28); + /* Ensure the BIOS has control of the memory lines */ + outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29); +} + +static void memreset(int controllers, const struct mem_controller *ctrl) +{ + udelay(800); + /* Set memreset_high */ + outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28); + udelay(90); +} + +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] = { + { 0x00050101, 0x00010404 }, + { 0x00010404, 0x00050101 } + }; + + if(maxnodes>2) { + print_debug("this mainboard is only designed for 2 cpus\r\n"); + maxnodes=2; + } + + + if (!(node>=maxnodes || row>=maxnodes)) { + ret=rows_2p[node][row]; + } + + return ret; +} + +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +/* no specific code here. this should go away completely */ +static void coherent_ht_mainboard(unsigned cpus) +{ +} + +#include "northbridge/amd/amdk8/cpu_ldtstop.c" +#include "southbridge/amd/amd8111/amd8111_ldtstop.c" + +#include "northbridge/amd/amdk8/raminit.c" +#include "northbridge/amd/amdk8/coherent_ht.c" +#include "sdram/generic_sdram.c" + +static void enable_lapic(void) +{ + + msr_t msr; + msr = rdmsr(0x1b); + msr.hi &= 0xffffff00; + msr.lo &= 0x000007ff; + msr.lo |= APIC_DEFAULT_BASE | (1 << 11); + wrmsr(0x1b, msr); +} + +static void stop_this_cpu(void) +{ + unsigned apicid; + apicid = apic_read(APIC_ID) >> 24; + + /* Send an APIC INIT to myself */ + apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); + apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT); + /* Wait for the ipi send to finish */ + apic_wait_icr_idle(); + + /* Deassert the APIC INIT */ + apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); + apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); + /* Wait for the ipi send to finish */ + apic_wait_icr_idle(); + + /* If I haven't halted spin forever */ + for(;;) { + hlt(); + } +} + +#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); +} + +#define FIRST_CPU 1 +#define SECOND_CPU 0 +#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) +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 cpu[] = { +#if FIRST_CPU + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x18, 0), + .f1 = PCI_DEV(0, 0x18, 1), + .f2 = PCI_DEV(0, 0x18, 2), + .f3 = PCI_DEV(0, 0x18, 3), + .channel0 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 }, + .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 }, + }, +#endif +#if SECOND_CPU + { + .node_id = 1, + .f0 = PCI_DEV(0, 0x19, 0), + .f1 = PCI_DEV(0, 0x19, 1), + .f2 = PCI_DEV(0, 0x19, 2), + .f3 = PCI_DEV(0, 0x19, 3), + .channel0 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 }, + .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 }, + }, +#endif + }; + if (cpu_init_detected()) { + asm("jmp __cpu_reset"); + } + enable_lapic(); + init_timer(); + if (!boot_cpu()) { + stop_this_cpu(); + } + pc87360_enable_serial(); + uart_init(); + console_init(); + setup_default_resource_map(); + setup_coherent_ht_domain(); + enumerate_ht_chain(0); + distinguish_cpu_resets(0); + +#if 0 + print_pci_devices(); +#endif + enable_smbus(); +#if 0 + dump_spd_registers(&cpu[0]); +#endif + memreset_setup(); + sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); + +#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 TOTAL_CPUS < 2 + /* Check 16MB of memory @ 0*/ + ram_check(0x00000000, 0x01000); +#else + /* Check 16MB of memory @ 2GB */ + ram_check(0x80000000, 0x81000000); +#endif +#endif +} diff --git a/src/mainboard/newisys/khepri/chip.h b/src/mainboard/newisys/khepri/chip.h new file mode 100644 index 0000000000..44fefaf2d8 --- /dev/null +++ b/src/mainboard/newisys/khepri/chip.h @@ -0,0 +1,5 @@ +struct chip_control mainboard_newisys_khepri_control; + +struct mainboard_newisys_khepri_config { + int nothing; +}; diff --git a/src/mainboard/newisys/khepri/cmos.layout b/src/mainboard/newisys/khepri/cmos.layout new file mode 100644 index 0000000000..5ba4c032c1 --- /dev/null +++ b/src/mainboard/newisys/khepri/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/newisys/khepri/failover.c b/src/mainboard/newisys/khepri/failover.c new file mode 100644 index 0000000000..8eeeaef7e1 --- /dev/null +++ b/src/mainboard/newisys/khepri/failover.c @@ -0,0 +1,38 @@ +#define ASSEMBLY 1 +#include +#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" +#include "cpu/p6/boot_cpu.c" +#include "northbridge/amd/amdk8/reset_test.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(0); + + /* Setup the 8111 */ + amd8111_enable_rom(); + + /* Is this a cpu reset? */ + if (cpu_init_detected()) { + if (last_boot_normal()) { + asm("jmp __normal_image"); + } else { + asm("jmp __cpu_reset"); + } + } + /* Is this a secondary cpu? */ + else if (!boot_cpu() && last_boot_normal()) { + asm("jmp __normal_image"); + } + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + asm("jmp __normal_image"); + } +} diff --git a/src/mainboard/newisys/khepri/irq_tables.c b/src/mainboard/newisys/khepri/irq_tables.c new file mode 100644 index 0000000000..5e4437ca11 --- /dev/null +++ b/src/mainboard/newisys/khepri/irq_tables.c @@ -0,0 +1,43 @@ +/* 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*18, /* there can be total 18 devices on the bus */ + 0, /* Where the interrupt router lies (bus) */ + 0x23, /* Where the interrupt router lies (dev) */ + 0, /* 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] */ + 0x35, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */ + { + {0,0xc0, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0}, + {0,0x50, {{0x1, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0}, + {0x2,0x8, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x3, 0}, + {0x2,0x10, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x4, 0}, + {0x1,0x18, {{0x4, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0x0, 0}, + {0x1,0x20, {{0x4, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0x0, 0}, + {0x2,0x28, {{0x2, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0xa, 0}, + {0,0x58, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0}, + {0x3,0x8, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x1, 0}, + {0x3,0x10, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x2, 0}, + {0x3,0x18, {{0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}}, 0x9, 0}, + {0,0x30, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0}, + {0x1,0, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0x4, 0xdef8}}, 0, 0}, + {0x1,0x28, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x5, 0}, + {0x1,0x20, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x6, 0}, + {0x1,0x30, {{0x3, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0xb, 0}, + {0,0x38, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0}, + {0,0xc8, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0}, + } +}; diff --git a/src/mainboard/newisys/khepri/mainboard.c b/src/mainboard/newisys/khepri/mainboard.c new file mode 100644 index 0000000000..9e5c0acc89 --- /dev/null +++ b/src/mainboard/newisys/khepri/mainboard.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include + +#include +#include +#include "chip.h" + + +unsigned long initial_apicid[MAX_CPUS] = +{ + 0, 1, +}; + +static void +enable(struct chip *chip, enum chip_pass pass) +{ + + struct mainboard_newisys_khepri_config *conf = + (struct mainboard_newisys_khepri_config *)chip->chip_info; + + switch (pass) { + default: break; + case CONF_PASS_PRE_BOOT: + break; + } + +} +struct chip_control mainboard_newisys_khepri_control = { + enable: enable, + name: "Newisys Khepri mainboard " +}; + diff --git a/src/mainboard/newisys/khepri/mptable.c b/src/mainboard/newisys/khepri/mptable.c new file mode 100644 index 0000000000..ba8692c1f5 --- /dev/null +++ b/src/mainboard/newisys/khepri/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] = "NEWISYS "; + static const char productid[12] = "KHEPRI "; + 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, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (1<<2)|1, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (1<<2)|2, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (1<<2)|3, 0x02, 0x10); + + /* PCI Slot 2 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (2<<2)|0, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (2<<2)|1, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (2<<2)|2, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_2, (2<<2)|3, 0x02, 0x11); + + /* PCI Slot 3 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (1<<2)|0, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (1<<2)|1, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (1<<2)|2, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (1<<2)|3, 0x02, 0x10); + + /* PCI Slot 4 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (2<<2)|0, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (2<<2)|1, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (2<<2)|2, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_8131_1, (2<<2)|3, 0x02, 0x11); + + /* 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); +} +