properly. And a few long standing bugs have been rooted out and removed. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@931 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
		
			
				
	
	
		
			1393 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1393 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| typedef unsigned char uint8_t;
 | |
| typedef signed char int8_t;
 | |
| 
 | |
| typedef unsigned short uint16_t;
 | |
| typedef signed short int16_t;
 | |
| 
 | |
| typedef unsigned int uint32_t;
 | |
| typedef signed int int32_t;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| typedef unsigned char uint_least8_t;
 | |
| typedef signed char int_least8_t;
 | |
| 
 | |
| typedef unsigned short uint_least16_t;
 | |
| typedef signed short int_least16_t;
 | |
| 
 | |
| typedef unsigned int uint_least32_t;
 | |
| typedef signed int int_least32_t;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| typedef unsigned char uint_fast8_t;
 | |
| typedef signed char int_fast8_t;
 | |
| 
 | |
| typedef unsigned int uint_fast16_t;
 | |
| typedef signed int int_fast16_t;
 | |
| 
 | |
| typedef unsigned int uint_fast32_t;
 | |
| typedef signed int int_fast32_t;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| typedef int intptr_t;
 | |
| typedef unsigned int uintptr_t;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| typedef long int intmax_t;
 | |
| typedef unsigned long int uintmax_t;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static void outb(unsigned char value, unsigned short port)
 | |
| {
 | |
|         __builtin_outb(value, port);
 | |
| }
 | |
| 
 | |
| static void outw(unsigned short value, unsigned short port)
 | |
| {
 | |
|         __builtin_outw(value, port);
 | |
| }
 | |
| 
 | |
| static void outl(unsigned int value, unsigned short port)
 | |
| {
 | |
|         __builtin_outl(value, port);
 | |
| }
 | |
| 
 | |
| 
 | |
| static unsigned char inb(unsigned short port)
 | |
| {
 | |
|         return __builtin_inb(port);
 | |
| }
 | |
| 
 | |
| 
 | |
| static unsigned char inw(unsigned short port)
 | |
| {
 | |
|         return __builtin_inw(port);
 | |
| }
 | |
| 
 | |
| static unsigned char inl(unsigned short port)
 | |
| {
 | |
|         return __builtin_inl(port);
 | |
| }
 | |
| 
 | |
| static void hlt(void)
 | |
| {
 | |
|         __builtin_hlt();
 | |
| }
 | |
| 
 | |
| int log2(int value)
 | |
| {
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         return __builtin_bsr(value);
 | |
| }
 | |
| 
 | |
| 
 | |
| typedef __builtin_msr_t msr_t;
 | |
| 
 | |
| static msr_t rdmsr(unsigned long index)
 | |
| {
 | |
|         return __builtin_rdmsr(index);
 | |
| }
 | |
| 
 | |
| static void wrmsr(unsigned long index, msr_t msr)
 | |
| {
 | |
|         __builtin_wrmsr(index, msr.lo, msr.hi);
 | |
| }
 | |
| 
 | |
| typedef unsigned device_t;
 | |
| 
 | |
| static unsigned char pci_read_config8(device_t dev, unsigned where)
 | |
| {
 | |
|         unsigned addr;
 | |
|         addr = dev | where;
 | |
|         outl(0x80000000 | (addr & ~3), 0xCF8);
 | |
|         return inb(0xCFC + (addr & 3));
 | |
| }
 | |
| 
 | |
| static unsigned short pci_read_config16(device_t dev, unsigned where)
 | |
| {
 | |
|         unsigned addr;
 | |
|         addr = dev | where;
 | |
|         outl(0x80000000 | (addr & ~3), 0xCF8);
 | |
|         return inw(0xCFC + (addr & 2));
 | |
| }
 | |
| 
 | |
| static unsigned int pci_read_config32(device_t dev, unsigned where)
 | |
| {
 | |
|         unsigned addr;
 | |
|         addr = dev | where;
 | |
|         outl(0x80000000 | (addr & ~3), 0xCF8);
 | |
|         return inl(0xCFC);
 | |
| }
 | |
| 
 | |
| static void pci_write_config8(device_t dev, unsigned where, unsigned char value)
 | |
| {
 | |
|         unsigned addr;
 | |
|         addr = dev | where;
 | |
|         outl(0x80000000 | (addr & ~3), 0xCF8);
 | |
|         outb(value, 0xCFC + (addr & 3));
 | |
| }
 | |
| 
 | |
| static void pci_write_config16(device_t dev, unsigned where, unsigned short value)
 | |
| {
 | |
|         unsigned addr;
 | |
|         addr = dev | where;
 | |
|         outl(0x80000000 | (addr & ~3), 0xCF8);
 | |
|         outw(value, 0xCFC + (addr & 2));
 | |
| }
 | |
| 
 | |
| static void pci_write_config32(device_t dev, unsigned where, unsigned int value)
 | |
| {
 | |
|         unsigned addr;
 | |
|         addr = dev | where;
 | |
|         outl(0x80000000 | (addr & ~3), 0xCF8);
 | |
|         outl(value, 0xCFC);
 | |
| }
 | |
| 
 | |
| 
 | |
| static device_t pci_locate_device(unsigned pci_id, device_t dev)
 | |
| {
 | |
|         for(; dev <= ( (((255) & 0xFF) << 16) | (((31) & 0x1f) << 11) | (((7) & 0x7) << 8)); dev += ( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((1) & 0x7) << 8))) {
 | |
|                 unsigned int id;
 | |
|                 id = pci_read_config32(dev, 0);
 | |
|                 if (id == pci_id) {
 | |
|                         return dev;
 | |
|                 }
 | |
|         }
 | |
|         return (0xffffffffU);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static int uart_can_tx_byte(void)
 | |
| {
 | |
|         return inb(0x3f8 + 0x05) & 0x20;
 | |
| }
 | |
| 
 | |
| static void uart_wait_to_tx_byte(void)
 | |
| {
 | |
|         while(!uart_can_tx_byte())
 | |
|                 ;
 | |
| }
 | |
| 
 | |
