diff options
author | Stefan Reinauer <stepan@coresystems.de> | 2010-02-08 12:20:50 +0000 |
---|---|---|
committer | Stefan Reinauer <stepan@openbios.org> | 2010-02-08 12:20:50 +0000 |
commit | 38f147ed3d9fdd6bfb23d7226f6fdd3fc5db53d0 (patch) | |
tree | ecb680abac7c73798a4abf5f5733c6ad3e179bb4 /src/mainboard/dell/s1850/romstage.c | |
parent | d51eddbb6611965165ad72eb3fb04377a51ab64a (diff) |
janitor task: unify and cleanup naming.
cache_as_ram_auto.c and auto.c are both called "romstage.c" now.
Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Acked-by: Patrick Georgi <patrick.georgi@coresystems.de>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5092 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/mainboard/dell/s1850/romstage.c')
-rw-r--r-- | src/mainboard/dell/s1850/romstage.c | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/src/mainboard/dell/s1850/romstage.c b/src/mainboard/dell/s1850/romstage.c new file mode 100644 index 0000000000..5f62ce80a8 --- /dev/null +++ b/src/mainboard/dell/s1850/romstage.c @@ -0,0 +1,372 @@ +#define ASSEMBLY 1 +#define __PRE_RAM__ +#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 <stdlib.h> +#include "option_table.h" +#include "pc80/mc146818rtc_early.c" +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "lib/ramtest.c" +#include "southbridge/intel/i82801er/i82801er_early_smbus.c" +#include "northbridge/intel/e7520/raminit.h" +#include "superio/nsc/pc8374/pc8374_early_init.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "debug.c" +#include "watchdog.c" +#include "reset.c" +#include "s1850_fixups.c" +#include "northbridge/intel/e7520/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, PC8374_SP1) + +#define DEVPRES_CONFIG ( \ + DEVPRES_D0F0 | \ + 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); +} + +/* this is very highly mainboard dependent, related to wiring */ +/* from factory BIOS via lspci */ +#define DIMM_MAP_LOGICAL 0x2841 +#include "northbridge/intel/e7520/raminit.c" +#include "lib/generic_sdram.c" + + +/* IPMI garbage. This is all test stuff, if it really works we'll move it somewhere + */ + +#define nftransport 0xc + +#define OBF 0 +#define IBF 1 + +#define ipmidata 0xca0 +#define ipmicsr 0xca4 + + +static inline void ibfzero(void) +{ + while(inb(ipmicsr) & (1<<IBF)) + ; +} +static inline void clearobf(void) +{ + (void) inb(ipmidata); +} + +static inline void waitobf(void) +{ + while((inb(ipmicsr) & (1<<OBF)) == 0) + ; +} +/* quite possibly the stupidest interface ever designed. */ +static inline void first_cmd_byte(unsigned char byte) +{ + ibfzero(); + clearobf(); + outb(0x61, ipmicsr); + ibfzero(); + clearobf(); + outb(byte, ipmidata); +} + +static inline void next_cmd_byte(unsigned char byte) +{ + + ibfzero(); + clearobf(); + outb(byte, ipmidata); +} + +static inline void last_cmd_byte(unsigned char byte) +{ + outb(0x62, ipmicsr); + + ibfzero(); + clearobf(); + outb(byte, ipmidata); +} + +static inline void read_response_byte(void) +{ + int val = -1; + if ((inb(ipmicsr)>>6) != 1) + return; + + ibfzero(); + waitobf(); + val = inb(ipmidata); + outb(0x68, ipmidata); + + /* see if it is done */ + if ((inb(ipmicsr)>>6) != 1){ + /* wait for the dummy read. Which describes this protocol */ + waitobf(); + (void)inb(ipmidata); + } +} + +static inline void ipmidelay(void) +{ + int i; + for(i = 0; i < 1000; i++) { + inb(0x80); + } +} + +static inline void bmc_foad(void) +{ + unsigned char c; + /* be safe; make sure it is really ready */ + while ((inb(ipmicsr)>>6)) { + outb(0x60, ipmicsr); + inb(ipmidata); + } + first_cmd_byte(nftransport << 2); + ipmidelay(); + next_cmd_byte(0x12); + ipmidelay(); + next_cmd_byte(2); + ipmidelay(); + last_cmd_byte(3); + ipmidelay(); +} + +/* end IPMI garbage */ + +static void main(unsigned long bist) +{ + u8 b; + u16 w; + u32 l; + int do_reset; + /* + * + * + */ + 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), + /* the wiring on this part is really messed up */ + /* this is my best guess so far */ + .channel0 = {(0xa<<3)|0, (0xa<<3)|1, (0xa<<3)|2, (0xa<<3)|3, }, + .channel1 = {(0xa<<3)|4, (0xa<<3)|5, (0xa<<3)|6, (0xa<<3)|7, }, + } + }; + + /* superio setup */ + /* observed from serialice */ + static const u8 earlyinit[] = { + 0x21, 0x11, 0x11, + 0x22, 1, 1, + 0x23, 05, 05, + 0x24, 0x81, 0x81, + 0x26, 0, 0, + 0, + }; + + /* using SerialICE, we've seen this basic reset sequence on the dell. + * we don't understand it as it uses undocumented registers, but + * we're going to clone it. + */ + /* enable a hidden device. */ + b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4); + b |= 0x8; + pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b); + + /* read-write lock in CMOS on LPC bridge on ICH5 */ + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd8, 4); + + /* operate on undocumented device */ + l = pci_read_config32(PCI_DEV(0, 0, 2), 0xa4); + l |= 0x1000; + pci_write_config32(PCI_DEV(0, 0, 2), 0xa4, l); + + l = pci_read_config32(PCI_DEV(0, 0, 2), 0x9c); + l |= 0x8000; + pci_write_config32(PCI_DEV(0, 0, 2), 0x9c, l); + + /* disable undocumented device */ + b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4); + b &= ~0x8; + pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b); + + /* set up LPC bridge bits, some of which reply on undocumented + * registers + */ + + b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xd8); + b |= 4; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd8, b); + + b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xd4); + b |= 2; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd4, b); + + /* ACPI base address */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x40, 0x800); + + /* Enable specific ACPI features */ + b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0x44); + b |= 0x10; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x44, b); + + /* ACPI control */ + w = inw(0x868); + outw(w|0x800, 0x868); + w = inw(0x866); + outw(w|2, 0x866); + +#if 0 + /*seriaice shows + dell does this so leave it here so I don't forget + */ + /* SMBUS */ + pci_write_config16(PCI_DEV(0, 0x1f, 3), 0x20, 0x08c0); + + /* unknown */ + b = inb(0x8c2); + outb(0xdf, 0x8c2); +#endif + + /* another device enable? */ + b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4); + b |= 2; + pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b); + + /* ?? */ + l = pci_read_config32(PCI_DEV(0, 8, 0), 0xc0); + do_reset = l & 0x8000000; + l |= 0x8000000; + pci_write_config32(PCI_DEV(0, 8, 0), 0xc0, l); + + if (! do_reset) { + outb(2, 0xcf9); + outb(6, 0xcf9); + } + 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 */ + mainboard_set_ich5(); + //bmc_foad(); + pc8374_enable_dev(CONSOLE_SERIAL_DEV, CONFIG_TTYS0_BASE); + uart_init(); + console_init(); + + + /* stuff we seem to need */ + pc8374_enable_dev(PNP_DEV(0x2e, PC8374_KBCK), 0); + + /* GPIOs */ + pc8374_enable_dev(PNP_DEV(0x2e, PC8374_GPIO), 0xc20); + + /* keep this in mind. + SerialICE-hlp: outb 002e <= 23 + SerialICE-hlp: inb 002f => 05 + SerialICE-hlp: outb 002f <= 05 + SerialICE-hlp: outb 002e <= 24 + SerialICE-hlp: inb 002f => c1 + SerialICE-hlp: outb 002f <= c1 + */ + + /* Halt if there was a built in self test failure */ +// report_bist_failure(bist); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + display_cpuid_update_microcode(); +#endif +#if 1 + print_pci_devices(); +#endif +#if 1 + enable_smbus(); +#endif +#if 0 +// dump_spd_registers(&cpu[0]); + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif +#if 1 + show_dram_slots(); +#endif + disable_watchdogs(); +// dump_ipmi_registers(); + mainboard_set_e7520_leds(); +// memreset_setup(); + + sdram_initialize(ARRAY_SIZE(mch), mch); +#if 0 + dump_pci_devices(); +#endif +#if 1 + dump_pci_device(PCI_DEV(0, 0x00, 0)); +// dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 1 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); +// ram_check(0x00100000, 0x01000000); + ram_check(0x00100000, 0x00100100); + /* 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 +} |