diff --git a/src/arch/i386/include/arch/intel.h b/src/arch/i386/include/arch/intel.h index 3daeba70b2..df6604e08e 100644 --- a/src/arch/i386/include/arch/intel.h +++ b/src/arch/i386/include/arch/intel.h @@ -354,7 +354,6 @@ NO FUNCTIONS YET! /* originally this macro was from STPC BIOS */ -/* kevin/Ispiri - changed to default to serial port POST codes */ #define intel_chip_post_macro(value) \ movb $value, %al ; \ outb %al, $0x80 diff --git a/src/include/southbridge/amd/amd768.h b/src/include/southbridge/amd/amd768.h new file mode 100644 index 0000000000..c2f9f15aa5 --- /dev/null +++ b/src/include/southbridge/amd/amd768.h @@ -0,0 +1,19 @@ +#ifndef AMD768_H +#define AMD768_H + +void amd768_disable_watchdog(void); +void amd768_enable_ioapic(void); +void amd768_enable_port92_reset(void); +void amd768_mouse_sends_irq12(void); +void amd768_enable_serial_irqs(int continuous, unsigned frames, unsigned startclocks); +void amd768_cpu_reset_sends_init(void); +#define DECODE_STPGNT_ADDR 0 +#define DECODE_STPGNT_DATA 1 +void amd768_decode_stop_grant(unsigned how); +void amd768_set_pm_classcode(void); +void amd768_usb_setup(void); +void amd768_power_after_power_fail(int on); +void amd768_posted_memory_write_enable(void); +void amd768_hard_reset(void); +void amd768_enable_ide(int enable_a, int enable_b); +#endif /* AMD768_H */ diff --git a/src/lib/video_subr.c b/src/lib/video_subr.c index ff7bfcb4b8..c1ea0dcbea 100644 --- a/src/lib/video_subr.c +++ b/src/lib/video_subr.c @@ -93,4 +93,3 @@ void video_tx_byte(unsigned char byte) write_crtc((video_col + (video_line *COLS)) >> 8, CRTC_CURSOR_HI); write_crtc((video_col + (video_line *COLS)) & 0x0ff, CRTC_CURSOR_LO); } - diff --git a/src/mainboard/supermicro/p4dpe/Config b/src/mainboard/supermicro/p4dpe/Config index 7ff9831c30..540ce23b63 100644 --- a/src/mainboard/supermicro/p4dpe/Config +++ b/src/mainboard/supermicro/p4dpe/Config @@ -99,6 +99,10 @@ object irq_tables.o HAVE_PIRQ_TABLE ### ### Build options ### +## + +## Number of consecutive times boot failures triggers a boot into fallback mode.## +option MAX_REBOOT_CNT=8 ## ## Location of the DIMM EEPROMS on the SMBUS diff --git a/src/mainboard/supermicro/p4dpe/cmos.layout b/src/mainboard/supermicro/p4dpe/cmos.layout index 69d140c104..7c9c1655b6 100644 --- a/src/mainboard/supermicro/p4dpe/cmos.layout +++ b/src/mainboard/supermicro/p4dpe/cmos.layout @@ -42,6 +42,8 @@ entries 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 diff --git a/src/mainboard/supermicro/p4dpe/devices.c b/src/mainboard/supermicro/p4dpe/devices.c new file mode 100644 index 0000000000..6e6d420756 --- /dev/null +++ b/src/mainboard/supermicro/p4dpe/devices.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +struct cdev { + unsigned int devfn; + struct cdev *next; + struct cdev *children; + void *private; +}; +static struct cdev nodev; + +#define DEV(NAME, DEVICE, FUNCTION, NEXT, CHILDREN, PRIVATE) \ +static struct cdev NEXT; \ +static struct cdev CHILDREN; \ +static struct cdev NAME = { \ + .devfn = PCI_DEVFN(DEVICE, FUNCTION), \ + .next = &NEXT, \ + .children = &CHILDREN, \ + .private = PRIVATE, \ +} + +DEV(dev0_2_0, 0x02, 0, dev0_1f_0, dev1_1c_0, 0); +DEV(dev0_1f_0, 0x1f, 0, nodev, nodev, 0); +DEV(dev1_1c_0, 0x1c, 0, dev1_1e_0, nodev, 0); +DEV(dev1_1e_0, 0x1e, 0, nodev, nodev, 0); + +static void add_dev_list(struct pci_bus *bus, struct cdev *dev); + +static void add_device(struct pci_bus *bus, struct cdev *dev) +{ + struct pci_dev *pdev; + struct pci_bus *pbus; + +#if 0 + printk_debug("Adding%s %02x.%01x\n", + (dev->children == &nodev)?"":" bus", + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); +#endif + + pdev = malloc(sizeof(*pdev)); + if (!pdev) + goto no_mem; + + memset(pdev, 0, sizeof(*pdev)); + pdev->bus = bus; + pdev->devfn = dev->devfn; + + /* Add to the list of devices on the parent bus. */ + pdev->sibling = bus->devices; + bus->devices = pdev; + + + /* Leave if we aren't a bus. */ + if (dev->children == &nodev) + return; + + pbus = malloc(sizeof(*pbus)); + if (!pbus) + goto no_mem; + + memset(pbus, 0, sizeof(*pbus)); + pbus->sibling = bus->children; + bus->children = pbus; + pbus->self = pdev; + pbus->parent = bus; + + add_dev_list(pbus, dev->children); + return; + no_mem: + printk_err("PCI: out of memory.\n"); + return; +} + +static void add_dev_list(struct pci_bus *bus, struct cdev *dev) +{ + while(dev != &nodev) { + add_device(bus, dev); + dev = dev->next; + } +} +void add_devices(void) +{ + struct cdev *dev = &dev0_2_0; + add_dev_list(&pci_root, dev); +} diff --git a/src/mainboard/supermicro/p4dpe/hardware.c b/src/mainboard/supermicro/p4dpe/hardware.c new file mode 100644 index 0000000000..541732acd7 --- /dev/null +++ b/src/mainboard/supermicro/p4dpe/hardware.c @@ -0,0 +1,25 @@ +#include +#include + +struct pci_bus pci_root = { + .children = &bus1; +}; +struct pci_dev dev0_2_0 = { + .bus = &pci_root, + .devfn = PCI_DEVFN(2,0), +}; +struct pci_bus bus1 = { + .parent = &pci_root, + .self = &dev0_2_0, +}; +struct pci_dev dev1_1c_0 = { + .bus = &bus1, + .devfn = PCI_DEVFN(0x1c, 0), + /* Hang ioapic information off of here */ +}; +struct pci_dev dev1_1e_0 = { + .bus = &bus1, + .devfn = PCI_DEVFN(0x1e, 0), + /* Hang ioapic information off of here */ +}; + diff --git a/src/mainboard/supermicro/p4dpe/mptable.c b/src/mainboard/supermicro/p4dpe/mptable.c index 5de6ced925..8b9a66beaf 100644 --- a/src/mainboard/supermicro/p4dpe/mptable.c +++ b/src/mainboard/supermicro/p4dpe/mptable.c @@ -127,21 +127,33 @@ void *smp_write_config_table(void *v, unsigned long * processor_map) /* Slot 1 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x02, (1<<2)|0, 0x04, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x02, (1<<2)|1, 0x04, 0x01); /* Slot 2 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x03, (1<<2)|0, 0x03, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x03, (1<<2)|1, 0x03, 0x01); /* Slot 3 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x06, (1<<2)|0, 0x05, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x06, (1<<2)|1, 0x05, 0x01); /* Slot 4 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x05, (1<<2)|0, 0x08, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x05, (1<<2)|1, 0x08, 0x01); /* Slot 5 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x05, (2<<2)|0, 0x08, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x05, (2<<2)|1, 0x08, 0x05); /* Slot 6 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x05, (3<<2)|0, 0x08, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x05, (3<<2)|1, 0x08, 0x09); /* Onboard Gigabit Intel NIC */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, @@ -154,10 +166,6 @@ void *smp_write_config_table(void *v, unsigned long * processor_map) 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)); -#if CONFIG_DEBUG_MPTABLE == 1 - hexdump ("_MP_", 0x10, 0x20); - hexdump("TABLE", mc, 0x1e4-0x20); -#endif return smp_next_mpe_entry(mc); } diff --git a/src/mainboard/supermicro/p4dpeg2/Config b/src/mainboard/supermicro/p4dpeg2/Config new file mode 100644 index 0000000000..6f94acd0cb --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/Config @@ -0,0 +1,265 @@ + +## Set all of the defaults for an x86 architecture +## +arch i386 + +## +## 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) +## +mainboardinit cpu/i386/reset16.inc USE_FALLBACK_IMAGE +ldscript cpu/i386/reset16.lds USE_FALLBACK_IMAGE +mainboardinit cpu/i386/reset32.inc USE_NORMAL_IMAGE +ldscript cpu/i386/reset32.lds USE_NORMAL_IMAGE + +## +## 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. +mainboardinit northbridge/intel/E7500/reset_test.inc +mainboardinit arch/i386/lib/noop_failover.inc USE_NORMAL_IMAGE +mainboardinit southbridge/intel/82801ca/cmos_failover.inc USE_FALLBACK_IMAGE +ldscript arch/i386/lib/failover.lds USE_FALLBACK_IMAGE + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup our mtrrs +## +mainboardinit cpu/i786/earlymtrr.inc + +## +## Setup the serial port +## +mainboardinit superio/winbond/w83627hf/setup_serial.inc +mainboardinit pc80/serial.inc +mainboardinit arch/i386/lib/console.inc +mainboardinit southbridge/intel/82801ca/watchdog_disable.inc + +## +## Reset pci clock for hardware bug work around +## +mainboardinit southbridge/intel/82801ca/smbus.inc +mainboardinit southbridge/intel/82801ca/smbus_write_block.inc +mainboardinit mainboard/supermicro/p4dpeg2/pci_clk_reset.inc + +## +## Smbus functions +## +mainboardinit southbridge/intel/82801ca/smbus_read_byte.inc +#mainboardinit southbridge/intel/82801ca/smbus_read_block.inc +#mainboardinit southbridge/intel/82801ca/smbus_print_block.inc +mainboardinit mainboard/supermicro/p4dpeg2/select_i2c_spd.inc + +## +## Setup RAM +## +#mainboardinit ram/dump_northbridge.inc +#mainboardinit sdram/generic_dump_smbus.inc +#mainboardinit sdram/generic_dump_spd.inc +mainboardinit mainboard/supermicro/p4dpeg2/mainboard_raminit.inc + +## +## Include the secondary Configuration files +## +northbridge intel/E7500 +southbridge intel/82801ca +southbridge intel/82870 +nsuperio winbond/w83627hf com1={1} com2={1} floppy=1 lpt=1 keyboard=1 hwmonitor=1 +dir /src/pc80 +dir /src/superio/winbond/w83627hf +dir /src/ram/ +cpu p5 +cpu p6 +cpu i786 + +## +## Build the objects we have code for in this directory. +## +object mainboard.o +#object devices.o +object mptable.o HAVE_MP_TABLE +object irq_tables.o HAVE_PIRQ_TABLE + + +### +### Build options +### + +## +## Number of consecutive times boot failures triggers a boot into fallback mode.## +option MAX_REBOOT_CNT=8 + +## +## Location of the DIMM EEPROMS on the SMBUS +## This is fixed into a narrow range by the DIMM package standard. +## +option SMBUS_MEM_DEVICE_START=(0xa << 3) +option SMBUS_MEM_DEVICE_END=(SMBUS_MEM_DEVICE_START +3) +option SMBUS_MEM_DEVICE_INC=1 +option SMBUS_MEM_CHANNEL_OFF=4 + +## +## Customize our winbond superio chip for this motherboard +## +option SIO_BASE=0x2e +option SIO_SYSTEM_CLK_INPUT=SIO_SYSTEM_CLK_INPUT_48MHZ + +## +## Build code for the fallback boot +## +option HAVE_FALLBACK_BOOT=1 + +## +## Build code for using cache as RAM +## +#option USE_CACHE_RAM=0 + +## +## Delay timer options +## +option CONFIG_UDELAY_TSC=1 +option CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + + +## +## Build code to reset the motherboard from linuxBIOS +## +option HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +option HAVE_PIRQ_TABLE=1 + + +## +## Do not build special code to the keyboard +## +option NO_KEYBOARD=1 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +option HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option tabe table +## +option HAVE_OPTION_TABLE=1 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +option SMP=1 +option MAX_CPUS=4 +option MAX_PHYSICAL_CPUS=2 + +## +## Build code to setup a generic IOAPIC +## +option IOAPIC=1 + +## +## MEMORY_HOLE instructs earlymtrr.inc to +## enable caching from 0-640KB and to disable +## caching from 640KB-1MB using fixed MTRRs +## +## Enabling this option breaks SMP because secondary +## CPU identification depends on only variable MTRRs +## being enabled. +## +nooption MEMORY_HOLE + +## +## Figure out which type of linuxBIOS image to build +## If we aren't a fallback image we must be a normal image +## This is useful for optional includes +## +option USE_FALLBACK_IMAGE=0 +expr USE_NORMAL_IMAGE=!USE_FALLBACK_IMAGE + +### +### LinuxBIOS layout values +### + +## ROM_SIZE is the size of boot ROM that this board will use. +option ROM_SIZE=524288 + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +option ROM_IMAGE_SIZE=49152 + +## LinuxBIOS C code runs at this location in RAM +option _RAMBASE=0x00008000 + +## For the trick of using cache as ram +## put the fake ram location at this address +option CACHE_RAM_BASE=0xfff70000 +option CACHE_RAM_SIZE=0x00010000 + +## +## Use a small 8K stack +## +option STACK_SIZE=0x2000 + +## +## Use a small 8K heap +## +option HEAP_SIZE=0x2000 + +## +## Clean up the motherboard id strings +## +option MAINBOARD_PART_NUMBER=P4DP6 +option MAINBOARD_VENDOR=Supermicro + +option UPDATE_MICROCODE=1 +option CPU_FIXUP=1 + +## +## Only use the option table in a normal image +## +expr USE_OPTION_TABLE=!USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +expr ROM_SECTION_SIZE =(USE_FALLBACK_IMAGE*65536)+(USE_NORMAL_IMAGE*(ROM_SIZE - 65536)) +expr ROM_SECTION_OFFSET=(USE_FALLBACK_IMAGE*(ROM_SIZE-65536))+(USE_NORMAL_IMAGE*0) + + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +expr ZKERNEL_START =(0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) +expr PAYLOAD_SIZE =ROM_SECTION_SIZE - ROM_IMAGE_SIZE + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +expr _ROMBASE =ZKERNEL_START + PAYLOAD_SIZE + +## +## Compute a range of ROM that can cached to speed of linuxBIOS, +## execution speed. +## +expr XIP_ROM_SIZE = 65536 +expr XIP_ROM_BASE = _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE diff --git a/src/mainboard/supermicro/p4dpeg2/cmos.layout b/src/mainboard/supermicro/p4dpeg2/cmos.layout new file mode 100644 index 0000000000..7c9c1655b6 --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/cmos.layout @@ -0,0 +1,96 @@ +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 2 hyper_threading +396 1 e 1 thermal_monitoring +397 1 e 1 remap_memory_high +400 1 e 1 power_on_after_fail +#402 1 e 2 hda_disk +#403 1 e 2 hdb_disk +#404 1 e 2 hdc_disk +#405 1 e 2 hdd_disk +#408 4 e 9 CPU_clock_speed +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 +#9 15 800MHZ +#9 11 900MHZ +#9 13 1GHZ +#9 9 1.1GHZ +#9 14 1.2GHZ +#9 10 1.3GHZ +#9 12 1.4GHZ +#9 8 1.5GHZ +#9 7 1.6GHZ +#9 3 1.7GHZ +#9 5 1.8GHZ +#9 1 1.9GHZ +#9 6 2.0GHZ +#9 2 2.1GHZ +#9 4 2.2GHZ +#9 0 2.3GHZ + +checksums + +checksum 392 1007 1008 diff --git a/src/mainboard/supermicro/p4dpeg2/devices.c b/src/mainboard/supermicro/p4dpeg2/devices.c new file mode 100644 index 0000000000..6e6d420756 --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/devices.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +struct cdev { + unsigned int devfn; + struct cdev *next; + struct cdev *children; + void *private; +}; +static struct cdev nodev; + +#define DEV(NAME, DEVICE, FUNCTION, NEXT, CHILDREN, PRIVATE) \ +static struct cdev NEXT; \ +static struct cdev CHILDREN; \ +static struct cdev NAME = { \ + .devfn = PCI_DEVFN(DEVICE, FUNCTION), \ + .next = &NEXT, \ + .children = &CHILDREN, \ + .private = PRIVATE, \ +} + +DEV(dev0_2_0, 0x02, 0, dev0_1f_0, dev1_1c_0, 0); +DEV(dev0_1f_0, 0x1f, 0, nodev, nodev, 0); +DEV(dev1_1c_0, 0x1c, 0, dev1_1e_0, nodev, 0); +DEV(dev1_1e_0, 0x1e, 0, nodev, nodev, 0); + +static void add_dev_list(struct pci_bus *bus, struct cdev *dev); + +static void add_device(struct pci_bus *bus, struct cdev *dev) +{ + struct pci_dev *pdev; + struct pci_bus *pbus; + +#if 0 + printk_debug("Adding%s %02x.%01x\n", + (dev->children == &nodev)?"":" bus", + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); +#endif + + pdev = malloc(sizeof(*pdev)); + if (!pdev) + goto no_mem; + + memset(pdev, 0, sizeof(*pdev)); + pdev->bus = bus; + pdev->devfn = dev->devfn; + + /* Add to the list of devices on the parent bus. */ + pdev->sibling = bus->devices; + bus->devices = pdev; + + + /* Leave if we aren't a bus. */ + if (dev->children == &nodev) + return; + + pbus = malloc(sizeof(*pbus)); + if (!pbus) + goto no_mem; + + memset(pbus, 0, sizeof(*pbus)); + pbus->sibling = bus->children; + bus->children = pbus; + pbus->self = pdev; + pbus->parent = bus; + + add_dev_list(pbus, dev->children); + return; + no_mem: + printk_err("PCI: out of memory.\n"); + return; +} + +static void add_dev_list(struct pci_bus *bus, struct cdev *dev) +{ + while(dev != &nodev) { + add_device(bus, dev); + dev = dev->next; + } +} +void add_devices(void) +{ + struct cdev *dev = &dev0_2_0; + add_dev_list(&pci_root, dev); +} diff --git a/src/mainboard/supermicro/p4dpeg2/example-fallback.config b/src/mainboard/supermicro/p4dpeg2/example-fallback.config new file mode 100644 index 0000000000..362c375515 --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/example-fallback.config @@ -0,0 +1,104 @@ +## This will make a target directory of ./fallback +## This is relative to where the configuration file resides in the filesystem +target ./fallback + +mainboard supermicro/p4dc6 + +## Build a fallback not a normal image. +option USE_FALLBACK_IMAGE=1 + +## Build an image for a 512KB rom +## ./fallback/romimage is just the last 64KB which we reserve for the fallback image. +option ROM_SIZE=524288 +#option ROM_SIZE=1048576 + +## Select the maximum size the linuxBIOS code can compile to. +## Allow linuxBIOS to be up to 48KB in size +option ROM_IMAGE_SIZE=49152 + + +## +### The Serial Console +## +## Hardware flow control is currently ignored. + +## Enable the Serial Console +option SERIAL_CONSOLE=1 + +## Select the serial console baud rate. +option TTYS0_BAUD=115200 +#option TTYS0_BAUD=57600 +#option TTYS0_BAUD=38400 +#option TTYS0_BAUD=19200 +#option TTYS0_BAUD=9600 +#option TTYS0_BAUD=4800 +#option TTYS0_BAUD=2400 +#option TTYS0_BAUD=1200 + +# Select the serial console base port +option TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +option 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 +option DEFAULT_CONSOLE_LOGLEVEL=9 +## At a maximum only compile in this level of debugging +option MAXIMUM_CONSOLE_LOGLEVEL=6 + +## Use the elf bootloader +option USE_ELF_BOOT=1 + +## Select the boot device +option USE_GENERIC_ROM=1 +#option BOOT_FLOPPY=1 +#option USE_SERIAL_FILL_INBUF=1 +#option BOOT_IDE=1 + +# Load etherboot with the elf bootloader +# The payload command is relative the build directory +# So .. is the directory this config file resides in +payload ../eepro100.ebi + + +## +## Cpu Speed +## +option CPU_CLOCK_MULTIPLIER=XEON_X8 +#option CPU_CLOCK_MULTIPLIER=XEON_X9 +#option CPU_CLOCK_MULTIPLIER=XEON_X10 +#option CPU_CLOCK_MULTIPLIER=XEON_X11 +#option CPU_CLOCK_MULTIPLIER=XEON_X12 +#option CPU_CLOCK_MULTIPLIER=XEON_X13 +#option CPU_CLOCK_MULTIPLIER=XEON_X14 +#option CPU_CLOCK_MULTIPLIER=XEON_X15 +#option CPU_CLOCK_MULTIPLIER=XEON_X16 +#option CPU_CLOCK_MULTIPLIER=XEON_X17 +#option CPU_CLOCK_MULTIPLIER=XEON_X18 +#option CPU_CLOCK_MULTIPLIER=XEON_X19 +#option CPU_CLOCK_MULTIPLIER=XEON_X19 +#option CPU_CLOCK_MULTIPLIER=XEON_X20 +#option CPU_CLOCK_MULTIPLIER=XEON_X21 +#option CPU_CLOCK_MULTIPLIER=XEON_X22 +#option CPU_CLOCK_MULTIPLIER=XEON_X23 + +## +## Select power on after power fail setting +option MAINBOARD_POWER_ON_AFTER_POWER_FAIL=MAINBOARD_POWER_ON +#option MAINBOARD_POWER_ON_AFTER_POWER_FAIL=MAINBOARD_POWER_ON + diff --git a/src/mainboard/supermicro/p4dpeg2/example-normal.config b/src/mainboard/supermicro/p4dpeg2/example-normal.config new file mode 100644 index 0000000000..0ce189d2bf --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/example-normal.config @@ -0,0 +1,105 @@ +## This will make a target directory of ./normal +## This is relative to where the configuration file resides in the filesystem +target ./normal + +mainboard supermicro/p4dc6 + +## Build a normal not a fallback image. +option USE_FALLBACK_IMAGE=0 + +## Build an image for a 512KB rom +## ./normal/romimage is the entire rom image except for the last 64KB +## which are reserved for the fallback image. +option ROM_SIZE=524288 +#option ROM_SIZE=1048576 + +## Select the maximum size the linuxBIOS code can compile to. +## Allow linuxBIOS to be up to 48KB in size +option ROM_IMAGE_SIZE=49152 + + +## +### The Serial Console +## +## Hardware flow control is currently ignored. + +## Enable the Serial Console +option SERIAL_CONSOLE=1 + +## Select the serial console baud rate. +option TTYS0_BAUD=115200 +#option TTYS0_BAUD=57600 +#option TTYS0_BAUD=38400 +#option TTYS0_BAUD=19200 +#option TTYS0_BAUD=9600 +#option TTYS0_BAUD=4800 +#option TTYS0_BAUD=2400 +#option TTYS0_BAUD=1200 + +# Select the serial console base port +option TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +option 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 +option DEFAULT_CONSOLE_LOGLEVEL=9 +## At a maximum only compile in this level of debugging +option MAXIMUM_CONSOLE_LOGLEVEL=8 + +## Use the elf bootloader +option USE_ELF_BOOT=1 + +## Select the boot device +option USE_GENERIC_ROM=1 +#option BOOT_FLOPPY=1 +#option USE_SERIAL_FILL_INBUF=1 +#option BOOT_IDE=1 + +# Load etherboot with the elf bootloader +# The payload command is relative the build directory +# So .. is the directory this config file resides in +payload ../eepro100.ebi + + +## +## Cpu Speed +## +#option CPU_CLOCK_MULTIPLIER=XEON_X8 +#option CPU_CLOCK_MULTIPLIER=XEON_X9 +#option CPU_CLOCK_MULTIPLIER=XEON_X10 +#option CPU_CLOCK_MULTIPLIER=XEON_X11 +#option CPU_CLOCK_MULTIPLIER=XEON_X12 +#option CPU_CLOCK_MULTIPLIER=XEON_X13 +#option CPU_CLOCK_MULTIPLIER=XEON_X14 +#option CPU_CLOCK_MULTIPLIER=XEON_X15 +#option CPU_CLOCK_MULTIPLIER=XEON_X16 +option CPU_CLOCK_MULTIPLIER=XEON_X17 +#option CPU_CLOCK_MULTIPLIER=XEON_X18 +#option CPU_CLOCK_MULTIPLIER=XEON_X19 +#option CPU_CLOCK_MULTIPLIER=XEON_X19 +#option CPU_CLOCK_MULTIPLIER=XEON_X20 +#option CPU_CLOCK_MULTIPLIER=XEON_X21 +#option CPU_CLOCK_MULTIPLIER=XEON_X22 +#option CPU_CLOCK_MULTIPLIER=XEON_X23 + +## +## Select power on after power fail setting +option MAINBOARD_POWER_ON_AFTER_POWER_FAIL=MAINBOARD_POWER_ON +#option MAINBOARD_POWER_ON_AFTER_POWER_FAIL=MAINBOARD_POWER_ON + diff --git a/src/mainboard/supermicro/p4dpeg2/hardware.c b/src/mainboard/supermicro/p4dpeg2/hardware.c new file mode 100644 index 0000000000..541732acd7 --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/hardware.c @@ -0,0 +1,25 @@ +#include +#include + +struct pci_bus pci_root = { + .children = &bus1; +}; +struct pci_dev dev0_2_0 = { + .bus = &pci_root, + .devfn = PCI_DEVFN(2,0), +}; +struct pci_bus bus1 = { + .parent = &pci_root, + .self = &dev0_2_0, +}; +struct pci_dev dev1_1c_0 = { + .bus = &bus1, + .devfn = PCI_DEVFN(0x1c, 0), + /* Hang ioapic information off of here */ +}; +struct pci_dev dev1_1e_0 = { + .bus = &bus1, + .devfn = PCI_DEVFN(0x1e, 0), + /* Hang ioapic information off of here */ +}; + diff --git a/src/mainboard/supermicro/p4dpeg2/irq_tables.c b/src/mainboard/supermicro/p4dpeg2/irq_tables.c new file mode 100644 index 0000000000..f085f604bf --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/irq_tables.c @@ -0,0 +1,48 @@ +/* PCI: Interrupt Routing Table found at 0x4011cdf0 size = 496 */ + +#include + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 496, /* u16 Table size 32+(16*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x8086, /* u16 Vendor */ + 0x122e, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0x19, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0x10, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x01, 0xe8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x02, 0x08, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x06, 0x00}, + {0x02, 0x10, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x07, 0x00}, + {0x01, 0xf8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x03, 0x08, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x05, 0x00}, + {0x03, 0x10, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x0b, 0x00}, + {0x00, 0x18, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x04, 0xe8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x05, 0x08, {{0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}}, 0x03, 0x00}, + {0x05, 0x10, {{0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}}, 0x02, 0x00}, + {0x05, 0x18, {{0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}}, 0x01, 0x00}, + {0x04, 0xf8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x06, 0x08, {{0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}}, 0x04, 0x00}, + {0x06, 0x10, {{0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}, {0x69, 0xdcb8}}, 0x09, 0x00}, + {0x00, 0x20, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x10, 0xe8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x11, 0x08, {{0x63, 0xdcb8}, {0x63, 0xdcb8}, {0x63, 0xdcb8}, {0x63, 0xdcb8}}, 0x08, 0x00}, + {0x10, 0xf8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x12, 0x08, {{0x63, 0xdcb8}, {0x63, 0xdcb8}, {0x63, 0xdcb8}, {0x63, 0xdcb8}}, 0x07, 0x00}, + {0x00, 0xf0, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x07, 0x08, {{0x60, 0xdcb8}, {0x60, 0xdcb8}, {0x60, 0xdcb8}, {0x60, 0xdcb8}}, 0x0a, 0x00}, + {0x07, 0x10, {{0x61, 0xdcb8}, {0x61, 0xdcb8}, {0x61, 0xdcb8}, {0x61, 0xdcb8}}, 0x0b, 0x00}, + {0x07, 0x18, {{0x62, 0xdcb8}, {0x62, 0xdcb8}, {0x62, 0xdcb8}, {0x62, 0xdcb8}}, 0x0c, 0x00}, + {0x00, 0xe8, {{0x60, 0xdcb8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0xe9, {{0x00, 0xdef8}, {0x63, 0xdcb8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0xea, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x62, 0xdcb8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0xf8, {{0x62, 0xdcb8}, {0x61, 0xdcb8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00} + } +}; diff --git a/src/mainboard/supermicro/p4dpeg2/mainboard.c b/src/mainboard/supermicro/p4dpeg2/mainboard.c new file mode 100644 index 0000000000..8fa71517b4 --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/mainboard.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +unsigned long initial_apicid[MAX_CPUS] = +{ + 0, 6, 1, 7 +}; + +#ifndef CPU_CLOCK_MULTIPLIER +#define CPU_CLOCK_MULTIPLIER XEON_X17 +#endif + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 + +#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL +#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON +#endif + +static void set_power_on_after_power_fail(int setting) +{ + switch(setting) { + case MAINBOARD_POWER_ON: + default: + ich3_power_after_power_fail(1); + w83627hf_power_after_power_fail(POWER_ON); + break; + case MAINBOARD_POWER_OFF: + ich3_power_after_power_fail(0); + w83627hf_power_after_power_fail(POWER_OFF); + break; + + } +} + +static void set_thermal_monitoring(int thermal_monitoring) +{ + int tm_high,tm_low; + + rdmsr(MISC_ENABLE,tm_low,tm_high); + if(thermal_monitoring != THERMAL_MONITORING_OFF) { + tm_low |= THERMAL_MONITORING_SET; + } + else { + tm_low &= ~THERMAL_MONITORING_SET; + } + wrmsr(MISC_ENABLE,tm_low,tm_high); + return; +} + +void mainboard_fixup(void) +{ + int cpu_clock_multiplier; + int power_on_after_power_fail; + int thermal_monitoring; + + w83627hf_power_led(LED_ON); + ich3_enable_ioapic(); + p64h2_enable_ioapic(); + p64h2_setup_pcibridge(); + ich3_enable_serial_irqs(); + ich3_enable_ide(1,1); + ich3_rtc_init(); + ich3_lpc_route_dma(0xff); + isa_dma_init(); + ich3_1e0_misc(); + ich3_1f0_misc(); + +#if 0 /* CPU clock option is not presently used */ + cpu_clock_multiplier = CPU_CLOCK_MULTIPLIER; + if(get_option(&cpu_clock_multiplier, "CPU_clock_speed")) + cpu_clock_multiplier = CPU_CLOCK_MULTIPLIER; + ich3_set_cpu_multiplier(cpu_clock_multiplier); +#endif + + power_on_after_power_fail = MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + if(get_option(&power_on_after_power_fail, "power_on_after_fail")) + power_on_after_power_fail = MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + set_power_on_after_power_fail(power_on_after_power_fail); + + thermal_monitoring = THERMAL_MONITORING_OFF; + if(get_option(&thermal_monitoring, "thermal_monitoring")) + thermal_monitoring = THERMAL_MONITORING_OFF; + set_thermal_monitoring(thermal_monitoring); + + return; +} + +void hard_reset(void) +{ + ich3_hard_reset(); +} + diff --git a/src/mainboard/supermicro/p4dpeg2/mainboard_raminit.inc b/src/mainboard/supermicro/p4dpeg2/mainboard_raminit.inc new file mode 100644 index 0000000000..8d1c8b69c3 --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/mainboard_raminit.inc @@ -0,0 +1 @@ + diff --git a/src/mainboard/supermicro/p4dpeg2/mptable.c b/src/mainboard/supermicro/p4dpeg2/mptable.c new file mode 100644 index 0000000000..da41f2592f --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/mptable.c @@ -0,0 +1,149 @@ +/* generatred by MPTable, version 2.0.15*/ +/* as modified by RGM for LinuxBIOS */ +#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] = "LNXI "; + static const char productid[12] = "P4DPE-G2 "; + struct mp_config_table *mc; + + 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); + + +/*Bus: Bus ID Type*/ + smp_write_bus(mc, 0, "PCI "); + smp_write_bus(mc, 1, "PCI "); + smp_write_bus(mc, 2, "PCI "); + smp_write_bus(mc, 3, "PCI "); + smp_write_bus(mc, 4, "PCI "); + smp_write_bus(mc, 5, "PCI "); + smp_write_bus(mc, 6, "PCI "); + smp_write_bus(mc, 7, "PCI "); + smp_write_bus(mc, 8, "ISA "); + +/*I/O APICs: APIC ID Version State Address*/ + smp_write_ioapic(mc, 2, 0x20, 0xfec00000); + { + struct pci_dev *dev; + uint32_t base; + dev = pci_find_slot(1, PCI_DEVFN(0x1e,0)); + if (dev) { + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &base); + base &= PCI_BASE_ADDRESS_MEM_MASK; + smp_write_ioapic(mc, 3, 0x20, base); + } + dev = pci_find_slot(1, PCI_DEVFN(0x1c,0)); + if (dev) { + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &base); + + base &= PCI_BASE_ADDRESS_MEM_MASK; + smp_write_ioapic(mc, 4, 0x20, base); + } + dev = pci_find_slot(4, PCI_DEVFN(0x1e,0)); + + if (dev) { + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &base); + base &= PCI_BASE_ADDRESS_MEM_MASK; + smp_write_ioapic(mc, 5, 0x20, base); + } + dev = pci_find_slot(4, PCI_DEVFN(0x1c,0)); + if (dev) { + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &base); + base &= PCI_BASE_ADDRESS_MEM_MASK; + smp_write_ioapic(mc, 8, 0x20, 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, 0x8, 0x0, 0x2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x1, 0x2, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x0, 0x2, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x3, 0x2, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x4, 0x2, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x5, 0x2, 0x5); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x6, 0x2, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x7, 0x2, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x8, 0x2, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x9, 0x2, 0x9); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x75, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x74, 0x2, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0xc, 0x2, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0xd, 0x2, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0xe, 0x2, 0xe); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0xf, 0x2, 0xf); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x76, 0x2, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x2, 0x4, 0x4, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x3, 0x8, 0x3, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x3, 0x9, 0x3, 0x5); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x7, 0x4, 0x2, 0x10); +/*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, 0x8, 0x0, MP_APIC_ALL, 0x0); + smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x8, 0x0, MP_APIC_ALL, 0x1); + + /* p4dp8-g2 onboard scsi? */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x06, (2 << 2)|0, 0x05, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x06, (2 << 2)|1, 0x05, 0x05); + + /* Slot 1 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x02, (1<<2)|0, 0x04, 0x00); + /* Slot 2 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x03, (1<<2)|0, 0x03, 0x00); + /* Slot 3 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x06, (1<<2)|0, 0x05, 0x00); + /* Slot 4 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x05, (1<<2)|0, 0x08, 0x00); + /* Slot 5 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x05, (2<<2)|0, 0x08, 0x04); + /* Slot 6 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x05, (3<<2)|0, 0x08, 0x08); + + /* 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 +", + 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/supermicro/p4dpeg2/pci_clk_reset.inc b/src/mainboard/supermicro/p4dpeg2/pci_clk_reset.inc new file mode 100644 index 0000000000..fdba672d9a --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/pci_clk_reset.inc @@ -0,0 +1,133 @@ +/* The algorithm is as follows: + */ +#include +#include + + +#define PM_DEVFN ((0x1f <<3) + 0) + + .section ".rom.data" + +pci_clk_stop_beg: + .byte 0x08, 0x47, 0x7f, 0xc7, 0x38 +pci_clk_stop_end: + +pci_clk_start_beg: + .byte 0x08, 0x47, 0x7f, 0xc7, 0x3f +pci_clk_start_end: + +pci_clk_restart_msg: + .asciz "Restarting pci clocks\r\n" +pci_clk_power_msg: + .asciz "Power failed\r\n" + + .previous + + /* The PC64H2 has a known errata where there is a race + * between getting a good level, and getting a clock signal. + * Nasting things normally boot failure while readding the pci + * bus happen when this errata is hit. + * + * Thw work around is to stop and restart the 66Mhz reference clock + * the PC64H2. And to do this I need to talk to the reference clock + * generator in this case a cypress CY28329. + * + * The I2C interface on the Cyrpess chip is fragile. If you talk + * to it wrong or if you talk to it long enough after getting power, + * it will not talk to you. So I have to be very careful. What is + * especially bad is that sometimes a failed attempt to talk + * to the Cypress chip will lock the i2c/smbus controller on + * the ICH3. So I cannot talk to i2c EEPROM on memory dimms + * to detect how much memory I have. + * + * Placing the motherboard in soft power off is not enough to get the + * cypress chip talking again. So I only attempt the PC64H2 + * errata work around when I boot up immediate after the + * motherboard has lost power. + * + * This procedure appears to navigate the cascading mines of + * the hardware bugs. + */ +__reboot_ck: + /* See if power is failed, making it is safe to talk to the + * cypress chip. + */ + movl $((PM_DEVFN << 8) + 0xA4), %eax + PCI_READ_CONFIG_DWORD + + /* If power has not failed get, skip the errata work around */ + testl $(1 << 1), %eax + jz __continue_booting + + /* Clear the power failed bit, so I don't apply this + * work around when it is not safe. + */ + movl $((PM_DEVFN << 8) + 0xA4), %eax + movl $(1 << 1), %ecx + PCI_WRITE_CONFIG_DWORD + + /* Report that I have detected a power failure */ + CONSOLE_INFO_TX_STRING($pci_clk_power_msg) + + /* Attempt to write to the cypress chip and bail out if this + * fails. + */ + /* stop the clocks */ + movb $0x69, %bl + movb $0x00, %bh + movb $(pci_clk_stop_end - pci_clk_stop_beg), %cl + movl $(pci_clk_stop_beg), %esi + /* stop the pci clock */ + CALLSP(smbus_write_block) + jc __continue_booting + + /* wait for about 100us */ + movl $0x2c, %ecx + rdmsr + andl $0xff000000,%eax + shrl $10, %eax /* this gives the ticks for 160usec */ + movl %eax, %ebx + rdtsc + addl %ebx, %eax + adcl $0, %edx + movl %eax, %ebx + movl %edx, %ecx +1: rdtsc + subl %ebx, %eax + sbbl %ecx, %edx + jb 1b + + /* Add an extra delay to display this message */ + CONSOLE_INFO_TX_STRING($pci_clk_restart_msg) + + /* restart the clocks */ + movb $0x69, %bl + movb $0x00, %bh + movb $(pci_clk_start_end - pci_clk_start_beg), %cl + movl $(pci_clk_start_beg), %esi + /* start the pci clock */ + CALLSP(smbus_write_block) + + /* Set boot_option to last_boot, so I don't fallback by accident */ + movb $RTC_BOOT_BYTE, %al + outb %al, $0x70 + inb $0x71, %al + movb %al, %bl + shrb $1, %bl + andb $1, %bl + andb $0xfe, %al + orb %bl, %al + outb %al, $0x71 + + /* reboot the motherboard */ + movw $0x0cf9, %dx + inb %dx, %al + andb $~((1 <<3)|(1<<2)), %al + orb $(1<<1), %al + outb %al, %dx + orb $(1<<2), %al + outb %al, %dx +2: hlt + jmp 2b + +__continue_booting: diff --git a/src/mainboard/supermicro/p4dpeg2/select_i2c_spd.inc b/src/mainboard/supermicro/p4dpeg2/select_i2c_spd.inc new file mode 100644 index 0000000000..ffe5557d4b --- /dev/null +++ b/src/mainboard/supermicro/p4dpeg2/select_i2c_spd.inc @@ -0,0 +1,17 @@ + SIO_ENTER_PNP_MODE() + + SIO_READ_CONFIG($0x2b) + movb %al, %bl + orb $0x30, %bl + SIO_WRITE_CONFIG(%bl, $0x2b) + + /* Enable the GPIO device */ + SIO_SET_LOGICAL_DEVICE($GPIO_PORT2_DEVICE) + SIO_WRITE_CONFIG($1, $0x30) + + SIO_READ_CONFIG($0xf0) + movb %al, %bl + andb $~(1 << 3), %bl + SIO_WRITE_CONFIG(%bl, $0xf0) + + SIO_EXIT_PNP_MODE() diff --git a/src/mainboard/supermicro/p4dpr/Config b/src/mainboard/supermicro/p4dpr/Config index 47a9ada4e9..8bbd269cc2 100644 --- a/src/mainboard/supermicro/p4dpr/Config +++ b/src/mainboard/supermicro/p4dpr/Config @@ -100,6 +100,11 @@ object irq_tables.o HAVE_PIRQ_TABLE ### Build options ### +## +## Number of consecutive times boot failures triggers a boot into fallback mode. +## +option MAX_REBOOT_CNT=8 + ## ## Location of the DIMM EEPROMS on the SMBUS ## This is fixed into a narrow range by the DIMM package standard. @@ -131,7 +136,6 @@ option HAVE_FALLBACK_BOOT=1 option CONFIG_UDELAY_TSC=1 option CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 - ## ## Build code to reset the motherboard from linuxBIOS ## diff --git a/src/mainboard/supermicro/p4dpr/cmos.layout b/src/mainboard/supermicro/p4dpr/cmos.layout index 69d140c104..7c9c1655b6 100644 --- a/src/mainboard/supermicro/p4dpr/cmos.layout +++ b/src/mainboard/supermicro/p4dpr/cmos.layout @@ -42,6 +42,8 @@ entries 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 diff --git a/src/mainboard/supermicro/p4dpr/hardware.c b/src/mainboard/supermicro/p4dpr/hardware.c new file mode 100644 index 0000000000..541732acd7 --- /dev/null +++ b/src/mainboard/supermicro/p4dpr/hardware.c @@ -0,0 +1,25 @@ +#include +#include + +struct pci_bus pci_root = { + .children = &bus1; +}; +struct pci_dev dev0_2_0 = { + .bus = &pci_root, + .devfn = PCI_DEVFN(2,0), +}; +struct pci_bus bus1 = { + .parent = &pci_root, + .self = &dev0_2_0, +}; +struct pci_dev dev1_1c_0 = { + .bus = &bus1, + .devfn = PCI_DEVFN(0x1c, 0), + /* Hang ioapic information off of here */ +}; +struct pci_dev dev1_1e_0 = { + .bus = &bus1, + .devfn = PCI_DEVFN(0x1e, 0), + /* Hang ioapic information off of here */ +}; + diff --git a/src/mainboard/supermicro/p4dpr/mainboard.c b/src/mainboard/supermicro/p4dpr/mainboard.c index 8fa71517b4..f9362956dd 100644 --- a/src/mainboard/supermicro/p4dpr/mainboard.c +++ b/src/mainboard/supermicro/p4dpr/mainboard.c @@ -65,6 +65,18 @@ static void set_thermal_monitoring(int thermal_monitoring) return; } +static void enable_perr_serr(void) +{ +#if 0 + uint8_t data61,data70,data74; + data61=inb(0x61); + data70=inb(0x70); + data74=inb(0x74); + printk_debug("Temp Test 70 = %x, 74 = %x, 61 = %x\n",data70,data74, + data61); +#endif + return; +} void mainboard_fixup(void) { int cpu_clock_multiplier; @@ -100,6 +112,8 @@ void mainboard_fixup(void) thermal_monitoring = THERMAL_MONITORING_OFF; set_thermal_monitoring(thermal_monitoring); + enable_perr_serr(); + return; } diff --git a/src/mainboard/supermicro/p4dpr/mptable.c b/src/mainboard/supermicro/p4dpr/mptable.c index 8f61098948..4badbc07aa 100644 --- a/src/mainboard/supermicro/p4dpr/mptable.c +++ b/src/mainboard/supermicro/p4dpr/mptable.c @@ -81,6 +81,8 @@ void *smp_write_config_table(void *v, unsigned long * processor_map) 0x05, 0x08, 0x02, 0x08); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x05, 0x09, 0x02, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x0c, 0x02, 0x0c); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x05, 0x0d, 0x02, 0x0d); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, @@ -107,21 +109,21 @@ void *smp_write_config_table(void *v, unsigned long * processor_map) smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x04, (0x1<<2)|0, 0x02, 0x10); -#if 1 /* Slot 1 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, - 0x02, (1<<2)|0, 0x04, 0x00); -#endif + 0x03, (1<<2)|0, 0x03, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x03, (1<<2)|1, 0x03, 0x01); -#if 1 /* Slot 2 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, - 0x03, (1<<2)|0, 0x03, 0x00); + 0x02, (1<<2)|0, 0x04, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x02, (1<<2)|1, 0x04, 0x01); /* Onboard Gigabit Intel NIC */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x03, (4<<2)|0, 0x03, 0x07); -#endif /* There is no extension information... */ diff --git a/src/mainboard/supermicro/p4dpr/select_i2c_m1.inc b/src/mainboard/supermicro/p4dpr/select_i2c_m1.inc new file mode 100644 index 0000000000..fd78933f5d --- /dev/null +++ b/src/mainboard/supermicro/p4dpr/select_i2c_m1.inc @@ -0,0 +1,17 @@ + SIO_ENTER_PNP_MODE() + + SIO_READ_CONFIG($0x2b) + movb %al, %bl + orb $0x30, %bl + SIO_WRITE_CONFIG(%bl, $0x2b) + + /* Enable the GPIO device */ + SIO_SET_LOGICAL_DEVICE($GPIO_PORT2_DEVICE) + SIO_WRITE_CONFIG($1, $0x30) + + SIO_READ_CONFIG($0xf0) + movb %al, %bl + orb $(1 << 3), %bl + SIO_WRITE_CONFIG(%bl, $0xf0) + + SIO_EXIT_PNP_MODE() diff --git a/src/mainboard/supermicro/x5dpr/Config b/src/mainboard/supermicro/x5dpr/Config new file mode 100644 index 0000000000..ea62277e94 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/Config @@ -0,0 +1,265 @@ + +## Set all of the defaults for an x86 architecture +## +arch i386 + +## +## 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) +## +mainboardinit cpu/i386/reset16.inc USE_FALLBACK_IMAGE +ldscript cpu/i386/reset16.lds USE_FALLBACK_IMAGE +mainboardinit cpu/i386/reset32.inc USE_NORMAL_IMAGE +ldscript cpu/i386/reset32.lds USE_NORMAL_IMAGE + +## +## 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. +mainboardinit northbridge/intel/E7501/reset_test.inc +mainboardinit arch/i386/lib/noop_failover.inc USE_NORMAL_IMAGE +mainboardinit southbridge/intel/82801ca/cmos_failover.inc USE_FALLBACK_IMAGE +ldscript arch/i386/lib/failover.lds USE_FALLBACK_IMAGE + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup our mtrrs +## +mainboardinit cpu/i786/earlymtrr.inc + +## +## Setup the serial port +## +mainboardinit superio/winbond/w83627hf/setup_serial.inc +mainboardinit pc80/serial.inc +mainboardinit arch/i386/lib/console.inc +mainboardinit southbridge/intel/82801ca/watchdog_disable.inc + +## +## Reset pci clock for hardware bug work around +## +mainboardinit southbridge/intel/82801ca/smbus.inc +mainboardinit southbridge/intel/82801ca/smbus_write_block.inc +mainboardinit mainboard/supermicro/x5dpr/pci_clk_reset.inc + +## +## Smbus functions +## +mainboardinit southbridge/intel/82801ca/smbus_read_byte.inc +#mainboardinit southbridge/intel/82801ca/smbus_read_block.inc +#mainboardinit southbridge/intel/82801ca/smbus_print_block.inc +mainboardinit mainboard/supermicro/x5dpr/select_i2c_spd.inc + +## +## Setup RAM +## +mainboardinit ram/dump_northbridge.inc +#mainboardinit sdram/generic_dump_smbus.inc +mainboardinit sdram/generic_dump_spd.inc +mainboardinit mainboard/supermicro/x5dpr/mainboard_raminit.inc + +## +## Include the secondary Configuration files +## +northbridge intel/E7501 +southbridge intel/82801ca +southbridge intel/82870 +nsuperio winbond/w83627hf com1={1} com2={1} floppy=1 lpt=1 keyboard=1 hwmonitor=1 +dir /src/pc80 +dir /src/superio/winbond/w83627hf +dir /src/ram/ +cpu p5 +cpu p6 +cpu i786 + +## +## Build the objects we have code for in this directory. +## +object mainboard.o +object devices.o +object mptable.o HAVE_MP_TABLE +object irq_tables.o HAVE_PIRQ_TABLE + + +### +### Build options +### + +## +## Number of consecutive times boot failures triggers a boot into fallback mode. +## +option MAX_REBOOT_CNT=8 + +## +## Location of the DIMM EEPROMS on the SMBUS +## This is fixed into a narrow range by the DIMM package standard. +## +option SMBUS_MEM_DEVICE_START=(0xa << 3) +option SMBUS_MEM_DEVICE_END=(SMBUS_MEM_DEVICE_START +3) +option SMBUS_MEM_DEVICE_INC=1 +option SMBUS_MEM_CHANNEL_OFF=4 + +## +## Customize our winbond superio chip for this motherboard +## +option SIO_BASE=0x2e +option SIO_SYSTEM_CLK_INPUT=SIO_SYSTEM_CLK_INPUT_48MHZ + +## +## Build code for the fallback boot +## +option HAVE_FALLBACK_BOOT=1 + +## +## Build code for using cache as RAM +## +#option USE_CACHE_RAM=0 + +## +## Delay timer options +## +option CONFIG_UDELAY_TSC=1 +option CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +option HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +option HAVE_PIRQ_TABLE=1 + + +## +## Do not build special code to the keyboard +## +option NO_KEYBOARD=1 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +option HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option tabe table +## +option HAVE_OPTION_TABLE=1 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +option SMP=1 +option MAX_CPUS=4 +option MAX_PHYSICAL_CPUS=2 + +## +## Build code to setup a generic IOAPIC +## +option IOAPIC=1 + +## +## MEMORY_HOLE instructs earlymtrr.inc to +## enable caching from 0-640KB and to disable +## caching from 640KB-1MB using fixed MTRRs +## +## Enabling this option breaks SMP because secondary +## CPU identification depends on only variable MTRRs +## being enabled. +## +nooption MEMORY_HOLE + +## +## Figure out which type of linuxBIOS image to build +## If we aren't a fallback image we must be a normal image +## This is useful for optional includes +## +option USE_FALLBACK_IMAGE=0 +expr USE_NORMAL_IMAGE=!USE_FALLBACK_IMAGE + +### +### LinuxBIOS layout values +### + +## ROM_SIZE is the size of boot ROM that this board will use. +option ROM_SIZE=524288 + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +option ROM_IMAGE_SIZE=49152 + +## LinuxBIOS C code runs at this location in RAM +option _RAMBASE=0x00008000 + +## For the trick of using cache as ram +## put the fake ram location at this address +option CACHE_RAM_BASE=0xfff70000 +option CACHE_RAM_SIZE=0x00010000 + +## +## Use a small 8K stack +## +option STACK_SIZE=0x2000 + +## +## Use a small 8K heap +## +option HEAP_SIZE=0x2000 + +## +## Clean up the motherboard id strings +## +option MAINBOARD_PART_NUMBER=X5DPR +option MAINBOARD_VENDOR=Supermicro + +option UPDATE_MICROCODE=1 +option CPU_FIXUP=1 + +## +## Only use the option table in a normal image +## +expr USE_OPTION_TABLE=!USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +expr ROM_SECTION_SIZE =(USE_FALLBACK_IMAGE*65536)+(USE_NORMAL_IMAGE*(ROM_SIZE - 65536)) +expr ROM_SECTION_OFFSET=(USE_FALLBACK_IMAGE*(ROM_SIZE-65536))+(USE_NORMAL_IMAGE*0) + + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +expr ZKERNEL_START =(0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) +expr PAYLOAD_SIZE =ROM_SECTION_SIZE - ROM_IMAGE_SIZE + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +expr _ROMBASE =ZKERNEL_START + PAYLOAD_SIZE + +## +## Compute a range of ROM that can cached to speed of linuxBIOS, +## execution speed. +## +expr XIP_ROM_SIZE = 65536 +expr XIP_ROM_BASE = _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE diff --git a/src/mainboard/supermicro/x5dpr/cmos.layout b/src/mainboard/supermicro/x5dpr/cmos.layout new file mode 100644 index 0000000000..7c9c1655b6 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/cmos.layout @@ -0,0 +1,96 @@ +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 2 hyper_threading +396 1 e 1 thermal_monitoring +397 1 e 1 remap_memory_high +400 1 e 1 power_on_after_fail +#402 1 e 2 hda_disk +#403 1 e 2 hdb_disk +#404 1 e 2 hdc_disk +#405 1 e 2 hdd_disk +#408 4 e 9 CPU_clock_speed +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 +#9 15 800MHZ +#9 11 900MHZ +#9 13 1GHZ +#9 9 1.1GHZ +#9 14 1.2GHZ +#9 10 1.3GHZ +#9 12 1.4GHZ +#9 8 1.5GHZ +#9 7 1.6GHZ +#9 3 1.7GHZ +#9 5 1.8GHZ +#9 1 1.9GHZ +#9 6 2.0GHZ +#9 2 2.1GHZ +#9 4 2.2GHZ +#9 0 2.3GHZ + +checksums + +checksum 392 1007 1008 diff --git a/src/mainboard/supermicro/x5dpr/devices.c b/src/mainboard/supermicro/x5dpr/devices.c new file mode 100644 index 0000000000..7be2f80294 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/devices.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include + +struct cdev { + unsigned int devfn; + struct cdev *next; + struct cdev *children; + void *private; +}; +static struct cdev nodev; + +#define DEV(NAME, DEVICE, FUNCTION, NEXT, CHILDREN, PRIVATE) \ +static struct cdev NEXT; \ +static struct cdev CHILDREN; \ +static struct cdev NAME = { \ + .devfn = PCI_DEVFN(DEVICE, FUNCTION), \ + .next = &NEXT, \ + .children = &CHILDREN, \ + .private = PRIVATE, \ +} + +DEV(dev0_2_0, 0x02, 0, dev0_1f_0, dev1_1c_0, 0); +DEV(dev0_1f_0, 0x1f, 0, nodev, nodev, 0); +DEV(dev1_1c_0, 0x1c, 0, dev1_1e_0, nodev, 0); +DEV(dev1_1e_0, 0x1e, 0, nodev, nodev, 0); + +static void add_dev_list(struct pci_dev *bus, struct cdev *dev); + +static void add_device(struct pci_dev *bus, struct cdev *dev) +{ + struct pci_dev *pdev; + +#if 0 + printk_debug("Adding%s %02x.%01x\n", + (dev->children == &nodev)?"":" bus", + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); +#endif + + pdev = malloc(sizeof(*pdev)); + if (!pdev) + goto no_mem; + + memset(pdev, 0, sizeof(*pdev)); + pdev->bus = bus; + pdev->devfn = dev->devfn; + + /* Add to the list of devices on the parent bus. */ + pdev->sibling = bus->children; + bus->children = pdev; + + /* Add any children we might have */ + add_dev_list(pdev, dev->children); + return; + no_mem: + printk_err("PCI: out of memory.\n"); + return; +} + +static void add_dev_list(struct pci_dev *bus, struct cdev *dev) +{ + while(dev != &nodev) { + add_device(bus, dev); + dev = dev->next; + } +} +void enumerate_static_devices(void) +{ + struct cdev *dev = &dev0_2_0; + add_dev_list(&pci_root, dev); +} diff --git a/src/mainboard/supermicro/x5dpr/example-fallback.config b/src/mainboard/supermicro/x5dpr/example-fallback.config new file mode 100644 index 0000000000..5b495b14e8 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/example-fallback.config @@ -0,0 +1,104 @@ +## This will make a target directory of ./fallback +## This is relative to where the configuration file resides in the filesystem +target ./fallback + +mainboard supermicro/x5dpr + +## Build a fallback not a normal image. +option USE_FALLBACK_IMAGE=1 + +## Build an image for a 512KB rom +## ./fallback/romimage is just the last 64KB which we reserve for the fallback image. +option ROM_SIZE=524288 +#option ROM_SIZE=1048576 + +## Select the maximum size the linuxBIOS code can compile to. +## Allow linuxBIOS to be up to 48KB in size +option ROM_IMAGE_SIZE=49152 + + +## +### The Serial Console +## +## Hardware flow control is currently ignored. + +## Enable the Serial Console +option SERIAL_CONSOLE=1 + +## Select the serial console baud rate. +option TTYS0_BAUD=115200 +#option TTYS0_BAUD=57600 +#option TTYS0_BAUD=38400 +#option TTYS0_BAUD=19200 +#option TTYS0_BAUD=9600 +#option TTYS0_BAUD=4800 +#option TTYS0_BAUD=2400 +#option TTYS0_BAUD=1200 + +# Select the serial console base port +option TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +option 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 +option DEFAULT_CONSOLE_LOGLEVEL=9 +## At a maximum only compile in this level of debugging +option MAXIMUM_CONSOLE_LOGLEVEL=6 + +## Use the elf bootloader +option USE_ELF_BOOT=1 + +## Select the boot device +option USE_GENERIC_ROM=1 +#option BOOT_FLOPPY=1 +#option USE_SERIAL_FILL_INBUF=1 +#option BOOT_IDE=1 + +# Load etherboot with the elf bootloader +# The payload command is relative the build directory +# So .. is the directory this config file resides in +payload ../eepro100.ebi + + +## +## Cpu Speed +## +option CPU_CLOCK_MULTIPLIER=XEON_X8 +#option CPU_CLOCK_MULTIPLIER=XEON_X9 +#option CPU_CLOCK_MULTIPLIER=XEON_X10 +#option CPU_CLOCK_MULTIPLIER=XEON_X11 +#option CPU_CLOCK_MULTIPLIER=XEON_X12 +#option CPU_CLOCK_MULTIPLIER=XEON_X13 +#option CPU_CLOCK_MULTIPLIER=XEON_X14 +#option CPU_CLOCK_MULTIPLIER=XEON_X15 +#option CPU_CLOCK_MULTIPLIER=XEON_X16 +#option CPU_CLOCK_MULTIPLIER=XEON_X17 +#option CPU_CLOCK_MULTIPLIER=XEON_X18 +#option CPU_CLOCK_MULTIPLIER=XEON_X19 +#option CPU_CLOCK_MULTIPLIER=XEON_X19 +#option CPU_CLOCK_MULTIPLIER=XEON_X20 +#option CPU_CLOCK_MULTIPLIER=XEON_X21 +#option CPU_CLOCK_MULTIPLIER=XEON_X22 +#option CPU_CLOCK_MULTIPLIER=XEON_X23 + +## +## Select power on after power fail setting +option MAINBOARD_POWER_ON_AFTER_POWER_FAIL=MAINBOARD_POWER_ON +#option MAINBOARD_POWER_ON_AFTER_POWER_FAIL=MAINBOARD_POWER_ON + diff --git a/src/mainboard/supermicro/x5dpr/example-normal.config b/src/mainboard/supermicro/x5dpr/example-normal.config new file mode 100644 index 0000000000..ed7037abb1 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/example-normal.config @@ -0,0 +1,105 @@ +## This will make a target directory of ./normal +## This is relative to where the configuration file resides in the filesystem +target ./normal + +mainboard supermicro/x5dpr + +## Build a normal not a fallback image. +option USE_FALLBACK_IMAGE=0 + +## Build an image for a 512KB rom +## ./normal/romimage is the entire rom image except for the last 64KB +## which are reserved for the fallback image. +option ROM_SIZE=524288 +#option ROM_SIZE=1048576 + +## Select the maximum size the linuxBIOS code can compile to. +## Allow linuxBIOS to be up to 48KB in size +option ROM_IMAGE_SIZE=49152 + + +## +### The Serial Console +## +## Hardware flow control is currently ignored. + +## Enable the Serial Console +option SERIAL_CONSOLE=1 + +## Select the serial console baud rate. +option TTYS0_BAUD=115200 +#option TTYS0_BAUD=57600 +#option TTYS0_BAUD=38400 +#option TTYS0_BAUD=19200 +#option TTYS0_BAUD=9600 +#option TTYS0_BAUD=4800 +#option TTYS0_BAUD=2400 +#option TTYS0_BAUD=1200 + +# Select the serial console base port +option TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +option 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 +option DEFAULT_CONSOLE_LOGLEVEL=9 +## At a maximum only compile in this level of debugging +option MAXIMUM_CONSOLE_LOGLEVEL=8 + +## Use the elf bootloader +option USE_ELF_BOOT=1 + +## Select the boot device +option USE_GENERIC_ROM=1 +#option BOOT_FLOPPY=1 +#option USE_SERIAL_FILL_INBUF=1 +#option BOOT_IDE=1 + +# Load etherboot with the elf bootloader +# The payload command is relative the build directory +# So .. is the directory this config file resides in +payload ../eepro100.ebi + + +## +## Cpu Speed +## +#option CPU_CLOCK_MULTIPLIER=XEON_X8 +#option CPU_CLOCK_MULTIPLIER=XEON_X9 +#option CPU_CLOCK_MULTIPLIER=XEON_X10 +#option CPU_CLOCK_MULTIPLIER=XEON_X11 +#option CPU_CLOCK_MULTIPLIER=XEON_X12 +#option CPU_CLOCK_MULTIPLIER=XEON_X13 +#option CPU_CLOCK_MULTIPLIER=XEON_X14 +#option CPU_CLOCK_MULTIPLIER=XEON_X15 +#option CPU_CLOCK_MULTIPLIER=XEON_X16 +option CPU_CLOCK_MULTIPLIER=XEON_X17 +#option CPU_CLOCK_MULTIPLIER=XEON_X18 +#option CPU_CLOCK_MULTIPLIER=XEON_X19 +#option CPU_CLOCK_MULTIPLIER=XEON_X19 +#option CPU_CLOCK_MULTIPLIER=XEON_X20 +#option CPU_CLOCK_MULTIPLIER=XEON_X21 +#option CPU_CLOCK_MULTIPLIER=XEON_X22 +#option CPU_CLOCK_MULTIPLIER=XEON_X23 + +## +## Select power on after power fail setting +option MAINBOARD_POWER_ON_AFTER_POWER_FAIL=MAINBOARD_POWER_ON +#option MAINBOARD_POWER_ON_AFTER_POWER_FAIL=MAINBOARD_POWER_ON + diff --git a/src/mainboard/supermicro/x5dpr/hardware.c b/src/mainboard/supermicro/x5dpr/hardware.c new file mode 100644 index 0000000000..541732acd7 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/hardware.c @@ -0,0 +1,25 @@ +#include +#include + +struct pci_bus pci_root = { + .children = &bus1; +}; +struct pci_dev dev0_2_0 = { + .bus = &pci_root, + .devfn = PCI_DEVFN(2,0), +}; +struct pci_bus bus1 = { + .parent = &pci_root, + .self = &dev0_2_0, +}; +struct pci_dev dev1_1c_0 = { + .bus = &bus1, + .devfn = PCI_DEVFN(0x1c, 0), + /* Hang ioapic information off of here */ +}; +struct pci_dev dev1_1e_0 = { + .bus = &bus1, + .devfn = PCI_DEVFN(0x1e, 0), + /* Hang ioapic information off of here */ +}; + diff --git a/src/mainboard/supermicro/x5dpr/irq_tables.c b/src/mainboard/supermicro/x5dpr/irq_tables.c new file mode 100644 index 0000000000..0c23b742a9 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/irq_tables.c @@ -0,0 +1,43 @@ +/* PCI: Interrupt Routing Table found at 0x4011ce40 size = 416 */ + +#include + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 416, /* u16 Table size 32+(16*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x8086, /* u16 Vendor */ + 0x122e, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0x94, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0x10, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x01, 0xe8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x02, 0x08, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x01, 0x00}, + {0x02, 0x18, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x0a, 0x00}, + {0x02, 0x10, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x03, 0x00}, + {0x01, 0xf8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x03, 0x08, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x02, 0x00}, + {0x03, 0x10, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x05, 0x00}, + {0x03, 0x18, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x06, 0x00}, + {0x03, 0x20, {{0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}, {0x68, 0xdcb8}}, 0x0b, 0x00}, + {0x00, 0x20, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x10, 0xe8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x11, 0x08, {{0x63, 0xdcb8}, {0x63, 0xdcb8}, {0x63, 0xdcb8}, {0x63, 0xdcb8}}, 0x03, 0x00}, + {0x10, 0xf8, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x12, 0x08, {{0x63, 0xdcb8}, {0x63, 0xdcb8}, {0x63, 0xdcb8}, {0x63, 0xdcb8}}, 0x04, 0x00}, + {0x00, 0xf0, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x04, 0x08, {{0x60, 0xdcb8}, {0x60, 0xdcb8}, {0x60, 0xdcb8}, {0x60, 0xdcb8}}, 0x07, 0x00}, + {0x04, 0x10, {{0x61, 0xdcb8}, {0x61, 0xdcb8}, {0x61, 0xdcb8}, {0x61, 0xdcb8}}, 0x08, 0x00}, + {0x04, 0x18, {{0x62, 0xdcb8}, {0x62, 0xdcb8}, {0x62, 0xdcb8}, {0x62, 0xdcb8}}, 0x09, 0x00}, + {0x00, 0xe8, {{0x60, 0xdcb8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0xe9, {{0x00, 0xdef8}, {0x63, 0xdcb8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0xea, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x62, 0xdcb8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0xf8, {{0x62, 0xdcb8}, {0x61, 0xdcb8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00} + } +}; diff --git a/src/mainboard/supermicro/x5dpr/mainboard.c b/src/mainboard/supermicro/x5dpr/mainboard.c new file mode 100644 index 0000000000..f9362956dd --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/mainboard.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +unsigned long initial_apicid[MAX_CPUS] = +{ + 0, 6, 1, 7 +}; + +#ifndef CPU_CLOCK_MULTIPLIER +#define CPU_CLOCK_MULTIPLIER XEON_X17 +#endif + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 + +#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL +#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON +#endif + +static void set_power_on_after_power_fail(int setting) +{ + switch(setting) { + case MAINBOARD_POWER_ON: + default: + ich3_power_after_power_fail(1); + w83627hf_power_after_power_fail(POWER_ON); + break; + case MAINBOARD_POWER_OFF: + ich3_power_after_power_fail(0); + w83627hf_power_after_power_fail(POWER_OFF); + break; + + } +} + +static void set_thermal_monitoring(int thermal_monitoring) +{ + int tm_high,tm_low; + + rdmsr(MISC_ENABLE,tm_low,tm_high); + if(thermal_monitoring != THERMAL_MONITORING_OFF) { + tm_low |= THERMAL_MONITORING_SET; + } + else { + tm_low &= ~THERMAL_MONITORING_SET; + } + wrmsr(MISC_ENABLE,tm_low,tm_high); + return; +} + +static void enable_perr_serr(void) +{ +#if 0 + uint8_t data61,data70,data74; + data61=inb(0x61); + data70=inb(0x70); + data74=inb(0x74); + printk_debug("Temp Test 70 = %x, 74 = %x, 61 = %x\n",data70,data74, + data61); +#endif + return; +} +void mainboard_fixup(void) +{ + int cpu_clock_multiplier; + int power_on_after_power_fail; + int thermal_monitoring; + + w83627hf_power_led(LED_ON); + ich3_enable_ioapic(); + p64h2_enable_ioapic(); + p64h2_setup_pcibridge(); + ich3_enable_serial_irqs(); + ich3_enable_ide(1,1); + ich3_rtc_init(); + ich3_lpc_route_dma(0xff); + isa_dma_init(); + ich3_1e0_misc(); + ich3_1f0_misc(); + +#if 0 /* CPU clock option is not presently used */ + cpu_clock_multiplier = CPU_CLOCK_MULTIPLIER; + if(get_option(&cpu_clock_multiplier, "CPU_clock_speed")) + cpu_clock_multiplier = CPU_CLOCK_MULTIPLIER; + ich3_set_cpu_multiplier(cpu_clock_multiplier); +#endif + + power_on_after_power_fail = MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + if(get_option(&power_on_after_power_fail, "power_on_after_fail")) + power_on_after_power_fail = MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + set_power_on_after_power_fail(power_on_after_power_fail); + + thermal_monitoring = THERMAL_MONITORING_OFF; + if(get_option(&thermal_monitoring, "thermal_monitoring")) + thermal_monitoring = THERMAL_MONITORING_OFF; + set_thermal_monitoring(thermal_monitoring); + + enable_perr_serr(); + + return; +} + +void hard_reset(void) +{ + ich3_hard_reset(); +} + diff --git a/src/mainboard/supermicro/x5dpr/mainboard_raminit.inc b/src/mainboard/supermicro/x5dpr/mainboard_raminit.inc new file mode 100644 index 0000000000..8d1c8b69c3 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/mainboard_raminit.inc @@ -0,0 +1 @@ + diff --git a/src/mainboard/supermicro/x5dpr/mptable.c b/src/mainboard/supermicro/x5dpr/mptable.c new file mode 100644 index 0000000000..ef6e9b10b8 --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/mptable.c @@ -0,0 +1,147 @@ +#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] = "LNXI "; + static const char productid[12] = "X5DPR "; + struct mp_config_table *mc; + + 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); + + smp_write_bus(mc, 0, "PCI "); + smp_write_bus(mc, 1, "PCI "); + smp_write_bus(mc, 2, "PCI "); + smp_write_bus(mc, 3, "PCI "); + smp_write_bus(mc, 4, "PCI "); + smp_write_bus(mc, 5, "ISA "); + + /* FIXME better IOAPIC handling */ + + smp_write_ioapic(mc, 2, 0x20, 0xfec00000); + { + struct pci_dev *dev; + uint32_t base; + /* 1:1e.0 */ + dev = pci_find_slot(1, PCI_DEVFN(0x1e,0)); + if (dev) { + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &base); + base &= PCI_BASE_ADDRESS_MEM_MASK; + smp_write_ioapic(mc, 3, 0x20, base); + } + /* 1:1c.0 */ + dev = pci_find_slot(1, PCI_DEVFN(0x1c,0)); + if (dev) { + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &base); + base &= PCI_BASE_ADDRESS_MEM_MASK; + smp_write_ioapic(mc, 4, 0x20, base); + } + } + + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x00, 0x02, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x01, 0x02, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x00, 0x02, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x03, 0x02, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x04, 0x02, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x05, 0x02, 0x05); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x06, 0x02, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x07, 0x02, 0x07); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x08, 0x02, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x09, 0x02, 0x09); + + /* USB Controller */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, (0x1d<<2)|1, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, (0x1d<<2)|0, 0x02, 0x10); + + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x06, 0x0c, 0x02, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x0d, 0x02, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x0e, 0x02, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x0f, 0x02, 0x0f); + + /* USB Controller */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, (0x1d<<2)|2, 0x02, 0x12); + + /* Onboard 82559 Ethernet */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x02, (0x3<<2)|0, 0x04, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x02, (0x3<<2)|1, 0x04, 0x07); + + /* PCI slot 1 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x03, (1<<2)|0, 0x03, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x03, (1<<2)|1, 0x03, 0x01); + + /* Slot 2 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x02, (1<<2)|0, 0x04, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x02, (1<<2)|1, 0x04, 0x01); + + /* VGA */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x04, (1<<2)|0, 0x02, 0x10); + + /* Standard local interrupt assignments */ + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x00, MP_APIC_ALL, 0x00); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + 0x05, 0x00, MP_APIC_ALL, 0x01); + + /* 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/supermicro/x5dpr/pci_clk_reset.inc b/src/mainboard/supermicro/x5dpr/pci_clk_reset.inc new file mode 100644 index 0000000000..fdba672d9a --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/pci_clk_reset.inc @@ -0,0 +1,133 @@ +/* The algorithm is as follows: + */ +#include +#include + + +#define PM_DEVFN ((0x1f <<3) + 0) + + .section ".rom.data" + +pci_clk_stop_beg: + .byte 0x08, 0x47, 0x7f, 0xc7, 0x38 +pci_clk_stop_end: + +pci_clk_start_beg: + .byte 0x08, 0x47, 0x7f, 0xc7, 0x3f +pci_clk_start_end: + +pci_clk_restart_msg: + .asciz "Restarting pci clocks\r\n" +pci_clk_power_msg: + .asciz "Power failed\r\n" + + .previous + + /* The PC64H2 has a known errata where there is a race + * between getting a good level, and getting a clock signal. + * Nasting things normally boot failure while readding the pci + * bus happen when this errata is hit. + * + * Thw work around is to stop and restart the 66Mhz reference clock + * the PC64H2. And to do this I need to talk to the reference clock + * generator in this case a cypress CY28329. + * + * The I2C interface on the Cyrpess chip is fragile. If you talk + * to it wrong or if you talk to it long enough after getting power, + * it will not talk to you. So I have to be very careful. What is + * especially bad is that sometimes a failed attempt to talk + * to the Cypress chip will lock the i2c/smbus controller on + * the ICH3. So I cannot talk to i2c EEPROM on memory dimms + * to detect how much memory I have. + * + * Placing the motherboard in soft power off is not enough to get the + * cypress chip talking again. So I only attempt the PC64H2 + * errata work around when I boot up immediate after the + * motherboard has lost power. + * + * This procedure appears to navigate the cascading mines of + * the hardware bugs. + */ +__reboot_ck: + /* See if power is failed, making it is safe to talk to the + * cypress chip. + */ + movl $((PM_DEVFN << 8) + 0xA4), %eax + PCI_READ_CONFIG_DWORD + + /* If power has not failed get, skip the errata work around */ + testl $(1 << 1), %eax + jz __continue_booting + + /* Clear the power failed bit, so I don't apply this + * work around when it is not safe. + */ + movl $((PM_DEVFN << 8) + 0xA4), %eax + movl $(1 << 1), %ecx + PCI_WRITE_CONFIG_DWORD + + /* Report that I have detected a power failure */ + CONSOLE_INFO_TX_STRING($pci_clk_power_msg) + + /* Attempt to write to the cypress chip and bail out if this + * fails. + */ + /* stop the clocks */ + movb $0x69, %bl + movb $0x00, %bh + movb $(pci_clk_stop_end - pci_clk_stop_beg), %cl + movl $(pci_clk_stop_beg), %esi + /* stop the pci clock */ + CALLSP(smbus_write_block) + jc __continue_booting + + /* wait for about 100us */ + movl $0x2c, %ecx + rdmsr + andl $0xff000000,%eax + shrl $10, %eax /* this gives the ticks for 160usec */ + movl %eax, %ebx + rdtsc + addl %ebx, %eax + adcl $0, %edx + movl %eax, %ebx + movl %edx, %ecx +1: rdtsc + subl %ebx, %eax + sbbl %ecx, %edx + jb 1b + + /* Add an extra delay to display this message */ + CONSOLE_INFO_TX_STRING($pci_clk_restart_msg) + + /* restart the clocks */ + movb $0x69, %bl + movb $0x00, %bh + movb $(pci_clk_start_end - pci_clk_start_beg), %cl + movl $(pci_clk_start_beg), %esi + /* start the pci clock */ + CALLSP(smbus_write_block) + + /* Set boot_option to last_boot, so I don't fallback by accident */ + movb $RTC_BOOT_BYTE, %al + outb %al, $0x70 + inb $0x71, %al + movb %al, %bl + shrb $1, %bl + andb $1, %bl + andb $0xfe, %al + orb %bl, %al + outb %al, $0x71 + + /* reboot the motherboard */ + movw $0x0cf9, %dx + inb %dx, %al + andb $~((1 <<3)|(1<<2)), %al + orb $(1<<1), %al + outb %al, %dx + orb $(1<<2), %al + outb %al, %dx +2: hlt + jmp 2b + +__continue_booting: diff --git a/src/mainboard/supermicro/x5dpr/select_i2c_m1.inc b/src/mainboard/supermicro/x5dpr/select_i2c_m1.inc new file mode 100644 index 0000000000..fd78933f5d --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/select_i2c_m1.inc @@ -0,0 +1,17 @@ + SIO_ENTER_PNP_MODE() + + SIO_READ_CONFIG($0x2b) + movb %al, %bl + orb $0x30, %bl + SIO_WRITE_CONFIG(%bl, $0x2b) + + /* Enable the GPIO device */ + SIO_SET_LOGICAL_DEVICE($GPIO_PORT2_DEVICE) + SIO_WRITE_CONFIG($1, $0x30) + + SIO_READ_CONFIG($0xf0) + movb %al, %bl + orb $(1 << 3), %bl + SIO_WRITE_CONFIG(%bl, $0xf0) + + SIO_EXIT_PNP_MODE() diff --git a/src/mainboard/supermicro/x5dpr/select_i2c_spd.inc b/src/mainboard/supermicro/x5dpr/select_i2c_spd.inc new file mode 100644 index 0000000000..ffe5557d4b --- /dev/null +++ b/src/mainboard/supermicro/x5dpr/select_i2c_spd.inc @@ -0,0 +1,17 @@ + SIO_ENTER_PNP_MODE() + + SIO_READ_CONFIG($0x2b) + movb %al, %bl + orb $0x30, %bl + SIO_WRITE_CONFIG(%bl, $0x2b) + + /* Enable the GPIO device */ + SIO_SET_LOGICAL_DEVICE($GPIO_PORT2_DEVICE) + SIO_WRITE_CONFIG($1, $0x30) + + SIO_READ_CONFIG($0xf0) + movb %al, %bl + andb $~(1 << 3), %bl + SIO_WRITE_CONFIG(%bl, $0xf0) + + SIO_EXIT_PNP_MODE() diff --git a/src/mainboard/tyan/guiness/Config b/src/mainboard/tyan/guiness/Config index 8cf452346d..8792cd93a5 100644 --- a/src/mainboard/tyan/guiness/Config +++ b/src/mainboard/tyan/guiness/Config @@ -36,8 +36,7 @@ ldscript arch/i386/lib/id.lds #mainboardinit arch/i386/lib/noop_failover.inc USE_NORMAL_IMAGE #mainboardinit southbridge/amd/amd766/cmos_reset_failover.inc USE_FALLBACK_IMAGE -#ldscript arch/i386/lib/failover.lds USE_FALLBACK_IMAGE -ldscript arch/i386/lib/failover-noz.lds USE_FALLBACK_IMAGE +ldscript arch/i386/lib/failover.lds USE_FALLBACK_IMAGE ## ## We aren't a reset so shutdown the second cpu if present. @@ -92,7 +91,6 @@ mainboardinit mainboard/tyan/guiness/mainboard_raminit.inc ## northbridge amd/amd76x southbridge amd/amd766 -#mainboardinit arch/i386/smp/secondary.inc nsuperio winbond/w83627hf com1={1} com2={0} floppy=1 lpt=1 keyboard=1 dir ../../../pc80 dir /src/superio/winbond/w83627hf @@ -210,7 +208,7 @@ option FINAL_MAINBOARD_FIXUP=1 ## This is useful for optional includes ## option USE_FALLBACK_IMAGE=0 -expr BUILD_NORMAL_IMAGE=!USE_FALLBACK_IMAGE +expr USE_NORMAL_IMAGE=!USE_FALLBACK_IMAGE ### ### LinuxBIOS layout values @@ -220,7 +218,7 @@ expr BUILD_NORMAL_IMAGE=!USE_FALLBACK_IMAGE option ROM_SIZE=524288 ## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. -option ROM_IMAGE_SIZE=65535 +option ROM_IMAGE_SIZE=49152 ## ## Use a small 8K stack @@ -241,24 +239,20 @@ expr USE_OPTION_TABLE=!USE_FALLBACK_IMAGE ## Compute the location and size of where this firmware image ## (linuxBIOS plus bootloader) will live in the boot rom chip. ## -expr ROM_SECTION_SIZE =(USE_FALLBACK_IMAGE*65536)+(BUILD_NORMAL_IMAGE*(ROM_SIZE - 65536)) -expr ROM_SECTION_OFFSET=(USE_FALLBACK_IMAGE*(ROM_SIZE-65536))+(BUILD_NORMAL_IMAGE*0) +expr ROM_SECTION_SIZE =(USE_FALLBACK_IMAGE*65536)+(USE_NORMAL_IMAGE*(ROM_SIZE - 65536)) +expr ROM_SECTION_OFFSET=(USE_FALLBACK_IMAGE*(ROM_SIZE-65536))+(USE_NORMAL_IMAGE*0) ## ## Compute the start location and size size of ## The linuxBIOS bootloader. ## -#expr ZKERNEL_START =(0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) - -expr ZKERNEL_START = 0xfff80000 +expr ZKERNEL_START =(0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) expr PAYLOAD_SIZE =ROM_SECTION_SIZE - ROM_IMAGE_SIZE ## ## Compute where this copy of linuxBIOS will start in the boot rom ## -#expr _ROMBASE =ZKERNEL_START + PAYLOAD_SIZE -expr _ROMBASE = 0xffff0000 - ( 0x10000 * BUILD_NORMAL_IMAGE) - +expr _ROMBASE =ZKERNEL_START + PAYLOAD_SIZE ## ## Compute a range of ROM that can cached to speed up linuxBIOS, diff --git a/src/mainboard/tyan/guiness/example-normal.config b/src/mainboard/tyan/guiness/example-normal.config index 475ae0672c..143ba703a1 100644 --- a/src/mainboard/tyan/guiness/example-normal.config +++ b/src/mainboard/tyan/guiness/example-normal.config @@ -5,8 +5,7 @@ target ./tdir/normal mainboard tyan/guiness ## Build a normal not a fallback image. -#option USE_FALLBACK_IMAGE=0 -option USE_NORMAL_IMAGE +option USE_FALLBACK_IMAGE=0 ## Build an image for a 512KB rom ## ./normal/romimage is the entire rom image except for the last 64KB diff --git a/src/mainboard/tyan/guiness/mainboard.c b/src/mainboard/tyan/guiness/mainboard.c index db5d2ff2a3..a1a8d6e40a 100644 --- a/src/mainboard/tyan/guiness/mainboard.c +++ b/src/mainboard/tyan/guiness/mainboard.c @@ -93,8 +93,7 @@ static void fixup_adaptec_7899P(struct pci_dev *pdev) /* Set the device id */ pci_write_config_word(pdev, PCI_DEVICE_ID, PCI_DEVICE_ID_ADAPTEC2_7899P); /* Set the subsytem vendor id */ -// pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_TYAN); - pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, 0x10f1); + pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_TYAN); /* Set the subsytem id */ pci_write_config_word(pdev, PCI_SUBSYSTEM_ID, 0x2462); /* Disable writes to the device id */ diff --git a/src/mainboard/tyan/s2466/Config b/src/mainboard/tyan/s2466/Config new file mode 100644 index 0000000000..2170914564 --- /dev/null +++ b/src/mainboard/tyan/s2466/Config @@ -0,0 +1,281 @@ +## +## Set all of the defaults for an x86 architecture +## +arch i386 + +## +## 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) +## +mainboardinit cpu/i386/reset16.inc USE_FALLBACK_IMAGE +ldscript cpu/i386/reset16.lds USE_FALLBACK_IMAGE +mainboardinit cpu/i386/reset32.inc USE_NORMAL_IMAGE +ldscript cpu/i386/reset32.lds USE_NORMAL_IMAGE + +## +## 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=15 +#mainboardinit northbridge/amd/amd76x/reset_test.inc +#mainboardinit arch/i386/lib/noop_failover.inc + +#mainboardinit arch/i386/lib/noop_failover.inc USE_NORMAL_IMAGE +#mainboardinit southbridge/amd/amd768/cmos_reset_failover.inc USE_FALLBACK_IMAGE +ldscript arch/i386/lib/failover.lds USE_FALLBACK_IMAGE + +## +## We aren't a reset so shutdown the second cpu if present. +## + +## +## Setup our mtrrs +## +mainboardinit cpu/k7/earlymtrr.inc + +## +## Initialize the processor busses +## +mainboardinit northbridge/amd/amd76x/mpinit.inc USE_FALLBACK_IMAGE + +## +## Only the bootstrap cpu makes it here. +## Failover if we need to +## +mainboardinit southbridge/amd/amd768/cmos_boot_failover.inc USE_FALLBACK_IMAGE + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## When debugging disable the watchdog timer +## +option MAXIMUM_CONSOLE_LOGLEVEL=8 +expr DISABLE_WATCHDOG= MAXIMUM_CONSOLE_LOGLEVEL >= 8 +mainboardinit southbridge/amd/amd768/disable_watchdog.inc DISABLE_WATCHDOG + +## +## Setup the serial port +## +mainboardinit southbridge/amd/amd768/lpc_com1.inc +mainboardinit superio/winbond/w83627hf/setup_serial.inc +mainboardinit pc80/serial.inc +mainboardinit arch/i386/lib/console.inc + +## +## Setup RAM +## +#mainboardinit ram/ramtest.inc +#mainboardinit mainboard/tyan/s2466/do_ramtest.inc +mainboardinit southbridge/amd/amd768/smbus.inc +#mainboardinit sdram/generic_dump_spd.inc +mainboardinit mainboard/tyan/s2466/mainboard_raminit.inc + +## +## Include the secondary Configuration files +## +northbridge amd/amd76x +southbridge amd/amd768 +nsuperio winbond/w83627hf com1={1} com2={1} floppy=1 lpt=1 keyboard=1 +dir ../../../pc80 +dir /src/superio/winbond/w83627hf +cpu p5 +cpu p6 +cpu k7 + +## +## Build the objects we have code for in this directory. +## +object mainboard.o +object mptable.o HAVE_MP_TABLE +object irq_tables.o HAVE_PIRQ_TABLE + +### +### Build options +### + +## +## Location of the DIMM EEPROMS on the SMBUS +## This is fixed into a narrow range by the DIMM package standard. +## +option SMBUS_MEM_DEVICE_START=(0xa << 3) +option SMBUS_MEM_DEVICE_END=(SMBUS_MEM_DEVICE_START +3) +option SMBUS_MEM_DEVICE_INC=1 + +## +## Customize our winbond superio chip for this motherboard +## +option SIO_BASE=0x2e +nooption SIO_SYSTEM_CLK_INPUT + +## +## Build code for the fallback boot +## +option HAVE_FALLBACK_BOOT=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +option HAVE_HARD_RESET=1 +option HAVE_MAINBOARD_CPU_FIXUP=1 +option HAVE_FULL_RESET=1 + +## +## Build code to export a programmable irq routing table +## +#option HAVE_PIRQ_TABLE=1 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +option HAVE_MP_TABLE=1 + +## +## Do not build special code for the keyboard +## +option NO_KEYBOARD=1 + +## +## Build code to export a CMOS option table +## +option HAVE_OPTION_TABLE=1 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +option SMP=1 +option MAX_CPUS=2 + +## +## Build code to setup a generic IOAPIC +## +option IOAPIC=1 + +## +## MEMORY_HOLE instructs earlymtrr.inc to +## enable caching from 0-640KB and to disable +## caching from 640KB-1MB using fixed MTRRs +## +## Enabling this option breaks SMP because secondary +## CPU identification depends on only variable MTRRs +## being enabled. +## +nooption MEMORY_HOLE + +## +## Enable both fixed and variable MTRRS +## When we setup MTRRs in mtrr.c +## +## We must setup the fixed mtrrs or we confuse SMP secondary +## processor identification +## +option ENABLE_FIXED_AND_VARIABLE_MTRRS=1 + +## +## Clean up the motherboard id strings +## +#option MAINBOARD_PART_NUMBER=THUNDER K7 +option MAINBOARD_PART_NUMBER=TIGER MPX +#option MAINBOARD_VENDOR=Tyan +option MAINBOARD_VENDOR=TYAN + +## +## Let Assembly code know where on the pci bus the AMD southbridge is +## +option AMD768_DEV=0x3800 + +## +## Call the final_mainboard_fixup function +## +option FINAL_MAINBOARD_FIXUP=1 + +## +## Figure out which type of linuxBIOS image to build +## If we aren't a fallback image we must be a normal image +## This is useful for optional includes +## +option USE_FALLBACK_IMAGE=0 +expr USE_NORMAL_IMAGE=!USE_FALLBACK_IMAGE + +### +### LinuxBIOS layout values +### + +## ROM_SIZE is the size of boot ROM that this board will use. +option ROM_SIZE=524288 + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +option ROM_IMAGE_SIZE=49152 + +## +## Use a small 8K stack +## +option STACK_SIZE=0x2000 + +## +## Use a small 8K heap +## +option HEAP_SIZE=0x2000 + +## +## Only use the option table in a normal image +## +expr USE_OPTION_TABLE=!USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +expr ROM_SECTION_SIZE =(USE_FALLBACK_IMAGE*65536)+(USE_NORMAL_IMAGE*(ROM_SIZE - 65536)) +expr ROM_SECTION_OFFSET=(USE_FALLBACK_IMAGE*(ROM_SIZE-65536))+(USE_NORMAL_IMAGE*0) + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +expr ZKERNEL_START =(0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) +expr PAYLOAD_SIZE =ROM_SECTION_SIZE - ROM_IMAGE_SIZE + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +expr _ROMBASE =ZKERNEL_START + PAYLOAD_SIZE + +## +## Compute a range of ROM that can cached to speed up linuxBIOS, +## execution speed. +## +#expr XIP_ROM_SIZE = 65536 +#expr XIP_ROM_BASE = _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE +#option XIP_ROM_SIZE=65536 +#option XIP_ROM_BASE=0xffff0000 + +# XIP_ROM_SIZE && XIP_ROM_BASE values that work. +#option XIP_ROM_SIZE=0x8000 +#option XIP_ROM_BASE=0xffff8000 + +## +## Compute where the SMP startup code needs to live +## FIXME I don't see how to make this work for the normal image.... +## +option START_CPU_SEG=0xf0000 + + diff --git a/src/mainboard/tyan/s2466/cmos.layout b/src/mainboard/tyan/s2466/cmos.layout new file mode 100644 index 0000000000..5ba4c032c1 --- /dev/null +++ b/src/mainboard/tyan/s2466/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/tyan/s2466/do_ramtest.inc b/src/mainboard/tyan/s2466/do_ramtest.inc new file mode 100644 index 0000000000..35ccad56d6 --- /dev/null +++ b/src/mainboard/tyan/s2466/do_ramtest.inc @@ -0,0 +1,28 @@ +#if 0 + movl $0x000f0000, %eax + movl $0x000f1000, %ebx + CALLSP(ramtest) +#endif + +#if 1 + movl $0x00100000, %eax + movl $0x00180000, %ebx + CALLSP(ramtest) + + xorl %eax, %eax + movl $0x00080000, %ebx + CALLSP(ramtest) +#endif + +#if 1 + + xorl %eax, %eax + movl $0x00001000, %ebx + CALLSP(ramtest) +#endif + +#if 0 + movl $0xffe00000, %eax + movl $0xfff00000, %ebx + CALLSP(ramtest) +#endif diff --git a/src/mainboard/tyan/s2466/example-fallback.config b/src/mainboard/tyan/s2466/example-fallback.config new file mode 100644 index 0000000000..2c4ab1c66c --- /dev/null +++ b/src/mainboard/tyan/s2466/example-fallback.config @@ -0,0 +1,85 @@ +## This will make a target directory of ./fallback +## This is relative to where the configuration file resides in the filesystem +target ./tdir/fallback + +mainboard tyan/s2466 + + +## Build a normal not a fallback image. +option USE_FALLBACK_IMAGE=1 + +## Build an image for a 512KB rom +## ./normal/romimage is the entire rom image except for the last 64KB +## which are reserved for the fallback image. +#option ROM_SIZE=524288 +option ROM_SIZE=262144 + +## Select the maximum size the linuxBIOS code can compile to. +## Allow linuxBIOS to be up to 48KB in size +option ROM_IMAGE_SIZE=45056 + +## +### The Serial Console +## +## Hardware flow control is currently ignored. + +## Enable the Serial Console +option SERIAL_CONSOLE=1 + +## Select the serial console baud rate. +#option TTYS0_BAUD=115200 +#option TTYS0_BAUD=57600 +#option TTYS0_BAUD=38400 +#option TTYS0_BAUD=19200 +option TTYS0_BAUD=9600 +#option TTYS0_BAUD=4800 +#option TTYS0_BAUD=2400 +#option TTYS0_BAUD=1200 + +# Select the serial console base port +option TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +option 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 +option DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +option MAXIMUM_CONSOLE_LOGLEVEL=7 + +## Use the elf bootloader +option USE_ELF_BOOT=1 + +## Select the boot device +option USE_GENERIC_ROM=1 +#option BOOT_FLOPPY=1 +#option USE_SERIAL_FILL_INBUF=1 +#option BOOT_IDE=1 + +# Load etherboot with the elf bootloader +# The payload command is relative the build directory +# So .. is the directory this config file resides in +payload ./bootloader.ebi + +# Path to your kernel (vmlinux) +# NOTE; you need a path to your test12 kernel here. +linux ~/projects/linux/linux-2.4.4.eb1.1 + +# Kernel command line parameters +#commandline ro panic=5 root=/dev/hda5 console=ttyS0,115200 debug 3 + + diff --git a/src/mainboard/tyan/s2466/example-normal.config b/src/mainboard/tyan/s2466/example-normal.config new file mode 100644 index 0000000000..876f6bd57b --- /dev/null +++ b/src/mainboard/tyan/s2466/example-normal.config @@ -0,0 +1,89 @@ +# This will make a target directory of ./normal +## This is relative to where the configuration file resides in the filesystem +target ./tdir/normal + +mainboard tyan/s2466 + +## Build a normal not a fallback image. +option USE_FALLBACK_IMAGE=0 + +## Build an image for a 512KB rom +## ./normal/romimage is the entire rom image except for the last 64KB +## which are reserved for the fallback image. +#option ROM_SIZE=524288 +option ROM_SIZE=262144 + +## Select the maximum size the linuxBIOS code can compile to. +## Allow linuxBIOS to be up to 48KB in size +#option ROM_IMAGE_SIZE=49152 +option ROM_IMAGE_SIZE=65536 +#option PAYLOAD_SIZE=131072 +#option _ROMBASE=0xFFFE0000 +#option ZKERNEL_START=0xFFFC0000 + + +## +### The Serial Console +## +## Hardware flow control is currently ignored. + +## Enable the Serial Console +option SERIAL_CONSOLE=1 + +## Select the serial console baud rate. +#option TTYS0_BAUD=115200 +#option TTYS0_BAUD=57600 +#option TTYS0_BAUD=38400 +#option TTYS0_BAUD=19200 +option TTYS0_BAUD=9600 +#option TTYS0_BAUD=4800 +#option TTYS0_BAUD=2400 +#option TTYS0_BAUD=1200 + +# Select the serial console base port +option TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +option 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 +option DEFAULT_CONSOLE_LOGLEVEL=7 +## At a maximum only compile in this level of debugging +option MAXIMUM_CONSOLE_LOGLEVEL=8 + +## Use the elf bootloader +option USE_ELF_BOOT=1 + +## Select the boot device +option USE_GENERIC_ROM=1 +#option BOOT_FLOPPY=1 +#option USE_SERIAL_FILL_INBUF=1 +#option BOOT_IDE=1 + +# Load etherboot with the elf bootloader +# The payload command is relative the build directory +# So .. is the directory this config file resides in +payload ./bootloader.ebi + +# Path to your kernel (vmlinux) +# NOTE; you need a path to your test12 kernel here. +linux ~/projects/linux/linux-2.4.4.eb1.1 + +# Kernel command line parameters +#commandline ro panic=5 root=/dev/hda5 console=ttyS0,115200 debug 3 + + diff --git a/src/mainboard/tyan/s2466/irq_tables.c b/src/mainboard/tyan/s2466/irq_tables.c new file mode 100644 index 0000000000..3b9e88c62a --- /dev/null +++ b/src/mainboard/tyan/s2466/irq_tables.c @@ -0,0 +1,31 @@ +/* PCI: Interrupt Routing Table found at 0x4011cf00 size = 224 */ + +#include + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 224, /* u16 Table size 32+(16*devices) */ + 0x00, /* u8 Bus 0 */ + 0x3b, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x1022, /* u16 Vendor */ + 0x7400, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0x52, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, 0x40, {{0x01, 0xdef8}, {0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}}, 0x01, 0x00}, + {0x00, 0x48, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}}, 0x02, 0x00}, + {0x02, 0x20, {{0x01, 0xdef8}, {0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}}, 0x03, 0x00}, + {0x02, 0x28, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}}, 0x04, 0x00}, + {0x02, 0x30, {{0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}, {0x02, 0xdef8}}, 0x05, 0x00}, + {0x02, 0x38, {{0x04, 0xdef8}, {0x01, 0xdef8}, {0x02, 0xdef8}, {0x03, 0xdef8}}, 0x06, 0x00}, + {0x00, 0x80, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}}, 0x00, 0x00}, + {0x00, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0x08, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x01, 0x28, {{0x03, 0xdef8}, {0x04, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0d, 0x00}, + {0x02, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x04, 0xdef8}}, 0x00, 0x00}, + {0x02, 0x40, {{0x04, 0xdef8}, {0x04, 0xdef8}, {0x04, 0xdef8}, {0x04, 0xdef8}}, 0x00, 0x00} + } +}; diff --git a/src/mainboard/tyan/s2466/mainboard.c b/src/mainboard/tyan/s2466/mainboard.c new file mode 100644 index 0000000000..717d736e89 --- /dev/null +++ b/src/mainboard/tyan/s2466/mainboard.c @@ -0,0 +1,303 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long initial_apicid[MAX_CPUS] = +{ + 0, 1 +}; + +static void lpc_routing_fixup(void) +{ + struct pci_dev *dev; + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440,0); + if (dev != NULL) { + + /* This register is not documented, but the factory sets + it to 0xde */ + pci_write_config_byte(dev, 0x75, 0xde); + + /* States in the documentation that this bit must be set + for things to work right */ + pci_write_config_byte(dev, 0x4d, 0x04); + +#if 0 + /* Send keyboard controller, + * FDC1, ECP + * to the LPC bus + * Send APCI ports 0x62 & 0x66 to the ISA bus + */ + pci_write_config_byte(dev, 0x51, (0<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(1)); + /* Route io for both serial ports to the LPC bus */ + pci_write_config_byte(dev, 0x52, (1<<7)|(1<<4)|(1<<3)|(0<<0)); + /* Don't route any audio ports to the LPC bus */ + pci_write_config_byte(dev, 0x53, (0<<6)|(0<<4)|(0<<3)|(0<<2)|(0<<0)); + /* Route superio configuration accesses to the LPC bus */ + pci_write_config_byte(dev, 0x54, (0<<5)|(1<<4)|(0<<2)|(0<<0)); + /* Don't use LPC decode register 4 */ + pci_write_config_byte(dev, 0x55, (0<<4)|(0<<0)); + /* Don't use LPC decode register 5 */ + pci_write_config_byte(dev, 0x56, (0<<4)|(0<<0)); + /* Route 512 byte io address range 0x0c00 - 0xc200 the LPC bus */ + pci_write_config_dword(dev, 0x58, 0x00000c01); + /* Route 1MB memory address range 0 - 0 to the LPC bus */ + pci_write_config_dword(dev, 0x5c, 0x00000000); +#endif + + } +} + + +static void enable_reset_port_0xcf9(void) +{ + struct pci_dev *dev; + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); + if (dev != NULL) { + unsigned char byte; + /* Enable reset port 0xcf9 */ + pci_read_config_byte(dev, 0x41, &byte); + pci_write_config_byte(dev, 0x41, byte | (1<<7) | (1<<5)); + pci_write_config_byte(dev, 0x42, 0x09); + } +} + + +static void print_whami(void) +{ + struct pci_dev *dev; + u32 whami; + /* Find out which processor I'm running on, and if it was the boot + * procesor so I can verify everything was setup correctly + */ + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C,0); + if (dev != NULL) { + pci_read_config_dword(dev, 0x80, &whami); + printk_spew("whami = 0x%08lx\n", whami); + } +} + +static void check_cpus(void) +{ + struct pci_dev *dev; + u32 biu1; + /* Find out which processor I'm running on, and if it was the boot + * procesor so I can verify everything was setup correctly + */ + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C,0); + if (dev != NULL) { + pci_read_config_dword(dev, 0x68, &biu1); + if( !(biu1 & 0x80000000)) { + initial_apicid[1] = -1; + } + printk_debug("biu1 = 0x%08lx, apicid[1] = %d\n", biu1, + initial_apicid[1]); + } +} + + + +static void fixup_adaptec_7899P(struct pci_dev *pdev) +{ + /* Enable writes to the device id */ + pci_write_config_byte(pdev, 0xff, 1); + /* Set the device id */ + pci_write_config_word(pdev, PCI_DEVICE_ID, PCI_DEVICE_ID_ADAPTEC2_7899P); + /* Set the subsytem vendor id */ + pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_TYAN); + /* Set the subsytem id */ + pci_write_config_word(pdev, PCI_SUBSYSTEM_ID, 0x2466); + /* Disable writes to the device id */ + pci_write_config_byte(pdev, 0xff, 0); +} + +static void onboard_scsi_fixup(void) +{ + struct pci_dev *dev; + + /* Set the scsi device id's */ + dev = pci_find_slot(0, PCI_DEVFN(0xd, 0)); + if (dev != NULL) { + fixup_adaptec_7899P(dev); + } + /* Set the scsi device id's */ + dev = pci_find_slot(0, PCI_DEVFN(0xd, 1)); + if (dev != NULL) { + fixup_adaptec_7899P(dev); + } +} + + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 + +#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL +#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON +#endif + +static void set_power_on_after_power_fail(int setting) +{ + switch(setting) { + case MAINBOARD_POWER_ON: + default: + amd768_power_after_power_fail(1); + w83627hf_power_after_power_fail(POWER_ON); + break; + case MAINBOARD_POWER_OFF: + amd768_power_after_power_fail(0); + w83627hf_power_after_power_fail(POWER_OFF); + break; + + } +} + + +#define ECC_DISABLE 0 +#define ECC_ENABLE 1 + +#ifndef ECC_OPTION +#define ECC_OPTION ECC_ENABLE +#endif + +static void set_ecc(int setting) +{ + struct pci_dev *dev; + + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, 0); + if (dev) { + switch(setting) { + case ECC_ENABLE: + default: + pci_write_config_dword(dev, 0x48, + (3 << 14)|(2 << 10)|(3 << 8)|(0 << 4)|(0 << 0)); + break; + case ECC_DISABLE: + pci_write_config_dword(dev, 0x48, + (0 << 14)|(0 << 10)|(0 << 8)|(0 << 4)|(0 << 0)); + break; + } + } +} + + +static void setup_pci_irq_to_isa_routing(void) +{ + struct pci_dev *dev; + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); + if (dev != NULL) { + /* + * PIRQA -> 5 + * PIRQB -> 10 + * PIRQC -> 11 + * PIRQD -> 3 + */ + pci_write_config_word(dev, 0x56, + (0xa << 12)|(0xb << 8)|(0x0 <<4)|(0x5 <<0)); +#if 0 + pci_write_config_word(dev, 0x56, + (3 << 12)|(0xb << 8)|(0xa <<4)|(5 <<0)); +#endif + } +} + +static void hide_devices(void) +{ + struct pci_dev *dev; + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440, 0); + if (dev) { + u8 byte; + pci_read_config_byte(dev, 0x48, &byte); +#if 0 + /* Hide both the ide controller and the usb controller */ + pci_write_config_byte(dev, 0x48, byte | (0<<3)|(1<<2)|(1<<1)); +#endif +#if 0 + /* Hide the usb controller */ + pci_write_config_byte(dev, 0x48, byte | (0<<3)|(1<<2)|(0<<1)); +#endif +#if 1 + /* Hide no devices */ + pci_write_config_byte(dev, 0x48, byte | (0<<3)|(0<<2)|(0<<1)); +#endif + } +} + +void mainboard_cpu_fixup(int cpu) +{ + if(cpu == 1) { + check_cpus(); + if(initial_apicid[1] == -1) { + printk_err("Only one CPU installed. Linux Bios requires 2\n"); + while(1); /* print error and spin */ + return; /* no apic because no cpu */ + } + } + /* This is an error, something is locked up */ + full_reset(); +} + +void mainboard_fixup(void) +{ + int power_on_after_power_fail; + int ecc; + + amd768_disable_watchdog(); + lpc_routing_fixup(); + amd768_enable_ioapic(); + amd768_enable_serial_irqs(1, 0, 0); + enable_reset_port_0xcf9(); + amd768_enable_port92_reset(); + check_cpus(); +#if 0 + print_whami(); +#endif + amd768_enable_ide(1,1); + onboard_scsi_fixup(); + amd768_cpu_reset_sends_init(); + rtc_init(0); + amd768_decode_stop_grant(DECODE_STPGNT_DATA); + amd768_posted_memory_write_enable(); + amd768_set_pm_classcode(); + amd768_mouse_sends_irq12(); + setup_pci_irq_to_isa_routing(); + amd76x_setup_pci_arbiter(); + isa_dma_init(); + + power_on_after_power_fail = MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + get_option(&power_on_after_power_fail, "power_on_after_fail"); + set_power_on_after_power_fail(power_on_after_power_fail); + + ecc = ECC_OPTION; + get_option(&ecc, "ECC_memory"); + set_ecc(ecc); + +#if 0 + amd768_usb_setup(); +#endif +#if 0 + hide_devices(); +#endif +} + + +void final_mainboard_fixup(void) +{ +#if 0 + enable_ide_devices(); +#endif +} + +void hard_reset(void) +{ + amd768_hard_reset(); +} diff --git a/src/mainboard/tyan/s2466/mainboard_raminit.inc b/src/mainboard/tyan/s2466/mainboard_raminit.inc new file mode 100644 index 0000000000..7bc57bb970 --- /dev/null +++ b/src/mainboard/tyan/s2466/mainboard_raminit.inc @@ -0,0 +1,140 @@ +jmp mainboard_raminit_out +#define DEFAULT_RAM_TRACE_SETTINGS 0 +#define USE_ECC_SDRAM 1 + + + + /* + * Routine: spd_to_dimm_side0 + * Arguments: %bl SMBUS_MEM_DEVICE + * + * Results: %edx DIMM register index + * + * Used: %ebx, %edx, %esp + * Trashed: %eflags + * Preserved: %eax, %ebx, %ecx, %esi, %edi, %ebp + * + * Effects: Dimms are not necessarily in the same order on the smbus + * as they are in chipset register indexes. This function + * maps the SMBUS device id to the logical index in + * the chipset, that is used to refer to a particular dimm. + */ +spd_to_dimm_side0: + movl %ebx, %edx + andl $0xff, %edx + subl $(SMBUS_MEM_DEVICE_START), %edx + /* 0 -> 0 */ + cmpl $0, %edx + jne 1f + movl $0, %edx + RETSP + /* 1 -> 6 */ +1: cmpl $1, %edx + jne 1f + movl $6, %edx + RETSP + /* 2 -> 4 */ +1: cmpl $2, %edx + jne 1f + movl $4, %edx + RETSP + /* 3 -> 2 */ +1: movl $2, %edx + RETSP + + + /* + * Routine: spd_to_dimm_side1 + * Arguments: %bl SMBUS_MEM_DEVICE + * + * Results: %edx DIMM register index + * + * Used: %ebx, %edx, %esp + * Trashed: %eflags + * Preserved: %eax, %ebx, %ecx, %esi, %edi, %ebp + * + * Effects: Dimms are not necessarily in the same order on the smbus + * as they are in chipset register indexes. This function + * maps the SMBUS device id to the logical index in + * the chipset, that is used to refer to a particular dimm. + */ +spd_to_dimm_side1: + movl %ebx, %edx + andl $0xff, %edx + subl $(SMBUS_MEM_DEVICE_START), %edx + /* 0 -> 1 */ + cmpl $0, %edx + jne 1f + movl $1, %edx + RETSP + /* 1 -> 7 */ +1: cmpl $1, %edx + jne 1f + movl $7, %edx + RETSP + /* 2 -> 5 */ +1: cmpl $2, %edx + jne 1f + movl $5, %edx + RETSP + /* 3 -> 3 */ +1: movl $3, %edx + RETSP + + +/* Set the calibration delay. These values may need to change per mainboard + * so we put them here. + */ + +sdram_software_calibration_delay: +#if DEFAULT_RAM_TRACE_SETTINGS + .byte 0x69, 0x00, 0x00, 0x6b +#else + .byte 0x69, 0x00, 0x00, 0x69 +#endif + +mainboard_constant_register_values: +#if DEFAULT_RAM_TRACE_SETTINGS +#else + .long 0x18c, 0x09052d05 + .long 0x190, 0x1b052d05 + .long 0x194, 0x2d052d05 + .long 0x198, 0x2d052d05 +#endif +#if USE_ECC_SDRAM + .long 0x48, (3 << 14)|(2 << 10)|(0 << 8)|(0 << 4)|(0 << 0) +#else + .long 0x48, 0 +#endif +mainboard_constant_register_values_end: + + + /* + * Routine: mainboard_verify_dram_timing + * Arguments: %edi the computed timing for the current dimm. + * Trashed: %eflags + * Results: cf clear + * %edi has a timing supported by this motherboard + * On Error: + * cf set + * %edi holds a timing not supported by this motherboard + * + * Effects: Verifies we can use the current dimm settings + * on the tyan 2466 motherboard. + * Currently the only potential problem is putting + * in unregistered SDRAM. + */ +mainboard_verify_dram_timing: + testl $(1<<27), %edi + jnz mainboard_verify_dram_timing_ok +mainboard_verify_dram_timing_error: + stc + jmp mainboard_verify_dram_timing_out +mainboard_verify_dram_timing_ok: + clc +mainboard_verify_dram_timing_out: + RET_LABEL(mainboard_verify_dram_timing) + +#undef DEFAULT_RAM_TRACE_SETTINGS +mainboard_raminit_out: + diff --git a/src/mainboard/tyan/s2466/mptable.c b/src/mainboard/tyan/s2466/mptable.c new file mode 100644 index 0000000000..8d628a276f --- /dev/null +++ b/src/mainboard/tyan/s2466/mptable.c @@ -0,0 +1,154 @@ +#include +#include +#include +#include + +#define __STR(X) #X +#define STR(X) __STR(X) + +void *smp_write_config_table(void *v, unsigned long * processor_map) +{ + static const char sig[4] = "PCMP"; + static const char oem[] = STR(MAINBOARD_VENDOR); + static const char productid[12] = STR(MAINBOARD_PART_NUMBER); + struct mp_config_table *mc; + int len; + int apic; + 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 */ + memset(mc->mpc_oem, ' ', sizeof(mc->mpc_oem)); + len = strnlen(oem, sizeof(mc->mpc_oem)); + memcpy(mc->mpc_oem, oem, len); + memset(mc->mpc_productid, ' ', sizeof(mc->mpc_productid)); + len = strnlen(productid, sizeof(mc->mpc_productid)); + memcpy(mc->mpc_productid, productid, len); + 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); + smp_write_bus(mc, 0, "PCI "); + smp_write_bus(mc, 1, "PCI "); + smp_write_bus(mc, 2, "PCI "); + smp_write_bus(mc, 3, "ISA "); + + for(i=apic=0;impe_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 apic %d\n", + mc, smp_next_mpe_entry(mc),apic); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map) +{ + void *v; + printk_debug("Writing the mp table\n"); + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v, processor_map); +} + + diff --git a/src/mainboard/tyan/s2469/Config b/src/mainboard/tyan/s2469/Config new file mode 100644 index 0000000000..f8f4bf74c5 --- /dev/null +++ b/src/mainboard/tyan/s2469/Config @@ -0,0 +1,282 @@ +## +## Set all of the defaults for an x86 architecture +## +arch i386 + +## +## 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) +## +mainboardinit cpu/i386/reset16.inc USE_FALLBACK_IMAGE +ldscript cpu/i386/reset16.lds USE_FALLBACK_IMAGE +mainboardinit cpu/i386/reset32.inc USE_NORMAL_IMAGE +ldscript cpu/i386/reset32.lds USE_NORMAL_IMAGE + +## +## 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=8 +mainboardinit northbridge/amd/amd76x/reset_test.inc +#mainboardinit arch/i386/lib/noop_failover.inc + +#mainboardinit arch/i386/lib/noop_failover.inc USE_NORMAL_IMAGE +#mainboardinit southbridge/amd/amd768/cmos_reset_failover.inc USE_FALLBACK_IMAGE +ldscript arch/i386/lib/failover.lds USE_FALLBACK_IMAGE + +## +## We aren't a reset so shutdown the second cpu if present. +## + +## +## Setup our mtrrs +## +mainboardinit cpu/k7/earlymtrr.inc + +## +## Initialize the processor busses +## +mainboardinit northbridge/amd/amd76x/mpinit.inc USE_FALLBACK_IMAGE + +## +## Only the bootstrap cpu makes it here. +## Failover if we need to +## +mainboardinit southbridge/amd/amd768/cmos_boot_failover.inc USE_FALLBACK_IMAGE + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## When debugging disable the watchdog timer +## +option MAXIMUM_CONSOLE_LOGLEVEL=8 +expr DISABLE_WATCHDOG= MAXIMUM_CONSOLE_LOGLEVEL >= 8 +mainboardinit southbridge/amd/amd768/disable_watchdog.inc DISABLE_WATCHDOG + +## +## Setup the serial port +## +mainboardinit southbridge/amd/amd768/lpc_com1.inc +mainboardinit superio/winbond/w83627hf/setup_serial.inc +mainboardinit pc80/serial.inc +mainboardinit arch/i386/lib/console.inc + +## +## Setup RAM +## +#mainboardinit ram/ramtest.inc +#mainboardinit mainboard/tyan/s2469/do_ramtest.inc +mainboardinit southbridge/amd/amd768/smbus.inc +#mainboardinit sdram/generic_dump_spd.inc +mainboardinit mainboard/tyan/s2469/mainboard_raminit.inc + +## +## Include the secondary Configuration files +## +northbridge amd/amd76x +southbridge amd/amd768 +nsuperio winbond/w83627hf com1={1} com2={1} floppy=1 lpt=1 keyboard=1 +dir ../../../pc80 +dir /src/superio/winbond/w83627hf +cpu p5 +cpu p6 +cpu k7 + +## +## Build the objects we have code for in this directory. +## +object mainboard.o +object mptable.o HAVE_MP_TABLE +object irq_tables.o HAVE_PIRQ_TABLE + +### +### Build options +### + +## +## Location of the DIMM EEPROMS on the SMBUS +## This is fixed into a narrow range by the DIMM package standard. +## +option SMBUS_MEM_DEVICE_START=(0xa << 3) +option SMBUS_MEM_DEVICE_END=(SMBUS_MEM_DEVICE_START +3) +option SMBUS_MEM_DEVICE_INC=1 + +## +## Customize our winbond superio chip for this motherboard +## +option SIO_BASE=0x2e +nooption SIO_SYSTEM_CLK_INPUT + +## +## Build code for the fallback boot +## +option HAVE_FALLBACK_BOOT=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +option HAVE_HARD_RESET=1 +option HAVE_MAINBOARD_CPU_FIXUP=1 +option HAVE_FULL_RESET=1 + +## +## Build code to export a programmable irq routing table +## +#option HAVE_PIRQ_TABLE=1 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +option HAVE_MP_TABLE=1 + +## +## Do not build special code for the keyboard +## +option NO_KEYBOARD=1 + +## +## Build code to export a CMOS option table +## +option HAVE_OPTION_TABLE=1 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +option SMP=1 +option MAX_CPUS=2 + +## +## Build code to setup a generic IOAPIC +## +option IOAPIC=1 + +## +## MEMORY_HOLE instructs earlymtrr.inc to +## enable caching from 0-640KB and to disable +## caching from 640KB-1MB using fixed MTRRs +## +## Enabling this option breaks SMP because secondary +## CPU identification depends on only variable MTRRs +## being enabled. +## +nooption MEMORY_HOLE + +## +## Enable both fixed and variable MTRRS +## When we setup MTRRs in mtrr.c +## +## We must setup the fixed mtrrs or we confuse SMP secondary +## processor identification +## +option ENABLE_FIXED_AND_VARIABLE_MTRRS=1 + +## +## Clean up the motherboard id strings +## +#option MAINBOARD_PART_NUMBER=THUNDER K7 +#option MAINBOARD_PART_NUMBER=TIGER MPX +option MAINBOARD_PART_NUMBER=S2469 THUNDER K7 PRO +#option MAINBOARD_VENDOR=Tyan +option MAINBOARD_VENDOR=TYAN + +## +## Let Assembly code know where on the pci bus the AMD southbridge is +## +option AMD768_DEV=0x3800 + +## +## Call the final_mainboard_fixup function +## +option FINAL_MAINBOARD_FIXUP=1 + +## +## Figure out which type of linuxBIOS image to build +## If we aren't a fallback image we must be a normal image +## This is useful for optional includes +## +option USE_FALLBACK_IMAGE=0 +expr USE_NORMAL_IMAGE=!USE_FALLBACK_IMAGE + +### +### LinuxBIOS layout values +### + +## ROM_SIZE is the size of boot ROM that this board will use. +option ROM_SIZE=524288 + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +option ROM_IMAGE_SIZE=49152 + +## +## Use a small 8K stack +## +option STACK_SIZE=0x2000 + +## +## Use a small 8K heap +## +option HEAP_SIZE=0x2000 + +## +## Only use the option table in a normal image +## +expr USE_OPTION_TABLE=!USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +expr ROM_SECTION_SIZE =(USE_FALLBACK_IMAGE*65536)+(USE_NORMAL_IMAGE*(ROM_SIZE - 65536)) +expr ROM_SECTION_OFFSET=(USE_FALLBACK_IMAGE*(ROM_SIZE-65536))+(USE_NORMAL_IMAGE*0) + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +expr ZKERNEL_START =(0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) +expr PAYLOAD_SIZE =ROM_SECTION_SIZE - ROM_IMAGE_SIZE + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +expr _ROMBASE =ZKERNEL_START + PAYLOAD_SIZE + +## +## Compute a range of ROM that can cached to speed up linuxBIOS, +## execution speed. +## +#expr XIP_ROM_SIZE = 65536 +#expr XIP_ROM_BASE = _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE +#option XIP_ROM_SIZE=65536 +#option XIP_ROM_BASE=0xffff0000 + +# XIP_ROM_SIZE && XIP_ROM_BASE values that work. +#option XIP_ROM_SIZE=0x8000 +#option XIP_ROM_BASE=0xffff8000 + +## +## Compute where the SMP startup code needs to live +## FIXME I don't see how to make this work for the normal image.... +## +option START_CPU_SEG=0xf0000 + + diff --git a/src/mainboard/tyan/s2469/cmos.layout b/src/mainboard/tyan/s2469/cmos.layout new file mode 100644 index 0000000000..5ba4c032c1 --- /dev/null +++ b/src/mainboard/tyan/s2469/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/tyan/s2469/do_ramtest.inc b/src/mainboard/tyan/s2469/do_ramtest.inc new file mode 100644 index 0000000000..35ccad56d6 --- /dev/null +++ b/src/mainboard/tyan/s2469/do_ramtest.inc @@ -0,0 +1,28 @@ +#if 0 + movl $0x000f0000, %eax + movl $0x000f1000, %ebx + CALLSP(ramtest) +#endif + +#if 1 + movl $0x00100000, %eax + movl $0x00180000, %ebx + CALLSP(ramtest) + + xorl %eax, %eax + movl $0x00080000, %ebx + CALLSP(ramtest) +#endif + +#if 1 + + xorl %eax, %eax + movl $0x00001000, %ebx + CALLSP(ramtest) +#endif + +#if 0 + movl $0xffe00000, %eax + movl $0xfff00000, %ebx + CALLSP(ramtest) +#endif diff --git a/src/mainboard/tyan/s2469/example-fallback.config b/src/mainboard/tyan/s2469/example-fallback.config new file mode 100644 index 0000000000..ad85eee67d --- /dev/null +++ b/src/mainboard/tyan/s2469/example-fallback.config @@ -0,0 +1,85 @@ +## This will make a target directory of ./fallback +## This is relative to where the configuration file resides in the filesystem +target ./tdir/fallback + +mainboard tyan/s2469 + + +## Build a normal not a fallback image. +option USE_FALLBACK_IMAGE=1 + +## Build an image for a 512KB rom +## ./normal/romimage is the entire rom image except for the last 64KB +## which are reserved for the fallback image. +#option ROM_SIZE=524288 +option ROM_SIZE=262144 + +## Select the maximum size the linuxBIOS code can compile to. +## Allow linuxBIOS to be up to 48KB in size +option ROM_IMAGE_SIZE=45056 + +## +### The Serial Console +## +## Hardware flow control is currently ignored. + +## Enable the Serial Console +option SERIAL_CONSOLE=1 + +## Select the serial console baud rate. +#option TTYS0_BAUD=115200 +#option TTYS0_BAUD=57600 +#option TTYS0_BAUD=38400 +#option TTYS0_BAUD=19200 +option TTYS0_BAUD=9600 +#option TTYS0_BAUD=4800 +#option TTYS0_BAUD=2400 +#option TTYS0_BAUD=1200 + +# Select the serial console base port +option TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +option 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 +option DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +option MAXIMUM_CONSOLE_LOGLEVEL=7 + +## Use the elf bootloader +option USE_ELF_BOOT=1 + +## Select the boot device +option USE_GENERIC_ROM=1 +#option BOOT_FLOPPY=1 +#option USE_SERIAL_FILL_INBUF=1 +#option BOOT_IDE=1 + +# Load etherboot with the elf bootloader +# The payload command is relative the build directory +# So .. is the directory this config file resides in +payload ./bootloader.ebi + +# Path to your kernel (vmlinux) +# NOTE; you need a path to your test12 kernel here. +linux ~/projects/linux/linux-2.4.4.eb1.1 + +# Kernel command line parameters +#commandline ro panic=5 root=/dev/hda5 console=ttyS0,115200 debug 3 + + diff --git a/src/mainboard/tyan/s2469/example-normal.config b/src/mainboard/tyan/s2469/example-normal.config new file mode 100644 index 0000000000..2af20d6bbd --- /dev/null +++ b/src/mainboard/tyan/s2469/example-normal.config @@ -0,0 +1,89 @@ +# This will make a target directory of ./normal +## This is relative to where the configuration file resides in the filesystem +target ./tdir/normal + +mainboard tyan/s2469 + +## Build a normal not a fallback image. +option USE_FALLBACK_IMAGE=0 + +## Build an image for a 512KB rom +## ./normal/romimage is the entire rom image except for the last 64KB +## which are reserved for the fallback image. +#option ROM_SIZE=524288 +option ROM_SIZE=262144 + +## Select the maximum size the linuxBIOS code can compile to. +## Allow linuxBIOS to be up to 48KB in size +#option ROM_IMAGE_SIZE=49152 +option ROM_IMAGE_SIZE=65536 +#option PAYLOAD_SIZE=131072 +#option _ROMBASE=0xFFFE0000 +#option ZKERNEL_START=0xFFFC0000 + + +## +### The Serial Console +## +## Hardware flow control is currently ignored. + +## Enable the Serial Console +option SERIAL_CONSOLE=1 + +## Select the serial console baud rate. +#option TTYS0_BAUD=115200 +#option TTYS0_BAUD=57600 +#option TTYS0_BAUD=38400 +#option TTYS0_BAUD=19200 +option TTYS0_BAUD=9600 +#option TTYS0_BAUD=4800 +#option TTYS0_BAUD=2400 +#option TTYS0_BAUD=1200 + +# Select the serial console base port +option TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +option 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 +option DEFAULT_CONSOLE_LOGLEVEL=7 +## At a maximum only compile in this level of debugging +option MAXIMUM_CONSOLE_LOGLEVEL=8 + +## Use the elf bootloader +option USE_ELF_BOOT=1 + +## Select the boot device +option USE_GENERIC_ROM=1 +#option BOOT_FLOPPY=1 +#option USE_SERIAL_FILL_INBUF=1 +#option BOOT_IDE=1 + +# Load etherboot with the elf bootloader +# The payload command is relative the build directory +# So .. is the directory this config file resides in +payload ./bootloader.ebi + +# Path to your kernel (vmlinux) +# NOTE; you need a path to your test12 kernel here. +linux ~/projects/linux/linux-2.4.4.eb1.1 + +# Kernel command line parameters +#commandline ro panic=5 root=/dev/hda5 console=ttyS0,115200 debug 3 + + diff --git a/src/mainboard/tyan/s2469/irq_tables.c b/src/mainboard/tyan/s2469/irq_tables.c new file mode 100644 index 0000000000..65c607598f --- /dev/null +++ b/src/mainboard/tyan/s2469/irq_tables.c @@ -0,0 +1,33 @@ +/* PCI: Interrupt Routing Table found at 0x4011cee0 size = 256 */ + +#include + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 256, /* u16 Table size 32+(16*devices) */ + 0x00, /* u8 Bus 0 */ + 0x3b, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x1022, /* u16 Vendor */ + 0x7400, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xf1, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, 0x40, {{0x01, 0xdef8}, {0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}}, 0x01, 0x00}, + {0x00, 0x48, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x01, 0xdef8}, {0x02, 0xdef8}}, 0x02, 0x00}, + {0x00, 0x50, {{0x01, 0xdef8}, {0x02, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0x58, {{0x04, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0x08, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x01, 0x28, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0d, 0x00}, + {0x00, 0x80, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}}, 0x00, 0x00}, + {0x02, 0x20, {{0x01, 0xdef8}, {0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}}, 0x03, 0x00}, + {0x02, 0x28, {{0x02, 0xdef8}, {0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}}, 0x04, 0x00}, + {0x02, 0x30, {{0x03, 0xdef8}, {0x04, 0xdef8}, {0x01, 0xdef8}, {0x02, 0xdef8}}, 0x05, 0x00}, + {0x02, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x04, 0xdef8}}, 0x00, 0x00}, + {0x02, 0x38, {{0x02, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x02, 0x40, {{0x03, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00} + } +}; diff --git a/src/mainboard/tyan/s2469/mainboard.c b/src/mainboard/tyan/s2469/mainboard.c new file mode 100644 index 0000000000..eb7bcb6ffb --- /dev/null +++ b/src/mainboard/tyan/s2469/mainboard.c @@ -0,0 +1,303 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long initial_apicid[MAX_CPUS] = +{ + 0, 1 +}; + +static void lpc_routing_fixup(void) +{ + struct pci_dev *dev; + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440,0); + if (dev != NULL) { + + /* This register is not documented, but the factory sets + it to 0xde */ + pci_write_config_byte(dev, 0x75, 0xde); + + /* States in the documentation that this bit must be set + for things to work right */ + pci_write_config_byte(dev, 0x4d, 0x04); + +#if 0 + /* Send keyboard controller, + * FDC1, ECP + * to the LPC bus + * Send APCI ports 0x62 & 0x66 to the ISA bus + */ + pci_write_config_byte(dev, 0x51, (0<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(1)); + /* Route io for both serial ports to the LPC bus */ + pci_write_config_byte(dev, 0x52, (1<<7)|(1<<4)|(1<<3)|(0<<0)); + /* Don't route any audio ports to the LPC bus */ + pci_write_config_byte(dev, 0x53, (0<<6)|(0<<4)|(0<<3)|(0<<2)|(0<<0)); + /* Route superio configuration accesses to the LPC bus */ + pci_write_config_byte(dev, 0x54, (0<<5)|(1<<4)|(0<<2)|(0<<0)); + /* Don't use LPC decode register 4 */ + pci_write_config_byte(dev, 0x55, (0<<4)|(0<<0)); + /* Don't use LPC decode register 5 */ + pci_write_config_byte(dev, 0x56, (0<<4)|(0<<0)); + /* Route 512 byte io address range 0x0c00 - 0xc200 the LPC bus */ + pci_write_config_dword(dev, 0x58, 0x00000c01); + /* Route 1MB memory address range 0 - 0 to the LPC bus */ + pci_write_config_dword(dev, 0x5c, 0x00000000); +#endif + + } +} + + +static void enable_reset_port_0xcf9(void) +{ + struct pci_dev *dev; + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); + if (dev != NULL) { + unsigned char byte; + /* Enable reset port 0xcf9 */ + pci_read_config_byte(dev, 0x41, &byte); + pci_write_config_byte(dev, 0x41, byte | (1<<7) | (1<<5)); + pci_write_config_byte(dev, 0x42, 0x09); + } +} + + +static void print_whami(void) +{ + struct pci_dev *dev; + u32 whami; + /* Find out which processor I'm running on, and if it was the boot + * procesor so I can verify everything was setup correctly + */ + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C,0); + if (dev != NULL) { + pci_read_config_dword(dev, 0x80, &whami); + printk_spew("whami = 0x%08lx\n", whami); + } +} + +static void check_cpus(void) +{ + struct pci_dev *dev; + u32 biu1; + /* Find out which processor I'm running on, and if it was the boot + * procesor so I can verify everything was setup correctly + */ + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C,0); + if (dev != NULL) { + pci_read_config_dword(dev, 0x68, &biu1); + if( !(biu1 & 0x80000000)) { + initial_apicid[1] = -1; + } + printk_debug("biu1 = 0x%08lx, apicid[1] = %d\n", biu1, + initial_apicid[1]); + } +} + + + +static void fixup_adaptec_7899P(struct pci_dev *pdev) +{ + /* Enable writes to the device id */ + pci_write_config_byte(pdev, 0xff, 1); + /* Set the device id */ + pci_write_config_word(pdev, PCI_DEVICE_ID, PCI_DEVICE_ID_ADAPTEC2_7899P); + /* Set the subsytem vendor id */ + pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_TYAN); + /* Set the subsytem id */ + pci_write_config_word(pdev, PCI_SUBSYSTEM_ID, 0x2469); + /* Disable writes to the device id */ + pci_write_config_byte(pdev, 0xff, 0); +} + +static void onboard_scsi_fixup(void) +{ + struct pci_dev *dev; + + /* Set the scsi device id's */ + dev = pci_find_slot(0, PCI_DEVFN(0xd, 0)); + if (dev != NULL) { + fixup_adaptec_7899P(dev); + } + /* Set the scsi device id's */ + dev = pci_find_slot(0, PCI_DEVFN(0xd, 1)); + if (dev != NULL) { + fixup_adaptec_7899P(dev); + } +} + + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 + +#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL +#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON +#endif + +static void set_power_on_after_power_fail(int setting) +{ + switch(setting) { + case MAINBOARD_POWER_ON: + default: + amd768_power_after_power_fail(1); + w83627hf_power_after_power_fail(POWER_ON); + break; + case MAINBOARD_POWER_OFF: + amd768_power_after_power_fail(0); + w83627hf_power_after_power_fail(POWER_OFF); + break; + + } +} + + +#define ECC_DISABLE 0 +#define ECC_ENABLE 1 + +#ifndef ECC_OPTION +#define ECC_OPTION ECC_ENABLE +#endif + +static void set_ecc(int setting) +{ + struct pci_dev *dev; + + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, 0); + if (dev) { + switch(setting) { + case ECC_ENABLE: + default: + pci_write_config_dword(dev, 0x48, + (3 << 14)|(2 << 10)|(3 << 8)|(0 << 4)|(0 << 0)); + break; + case ECC_DISABLE: + pci_write_config_dword(dev, 0x48, + (0 << 14)|(0 << 10)|(0 << 8)|(0 << 4)|(0 << 0)); + break; + } + } +} + + +static void setup_pci_irq_to_isa_routing(void) +{ + struct pci_dev *dev; + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); + if (dev != NULL) { + /* + * PIRQA -> 5 + * PIRQB -> 10 + * PIRQC -> 11 + * PIRQD -> 3 + */ + pci_write_config_word(dev, 0x56, + (0xa << 12)|(0xb << 8)|(0x0 <<4)|(0x5 <<0)); +#if 0 + pci_write_config_word(dev, 0x56, + (3 << 12)|(0xb << 8)|(0xa <<4)|(5 <<0)); +#endif + } +} + +static void hide_devices(void) +{ + struct pci_dev *dev; + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440, 0); + if (dev) { + u8 byte; + pci_read_config_byte(dev, 0x48, &byte); +#if 0 + /* Hide both the ide controller and the usb controller */ + pci_write_config_byte(dev, 0x48, byte | (0<<3)|(1<<2)|(1<<1)); +#endif +#if 0 + /* Hide the usb controller */ + pci_write_config_byte(dev, 0x48, byte | (0<<3)|(1<<2)|(0<<1)); +#endif +#if 1 + /* Hide no devices */ + pci_write_config_byte(dev, 0x48, byte | (0<<3)|(0<<2)|(0<<1)); +#endif + } +} + +void mainboard_cpu_fixup(int cpu) +{ + if(cpu == 1) { + check_cpus(); + if(initial_apicid[1] == -1) { + printk_err("Only one CPU installed, Linux Bios requires 2\n"); + while(1); /* print error and spin */ + return; /* no apic because no cpu */ + } + } + /* This is an error, something is locked up */ + full_reset(); +} + +void mainboard_fixup(void) +{ + int power_on_after_power_fail; + int ecc; + + amd768_disable_watchdog(); + lpc_routing_fixup(); + amd768_enable_ioapic(); + amd768_enable_serial_irqs(1, 0, 0); + enable_reset_port_0xcf9(); + amd768_enable_port92_reset(); + check_cpus(); +#if 0 + print_whami(); +#endif + amd768_enable_ide(1,1); + onboard_scsi_fixup(); + amd768_cpu_reset_sends_init(); + rtc_init(0); + amd768_decode_stop_grant(DECODE_STPGNT_DATA); + amd768_posted_memory_write_enable(); + amd768_set_pm_classcode(); + amd768_mouse_sends_irq12(); + setup_pci_irq_to_isa_routing(); + amd76x_setup_pci_arbiter(); + isa_dma_init(); + + power_on_after_power_fail = MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + get_option(&power_on_after_power_fail, "power_on_after_fail"); + set_power_on_after_power_fail(power_on_after_power_fail); + + ecc = ECC_OPTION; + get_option(&ecc, "ECC_memory"); + set_ecc(ecc); + +#if 0 + amd768_usb_setup(); +#endif +#if 0 + hide_devices(); +#endif +} + + +void final_mainboard_fixup(void) +{ +#if 0 + enable_ide_devices(); +#endif +} + +void hard_reset(void) +{ + amd768_hard_reset(); +} diff --git a/src/mainboard/tyan/s2469/mainboard_raminit.inc b/src/mainboard/tyan/s2469/mainboard_raminit.inc new file mode 100644 index 0000000000..e72c33e45c --- /dev/null +++ b/src/mainboard/tyan/s2469/mainboard_raminit.inc @@ -0,0 +1,140 @@ +jmp mainboard_raminit_out +#define DEFAULT_RAM_TRACE_SETTINGS 0 +#define USE_ECC_SDRAM 1 + + + + /* + * Routine: spd_to_dimm_side0 + * Arguments: %bl SMBUS_MEM_DEVICE + * + * Results: %edx DIMM register index + * + * Used: %ebx, %edx, %esp + * Trashed: %eflags + * Preserved: %eax, %ebx, %ecx, %esi, %edi, %ebp + * + * Effects: Dimms are not necessarily in the same order on the smbus + * as they are in chipset register indexes. This function + * maps the SMBUS device id to the logical index in + * the chipset, that is used to refer to a particular dimm. + */ +spd_to_dimm_side0: + movl %ebx, %edx + andl $0xff, %edx + subl $(SMBUS_MEM_DEVICE_START), %edx + /* 0 -> 0 */ + cmpl $0, %edx + jne 1f + movl $0, %edx + RETSP + /* 1 -> 6 */ +1: cmpl $1, %edx + jne 1f + movl $6, %edx + RETSP + /* 2 -> 4 */ +1: cmpl $2, %edx + jne 1f + movl $4, %edx + RETSP + /* 3 -> 2 */ +1: movl $2, %edx + RETSP + + + /* + * Routine: spd_to_dimm_side1 + * Arguments: %bl SMBUS_MEM_DEVICE + * + * Results: %edx DIMM register index + * + * Used: %ebx, %edx, %esp + * Trashed: %eflags + * Preserved: %eax, %ebx, %ecx, %esi, %edi, %ebp + * + * Effects: Dimms are not necessarily in the same order on the smbus + * as they are in chipset register indexes. This function + * maps the SMBUS device id to the logical index in + * the chipset, that is used to refer to a particular dimm. + */ +spd_to_dimm_side1: + movl %ebx, %edx + andl $0xff, %edx + subl $(SMBUS_MEM_DEVICE_START), %edx + /* 0 -> 1 */ + cmpl $0, %edx + jne 1f + movl $1, %edx + RETSP + /* 1 -> 7 */ +1: cmpl $1, %edx + jne 1f + movl $7, %edx + RETSP + /* 2 -> 5 */ +1: cmpl $2, %edx + jne 1f + movl $5, %edx + RETSP + /* 3 -> 3 */ +1: movl $3, %edx + RETSP + + +/* Set the calibration delay. These values may need to change per mainboard + * so we put them here. + */ + +sdram_software_calibration_delay: +#if DEFAULT_RAM_TRACE_SETTINGS + .byte 0x69, 0x00, 0x00, 0x6b +#else + .byte 0x69, 0x00, 0x00, 0x69 +#endif + +mainboard_constant_register_values: +#if DEFAULT_RAM_TRACE_SETTINGS +#else + .long 0x18c, 0x09052d05 + .long 0x190, 0x1b052d05 + .long 0x194, 0x2d052d05 + .long 0x198, 0x2d052d05 +#endif +#if USE_ECC_SDRAM + .long 0x48, (3 << 14)|(2 << 10)|(0 << 8)|(0 << 4)|(0 << 0) +#else + .long 0x48, 0 +#endif +mainboard_constant_register_values_end: + + + /* + * Routine: mainboard_verify_dram_timing + * Arguments: %edi the computed timing for the current dimm. + * Trashed: %eflags + * Results: cf clear + * %edi has a timing supported by this motherboard + * On Error: + * cf set + * %edi holds a timing not supported by this motherboard + * + * Effects: Verifies we can use the current dimm settings + * on the tyan 2469 motherboard. + * Currently the only potential problem is putting + * in unregistered SDRAM. + */ +mainboard_verify_dram_timing: + testl $(1<<27), %edi + jnz mainboard_verify_dram_timing_ok +mainboard_verify_dram_timing_error: + stc + jmp mainboard_verify_dram_timing_out +mainboard_verify_dram_timing_ok: + clc +mainboard_verify_dram_timing_out: + RET_LABEL(mainboard_verify_dram_timing) + +#undef DEFAULT_RAM_TRACE_SETTINGS +mainboard_raminit_out: + diff --git a/src/mainboard/tyan/s2469/mptable.c b/src/mainboard/tyan/s2469/mptable.c new file mode 100644 index 0000000000..450604be91 --- /dev/null +++ b/src/mainboard/tyan/s2469/mptable.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include + +#define __STR(X) #X +#define STR(X) __STR(X) + +void *smp_write_config_table(void *v, unsigned long * processor_map) +{ + static const char sig[4] = "PCMP"; + static const char oem[] = STR(MAINBOARD_VENDOR); + static const char productid[12] = STR(MAINBOARD_PART_NUMBER); + struct mp_config_table *mc; + int len; + int apic; + 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 */ + memset(mc->mpc_oem, ' ', sizeof(mc->mpc_oem)); + len = strnlen(oem, sizeof(mc->mpc_oem)); + memcpy(mc->mpc_oem, oem, len); + memset(mc->mpc_productid, ' ', sizeof(mc->mpc_productid)); + len = strnlen(productid, sizeof(mc->mpc_productid)); + memcpy(mc->mpc_productid, productid, len); + 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); + smp_write_bus(mc, 0, "PCI "); + smp_write_bus(mc, 1, "PCI "); + smp_write_bus(mc, 2, "PCI "); + smp_write_bus(mc, 3, "ISA "); + + for(i=apic=0;impe_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 apic %d\n", + mc, smp_next_mpe_entry(mc),apic); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map) +{ + void *v; + printk_debug("Writing the mp table\n"); + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v, processor_map); +} + + diff --git a/src/northbridge/amd/amd76x/northbridge.c b/src/northbridge/amd/amd76x/northbridge.c index 85e6012bb3..b16bafbf7d 100644 --- a/src/northbridge/amd/amd76x/northbridge.c +++ b/src/northbridge/amd/amd76x/northbridge.c @@ -2,20 +2,30 @@ #include #include #include +#include + struct mem_range *sizeram(void) { static struct mem_range mem[3]; - u32 size; + u32 size, size_10, pci_low; /* Use the PCI top memory register */ pcibios_read_config_dword(0, 0, 0x9c, &size); + + /* change the memory size if it is above pci space */ + pci_low = (u32)(pci_memory_base & 0xf8000000); + if(size > pci_low) { + size = pci_low; + pcibios_write_config_dword(0, 0, 0x9c, size); + } + /* Convert size in bytes to size in K */ - size = size >> 10; + size_10 = size >> 10; mem[0].basek = 0; mem[0].sizek = 640; mem[1].basek = 1024; - mem[1].sizek = size - mem[1].basek; + mem[1].sizek = size_10 - mem[1].basek; mem[2].basek = 0; mem[2].sizek = 0; return mem; diff --git a/src/northbridge/amd/amd76x/raminit.inc b/src/northbridge/amd/amd76x/raminit.inc index 73507d2df0..2dfbd57878 100644 --- a/src/northbridge/amd/amd76x/raminit.inc +++ b/src/northbridge/amd/amd76x/raminit.inc @@ -531,8 +531,10 @@ RET_LABEL(ram_set_registers) * Routine: sdram_spd_get_dimm_size * Arguments: %bl SMBUS_MEM_DEVICE * Results: - * %edi log base 2 size of DIMM side 1 in bits - * %esi log base 2 size of DIMM side 2 in bits + * %edi log base 2 size of DIMM side 1 in bits upper 16 + * bits have the chip size. + * %esi log base 2 size of DIMM side 2 in bits upper 16 + * bits have the chip size. * * Preserved: %ebx (except %bh), %ebp * @@ -577,6 +579,16 @@ sdram_spd_get_dimm_size: bsrl %eax, %ecx /* compute cheap log base 2 */ addl %ecx, %edi + movb $13, %bh /* chip width */ + CALLSP(smbus_read_byte) + jz sdram_spd_get_dimm_size_out + andl $0xff, %eax + bsrl %eax, %ecx /* compute cheap log base 2 */ + movl %edi, %eax + addl %ecx, %edi /* edi now has the chip base 2 size in bits */ + shll $16, %edi /* move the value to the top 16 bits */ + orl %eax, %edi /* restore part of the dimm size */ + /* Get the module data width and convert it to a power of two */ movb $7, %bh /* (high byte) */ CALLSP(smbus_read_byte) @@ -611,9 +623,13 @@ sdram_spd_get_dimm_size: movl %eax, %ecx andl $0xf, %ecx subl %ecx, %esi /* Subtract out rows on side 1 */ + shll $16,%ecx + subl %ecx, %esi /* Subtract out rows on side 1 */ shrl $4, %eax andl $0xf, %eax addl %eax, %esi /* Add in rows on side 2 */ + shll $16, %eax + addl %eax,%esi movb $4, %bh /* columns */ CALLSP(smbus_read_byte) @@ -621,9 +637,13 @@ sdram_spd_get_dimm_size: movl %eax, %ecx andl $0xf, %ecx subl %ecx, %esi /* Subtract out columns on side 1 */ + shll $16,%ecx + subl %ecx, %esi /* Subtract out rows on side 1 */ shrl $4, %eax andl $0xf, %eax addl %eax, %esi /* Add in columns on side 2 */ + shll $16, %eax + addl %eax,%esi sdram_spd_get_dimm_size_out: RET_LABEL(sdram_spd_get_dimm_size) @@ -632,7 +652,8 @@ sdram_spd_get_dimm_size_out: /* * Routine: set_dimm_size * Arguments: %esp return address - * %edi width of the dimm in bits + * %edi 0-15 width of the dimm in bits + * %edi 16-31 width of the chips in bits * %edx dim base register * * Preserved: %ebx, %esi @@ -645,8 +666,11 @@ sdram_spd_get_dimm_size_out: set_dimm_size: /* Convert ram width in bits to log base 2 ram size in 8MB quantities */ xorl %eax, %eax - subl $26, %edi + movl %edi, %ecx + andl $0x0ff, %ecx + subl $26, %ecx jb 1f + subl $26, %edi /* Compute the ignore bits for the DIMM side 1 */ movl %edi, %ecx @@ -658,7 +682,8 @@ set_dimm_size: /* Add in the addressing mode */ shll $7, %eax orl $3, %eax /* Set the enable and mode 1 */ - cmpl $32, %edi /* 256MB */ + shrl $16, %ecx + cmpl $28, %ecx /* 512Mbits chip size row+col+banks+chip_width */ jb 1f xorl $6, %eax /* Clear mode 1 set mode 2 */ 1: @@ -843,6 +868,12 @@ order_next_dimm: /* Increment the top of memory */ addl %edx, %ebp + cmpl %edx, %ebp + jnc tom_ok + /* top of memory overflowed 4 gig */ + andl $0x000000ff, %ebp + orl $0xfc000000, %ebp +tom_ok: /* Write the base register */ PCI_WRITE_CONFIG_DWORD @@ -1403,6 +1434,7 @@ get_dimm_row_cycle_setting: * units SPD byte 41 is in */ jnz get_dimm_row_cycle_setting_new + movb $30, %bh CALLSP(smbus_read_byte) jz get_dimm_row_cycle_setting_error @@ -1435,10 +1467,25 @@ get_dimm_row_cycle_setting_low: jmp set_dimm_row_cycle_setting dimm_row_new_cycle_setting_msg: - .string "\r\n Newly defined SPD byte 41 populated please update the code to handle this\r\n" + .string "\r\n ERROR - Memory tRC is to slow for bus speed. \r\n" get_dimm_row_cycle_setting_new: - CONSOLE_DEBUG_TX_STRING($dimm_row_new_cycle_setting_msg) - /* fall through */ + + /* %eax has the delay time in nanoseconds. + To get the cycles delay, devide time by nano sec per bus cycle */ + movl MEM_NS_PER_CYCLE(%ebp), %edx + addb %dl, %al /* Make certain to round up */ + subb $1, %al + divb %dl, %al + subb $3, %al + movb %al, %ah + andb $0xf8, %ah /* test for overflow of max 7 */ + jz 2f + movl %ebx, %ecx + CONSOLE_WARNING_INLINE_TX_STRING($dimm_row_new_cycle_setting_msg) + movl %ecx, %ebx + movb $7, %al /* overflow, so make it it max of 7 */ +2: + jmp set_dimm_row_cycle_setting get_dimm_row_cycle_setting_error: stc @@ -2018,8 +2065,6 @@ ram_set_spd_registers: * Effects: After this routine has been run you can access * memory on the currently plugged in DIMMS. */ -ram_enabled: .string "Ram Enabled\r\n" - enable_sdram: /* Recalibrate the PDL timing registers */ movl $0x80000140, %eax @@ -2053,8 +2098,6 @@ enable_sdram_wait: testl $(1 << 23), %eax /* Wait until the mode register is set */ jnz enable_sdram_wait - CONSOLE_DEBUG_TX_STRING($ram_enabled) - RET_LABEL(enable_sdram) diff --git a/src/northbridge/intel/E7500/raminit.inc b/src/northbridge/intel/E7500/raminit.inc index 6340c91197..cc45fbf6a5 100644 --- a/src/northbridge/intel/E7500/raminit.inc +++ b/src/northbridge/intel/E7500/raminit.inc @@ -316,7 +316,7 @@ constant_register_values: #endif /* Most aggressive settings possible */ - .long 0x78, 0xc0fff8c4, (1<<29)|(1<<28)|(1<<27)|(2<<24)|(2<<9)|DRT_CL|(1<<3)|(1<<1)|(1<<0) + .long 0x78, 0xc0fff8c0, (1<<29)|(1<<28)|(1<<27)|(2<<24)|(2<<9)|DRT_CL|(1<<3)|(3<<1)|(1<<0) /* FIXME why was I attempting to set a reserved bit? */ /* 0x0100040f */ @@ -1332,7 +1332,7 @@ cas_latency_80: * I am not prepared to change this value, to the intel recommended value * of 0x0d. Eric Biederman */ - .byte 0x05, 0x01, 0x06 + .byte 0x05, 0x0d, 0x06 cas_latency_78: .byte DRT_CAS_1_5, DRT_CAS_2_0, DRT_CAS_2_5 @@ -1539,8 +1539,9 @@ spd_get_dram_timing: /* * tRD */ - /* Set to a 7 clock read delay */ + /* Set to a 6 clock read delay */ andl $~(7<<24), %esi + orl $(1<<24), %esi /* * Back to Back Read Turn Around diff --git a/src/northbridge/intel/E7501/raminit.inc b/src/northbridge/intel/E7501/raminit.inc index 2f26371b59..ecf49661f4 100644 --- a/src/northbridge/intel/E7501/raminit.inc +++ b/src/northbridge/intel/E7501/raminit.inc @@ -1,4 +1,4 @@ -jmp intel_E7500_out +jmp intel_E7501_out /* This was originally for the e7500, modified for e7501 * The primary differences are that 7501 apparently can @@ -11,7 +11,7 @@ jmp intel_E7500_out * Steven James 02/06/2003 */ -#define DEBUG_RAM_CONFIG 0 +#define DEBUG_RAM_CONFIG 1 /* DDR DIMM Mode register Definitions */ @@ -34,7 +34,7 @@ jmp intel_E7500_out #define BURST_LENGTH BURST_4 #define BURST_TYPE BURST_INTERLEAVED -#define CAS_LATENCY CAS_2_0 +#define CAS_LATENCY CAS_2_5 //#define CAS_LATENCY CAS_1_5 #define MRS_VALUE (MODE_NORM | CAS_LATENCY | BURST_TYPE | BURST_LENGTH) @@ -176,7 +176,7 @@ constant_register_values: * 0x2e - 0x2f * [15:00] Subsystem ID */ - .long 0x2c, 0, (0x15d9 << 0) | (0x3480 << 16) + .long 0x2c, 0, (0x15d9 << 0) | (0x3580 << 16) /* Undocumented * 0x80 - 0x80 @@ -196,13 +196,16 @@ constant_register_values: */ #if CAS_LATENCY == CAS_2_5 # .long 0x80, 0xfffffe00, 0x06 /* Intel E7500 recommended */ - .long 0x80, 0xfffff000, 0x0bb6 /* Intel E7500 recommended */ +# .long 0x80, 0xfffff000, 0x0bb6 /* Intel E7500 recommended */ + .long 0x80, 0xfffff000, 0x0662 /* from Factory Bios */ #elif CAS_LATENCY == CAS_2_0 # .long 0x80, 0xfffffe00, 0x0d /* values for register 0x80 */ - .long 0x80, 0xfffff000, 0x0bb1 /* values for register 0x80 */ +# .long 0x80, 0xfffff000, 0x0bb1 /* values for register 0x80 */ + .long 0x80, 0xfffff000, 0x0662 /* from Factory Bios */ #elif CAS_LATENCY == CAS_1_5 # .long 0x80, 0xfffffe00, 0x05 - .long 0x80, 0xfffff000, 0x0bb5 +# .long 0x80, 0xfffff000, 0x0bb5 + .long 0x80, 0xfffff000, 0x0662 /* from Factory Bios */ #endif /* Enable periodic memory recalibration */ @@ -332,7 +335,7 @@ constant_register_values: * 1 == 2 DRAM Clocks */ #define DRT_CAS_2_5 (0<<4) -#define DRT_CAS_2_0 (1<<4) +#define DRT_CAS_2_0 (1<<4) #define DRT_CAS_1_5 (2<<4) #define DRT_CAS_MASK (3<<4) @@ -346,7 +349,8 @@ constant_register_values: /* Most aggressive settings possible */ # .long 0x78, 0xc0fff8c4, (1<<29)|(1<<28)|(1<<27)|(2<<24)|(2<<9)|DRT_CL|(1<<3)|(1<<1)|(1<<0) - .long 0x78, 0xc0f8f8c0, (1<<29)|(1<<28)|(1<<27)|(1<<24)|(1<<16)|(2<<9)|DRT_CL|(1<<3)|(3<<1)|(1<<0) +# .long 0x78, 0xc0f8f8c0, (1<<29)|(1<<28)|(1<<27)|(1<<24)|(1<<16)|(2<<9)|DRT_CL|(1<<3)|(3<<1)|(1<<0) + .long 0x78, 0xc0f8f9c0, (1<<29)|(1<<28)|(1<<27)|(1<<24)|(1<<16)|(2<<9)|DRT_CL|(1<<3)|(3<<1)|(1<<0) /* FIXME why was I attempting to set a reserved bit? */ /* 0x0100040f */ @@ -392,7 +396,8 @@ constant_register_values: * [03:00] Reserved */ # .long 0x7c, 0xffcefcff, (1<<22)|(2 << 20)|(1 << 16)| (0 << 8) - .long 0x7c, 0xff8cfcff, (1<<22)|(2 << 20)|(1 << 17)|(1 << 16)| (0 << 8) +# .long 0x7c, 0xff8cfcff, (1<<22)|(2 << 20)|(1 << 17)|(1 << 16)| (0 << 8) + .long 0x7c, 0xff82fcff, (1<<22)|(2 << 20)|(1 << 18)|(1 << 16)| (0 << 8) /* CLOCK_DIS - CK/CK# Disable Register * 0x8C @@ -433,6 +438,7 @@ constant_register_values: * When remaplimit < remapbase this register is disabled. */ .long 0xc8, 0xfffffc00, 0 + /* DVNP - Device Not Present Register * 0xE0 - 0xE1 * [15:05] Reserved @@ -1332,9 +1338,11 @@ spd_enable_clocks: movl $0x8c, %eax PCI_READ_CONFIG_DWORD movl %eax, %esi - +#if 0 # Intel clears top bit here, should we? +# No the default is on and for normal timming it should be on. Tom Z andl $0x7f, %esi +#endif spd_get_clocks: /* Read any spd byte to see if the dimm is present */ @@ -1356,7 +1364,6 @@ spd_enable_clocks_next_dimm: addb $(SMBUS_MEM_DEVICE_INC), %bl /* increment the smbus device */ cmpb $SMBUS_MEM_DEVICE_END, %bl jbe spd_get_clocks - movl $0x8c, %eax movl %esi, %ecx PCI_WRITE_CONFIG_DWORD @@ -1380,7 +1387,8 @@ cas_latency_80: */ # .byte 0x05, 0x01, 0x06 - .byte 0xb5, 0xb1, 0xb6 +# .byte 0xb5, 0xb1, 0xb6 + .byte 0x62, 0x62, 0x62 /* factory setting for 0 undocumented reg tnz */ cas_latency_78: .byte DRT_CAS_1_5, DRT_CAS_2_0, DRT_CAS_2_5 @@ -1389,16 +1397,17 @@ spd_set_cas_latency: * supported cas latencies. */ movl $(SMBUS_MEM_DEVICE_START), %ebx - /* Initially allow cas latencies 2.5, 2.0, 1.5 + /* Initially allow cas latencies 2.5, 2.0 * which the chipset supports. */ - movl $((1 << 3)|(1 << 2)|(1 <<1)), %esi + movl $((1 << 3)|(1 << 2)), %esi spd_get_cas_latencies: movb $18, %bh CALLSP(smbus_read_byte) jz spd_set_cas_latency_next_dimm /* Find the highest supported cas latency */ + andl $0x0ff, %eax bsrl %eax, %ecx movl $1, %edi shll %cl, %edi @@ -1406,13 +1415,13 @@ spd_get_cas_latencies: /* Remember the supported cas latencies */ movl %eax, %ecx - /* Verify each cas latency at 100Mhz */ + /* Verify each cas latency at 133Mhz */ /* Verify slowest/highest CAS latency */ movb $9, %bh CALLSP(smbus_read_byte) jz spd_set_cas_latency_next_dimm - cmpb $0xa0, %al + cmpb $0x75, %al jbe 1f /* The bus is too fast so we cannot support this case latency */ notl %edi @@ -1429,7 +1438,7 @@ spd_get_cas_latencies: CALLSP(smbus_read_byte) jz spd_set_cas_latency_next_dimm - cmpb $0xa0, %al + cmpb $0x75, %al jbe 1f /* The bus is too fast so we cannot support this cas latency */ notl %edi @@ -1446,7 +1455,7 @@ spd_get_cas_latencies: CALLSP(smbus_read_byte) jz spd_set_cas_latency_next_dimm - movb $0xa0, %al + cmpb $0x75, %al jbe 1f /* The bus is too fast so we cannot support this cas latency */ notl %edi @@ -1485,8 +1494,13 @@ spd_set_cas_latency_next_dimm: movl %eax, %ecx movl $0x88, %eax PCI_WRITE_CONFIG_DWORD +#if 0 andl $0xfc00ffff, %ecx /* set DQS delays to 2.2ns */ orl $0x02310000, %ecx +#endif + andl $0x0c0000ff, %ecx /* patch try register 88 is undocumented tnz */ + orl $0xd2109800, %ecx + movl $0x88, %eax PCI_WRITE_CONFIG_DWORD movl %ebx, %ecx @@ -1519,9 +1533,9 @@ spd_get_dram_timing: movb $27, %bh CALLSP(smbus_read_byte) jz spd_set_dram_timing_next_dimm - cmpb $(20<<2), %al + cmpb $(15<<2), %al jbe 1f - /* At 100Mhz if row precharge time is above than 20ns than we + /* At 133Mhz if row precharge time is above than 15ns than we * need 3 clocks not 2 clocks. */ andl $~(1<<0), %esi @@ -1532,9 +1546,9 @@ spd_get_dram_timing: movb $29, %bh CALLSP(smbus_read_byte) jz spd_set_dram_timing_next_dimm - cmpb $(20<<2), %al + cmpb $(15<<2), %al jbe 1f - /* At 100Mhz if the Minimum ras to cas delay is about 20ns we + /* At 133Mhz if the Minimum ras to cas delay is about 15ns we * need 3 clocks not 2 clocks. */ andl $~((1<<3)|(1<<1)), %esi @@ -1546,8 +1560,9 @@ spd_get_dram_timing: movb $30, %bh CALLSP(smbus_read_byte) jz spd_set_dram_timing_next_dimm - /* Convert tRAS from ns to 100Mhz clock cycles */ - movb $10, %dl + /* Convert tRAS from ns to 133Mhz clock cycles */ + movb $15, %dl + shll $1, %eax /* mult by 2 to make 7.5 15 */ addb %dl, %al /* Make certain we round up */ subb $1, %al andl $0xff, %eax /* Clear the upper bits of eax */ @@ -1572,7 +1587,7 @@ spd_get_dram_timing: subl $1, %ecx /* See if we need a slower timing */ - cmpb %al, %cl + cmpb %cl, %al jbe 1f /* O.k. put in our slower timing */ @@ -1580,7 +1595,7 @@ spd_get_dram_timing: addb $1, %cl notl %ecx shll $9, %ecx - andl $(3<<9), %esi + andl $~(3<<9), %esi orl %ecx, %esi 1: @@ -1594,7 +1609,7 @@ spd_get_dram_timing: * Back to Back Read Turn Around */ /* Set to a 4 clock back to back read turn around */ - andl $~(1<<27), %esi +# andl $~(1<<27), %esi /* * Back to Back Read-Write Turn Around */ @@ -1604,7 +1619,7 @@ spd_get_dram_timing: * Back to Back Write-Read Turn Around */ /* Set to a 3 clock back to back write to read turn around */ - andl $~(1<<29), %esi +# andl $~(1<<29), %esi spd_set_dram_timing_next_dimm: /* go to the next DIMM */ @@ -1919,4 +1934,4 @@ mem_err: CONSOLE_ERR_TX_HEX8(%bh) jmp mem_stop -intel_E7500_out: +intel_E7501_out: diff --git a/src/ram/spotcheck.inc b/src/ram/spotcheck.inc index 0da12dfe20..b0bc0388a5 100644 --- a/src/ram/spotcheck.inc +++ b/src/ram/spotcheck.inc @@ -12,10 +12,6 @@ #ifndef CONFIG_MAX_SPOTCHECK_ERRORS #define CONFIG_MAX_SPOTCHECK_ERRORS 20 #endif - -# debugging SMJ -//#define NO_HLT - spot_test: .string " Spot checking: " spot_error: .string "Blatant memory errors found.\r\n" @@ -83,19 +79,15 @@ spot_check: incl %esi cmpl $CONFIG_MAX_SPOTCHECK_ERRORS, %esi jbe 3b -#ifndef NO_HLT 5: CONSOLE_INFO_TX_STRING($spot_error) intel_chip_post_macro(0xf1) jmp .Lhlt -#endif 6: -#ifndef NO_HLT /* If any memory errors occured hlt */ testl %esi, %esi jnz 5b -#endif mov %ebp, %esp RETSP diff --git a/src/sdram/generic_zero_ecc_sdram.inc b/src/sdram/generic_zero_ecc_sdram.inc index f0bec86351..2e04632632 100644 --- a/src/sdram/generic_zero_ecc_sdram.inc +++ b/src/sdram/generic_zero_ecc_sdram.inc @@ -24,6 +24,7 @@ ecc_ram_initialize: jz 1f incl %ecx 1: movl $1, %esi + subl $12, %ecx shll %cl, %esi /* Set caching on all of memory into write-combining mode. @@ -40,10 +41,12 @@ ecc_ram_initialize: wrmsr movl $0x201, %ecx /* mtrr[0] physical mask register */ - movl $0x0000000f, %edx xorl %eax, %eax subl %esi, %eax - andl $0xfffff000, %eax + movl %eax, %edx + shrl $20, %edx + andl $0x0f, %edx + shll $12, %eax orl $0x800, %eax wrmsr diff --git a/src/southbridge/amd/amd768/amd768_ide.c b/src/southbridge/amd/amd768/amd768_ide.c index dd8f655ab6..2035ced343 100644 --- a/src/southbridge/amd/amd768/amd768_ide.c +++ b/src/southbridge/amd/amd768/amd768_ide.c @@ -1,16 +1,17 @@ #include #include -#include -#include -#include +#include +#include +#include -void amd766_enable_ide(int enable_a, int enable_b) +void amd768_enable_ide(int enable_a, int enable_b) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7441, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7441, 0); if (dev != NULL) { /* Enable ide devices so the linux ide driver will work */ u16 word; + u8 byte; pci_read_config_word(dev, 0x40, &word); /* Ensure prefetch is disabled */ word &= ~((1 << 15) | (1 << 13)); @@ -22,29 +23,26 @@ void amd766_enable_ide(int enable_a, int enable_b) /* Enable primary ide interface */ word |= (1<<1); } + + word |= (1<<12); + word |= (1<<14); + pci_write_config_word(dev, 0x40, word); - /* The AMD766 has a bug where the BM DMA address must be + + word = 0x0f; + pci_write_config_word(dev, 0x42, word); + + /* The AMD768 has a bug where the BM DMA address must be * 256 byte aligned while it is only 16 bytes long. * Hard code this to a valid address below 0x1000 * where automatic port address assignment starts. */ pci_write_config_dword(dev, 0x20, 0xf01); -#if 0 - if (enable_a) { - ide_probe(0x1f0, 0); - } - if (enable_b) { - ide_probe(0x170, 2); - } -#endif -#if 0 - if (enable_a) { - ide_spinup(0x1f0, 0); - } - if (enable_b) { - ide_spinup(0x170, 2); - } -#endif + + pci_write_config_dword(dev, 0x48, 0x205e5e5e); + word = 0x06a; + pci_write_config_word(dev, 0x4c, word); + } else printk_alert("Could not locate IDE controller\n"); diff --git a/src/southbridge/amd/amd768/amd768_ioapic.c b/src/southbridge/amd/amd768/amd768_ioapic.c index 58511ea837..279e0280d3 100644 --- a/src/southbridge/amd/amd768/amd768_ioapic.c +++ b/src/southbridge/amd/amd768/amd768_ioapic.c @@ -1,16 +1,20 @@ #include #include -#include -#include +#include -void amd766_enable_ioapic(void) +void amd768_enable_ioapic(void) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440,0); if (dev != NULL) { /* Enable the ioapic */ - pci_write_config_byte(dev, 0x4b, (0 << 3)|(0 <<2)|(0 << 1)|(1<< 0)); - } else - printk_alert("Could not locate IOAPIC!\n"); + pci_write_config_byte(dev, 0x4b, (1 <<7)|(0 << 3)|(1<< 0)); + } + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7448,0); + if (dev != NULL) { + /* Enable the ioapic */ + pci_write_config_byte(dev, 0x3e, 4); + } + } diff --git a/src/southbridge/amd/amd768/amd768_lpc.c b/src/southbridge/amd/amd768/amd768_lpc.c index 5f1136adc0..00d55e2c95 100644 --- a/src/southbridge/amd/amd768/amd768_lpc.c +++ b/src/southbridge/amd/amd768/amd768_lpc.c @@ -1,19 +1,17 @@ #include #include -#include -#include +#include -void amd766_enable_serial_irqs(int continuous, unsigned frames, unsigned startclocks) +void amd768_enable_serial_irqs(int continuous, unsigned frames, unsigned startclocks) { struct pci_dev *dev; unsigned value; value = ((!!continuous) << 6)|((frames & 0xf) << 2)|((startclocks & 3) << 0); - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7443,0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443,0); if (dev != NULL) { /* Setup serial irq's for the LPC bus. */ pci_write_config_byte(dev, 0x4a, value); - } else - printk_alert("Could not locate ACPI bridge\n"); + } } diff --git a/src/southbridge/amd/amd768/amd768_mem.c b/src/southbridge/amd/amd768/amd768_mem.c index 6531cf9480..831d992e18 100644 --- a/src/southbridge/amd/amd768/amd768_mem.c +++ b/src/southbridge/amd/amd768/amd768_mem.c @@ -1,11 +1,11 @@ #include #include -#include +#include -void amd766_posted_memory_write_enable(void) +void amd768_posted_memory_write_enable(void) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440, 0); if (dev != NULL) { unsigned char byte; pci_read_config_byte(dev, 0x46, &byte); diff --git a/src/southbridge/amd/amd768/amd768_mouse.c b/src/southbridge/amd/amd768/amd768_mouse.c index 52e2ccbed0..22b370fe4d 100644 --- a/src/southbridge/amd/amd768/amd768_mouse.c +++ b/src/southbridge/amd/amd768/amd768_mouse.c @@ -1,11 +1,11 @@ #include #include -#include +#include -void amd766_mouse_sends_irq12(void) +void amd768_mouse_sends_irq12(void) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); if (dev != NULL) { unsigned short word; /* Setup so irq12 is sent by the ps2 mouse port. */ diff --git a/src/southbridge/amd/amd768/amd768_pm.c b/src/southbridge/amd/amd768/amd768_pm.c index 240ba3064d..b76bfcd319 100644 --- a/src/southbridge/amd/amd768/amd768_pm.c +++ b/src/southbridge/amd/amd768/amd768_pm.c @@ -1,11 +1,11 @@ #include #include -#include +#include -void amd766_set_pm_classcode(void) +void amd768_set_pm_classcode(void) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); if (dev != NULL) { pci_write_config_dword(dev, 0x60, 0x06800000); } diff --git a/src/southbridge/amd/amd768/amd768_power.c b/src/southbridge/amd/amd768/amd768_power.c index af1a3b0495..0a3655e60c 100644 --- a/src/southbridge/amd/amd768/amd768_power.c +++ b/src/southbridge/amd/amd768/amd768_power.c @@ -1,11 +1,11 @@ #include #include -#include +#include -void amd766_power_after_power_fail(int on) +void amd768_power_after_power_fail(int on) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); if (dev != NULL) { unsigned char byte; pci_read_config_byte(dev, 0x43, &byte); diff --git a/src/southbridge/amd/amd768/amd768_reboot.c b/src/southbridge/amd/amd768/amd768_reboot.c index 66013dfcf5..ddc0059837 100644 --- a/src/southbridge/amd/amd768/amd768_reboot.c +++ b/src/southbridge/amd/amd768/amd768_reboot.c @@ -1,14 +1,14 @@ #include #include #include -#include +#include -void amd766_hard_reset(void) +void amd768_hard_reset(void) { pci_set_method(); /* Allow the watchdog timer to reboot us, and enable 0xcf9 */ - pcibios_write_config_byte(0, (AMD766_DEV >> 8) | 3, 0x41, (1<<5)|(1<<1)); + pcibios_write_config_byte(0, (AMD768_DEV >> 8) | 3, 0x41, (1<<5)|(1<<1)); /* Try rebooting though port 0xcf9 */ outb((0<<3)|(1<<2)|(1<<1), 0xcf9); return; diff --git a/src/southbridge/amd/amd768/amd768_reset.c b/src/southbridge/amd/amd768/amd768_reset.c index 3bbbad2cca..0ef2e1bd80 100644 --- a/src/southbridge/amd/amd768/amd768_reset.c +++ b/src/southbridge/amd/amd768/amd768_reset.c @@ -1,11 +1,13 @@ #include #include -#include +#include +#include +#include -void amd766_enable_port92_reset(void) +void amd768_enable_port92_reset(void) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440, 0); if (dev != NULL) { unsigned char byte; /* Enable reset using port 0x92 */ @@ -14,10 +16,10 @@ void amd766_enable_port92_reset(void) } } -void amd766_cpu_reset_sends_init(void) +void amd768_cpu_reset_sends_init(void) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440, 0); if (dev != NULL) { unsigned char byte; pci_read_config_byte(dev, 0x47, &byte); @@ -25,15 +27,30 @@ void amd766_cpu_reset_sends_init(void) } } -void amd766_decode_stop_grant(unsigned how) +void amd768_decode_stop_grant(unsigned how) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); if (dev != NULL) { unsigned char byte; pci_read_config_byte(dev, 0x41, &byte); pci_write_config_byte(dev, 0x41, byte | ((how & 1)<<1)); } - - +} + +void full_reset(void) +{ + struct pci_dev *dev; + + printk_err("Doing a Full Reset\n"); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); + /* make sure the cf9 port is enabled */ + if (dev != NULL) { + unsigned char byte; + /* Enable reset port 0xcf9 */ + pci_read_config_byte(dev, 0x41, &byte); + pci_write_config_byte(dev, 0x41, byte | (1<<7) | (1<<5)); + } + outb(0x0e, 0x0cf9); /* full reset command */ + while(1); } diff --git a/src/southbridge/amd/amd768/amd768_usb.c b/src/southbridge/amd/amd768/amd768_usb.c index d2f9cd8739..bec76ce56a 100644 --- a/src/southbridge/amd/amd768/amd768_usb.c +++ b/src/southbridge/amd/amd768/amd768_usb.c @@ -1,12 +1,12 @@ #include #include -#include +#include -void amd766_usb_setup(void) +void amd768_usb_setup(void) { /* FIXME this is untested incomplete implementation. */ struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7414, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7449, 0); if (dev) { u32 cmd; pci_read_config_dword(dev, PCI_COMMAND, &cmd); diff --git a/src/southbridge/amd/amd768/amd768_watchdog.c b/src/southbridge/amd/amd768/amd768_watchdog.c index 5cc3b9926b..c177965106 100644 --- a/src/southbridge/amd/amd768/amd768_watchdog.c +++ b/src/southbridge/amd/amd768/amd768_watchdog.c @@ -1,14 +1,16 @@ #include #include -#include +#include -void amd766_disable_watchdog(void) +void amd768_disable_watchdog(void) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7443, 0); if (dev != NULL) { unsigned char byte; /* Disable the watchdog timer */ + pci_read_config_byte(dev, 0x41, &byte); + pci_write_config_byte(dev, 0x41, byte | (1<<6)); pci_read_config_byte(dev, 0x49, &byte); pci_write_config_byte(dev, 0x49, byte | (1<<2)); } diff --git a/src/southbridge/amd/amd768/cmos_boot_failover.inc b/src/southbridge/amd/amd768/cmos_boot_failover.inc index 04575ac7cf..6d59df9ec8 100644 --- a/src/southbridge/amd/amd768/cmos_boot_failover.inc +++ b/src/southbridge/amd/amd768/cmos_boot_failover.inc @@ -34,7 +34,11 @@ */ #include #include - + +#if 0 +#define MAX_REBOOT_CNT 8 +#endif + /* See if the CMOS error condition has been flagged */ movb $RTC_REG_D, %al outb %al, $0x70 @@ -44,7 +48,7 @@ jz __rtc_failed /* Compute the cmos checksum, and see if it is valid */ - movb $PC_CKS_RANGE_START, %bl + movb $LB_CKS_RANGE_START, %bl xorl %ecx, %ecx 1: movb %bl, %al @@ -53,16 +57,16 @@ inb $0x71, %al addl %eax, %ecx incb %bl - cmpb $PC_CKS_RANGE_END, %bl + cmpb $LB_CKS_RANGE_END, %bl jbe 1b /* Compute the cmos checksum, and see if it is valid */ /* Read the stored checksum */ - movb $(PC_CKS_LOC), %al + movb $(LB_CKS_LOC), %al outb %al,$0x70 inb $0x71, %al movb %al, %bh - movb $(PC_CKS_LOC+1), %al + movb $(LB_CKS_LOC+1), %al outb %al, $0x70 inb $0x71, %al movb %al, %bl @@ -81,6 +85,7 @@ __rtc_failed: outb %al, $0x70 inb $0x71, %al andb $0xfc, %al + orb $(MAX_REBOOT_CNT << 4), %al outb %al, $0x71 jmp __rtc_ok @@ -89,29 +94,44 @@ __rtc_ok: movb $RTC_BOOT_BYTE, %al outb %al, $0x70 inb $0x71, %al - + testb $1, %al /* are we in normal mode */ + jz 2f + andb $0x0f, %al /* if yes, clear the boot count */ /* Transfer the boot bit from bit 0 to bit 1. * And clear bit 0 so that unless we say it works we * fallback to the other bios image immediately. */ +2: movb %al, %bl + shrb $4, %bl /* are we already at the max cnt */ + cmpb $MAX_REBOOT_CNT, %bl + jz 1f + addb $(1<<4), %al /* no, so add one count */ movb %al, %bl - andb $0xfc, %al - andb $1, %bl + shrb $4, %bl /* now are we at the max count */ + cmpb $MAX_REBOOT_CNT, %bl + jnz 1f + andb $0xfc, %al /* yes, so put in fallback mode */ +1: movb %al, %bl + testb $0xe0, %al /* is this the first boot */ + jnz 2f + andb $1, %bl /* if yes, shift the boot bits */ shlb %bl + andb $0xfc, %al orb %bl, %al - outb %al, $0x71 - - testb $(1<<1), %al +2: outb %al, $0x71 /* save the boot byte */ + movb %al, %bl + shrb $4, %bl /* are we at the max count */ + cmpb $MAX_REBOOT_CNT, %bl jz __failover_boot /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */ - movl $(0x80000000 | AMD766_DEV | 0x40), %eax + movl $(0x80000000 | AMD768_DEV | 0x40), %eax movw $0xcf8, %dx outl %eax, %dx movw $(0xcfc + 3), %dx inb %dx, %al orb $0x80, %al outb %al, %dx - jmp __normal_image + __failover_boot: diff --git a/src/southbridge/amd/amd768/disable_watchdog.inc b/src/southbridge/amd/amd768/disable_watchdog.inc index f436beaf36..dc751b8ce7 100644 --- a/src/southbridge/amd/amd768/disable_watchdog.inc +++ b/src/southbridge/amd/amd768/disable_watchdog.inc @@ -1,10 +1,26 @@ -#define PM_DEV_FN (AMD766_DEV + 0x300) +#define PM_DEV_FN (AMD768_DEV + 0x300) /* Disable the watchdog timer */ - movl $(0x80000000 | PM_DEV_FN | 0x48), %eax + movl $(0x80000000 | PM_DEV_FN | 0x49), %eax movw $0xcf8, %dx outl %eax, %dx movw $0xcfd, %dx inb %dx, %al - orb $0x8, %al + orb $0x04, %al outb %al, %dx + movl $(0x80000000 | PM_DEV_FN | 0x41), %eax + movw $0xcf8, %dx + outl %eax, %dx + movw $0xcfd, %dx + inb %dx, %al + orb $0x40, %al + outb %al, %dx + /* added from sourceforge */ + movl $(0x80000000 | PM_DEV_FN | 0x48), %eax + movw $0xcf8, %dx + outl %eax, %dx + movw $0xcfd, %dx + inb %dx, %al + orb $0x8, %al + outb %al, %dx + diff --git a/src/southbridge/amd/amd768/nvram.c b/src/southbridge/amd/amd768/nvram.c index 35c54555e5..fdc0011d50 100644 --- a/src/southbridge/amd/amd768/nvram.c +++ b/src/southbridge/amd/amd768/nvram.c @@ -6,7 +6,7 @@ void nvram_on(void) { struct pci_dev *dev; - dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 0); + dev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB768_7440, 0); if (dev != NULL) { u8 segen; pci_read_config_byte(dev, 0x43, &segen); diff --git a/src/southbridge/amd/amd768/smbus.inc b/src/southbridge/amd/amd768/smbus.inc index 71977c538f..eb5bef0209 100644 --- a/src/southbridge/amd/amd768/smbus.inc +++ b/src/southbridge/amd/amd768/smbus.inc @@ -1,7 +1,7 @@ jmp smbus_code_end -#define PM_DEV_FN (AMD766_DEV + 0x300) - +#define PM_DEV_FN (AMD768_DEV + 0x300) +#define SMBUS_TIMEOUT (100*1000) #define PM_BASE 0xDD00 #define SMBUS_IO_BASE (PM_BASE + 0xE0) @@ -42,11 +42,8 @@ jmp smbus_code_end #define SMB_GCTL_SLAVE_INTERRUPT (1 << 9) #define SMB_GCTL_ALERT_INTERRUPT (1 << 10) -enable_string: .string "Enabling smbus\r\n" -setup_string: .string "Setting up smbus\r\n" enable_smbus: - CONSOLE_INFO_TX_STRING($enable_string) /* Enable PM IO C3A41 */ movl $(0x80000000 | PM_DEV_FN | 0x40), %eax movw $0xcf8, %dx @@ -74,7 +71,6 @@ enable_smbus: * Effects: The smbus is enabled */ setup_smbus: - CONSOLE_INFO_TX_STRING($setup_string) movl $(SMB_GSTAT_ABORT | SMB_GSTAT_COLLISION | \ SMB_GSTAT_PROTO_ERROR | SMB_GSTAT_COMPLETE | \ SMB_GSTAT_TIMEOUT | SMB_GSTAT_SNOOP_MATCH | \ @@ -83,6 +79,10 @@ setup_smbus: outb %al, %dx RET_LABEL(setup_smbus) +smbus_never_ready: .string "smbus_never_ready\r\n" +smbus_never_done: .string "smbus_never_done\r\n" +full_reset_text: .string "full_reset\r\n" + /* * Routine: smbus_wait_until_ready * Arguments: none @@ -91,12 +91,17 @@ setup_smbus: * Effects: Upon return the smbus is ready to accept commands */ smbus_wait_until_ready: + movl $(SMBUS_TIMEOUT << 8), %eax movl $SMB_GSTAT, %edx 1: inb %dx, %al + subl $0x00000100, %eax + testl $0xffffff00, %eax + jz 2f testb $SMB_GSTAT_HOST_BUSY, %al jnz 1b RET_LABEL(smbus_wait_until_ready) - +2: CONSOLE_DEBUG_TX_STRING($smbus_never_ready) + jmp full_reset /* * Routine: smbus_wait_until_done @@ -105,21 +110,33 @@ smbus_wait_until_ready: * Trashed: eax, edx * Effects: Upon return the smbus has completed it's most recent transation */ +smbus_wait_until_done: + movl $SMB_GSTAT, %edx + movl $(SMBUS_TIMEOUT << 8), %eax +1: inb %dx, %al + subl $0x00000100, %eax + testl $0xffffff00, %eax + jz 4f + testb $(SMB_GSTAT_HOST_BUSY), %al + jnz 1b +2: testb $(~(SMB_GSTAT_HOST_BUSY)), %al + jnz 3f + inb %dx, %al + testb $(~(SMB_GSTAT_HOST_BUSY)), %al + jz 2b +3: RET_LABEL(smbus_wait_until_done) +4: CONSOLE_DEBUG_TX_STRING($smbus_never_done) + jmp full_reset -/* - *smbus_wait_until_done: - * movl $SMB_GSTAT, %edx - *1: inb %dx, %al - * testb $(SMB_GSTAT_HOST_BUSY), %al - * jnz 1b - *2: testb $(~(SMB_GSTAT_HOST_BUSY)), %al - * jnz 3f - * inb %dx, %al - * testb $(~(SMB_GSTAT_HOST_BUSY)), %al - * jz 2b - *3: RET_LABEL(smbus_wait_until_done) - * - */ +full_reset: + CONSOLE_DEBUG_TX_STRING($full_reset_text) + movl $0x00003b41, %eax /*bus 0, device 7, function 3, reg 0x41 */ + movb $(1<<5), %dl + PCI_WRITE_CONFIG_BYTE /* enable port cf9 */ + movb $0x0e, %al + movw $0x0cf9, %dx + outb %al,%dx /* do the full reset */ +1: jmp 1b /* * Routine: smbus_read_byte @@ -170,14 +187,8 @@ smbus_read_byte: outw %ax, %dx /* poll for transaction completion */ -# CALL_LABEL(smbus_wait_until_done) -# code copied since CALL_LABEL can only be used once! - movl $SMB_GSTAT, %edx -1: inb %dx, %al - testb $SMB_GSTAT_HOST_BUSY, %al - jnz 1b -#endcopy of smbus_wait_until_ready - + CALL_LABEL(smbus_wait_until_done) + xorl %eax, %eax /* read the results and see if we succeded */ movl $SMB_GSTAT, %edx inb %dx, %al diff --git a/src/southbridge/intel/82801ca/cmos_failover.inc b/src/southbridge/intel/82801ca/cmos_failover.inc index 4a4f0a99ee..e68c376a25 100644 --- a/src/southbridge/intel/82801ca/cmos_failover.inc +++ b/src/southbridge/intel/82801ca/cmos_failover.inc @@ -15,27 +15,35 @@ * condition is signaled clear the CMOS ram. * * Step 4: Test for which copy of linuxbios to boot. - * We use 2 bits of CMOS ram. + * + * We use 6 bits of CMOS ram. * Bit 0: Initial boot direction * 0 - Boot the failsafe image. * 1 - Boot the other image. * Bit 1: Reboot direction * 0 - Boot the failsafe image. * 1 - Boot the other image. + * Bits 4-7: Reboot count * * On initial boot we read bit0, and write it to bit1, and clear - * bit0. + * bit0. Additionally we clear bit1 if we bit0 was initially set + * and we have reached the maximum boot count. * * On a reboot the bits are not touched. * * Then the appropriate image is jumped to. - * * */ #include "82801.h" #include #include +#ifndef MAX_REBOOT_CNT +#error "MAX_REBOOT_CNT not defined" +#endif +#if MAX_REBOOT_CNT > 15 +#error "MAX_REBOOT_CNT to large" +#endif /* Intel systems magically stop the second cpu in hardware */ testb %al, %al @@ -108,17 +116,33 @@ __rtc_ok: outb %al, $0x70 inb $0x71, %al - /* Transfer the boot bit from bit 0 to bit 1. - * And clear bit 0 so that unless we say it works we - * fallback to the other bios image immediately. - */ movb %al, %bl - andb $0xfc, %al - andb $1, %bl - shlb %bl + movb %al, %cl + andb $0x0c, %al /* Remove the boot bits from %al */ + shrb $4, %cl /* Isolate the boot count */ + + /* If we are in fallback mode set the reboot count to max */ + testb $1, %bl + jnz __reboot_cnt_read + movb $MAX_REBOOT_CNT, %cl +__reboot_cnt_read: + /* Increment the reboot count and see if we have hit the limit */ + incb %cl + cmpb $MAX_REBOOT_CNT, %cl + jb __reboot_cnt_ok +__reboot_cnt_bad: + xorb %cl, %cl /* clear the boot count in fallback */ + xorb %bl, %bl /* clear the boot bits in fallback */ + jmp __reboot_cnt_set + +__reboot_cnt_ok: + movb $((1<<1)|(1<<0)), %bl /* Set boot_option=1 last_boot=1 */ + /* Save the new boot bits */ +__reboot_cnt_set: + shlb $4, %cl orb %bl, %al + orb %cl, %al outb %al, $0x71 testb $(1<<1), %al jnz __normal_image - diff --git a/src/southbridge/intel/piix4e/southbridge.c b/src/southbridge/intel/piix4e/southbridge.c index 208fb6f651..674fb19f2f 100644 --- a/src/southbridge/intel/piix4e/southbridge.c +++ b/src/southbridge/intel/piix4e/southbridge.c @@ -69,7 +69,6 @@ southbridge_fixup() } printk_info("done.\n"); - } void nvram_on()