| static void uart_wait_until_sent(void)
 | |
| {
 | |
|         while(!(inb(0x3f8 + 0x05) & 0x40))
 | |
|                 ;
 | |
| }
 | |
| 
 | |
| static void uart_tx_byte(unsigned char data)
 | |
| {
 | |
|         uart_wait_to_tx_byte();
 | |
|         outb(data, 0x3f8 + 0x00);
 | |
| 
 | |
|         uart_wait_until_sent();
 | |
| }
 | |
| 
 | |
| static void uart_init(void)
 | |
| {
 | |
| 
 | |
|         outb(0x0, 0x3f8 + 0x01);
 | |
| 
 | |
|         outb(0x01, 0x3f8 + 0x02);
 | |
| 
 | |
|         outb(0x80 | 0x3, 0x3f8 + 0x03);
 | |
| 
 | |
|         outb((115200/115200) & 0xFF, 0x3f8 + 0x00);
 | |
|         outb(((115200/115200) >> 8) & 0xFF, 0x3f8 + 0x01);
 | |
| 
 | |
|         outb(0x3, 0x3f8 + 0x03);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static void __console_tx_byte(unsigned char byte)
 | |
| {
 | |
|         uart_tx_byte(byte);
 | |
| }
 | |
| 
 | |
| static void __console_tx_nibble(unsigned nibble)
 | |
| {
 | |
|         unsigned char digit;
 | |
|         digit = nibble + '0';
 | |
|         if (digit > '9') {
 | |
|                 digit += 39;
 | |
|         }
 | |
|         __console_tx_byte(digit);
 | |
| }
 | |
| 
 | |
| static void __console_tx_char(int loglevel, unsigned char byte)
 | |
| {
 | |
|         if (8 > loglevel) {
 | |
|                 uart_tx_byte(byte);
 | |
|         }
 | |
| }
 | |
| 
 | |
| static void __console_tx_hex8(int loglevel, unsigned char value)
 | |
| {
 | |
|         if (8 > loglevel) {
 | |
|                 __console_tx_nibble((value >> 4U) & 0x0fU);
 | |
|                 __console_tx_nibble(value & 0x0fU);
 | |
|         }
 | |
| }
 | |
| 
 | |
| static void __console_tx_hex16(int loglevel, unsigned short value)
 | |
| {
 | |
|         if (8 > loglevel) {
 | |
|                 __console_tx_nibble((value >> 12U) & 0x0fU);
 | |
|                 __console_tx_nibble((value >> 8U) & 0x0fU);
 | |
|                 __console_tx_nibble((value >> 4U) & 0x0fU);
 | |
|                 __console_tx_nibble(value & 0x0fU);
 | |
|         }
 | |
| }
 | |
| 
 | |
| static void __console_tx_hex32(int loglevel, unsigned int value)
 | |
| {
 | |
|         if (8 > loglevel) {
 | |
|                 __console_tx_nibble((value >> 28U) & 0x0fU);
 | |
|                 __console_tx_nibble((value >> 24U) & 0x0fU);
 | |
|                 __console_tx_nibble((value >> 20U) & 0x0fU);
 | |
|                 __console_tx_nibble((value >> 16U) & 0x0fU);
 | |
|                 __console_tx_nibble((value >> 12U) & 0x0fU);
 | |
|                 __console_tx_nibble((value >> 8U) & 0x0fU);
 | |
|                 __console_tx_nibble((value >> 4U) & 0x0fU);
 | |
|                 __console_tx_nibble(value & 0x0fU);
 | |
|         }
 | |
| }
 | |
| 
 | |
| static void __console_tx_string(int loglevel, const char *str)
 | |
| {
 | |
|         if (8 > loglevel) {
 | |
|                 unsigned char ch;
 | |
|                 while((ch = *str++) != '\0') {
 | |
|                         __console_tx_byte(ch);
 | |
|                 }
 | |
|         }
 | |
| }
 | |
| 
 | |
| static void print_emerg_char(unsigned char byte) { __console_tx_char(0, byte); }
 | |
| static void print_emerg_hex8(unsigned char value){ __console_tx_hex8(0, value); }
 | |
| static void print_emerg_hex16(unsigned short value){ __console_tx_hex16(0, value); }
 | |
| static void print_emerg_hex32(unsigned int value) { __console_tx_hex32(0, value); }
 | |
| static void print_emerg(const char *str) { __console_tx_string(0, str); }
 | |
| 
 | |
| static void print_alert_char(unsigned char byte) { __console_tx_char(1, byte); }
 | |
| static void print_alert_hex8(unsigned char value) { __console_tx_hex8(1, value); }
 | |
| static void print_alert_hex16(unsigned short value){ __console_tx_hex16(1, value); }
 | |
| static void print_alert_hex32(unsigned int value) { __console_tx_hex32(1, value); }
 | |
| static void print_alert(const char *str) { __console_tx_string(1, str); }
 | |
| 
 | |
| static void print_crit_char(unsigned char byte) { __console_tx_char(2, byte); }
 | |
| static void print_crit_hex8(unsigned char value) { __console_tx_hex8(2, value); }
 | |
| static void print_crit_hex16(unsigned short value){ __console_tx_hex16(2, value); }
 | |
| static void print_crit_hex32(unsigned int value) { __console_tx_hex32(2, value); }
 | |
| static void print_crit(const char *str) { __console_tx_string(2, str); }
 | |
| 
 | |
| static void print_err_char(unsigned char byte) { __console_tx_char(3, byte); }
 | |
| static void print_err_hex8(unsigned char value) { __console_tx_hex8(3, value); }
 | |
| static void print_err_hex16(unsigned short value){ __console_tx_hex16(3, value); }
 | |
| static void print_err_hex32(unsigned int value) { __console_tx_hex32(3, value); }
 | |
| static void print_err(const char *str) { __console_tx_string(3, str); }
 | |
| 
 | |
| static void print_warning_char(unsigned char byte) { __console_tx_char(4, byte); }
 | |
| static void print_warning_hex8(unsigned char value) { __console_tx_hex8(4, value); }
 | |
| static void print_warning_hex16(unsigned short value){ __console_tx_hex16(4, value); }
 | |
| static void print_warning_hex32(unsigned int value) { __console_tx_hex32(4, value); }
 | |
| static void print_warning(const char *str) { __console_tx_string(4, str); }
 | |
| 
 | |
| static void print_notice_char(unsigned char byte) { __console_tx_char(5, byte); }
 | |
| static void print_notice_hex8(unsigned char value) { __console_tx_hex8(5, value); }
 | |
| static void print_notice_hex16(unsigned short value){ __console_tx_hex16(5, value); }
 | |
| static void print_notice_hex32(unsigned int value) { __console_tx_hex32(5, value); }
 | |
| static void print_notice(const char *str) { __console_tx_string(5, str); }
 | |
| 
 | |
| static void print_info_char(unsigned char byte) { __console_tx_char(6, byte); }
 | |
| static void print_info_hex8(unsigned char value) { __console_tx_hex8(6, value); }
 | |
| static void print_info_hex16(unsigned short value){ __console_tx_hex16(6, value); }
 | |
| static void print_info_hex32(unsigned int value) { __console_tx_hex32(6, value); }
 | |
| static void print_info(const char *str) { __console_tx_string(6, str); }
 | |
| 
 | |
| static void print_debug_char(unsigned char byte) { __console_tx_char(7, byte); }
 | |
| static void print_debug_hex8(unsigned char value) { __console_tx_hex8(7, value); }
 | |
| static void print_debug_hex16(unsigned short value){ __console_tx_hex16(7, value); }
 | |
| static void print_debug_hex32(unsigned int value) { __console_tx_hex32(7, value); }
 | |
| static void print_debug(const char *str) { __console_tx_string(7, str); }
 | |
| 
 | |
| static void print_spew_char(unsigned char byte) { __console_tx_char(8, byte); }
 | |
| static void print_spew_hex8(unsigned char value) { __console_tx_hex8(8, value); }
 | |
| static void print_spew_hex16(unsigned short value){ __console_tx_hex16(8, value); }
 | |
| static void print_spew_hex32(unsigned int value) { __console_tx_hex32(8, value); }
 | |
| static void print_spew(const char *str) { __console_tx_string(8, str); }
 | |
| 
 | |
| static void console_init(void)
 | |
| {
 | |
|         static const char console_test[] =
 | |
|                 "\r\n\r\nLinuxBIOS-"
 | |
|                 "1.1.0"
 | |
|                 ".0Fallback"
 | |
|                 " "
 | |
|                 "Thu Jun 19 05:42:16 MDT 2003"
 | |
|                 " starting...\r\n";
 | |
|         print_info(console_test);
 | |
| }
 | |
| 
 | |
| 
 | |
| static void die(const char *str)
 | |
| {
 | |
|         print_emerg(str);
 | |
|         do {
 | |
|                 hlt();
 | |
|         } while(1);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static void write_phys(unsigned long addr, unsigned long value)
 | |
| {
 | |
| 
 | |
|         asm volatile(
 | |
|                 "movnti %1, (%0)"
 | |
|                 :
 | |
|                 : "r" (addr), "r" (value)
 | |
|                 :
 | |
|                 );
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| static unsigned long read_phys(unsigned long addr)
 | |
| {
 | |
|         volatile unsigned long *ptr;
 | |
|         ptr = (void *)addr;
 | |
|         return *ptr;
 | |
| }
 | |
| 
 | |
| static void ram_fill(unsigned long start, unsigned long stop)
 | |
| {
 | |
|         unsigned long addr;
 | |
| 
 | |
| 
 | |
| 
 | |
|         print_debug("DRAM fill: ");
 | |
|         print_debug_hex32(start);
 | |
|         print_debug("-");
 | |
|         print_debug_hex32(stop);
 | |
|         print_debug("\r\n");
 | |
|         for(addr = start; addr < stop ; addr += 4) {
 | |
| 
 | |
|                 if (!(addr & 0xffff)) {
 | |
|                         print_debug_hex32(addr);
 | |
|                         print_debug("\r");
 | |
|                 }
 | |
|                 write_phys(addr, addr);
 | |
|         };
 | |
| 
 | |
|         print_debug_hex32(addr);
 | |
|         print_debug("\r\nDRAM filled\r\n");
 | |
| }
 | |
| 
 | |
| static void ram_verify(unsigned long start, unsigned long stop)
 | |
| {
 | |
|         unsigned long addr;
 | |
| 
 | |
| 
 | |
| 
 | |
|         print_debug("DRAM verify: ");
 | |
|         print_debug_hex32(start);
 | |
|         print_debug_char('-');
 | |
|         print_debug_hex32(stop);
 | |
|         print_debug("\r\n");
 | |
|         for(addr = start; addr < stop ; addr += 4) {
 | |
|                 unsigned long value;
 | |
| 
 | |
|                 if (!(addr & 0xffff)) {
 | |
|                         print_debug_hex32(addr);
 | |
|                         print_debug("\r");
 | |
|                 }
 | |
|                 value = read_phys(addr);
 | |
|                 if (value != addr) {
 | |
| 
 | |
|                         print_err_hex32(addr);
 | |
|                         print_err_char(':');
 | |
|                         print_err_hex32(value);
 | |
|                         print_err("\r\n");
 | |
|                 }
 | |
|         }
 | |
| 
 | |
|         print_debug_hex32(addr);
 | |
|         print_debug("\r\nDRAM verified\r\n");
 | |
| }
 | |
| 
 | |
| 
 | |
| void ram_check(unsigned long start, unsigned long stop)
 | |
| {
 | |
|         int result;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         print_debug("Testing DRAM : ");
 | |
|         print_debug_hex32(start);
 | |
|         print_debug("-");
 | |
|         print_debug_hex32(stop);
 | |
|         print_debug("\r\n");
 | |
|         ram_fill(start, stop);
 | |
|         ram_verify(start, stop);
 | |
|         print_debug("Done.\n");
 | |
| }
 | |
| 
 | |
| 
 | |
| static void enumerate_ht_chain(void)
 | |
| {
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         unsigned next_unitid, last_unitid;;
 | |
|         next_unitid = 1;
 | |
|         do {
 | |
|                 uint32_t id;
 | |
|                 uint8_t hdr_type, pos;
 | |
|                 last_unitid = next_unitid;
 | |
| 
 | |
|                 id = pci_read_config32(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), 0x00);
 | |
| 
 | |
|                 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
 | |
|                         (((id >> 16) & 0xffff) == 0xffff) ||
 | |
|                         (((id >> 16) & 0xffff) == 0x0000)) {
 | |
|                         break;
 | |
|                 }
 | |
|                 hdr_type = pci_read_config8(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), 0x0e);
 | |
|                 pos = 0;
 | |
|                 hdr_type &= 0x7f;
 | |
| 
 | |
|                 if ((hdr_type == 0) ||
 | |
|                         (hdr_type == 1)) {
 | |
|                         pos = pci_read_config8(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), 0x34);
 | |
|                 }
 | |
|                 while(pos != 0) {
 | |
|                         uint8_t cap;
 | |
|                         cap = pci_read_config8(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), pos + 0);
 | |
|                         if (cap == 0x08) {
 | |
|                                 uint16_t flags;
 | |
|                                 flags = pci_read_config16(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), pos + 2);
 | |
|                                 if ((flags >> 13) == 0) {
 | |
|                                         unsigned count;
 | |
|                                         flags &= ~0x1f;
 | |
|                                         flags |= next_unitid & 0x1f;
 | |
|                                         count = (flags >> 5) & 0x1f;
 | |
|                                         pci_write_config16(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), pos + 2, flags);
 | |
|                                         next_unitid += count;
 | |
|                                         break;
 | |
|                                 }
 | |
