diff options
Diffstat (limited to 'src/mainboard/supermicro/x6dai_g')
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/Config.lb | 198 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/Options.lb | 229 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/auto.c | 139 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/chip.h | 5 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/cmos.layout | 80 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/debug.c | 330 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/failover.c | 46 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/irq_tables.c | 34 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/mainboard.c | 12 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/mptable.c | 142 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/reset.c | 40 | ||||
-rw-r--r-- | src/mainboard/supermicro/x6dai_g/watchdog.c | 42 |
12 files changed, 1297 insertions, 0 deletions
diff --git a/src/mainboard/supermicro/x6dai_g/Config.lb b/src/mainboard/supermicro/x6dai_g/Config.lb new file mode 100644 index 0000000000..8d4ada557b --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/Config.lb @@ -0,0 +1,198 @@ +## +## Only use the option table in a normal image +## +default 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. +## +if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE ) +else + default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE ) + default ROM_SECTION_OFFSET = 0 +end + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE ) +default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE ) + +## +## Compute a range of ROM that can be cached to speed up linuxBIOS, +## execution speed. +## +## XIP_ROM_SIZE must be a power of 2. +## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE +## +default XIP_ROM_SIZE=131072 +default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) + +## +## Set all of the defaults for an x86 architecture +## + +arch i386 end + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o + +## +## Romcc output +## +makerule ./failover.E + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./failover.inc + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./auto.E + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end +makerule ./auto.inc + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +## +## Build our 16 bit and 32 bit linuxBIOS entry code +## +mainboardinit cpu/x86/16bit/entry16.inc +mainboardinit cpu/x86/32bit/entry32.inc +ldscript /cpu/x86/16bit/entry16.lds +ldscript /cpu/x86/32bit/entry32.lds + +## +## Build our reset vector (This is where linuxBIOS is entered) +## +if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds +else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds +end + +### Should this be in the northbridge code? +mainboardinit arch/i386/lib/cpu_reset.inc + +## +## Include an id string (For safe flashing) +## +mainboardinit 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. +### +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup RAM +## +mainboardinit cpu/x86/fpu/enable_fpu.inc +mainboardinit cpu/x86/mmx/enable_mmx.inc +mainboardinit cpu/x86/sse/enable_sse.inc +mainboardinit ./auto.inc +mainboardinit cpu/x86/sse/disable_sse.inc +mainboardinit cpu/x86/mmx/disable_mmx.inc + +## +## Include the secondary Configuration files +## +dir /pc80 +config chip.h + +chip northbridge/intel/E7525 # mch + device pci_domain 0 on + chip southbridge/intel/esb6300 # esb6300 + register "pirq_a_d" = "0x0b0a0a05" + register "pirq_e_h" = "0x0a0b0c80" + + device pci 1c.0 on end + + device pci 1d.0 on end + device pci 1d.1 on end + device pci 1d.4 on end + device pci 1d.5 on end + device pci 1d.7 on end + + device pci 1e.0 on end + + device pci 1f.0 on + chip superio/winbond/w83627hf + device pnp 2e.0 off end + device pnp 2e.1 off end + device pnp 2e.2 on + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 on + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.4 off end + device pnp 2e.5 off end + device pnp 2e.6 off end + device pnp 2e.7 off end + device pnp 2e.9 off end + device pnp 2e.a on end + device pnp 2e.b off end + device pnp 2e.f off end + device pnp 2e.10 off end + device pnp 2e.14 off end + end + end + device pci 1f.1 on end + device pci 1f.2 on end + device pci 1f.3 on end + device pci 1f.5 off end + device pci 1f.6 on end + end + device pci 00.0 on end + device pci 00.1 on end + device pci 00.2 on end + device pci 02.0 on end + device pci 03.0 on end + device pci 04.0 on end + device pci 08.0 on end + end + device apic_cluster 0 on + chip cpu/intel/socket_mPGA604_800Mhz # cpu0 + device apic 0 on end + end + chip cpu/intel/socket_mPGA604_800Mhz # cpu1 + device apic 6 on end + end + end +end + diff --git a/src/mainboard/supermicro/x6dai_g/Options.lb b/src/mainboard/supermicro/x6dai_g/Options.lb new file mode 100644 index 0000000000..822e31f03f --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/Options.lb @@ -0,0 +1,229 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_HARD_RESET +uses IRQ_SLOT_COUNT +uses HAVE_OPTION_TABLE +uses CONFIG_LOGICAL_CPUS +uses CONFIG_MAX_CPUS +uses CONFIG_IOAPIC +uses CONFIG_SMP +uses FALLBACK_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_STREAM +uses CONFIG_ROM_STREAM_START +uses PAYLOAD_SIZE +uses _ROMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses STACK_SIZE +uses HEAP_SIZE +uses USE_OPTION_TABLE +uses LB_CKS_RANGE_START +uses LB_CKS_RANGE_END +uses LB_CKS_LOC +uses MAINBOARD +uses MAINBOARD_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses CONFIG_UDELAY_TSC +uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses _RAMBASE +uses CONFIG_GDB_STUB +uses CONFIG_CONSOLE_SERIAL8250 +uses TTYS0_BAUD +uses TTYS0_BASE +uses TTYS0_LCS +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL +uses CONFIG_CONSOLE_BTEXT +uses CC +uses HOSTCC +uses CROSS_COMPILE +uses OBJCOPY + + +### +### Build options +### + +## +## ROM_SIZE is the size of boot ROM that this board will use. +## +default ROM_SIZE=1048576 + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 + +## +## Delay timer options +## Use timer2 +## +default CONFIG_UDELAY_TSC=1 +default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +default HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=16 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +default HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option table +## +default HAVE_OPTION_TABLE=1 + +## +## Move the default LinuxBIOS cmos range off of AMD RTC registers +## +default LB_CKS_RANGE_START=49 +default LB_CKS_RANGE_END=122 +default LB_CKS_LOC=123 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +default CONFIG_SMP=1 +default CONFIG_MAX_CPUS=4 +default CONFIG_LOGICAL_CPUS=0 + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="X6DAI" +default MAINBOARD_VENDOR= "Supermicro" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x6780 + +### +### LinuxBIOS layout values +### + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +default ROM_IMAGE_SIZE = 65536 + +## +## Use a small 8K stack +## +default STACK_SIZE=0x2000 + +## +## Use a small 32K heap +## +default HEAP_SIZE=0x8000 + + +### +### Compute the location and size of where this firmware image +### (linuxBIOS plus bootloader) will live in the boot rom chip. +### +default FALLBACK_SIZE=131072 + +## +## LinuxBIOS C code runs at this location in RAM +## +default _RAMBASE=0x00004000 + +## +## Load the payload from the ROM +## +default CONFIG_ROM_STREAM=1 + + +### +### Defaults of options that you may want to override in the target config file +### + +## +## The default compiler +## +default CC="$(CROSS_COMPILE)gcc -m32" +default HOSTCC="gcc" + +## +## Disable the gdb stub by default +## +default CONFIG_GDB_STUB=0 + +## +## The Serial Console +## + +# To Enable the Serial Console +default CONFIG_CONSOLE_SERIAL8250=1 + +## Select the serial console baud rate +default TTYS0_BAUD=115200 +#default TTYS0_BAUD=57600 +#default TTYS0_BAUD=38400 +#default TTYS0_BAUD=19200 +#default TTYS0_BAUD=9600 +#default TTYS0_BAUD=4800 +#default TTYS0_BAUD=2400 +#default TTYS0_BAUD=1200 + +# Select the serial console base port +default TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +default TTYS0_LCS=0x3 + +## +### Select the linuxBIOS loglevel +## +## EMERG 1 system is unusable +## ALERT 2 action must be taken immediately +## CRIT 3 critical conditions +## ERR 4 error conditions +## WARNING 5 warning conditions +## NOTICE 6 normal but significant condition +## INFO 7 informational +## DEBUG 8 debug-level messages +## SPEW 9 Way too many details + +## Request this level of debugging output +default DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +default MAXIMUM_CONSOLE_LOGLEVEL=8 + +## +## Select power on after power fail setting +default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" + +## +## Don't enable the btext console +## +default CONFIG_CONSOLE_BTEXT=0 + + +### End Options.lb +end + diff --git a/src/mainboard/supermicro/x6dai_g/auto.c b/src/mainboard/supermicro/x6dai_g/auto.c new file mode 100644 index 0000000000..f148a8c38b --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/auto.c @@ -0,0 +1,139 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include "option_table.h" +#include "pc80/mc146818rtc_early.c" +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "ram/ramtest.c" +#include "southbridge/intel/esb6300/esb6300_early_smbus.c" +#include "northbridge/intel/E7525/raminit.h" +#include "superio/winbond/w83627hf/w83627hf.h" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "debug.c" +#include "watchdog.c" +#include "reset.c" +#include "superio/winbond/w83627hf/w83627hf_early_init.c" +#include "northbridge/intel/E7525/memory_initialized.c" +#include "cpu/x86/bist.h" + + +#define SIO_GPIO_BASE 0x680 +#define SIO_XBUS_BASE 0x4880 + +#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP2) + +#define DEVPRES_CONFIG ( \ + DEVPRES_D1F0 | \ + DEVPRES_D2F0 | \ + DEVPRES_D3F0 | \ + DEVPRES_D4F0 | \ + DEVPRES_D6F0 | \ + 0 ) +#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0) + +#define RECVENA_CONFIG 0x0808090a +#define RECVENB_CONFIG 0x0808090a + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/intel/E7525/raminit.c" +#include "sdram/generic_sdram.c" + + +static void main(unsigned long bist) +{ + /* + * + * + */ + static const struct mem_controller mch[] = { + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x00, 0), + .f1 = PCI_DEV(0, 0x00, 1), + .f2 = PCI_DEV(0, 0x00, 2), + .f3 = PCI_DEV(0, 0x00, 3), + .channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, }, + .channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, }, + } + }; + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + early_mtrr_init(); + if (memory_initialized()) { + asm volatile ("jmp __cpu_reset"); + } + } + /* Setup the console */ + outb(0x87,0x2e); + outb(0x87,0x2e); + pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6)); + w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE); + uart_init(); + console_init(); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing 6300ESB?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + display_cpuid_update_microcode(); +#endif +#if 0 + print_pci_devices(); +#endif +#if 1 + enable_smbus(); +#endif +#if 0 + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif + disable_watchdogs(); + sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch); +#if 1 + dump_pci_device(PCI_DEV(0, 0x00, 0)); +// dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 0 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); + ram_check(0x00100000, 0x01000000); + /* check the first 1M in the 3rd Gig */ + ram_check(0x30100000, 0x31000000); +#endif +#if 0 + ram_check(0x00000000, 0x02000000); +#endif + +#if 0 + while(1) { + hlt(); + } +#endif +} diff --git a/src/mainboard/supermicro/x6dai_g/chip.h b/src/mainboard/supermicro/x6dai_g/chip.h new file mode 100644 index 0000000000..02f15189d6 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/chip.h @@ -0,0 +1,5 @@ +struct chip_operations mainboard_supermicro_x6dai_g_ops; + +struct mainboard_supermicro_x6dai_g_config { + int nothing; +}; diff --git a/src/mainboard/supermicro/x6dai_g/cmos.layout b/src/mainboard/supermicro/x6dai_g/cmos.layout new file mode 100644 index 0000000000..6f3cd189e3 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/cmos.layout @@ -0,0 +1,80 @@ +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 +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 +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 reserved_memory + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/supermicro/x6dai_g/debug.c b/src/mainboard/supermicro/x6dai_g/debug.c new file mode 100644 index 0000000000..5546421156 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/debug.c @@ -0,0 +1,330 @@ +#define SMBUS_MEM_DEVICE_START 0x50 +#define SMBUS_MEM_DEVICE_END 0x57 +#define SMBUS_MEM_DEVICE_INC 1 + +static void print_reg(unsigned char index) +{ + unsigned char data; + + outb(index, 0x2e); + data = inb(0x2f); + print_debug("0x"); + print_debug_hex8(index); + print_debug(": 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + return; +} + +static void xbus_en(void) +{ + /* select the XBUS function in the SIO */ + outb(0x07, 0x2e); + outb(0x0f, 0x2f); + outb(0x30, 0x2e); + outb(0x01, 0x2f); + return; +} + +static void setup_func(unsigned char func) +{ + /* select the function in the SIO */ + outb(0x07, 0x2e); + outb(func, 0x2f); + /* print out the regs */ + print_reg(0x30); + print_reg(0x60); + print_reg(0x61); + print_reg(0x62); + print_reg(0x63); + print_reg(0x70); + print_reg(0x71); + print_reg(0x74); + print_reg(0x75); + return; +} + +static void siodump(void) +{ + int i; + unsigned char data; + + print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n"); + for (i=0x10; i<=0x2d; i++) { + print_reg((unsigned char)i); + } +#if 0 + print_debug("\r\n*** XBUS REGISTERS ***\r\n"); + setup_func(0x0f); + for (i=0xf0; i<=0xff; i++) { + print_reg((unsigned char)i); + } + + print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n"); + setup_func(0x03); + print_reg(0xf0); + + print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n"); + setup_func(0x02); + print_reg(0xf0); + +#endif + print_debug("\r\n*** GPIO REGISTERS ***\r\n"); + setup_func(0x07); + for (i=0xf0; i<=0xf8; i++) { + print_reg((unsigned char)i); + } + print_debug("\r\n*** GPIO VALUES ***\r\n"); + data = inb(0x68a); + print_debug("\r\nGPDO 4: 0x"); + print_debug_hex8(data); + data = inb(0x68b); + print_debug("\r\nGPDI 4: 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + +#if 0 + + print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n"); + setup_func(0x0a); + print_reg(0xf0); + + print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n"); + setup_func(0x09); + print_reg(0xf0); + print_reg(0xf1); + + print_debug("\r\n*** RTC REGISTERS ***\r\n"); + setup_func(0x10); + print_reg(0xf0); + print_reg(0xf1); + print_reg(0xf3); + print_reg(0xf6); + print_reg(0xf7); + print_reg(0xfe); + print_reg(0xff); + + print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n"); + setup_func(0x14); + print_reg(0xf0); +#endif + return; +} + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + device_t dev; + for(dev = PCI_DEV(0, 0, 0); + dev <= PCI_DEV(0, 0x1f, 0x7); + dev += PCI_DEV(0,0,1)) { + uint32_t id; + id = pci_read_config32(dev, PCI_VENDOR_ID); + if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0x0000)) { + continue; + } + print_debug_pci_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_bar14(unsigned dev) +{ + int i; + unsigned long bar; + + print_debug("BAR 14 Dump\r\n"); + + bar = pci_read_config32(dev, 0x14); + for(i = 0; i <= 0x300; i+=4) { +#if 0 + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); +#endif + if((i%4)==0) { + print_debug("\r\n"); + print_debug_hex16(i); + print_debug_char(' '); + } + print_debug_hex32(read32(bar + i)); + print_debug_char(' '); + } + print_debug("\r\n"); +} + +static void dump_pci_devices(void) +{ + device_t dev; + for(dev = PCI_DEV(0, 0, 0); + dev <= PCI_DEV(0, 0x1f, 0x7); + dev += PCI_DEV(0,0,1)) { + uint32_t id; + id = pci_read_config32(dev, PCI_VENDOR_ID); + if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0x0000)) { + continue; + } + dump_pci_device(dev); + } +} + +#if 0 +static void dump_spd_registers(const struct mem_controller *ctrl) +{ + int i; + print_debug("\r\n"); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl->channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl->channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + } +} +#endif + +void dump_spd_registers(void) +{ + unsigned device; + device = SMBUS_MEM_DEVICE_START; + while(device <= SMBUS_MEM_DEVICE_END) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("dimm "); + print_debug_hex8(device); + + for(i = 0; (i < 256) ; i++) { + unsigned char byte; + if ((i % 16) == 0) { + print_debug("\r\n"); + print_debug_hex8(i); + print_debug(": "); + } + status = smbus_read_byte(device, i); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} + +void dump_ipmi_registers(void) +{ + unsigned device; + device = 0x42; + while(device <= 0x42) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("ipmi "); + print_debug_hex8(device); + + for(i = 0; (i < 8) ; i++) { + unsigned char byte; + status = smbus_read_byte(device, 2); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} diff --git a/src/mainboard/supermicro/x6dai_g/failover.c b/src/mainboard/supermicro/x6dai_g/failover.c new file mode 100644 index 0000000000..1a4a88ebfa --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/failover.c @@ -0,0 +1,46 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "pc80/mc146818rtc_early.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/intel/E7525/memory_initialized.c" + +static unsigned long main(unsigned long bist) +{ + /* Did just the cpu reset? */ + if (memory_initialized()) { + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + goto normal_image; + } + else { + goto fallback_image; + } + normal_image: + asm volatile ("jmp __normal_image" + : /* outputs */ + : "a" (bist) /* inputs */ + : /* clobbers */ + ); + cpu_reset: + asm volatile ("jmp __cpu_reset" + : /* outputs */ + : "a"(bist) /* inputs */ + : /* clobbers */ + ); + fallback_image: + return bist; +} diff --git a/src/mainboard/supermicro/x6dai_g/irq_tables.c b/src/mainboard/supermicro/x6dai_g/irq_tables.c new file mode 100644 index 0000000000..c34a722141 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/irq_tables.c @@ -0,0 +1,34 @@ +/* PCI: Interrupt Routing Table found at 0x40163ed0 size = 272 */ + +#include <arch/pirq_routing.h> + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 272, /* 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] */ + 0x78, /* 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, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00}, + {0x01, 0x00, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}}, 0x04, 0x00}, + {0x00, 0x20, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00}, + {0x02, 0x00, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}}, 0x06, 0x00}, + {0x00, 0xe0, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00}, + {0x04, 0x08, {{0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}}, 0x01, 0x00}, + {0x04, 0x10, {{0x6a, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x07, 0x00}, + {0x04, 0x18, {{0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}}, 0x02, 0x00}, + {0x00, 0xf0, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00}, + {0x05, 0x40, {{0x68, 0x1ef8}, {0x69, 0x1ef8}, {0x6a, 0x1ef8}, {0x6b, 0x1ef8}}, 0x03, 0x00}, + {0x05, 0x18, {{0x6a, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x08, 0x00}, + {0x05, 0x10, {{0x69, 0x1ef8}, {0x6a, 0x1ef8}, {0x6b, 0x1ef8}, {0x68, 0x1ef8}}, 0x05, 0x00}, + {0x00, 0xf8, {{0x62, 0x1ef8}, {0x61, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0xe8, {{0x60, 0x1ef8}, {0x63, 0x1ef8}, {0x00, 0xdef8}, {0x6b, 0x1ef8}}, 0x00, 0x00} + } +}; diff --git a/src/mainboard/supermicro/x6dai_g/mainboard.c b/src/mainboard/supermicro/x6dai_g/mainboard.c new file mode 100644 index 0000000000..bf741989ee --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/mainboard.c @@ -0,0 +1,12 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <cpu/x86/msr.h> +#include "chip.h" + +struct chip_operations supermicro_x6dai_g_ops = { + CHIP_NAME("Supermicro X6DAI_G mainboard ") +}; + diff --git a/src/mainboard/supermicro/x6dai_g/mptable.c b/src/mainboard/supermicro/x6dai_g/mptable.c new file mode 100644 index 0000000000..9d793c44a6 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/mptable.c @@ -0,0 +1,142 @@ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "LNXI "; + static const char productid[12] = "X6DAI-G "; + struct mp_config_table *mc; + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_6300; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* initially just the header */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* not yet computed */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet... */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + { + device_t dev; + + /* southbridge */ + dev = dev_find_slot(0, PCI_DEVFN(0x1e,0)); + if (dev) { + bus_6300 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_isa++; + } + else { + printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n"); + bus_6300 = 5; + bus_isa = 6; + } + } + + /* define bus and isa numbers */ + for(bus_num = 0; bus_num < bus_isa; bus_num++) { + smp_write_bus(mc, bus_num, "PCI "); + } + smp_write_bus(mc, bus_isa, "ISA "); + + /* IOAPIC handling */ + + smp_write_ioapic(mc, 2, 0x20, 0xfec00000); + smp_write_ioapic(mc, 3, 0x20, 0xfec10000); + + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x01, 0x02, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x03, 0x02, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x04, 0x02, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x74, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x06, 0x02, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x07, 0x02, 0x07); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x08, 0x02, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x09, 0x02, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x77, 0x02, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x75, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0c, 0x02, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0d, 0x02, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0e, 0x02, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0f, 0x02, 0x0f); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7c, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7d, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7d, 0x02, 0x11); + /* Slot 1 function 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 4, 0x04, 0x03, 0x00); + /* Slot 2 function 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 4, 0x0c, 0x03, 0x01); + /* Slot 3 function 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_6300, 0x20, 0x02, 0x14); + /* Slot 4 function 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_6300, 0x08, 0x02, 0x15); + /* On board NIC */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_6300, 0x0c, 0x02, 0x16); + + /* Standard local interrupt assignments */ +// smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, +// bus_isa, 0x00, MP_APIC_ALL, 0x00); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 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) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} + diff --git a/src/mainboard/supermicro/x6dai_g/reset.c b/src/mainboard/supermicro/x6dai_g/reset.c new file mode 100644 index 0000000000..1d7f5a3301 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/reset.c @@ -0,0 +1,40 @@ +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#ifndef __ROMCC__ +#include <device/device.h> +#define PCI_ID(VENDOR_ID, DEVICE_ID) \ + ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF)) +#define PCI_DEV_INVALID 0 + +static inline device_t pci_locate_device(unsigned pci_id, device_t from) +{ + return dev_find_device(pci_id >> 16, pci_id & 0xffff, from); +} +#endif + +void soft_reset(void) +{ + outb(0x04, 0xcf9); +} +void hard_reset(void) +{ + outb(0x02, 0xcf9); + outb(0x06, 0xcf9); +} +void full_reset(void) +{ + device_t dev; + /* Enable power on after power fail... */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_6300ESB_ISA), 0); + if (dev != PCI_DEV_INVALID) { + unsigned byte; + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + pci_write_config8(dev, 0xa4, byte); + + } + outb(0x0e, 0xcf9); +} + + diff --git a/src/mainboard/supermicro/x6dai_g/watchdog.c b/src/mainboard/supermicro/x6dai_g/watchdog.c new file mode 100644 index 0000000000..465ba4c7b3 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/watchdog.c @@ -0,0 +1,42 @@ +#include <device/pnp_def.h> + +#define NSC_WD_DEV PNP_DEV(0x2e, 0xa) +#define NSC_WDBASE 0x600 +#define ICH5_WDBASE 0x400 +#define ICH5_GPIOBASE 0x500 + +static void disable_esb6300_watchdog(void) +{ + /* FIXME move me somewhere more appropriate */ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing 6300ESB?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + + /* Set and enable acpibase */ + pci_write_config32(dev, 0x40, ICH5_WDBASE | 1); + pci_write_config8(dev, 0x44, 0x10); + base = ICH5_WDBASE + 0x60; + + /* Set bit 11 in TCO1_CNT */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); +} + +static void disable_watchdogs(void) +{ + disable_esb6300_watchdog(); + print_debug("Watchdogs disabled\r\n"); +} + |