|                         }
 | |
|                         pos = pci_read_config8(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), pos + 1);
 | |
|                 }
 | |
|         } while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| static void enable_smbus(void)
 | |
| {
 | |
|         device_t dev;
 | |
|         dev = pci_locate_device(((((0x746b) & 0xFFFF) << 16) | ((0x1022) & 0xFFFF)), 0);
 | |
|         if (dev == (0xffffffffU)) {
 | |
|                 die("SMBUS controller not found\r\n");
 | |
|         }
 | |
|         uint8_t enable;
 | |
|         print_debug("SMBus controller enabled\r\n");
 | |
|         pci_write_config32(dev, 0x58, 0x1000 | 1);
 | |
|         enable = pci_read_config8(dev, 0x41);
 | |
|         pci_write_config8(dev, 0x41, enable | (1 << 7));
 | |
| }
 | |
| 
 | |
| 
 | |
| static inline void smbus_delay(void)
 | |
| {
 | |
|         outb(0x80, 0x80);
 | |
| }
 | |
| 
 | |
| static int smbus_wait_until_ready(void)
 | |
| {
 | |
|         unsigned long loops;
 | |
|         loops = (100*1000*10);
 | |
|         do {
 | |
|                 unsigned short val;
 | |
|                 smbus_delay();
 | |
|                 val = inw(0x1000 + 0xe0);
 | |
|                 if ((val & 0x800) == 0) {
 | |
|                         break;
 | |
|                 }
 | |
|         } while(--loops);
 | |
|         return loops?0:-1;
 | |
| }
 | |
| 
 | |
| static int smbus_wait_until_done(void)
 | |
| {
 | |
|         unsigned long loops;
 | |
|         loops = (100*1000*10);
 | |
|         do {
 | |
|                 unsigned short val;
 | |
|                 smbus_delay();
 | |
| 
 | |
|                 val = inw(0x1000 + 0xe0);
 | |
|                 if (((val & 0x8) == 0) | ((val & 0x437) != 0)) {
 | |
|                         break;
 | |
|                 }
 | |
|         } while(--loops);
 | |
|         return loops?0:-1;
 | |
| }
 | |
| 
 | |
| static int smbus_read_byte(unsigned device, unsigned address)
 | |
| {
 | |
|         unsigned char global_control_register;
 | |
|         unsigned char global_status_register;
 | |
|         unsigned char byte;
 | |
| 
 | |
|         if (smbus_wait_until_ready() < 0) {
 | |
|                 return -1;
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
|         outw(inw(0x1000 + 0xe2) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), 0x1000 + 0xe2);
 | |
| 
 | |
|         outw(((device & 0x7f) << 1) | 1, 0x1000 + 0xe4);
 | |
| 
 | |
|         outb(address & 0xFF, 0x1000 + 0xe8);
 | |
| 
 | |
|         outw((inw(0x1000 + 0xe2) & ~7) | (0x2), 0x1000 + 0xe2);
 | |
| 
 | |
| 
 | |
| 
 | |
|         outw(inw(0x1000 + 0xe0), 0x1000 + 0xe0);
 | |
| 
 | |
| 
 | |
|         outw(0, 0x1000 + 0xe6);
 | |
| 
 | |
| 
 | |
|         outw((inw(0x1000 + 0xe2) | (1 << 3)), 0x1000 + 0xe2);
 | |
| 
 | |
| 
 | |
| 
 | |
|         if (smbus_wait_until_done() < 0) {
 | |
|                 return -1;
 | |
|         }
 | |
| 
 | |
|         global_status_register = inw(0x1000 + 0xe0);
 | |
| 
 | |
| 
 | |
|         byte = inw(0x1000 + 0xe6) & 0xff;
 | |
| 
 | |
|         if (global_status_register != (1 << 4)) {
 | |
|                 return -1;
 | |
|         }
 | |
|         return byte;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| static void setup_resource_map(const unsigned int *register_values, int max)
 | |
| {
 | |
|         int i;
 | |
|         print_debug("setting up resource map....\r\n");
 | |
|         for(i = 0; i < max; i += 3) {
 | |
|                 device_t dev;
 | |
|                 unsigned where;
 | |
|                 unsigned long reg;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|                 dev = register_values[i] & ~0xff;
 | |
|                 where = register_values[i] & 0xff;
 | |
|                 reg = pci_read_config32(dev, where);
 | |
|                 reg &= register_values[i+1];
 | |
|                 reg |= register_values[i+2];
 | |
|                 pci_write_config32(dev, where, reg);
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         }
 | |
|         print_debug("done.\r\n");
 | |
| }
 | |
| 
 | |
| static void setup_default_resource_map(void)
 | |
| {
 | |
|         static const unsigned int register_values[] = {
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x44) & 0xFF)), 0x0000f8f8, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x4C) & 0xFF)), 0x0000f8f8, 0x00000001,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x54) & 0xFF)), 0x0000f8f8, 0x00000002,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x0000f8f8, 0x00000003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x64) & 0xFF)), 0x0000f8f8, 0x00000004,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x6C) & 0xFF)), 0x0000f8f8, 0x00000005,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x74) & 0xFF)), 0x0000f8f8, 0x00000006,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x7C) & 0xFF)), 0x0000f8f8, 0x00000007,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x40) & 0xFF)), 0x0000f8fc, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x48) & 0xFF)), 0x0000f8fc, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x50) & 0xFF)), 0x0000f8fc, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x58) & 0xFF)), 0x0000f8fc, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x60) & 0xFF)), 0x0000f8fc, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x68) & 0xFF)), 0x0000f8fc, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x70) & 0xFF)), 0x0000f8fc, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x78) & 0xFF)), 0x0000f8fc, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x84) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x8C) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x94) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x9C) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA4) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xAC) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB4) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xBC) & 0xFF)), 0x00000048, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x80) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x88) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x90) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x98) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA0) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA8) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB0) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB8) & 0xFF)), 0x000000f0, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC4) & 0xFF)), 0xFE000FC8, 0x01fff000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xCC) & 0xFF)), 0xFE000FC8, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD4) & 0xFF)), 0xFE000FC8, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xDC) & 0xFF)), 0xFE000FC8, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC0) & 0xFF)), 0xFE000FCC, 0x00000003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC8) & 0xFF)), 0xFE000FCC, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD0) & 0xFF)), 0xFE000FCC, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD8) & 0xFF)), 0xFE000FCC, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE0) & 0xFF)), 0x0000FC88, 0xff000003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE4) & 0xFF)), 0x0000FC88, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE8) & 0xFF)), 0x0000FC88, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xEC) & 0xFF)), 0x0000FC88, 0x00000000,
 | |
|         };
 | |
|         int max;
 | |
|         max = sizeof(register_values)/sizeof(register_values[0]);
 | |
|         setup_resource_map(register_values, max);
 | |
| }
 | |
| 
 | |
| static void sdram_set_registers(void)
 | |
| {
 | |
|         static const unsigned int register_values[] = {
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x44) & 0xFF)), 0x0000f8f8, 0x003f0000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x4C) & 0xFF)), 0x0000f8f8, 0x00000001,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x54) & 0xFF)), 0x0000f8f8, 0x00000002,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x0000f8f8, 0x00000003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x64) & 0xFF)), 0x0000f8f8, 0x00000004,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x6C) & 0xFF)), 0x0000f8f8, 0x00000005,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x74) & 0xFF)), 0x0000f8f8, 0x00000006,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x7C) & 0xFF)), 0x0000f8f8, 0x00000007,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x40) & 0xFF)), 0x0000f8fc, 0x00000003,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x48) & 0xFF)), 0x0000f8fc, 0x00400000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x50) & 0xFF)), 0x0000f8fc, 0x00400000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x58) & 0xFF)), 0x0000f8fc, 0x00400000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x60) & 0xFF)), 0x0000f8fc, 0x00400000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x68) & 0xFF)), 0x0000f8fc, 0x00400000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x70) & 0xFF)), 0x0000f8fc, 0x00400000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x78) & 0xFF)), 0x0000f8fc, 0x00400000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x84) & 0xFF)), 0x00000048, 0x00e1ff00,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x8C) & 0xFF)), 0x00000048, 0x00dfff00,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x94) & 0xFF)), 0x00000048, 0x00e3ff00,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x9C) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA4) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xAC) & 0xFF)), 0x00000048, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB4) & 0xFF)), 0x00000048, 0x00000b00,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xBC) & 0xFF)), 0x00000048, 0x00fe0b00,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x80) & 0xFF)), 0x000000f0, 0x00e00003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x88) & 0xFF)), 0x000000f0, 0x00d80003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x90) & 0xFF)), 0x000000f0, 0x00e20003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x98) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA0) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA8) & 0xFF)), 0x000000f0, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB0) & 0xFF)), 0x000000f0, 0x00000a03,
 | |
| 
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB8) & 0xFF)), 0x000000f0, 0x00400003,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC4) & 0xFF)), 0xFE000FC8, 0x0000d000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xCC) & 0xFF)), 0xFE000FC8, 0x000ff000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD4) & 0xFF)), 0xFE000FC8, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xDC) & 0xFF)), 0xFE000FC8, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC0) & 0xFF)), 0xFE000FCC, 0x0000d003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC8) & 0xFF)), 0xFE000FCC, 0x00001013,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD0) & 0xFF)), 0xFE000FCC, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD8) & 0xFF)), 0xFE000FCC, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE0) & 0xFF)), 0x0000FC88, 0xff000003,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE4) & 0xFF)), 0x0000FC88, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE8) & 0xFF)), 0x0000FC88, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xEC) & 0xFF)), 0x0000FC88, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x40) & 0xFF)), 0x001f01fe, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x44) & 0xFF)), 0x001f01fe, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x48) & 0xFF)), 0x001f01fe, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x4C) & 0xFF)), 0x001f01fe, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x50) & 0xFF)), 0x001f01fe, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x54) & 0xFF)), 0x001f01fe, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x58) & 0xFF)), 0x001f01fe, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x001f01fe, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x60) & 0xFF)), 0xC01f01ff, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x64) & 0xFF)), 0xC01f01ff, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x68) & 0xFF)), 0xC01f01ff, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x6C) & 0xFF)), 0xC01f01ff, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x70) & 0xFF)), 0xC01f01ff, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x74) & 0xFF)), 0xC01f01ff, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x78) & 0xFF)), 0xC01f01ff, 0x00000000,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x7C) & 0xFF)), 0xC01f01ff, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x80) & 0xFF)), 0xffff8888, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x88) & 0xFF)), 0xe8088008, 0x03623125,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x8c) & 0xFF)), 0xff8fe08e, 0x00000930,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x90) & 0xFF)), 0xf0000000,
 | |
|         (4 << 25)|(0 << 24)|
 | |
|         (0 << 23)|(0 << 22)|(0 << 21)|(0 << 20)|
 | |
|         (1 << 19)|(1 << 18)|(0 << 17)|(0 << 16)|
 | |
|         (2 << 14)|(0 << 13)|(0 << 12)|
 | |
|         (0 << 11)|(0 << 10)|(0 << 9)|(0 << 8)|
 | |
|         (0 << 3) |(0 << 1) |(0 << 0),
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x94) & 0xFF)), 0xc180f0f0, 0x0e2b0a05,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x98) & 0xFF)), 0xfc00ffff, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((3) & 0x07) << 8) | ((0x58) & 0xFF)), 0xffe0e0e0, 0x00000000,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((3) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x0000003e, 0x00000000,
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((3) & 0x07) << 8) | ((0x60) & 0xFF)), 0xffffff00, 0x00000000,
 | |
|         };
 | |
|         int i;
 | |
|         int max;
 | |
|         print_debug("setting up CPU0 northbridge registers\r\n");
 | |
|         max = sizeof(register_values)/sizeof(register_values[0]);
 | |
|         for(i = 0; i < max; i += 3) {
 | |
|                 device_t dev;
 | |
|                 unsigned where;
 | |
|                 unsigned long reg;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|                 dev = register_values[i] & ~0xff;
 | |
|                 where = register_values[i] & 0xff;
 | |
|                 reg = pci_read_config32(dev, where);
 | |
|                 reg &= register_values[i+1];
 | |
|                 reg |= register_values[i+2];
 | |
|                 pci_write_config32(dev, where, reg);
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         }
 | |
|         print_debug("done.\r\n");
 | |
| }
 | |
| 
 | |
| 
 | |
| struct dimm_size {
 | |
|         unsigned long side1;
 | |
|         unsigned long side2;
 | |
| };
 | |
| static struct dimm_size spd_get_dimm_size(unsigned device)
 | |
| {
 | |
| 
 | |
|         struct dimm_size sz;
 | |
|         int value, low;
 | |
|         sz.side1 = 0;
 | |
|         sz.side2 = 0;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         value = smbus_read_byte(device, 3);
 | |
|         if (value < 0) return sz;
 | |
|         sz.side1 += value & 0xf;
 | |
| 
 | |
|         value = smbus_read_byte(device, 4);
 | |
|         if (value < 0) return sz;
 | |
|         sz.side1 += value & 0xf;
 | |
| 
 | |
|         value = smbus_read_byte(device, 17);
 | |
|         if (value < 0) return sz;
 | |
|         sz.side1 += log2(value & 0xff);
 | |
| 
 | |
| 
 | |
|         value = smbus_read_byte(device, 7);
 | |
|         if (value < 0) return sz;
 | |
|         value &= 0xff;
 | |
|         value <<= 8;
 | |
| 
 | |
|         low = smbus_read_byte(device, 6);
 | |
|         if (low < 0) return sz;
 | |
|         value = value | (low & 0xff);
 | |
|         sz.side1 += log2(value);
 | |
| 
 | |
| 
 | |
|         value = smbus_read_byte(device, 5);
 | |
|         if (value <= 1) return sz;
 | |
| 
 | |
| 
 | |
|         sz.side2 = sz.side1;
 | |
| 
 | |
|         value = smbus_read_byte(device, 3);
 | |
|         if (value < 0) return sz;
 | |
|         if ((value & 0xf0) == 0) return sz;
 | |
|         sz.side2 -= (value & 0x0f);
 | |
|         sz.side2 += ((value >> 4) & 0x0f);
 | |
| 
 | |
|         value = smbus_read_byte(device, 4);
 | |
|         if (value < 0) return sz;
 | |
|         sz.side2 -= (value & 0x0f);
 | |
|         sz.side2 += ((value >> 4) & 0x0f);
 | |
|         return sz;
 | |
| }
 | |
| 
 | |
| static unsigned spd_to_dimm(unsigned device)
 | |
| {
 | |
|         return (device - (0xa << 3));
 | |
| }
 | |
| 
 | |
| static void set_dimm_size(struct dimm_size sz, unsigned index)
 | |
| {
 | |
|         uint32_t base0, base1, map;
 | |
| 
 | |
| 
 | |
|         print_debug("set_dimm_size: (");
 | |
|         print_debug_hex32(sz.side1);
 | |
|         print_debug_char(',');
 | |
|         print_debug_hex32(sz.side2);
 | |
|         print_debug_char(',');
 | |
|         print_debug_hex32(index);
 | |
|         print_debug(")\r\n");
 | |
| 
 | |
|         if (sz.side1 != sz.side2) {
 | |
|                 sz.side2 = 0;
 | |
|         }
 | |
|         map = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x80);
 | |
|         map &= ~(0xf << (index + 4));
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         base0 = base1 = 0;
 | |
| 
 | |
| 
 | |
|         if (sz.side1 >= (25 + 3)) {
 | |
|                 base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1;
 | |
|                 map |= (sz.side1 - (25 + 3)) << (index *4);
 | |
|         }
 | |
| 
 | |
| 
 | |
|         if (sz.side2 >= (25 + 3)) {
 | |
|                 base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x40 + (((index << 1)+0)<<2), base0);
 | |
|         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x40 + (((index << 1)+1)<<2), base1);
 | |
|         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x80, map);
 | |
| }
 | |
| 
 | |
| static void spd_set_ram_size(void)
 | |
| {
 | |
|         unsigned device;
 | |
|         for(device = (0xa << 3);
 | |
|                 device <= ((0xa << 3) +1);
 | |
|                 device += 1)
 | |
|         {
 | |
|                 struct dimm_size sz;
 | |
|                 sz = spd_get_dimm_size(device);
 | |
|                 set_dimm_size(sz, spd_to_dimm(device));
 | |
|         }
 | |
| }
 | |
| 
 | |
| static void set_top_mem(unsigned tom_k)
 | |
| {
 | |
| 
 | |
|         if (!tom_k) {
 | |
|                 die("No memory");
 | |
|         }
 | |
| 
 | |
|         msr_t msr;
 | |
|         msr.lo = (tom_k & 0x003fffff) << 10;
 | |
|         msr.hi = (tom_k & 0xffc00000) >> 22;
 | |
|         wrmsr(0xC001001A, msr);
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| static void order_dimms(void)
 | |
| {
 | |
|         unsigned long tom;
 | |
|         unsigned mask;
 | |
|         unsigned index;
 | |
| 
 | |
| 
 | |
|         tom = 0;
 | |
|         for(;;) {
 | |
| 
 | |
|                 unsigned canidate;
 | |
|                 uint32_t csbase, csmask;
 | |
|                 unsigned size;
 | |
|                 csbase = 0;
 | |
|                 canidate = 0;
 | |
|                 for(index = 0; index < 8; index++) {
 | |
|                         uint32_t value;
 | |
|                         value = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x40 + (index << 2));
 | |
| 
 | |
| 
 | |
|                         if (!(value & 1)) {
 | |
|                                 continue;
 | |
|                         }
 | |
| 
 | |
| 
 | |
|                         if (value <= csbase) {
 | |
|                                 continue;
 | |
|                         }
 | |
| 
 | |
| 
 | |
|                         if (tom & (1 << (index + 24))) {
 | |
|                                 continue;
 | |
|                         }
 | |
| 
 | |
|                         csbase = value;
 | |
|                         canidate = index;
 | |
|                 }
 | |
| 
 | |
|                 if (csbase == 0) {
 | |
|                         break;
 | |
|                 }
 | |
| 
 | |
| 
 | |
|                 tom |= (1 << (canidate + 24));
 | |
| 
 | |
| 
 | |
|                 size = csbase >> 21;
 | |
| 
 | |
| 
 | |
|                 csbase = (tom << 21) | 1;
 | |
| 
 | |
| 
 | |
|                 tom += size;
 | |
| 
 | |
| 
 | |
|                 csmask = ((size -1) << 21);
 | |
|                 csmask |= 0xfe00;
 | |
| 
 | |
| 
 | |
|                 pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x40 + (canidate << 2), csbase);
 | |
| 
 | |
|                 pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x60 + (canidate << 2), csmask);
 | |
| 
 | |
|         }
 | |
|         set_top_mem((tom & ~0xff000000) << 15);
 | |
| }
 | |
| 
 | |
| static void spd_set_dram_timing(void)
 | |
| {
 | |
| 
 | |
| }
 | |
| 
 | |
| static void spd_set_ecc_mode(void)
 | |
| {
 | |
|         unsigned long dcl;
 | |
|         dcl = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90);
 | |
| 
 | |
|         dcl &= ~(1<<17);
 | |
|         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90, dcl);
 | |
| 
 | |
| }
 | |
| static void sdram_set_spd_registers(void)
 | |
| {
 | |
|         spd_set_ram_size();
 | |
|         spd_set_dram_timing();
 | |
|         spd_set_ecc_mode();
 | |
|         order_dimms();
 | |
| }
 | |
| 
 | |
| 
 | |
| static void sdram_enable(void)
 | |
| {
 | |
|         unsigned long dcl;
 | |
| 
 | |
| 
 | |
|         dcl = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90);
 | |
|         print_debug("dcl: ");
 | |
|         print_debug_hex32(dcl);
 | |
|         print_debug("\r\n");
 | |
|         dcl |= (1<<3);
 | |
|         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90, dcl);
 | |
|         dcl &= ~(1<<3);
 | |
|         dcl &= ~(1<<0);
 | |
|         dcl &= ~(1<<1);
 | |
|         dcl &= ~(1<<2);
 | |
|         dcl |= (1<<8);
 | |
|         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90, dcl);
 | |
| 
 | |
|         print_debug("Initializing memory: ");
 | |
|         int loops = 0;
 | |
|         do {
 | |
|                 dcl = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90);
 | |
|                 loops += 1;
 | |
|                 if ((loops & 1023) == 0) {
 | |
|                         print_debug(".");
 | |
|                 }
 | |
|         } while(((dcl & (1<<8)) != 0) && (loops < 300000));
 | |
|         if (loops >= 300000) {
 | |
|                 print_debug(" failed\r\n");
 | |
|         } else {
 | |
|                 print_debug(" done\r\n");
 | |
|         }
 | |
| 
 | |
| }
 | |
| 
 | |
| static void sdram_first_normal_reference(void) {}
 | |
| static void sdram_enable_refresh(void) {}
 | |
| static void sdram_special_finishup(void) {}
 | |
| 
 | |
| 
 | |
| static void setup_coherent_ht_domain(void)
 | |
| {
 | |
|         static const unsigned int register_values[] = {
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x40) & 0xFF)), 0xfff0f0f0, 0x00010101,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x44) & 0xFF)), 0xfff0f0f0, 0x00010101,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x48) & 0xFF)), 0xfff0f0f0, 0x00010101,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x4c) & 0xFF)), 0xfff0f0f0, 0x00010101,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x50) & 0xFF)), 0xfff0f0f0, 0x00010101,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x54) & 0xFF)), 0xfff0f0f0, 0x00010101,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x58) & 0xFF)), 0xfff0f0f0, 0x00010101,
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x5c) & 0xFF)), 0xfff0f0f0, 0x00010101,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x68) & 0xFF)), 0x00800000, 0x0f00840f,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x6C) & 0xFF)), 0xffffff8c, 0x00000000 | (1 << 6) |(1 << 5)| (1 << 4),
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x84) & 0xFF)), 0x00009c05, 0x11110020,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x88) & 0xFF)), 0xfffff0ff, 0x00000200,
 | |
| 
 | |
|         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x94) & 0xFF)), 0xff000000, 0x00ff0000,
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         };
 | |
|         int i;
 | |
|         int max;
 | |
|         print_debug("setting up coherent ht domain....\r\n");
 | |
|         max = sizeof(register_values)/sizeof(register_values[0]);
 | |
|         for(i = 0; i < max; i += 3) {
 | |
|                 device_t dev;
 | |
|                 unsigned where;
 | |
|                 unsigned long reg;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|                 dev = register_values[i] & ~0xff;
 | |
|                 where = register_values[i] & 0xff;
 | |
|                 reg = pci_read_config32(dev, where);
 | |
|                 reg &= register_values[i+1];
 | |
|                 reg |= register_values[i+2];
 | |
|                 pci_write_config32(dev, where, reg);
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         }
 | |
|         print_debug("done.\r\n");
 | |
| }
 | |
| 
 | |
| 
 | |
| void sdram_no_memory(void)
 | |
| {
 | |
|         print_err("No memory!!\r\n");
 | |
|         while(1) {
 | |
|                 hlt();
 | |
|         }
 | |
| }
 | |
| 
 | |
| 
 | |
| void sdram_initialize(void)
 | |
| {
 | |
|         print_debug("Ram1\r\n");
 | |
| 
 | |
|         sdram_set_registers();
 | |
| 
 | |
|         print_debug("Ram2\r\n");
 | |
| 
 | |
|         sdram_set_spd_registers();
 | |
| 
 | |
|         print_debug("Ram3\r\n");
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         sdram_enable();
 | |
| 
 | |
|         print_debug("Ram4\r\n");
 | |
|         sdram_first_normal_reference();
 | |
| 
 | |
|         print_debug("Ram5\r\n");
 | |
|         sdram_enable_refresh();
 | |
|         sdram_special_finishup();
 | |
| 
 | |
|         print_debug("Ram6\r\n");
 | |
| }
 | |
| 
 | |
| 
 | |
| static int boot_cpu(void)
 | |
| {
 | |
|         volatile unsigned long *local_apic;
 | |
|         unsigned long apic_id;
 | |
|         int bsp;
 | |
|         msr_t msr;
 | |
|         msr = rdmsr(0x1b);
 | |
|         bsp = !!(msr.lo & (1 << 8));
 | |
|         if (bsp) {
 | |
|                 print_debug("Bootstrap processor\r\n");
 | |
|         } else {
 | |
|                 print_debug("Application processor\r\n");
 | |
|         }
 | |
| 
 | |
|         return bsp;
 | |
| }
 | |
| 
 | |
| static int cpu_init_detected(void)
 | |
| {
 | |
|         unsigned long dcl;
 | |
|         int cpu_init;
 | |
| 
 | |
|         unsigned long htic;
 | |
| 
 | |
|         htic = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x7) << 8)), 0x6c);
 | |
| 
 | |
|         cpu_init = (htic & (1<<6));
 | |
|         if (cpu_init) {
 | |
|                 print_debug("CPU INIT Detected.\r\n");
 | |
|         }
 | |
|         return cpu_init;
 | |
| }
 | |
| 
 | |
| 
 | |
| 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 = ( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8));
 | |
|                 dev <= ( (((0) & 0xFF) << 16) | (((0x1f) & 0x1f) << 11) | (((0x7) & 0x7) << 8));
 | |
|                 dev += ( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((1) & 0x7) << 8))) {
 | |
|                 uint32_t id;
 | |
|                 id = pci_read_config32(dev, 0x00);
 | |
|                 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_spd_registers(void)
 | |
| {
 | |
|         unsigned device;
 | |
|         device = (0xa << 3);
 | |
|         print_debug("\r\n");
 | |
|         while(device <= ((0xa << 3) +1)) {
 | |
|                 int i;
 | |
|                 print_debug("dimm: ");
 | |
|                 print_debug_hex8(device);
 | |
|                 for(i = 0; i < 256; i++) {
 | |
|                         int status;
 | |
|                         unsigned char byte;
 | |
|                         if ((i & 0xf) == 0) {
 | |
|                                 print_debug("\r\n");
 | |
|                                 print_debug_hex8(i);
 | |
|                                 print_debug(": ");
 | |
|                         }
 | |
|                         status = smbus_read_byte(device, i);
 | |
|                         if (status < 0) {
 | |
|                                 print_debug("bad device\r\n");
 | |
|                                 break;
 | |
|                         }
 | |
|                         byte = status & 0xff;
 | |
|                         print_debug_hex8(byte);
 | |
|                         print_debug_char(' ');
 | |
|                 }
 | |
|                 device += 1;
 | |
|                 print_debug("\r\n");
 | |
|         }
 | |
| }
 | |
| 
 | |
| 
 | |
| static void main(void)
 | |
| {
 | |
|         uart_init();
 | |
|         console_init();
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         if (boot_cpu() && !cpu_init_detected()) {
 | |
|                 setup_default_resource_map();
 | |
|                 setup_coherent_ht_domain();
 | |
|                 enumerate_ht_chain();
 | |
|                 print_pci_devices();
 | |
|                 enable_smbus();
 | |
|                 sdram_initialize();
 | |
| 
 | |
|                 dump_spd_registers();
 | |
|                 dump_pci_device(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)));
 | |
| 
 | |
| 
 | |
|                 msr_t msr;
 | |
|                 msr = rdmsr(0xC001001A);
 | |
|                 print_debug("TOP_MEM: ");
 | |
|                 print_debug_hex32(msr.hi);
 | |
|                 print_debug_hex32(msr.lo);
 | |
|                 print_debug("\r\n");
 | |
|                 ram_check(0x00000000, msr.lo);
 | |
|         }
 | |
| }
 |