1typedef unsigned char uint8_t; 2typedef signed char int8_t; 3typedef unsigned short uint16_t; 4typedef signed short int16_t; 5typedef unsigned int uint32_t; 6typedef signed int int32_t; 7 8typedef unsigned char uint_least8_t; 9typedef signed char int_least8_t; 10typedef unsigned short uint_least16_t; 11typedef signed short int_least16_t; 12typedef unsigned int uint_least32_t; 13typedef signed int int_least32_t; 14 15typedef unsigned char uint_fast8_t; 16typedef signed char int_fast8_t; 17typedef unsigned int uint_fast16_t; 18typedef signed int int_fast16_t; 19typedef unsigned int uint_fast32_t; 20typedef signed int int_fast32_t; 21 22typedef int intptr_t; 23typedef unsigned int uintptr_t; 24 25typedef long int intmax_t; 26typedef unsigned long int uintmax_t; 27 28static inline unsigned long apic_read(unsigned long reg) 29{ 30 return *((volatile unsigned long *)(0xfee00000 +reg)); 31} 32static inline void apic_write(unsigned long reg, unsigned long v) 33{ 34 *((volatile unsigned long *)(0xfee00000 +reg)) = v; 35} 36static inline void apic_wait_icr_idle(void) 37{ 38 do { } while ( apic_read( 0x300 ) & 0x01000 ); 39} 40 41static void outb(unsigned char value, unsigned short port) 42{ 43 __builtin_outb(value, port); 44} 45static void outw(unsigned short value, unsigned short port) 46{ 47 __builtin_outw(value, port); 48} 49static void outl(unsigned int value, unsigned short port) 50{ 51 __builtin_outl(value, port); 52} 53static unsigned char inb(unsigned short port) 54{ 55 return __builtin_inb(port); 56} 57static unsigned char inw(unsigned short port) 58{ 59 return __builtin_inw(port); 60} 61static unsigned char inl(unsigned short port) 62{ 63 return __builtin_inl(port); 64} 65static inline void outsb(uint16_t port, const void *addr, unsigned long count) 66{ 67 __asm__ __volatile__ ( 68 "cld ; rep ; outsb " 69 : "=S" (addr), "=c" (count) 70 : "d"(port), "0"(addr), "1" (count) 71 ); 72} 73static inline void outsw(uint16_t port, const void *addr, unsigned long count) 74{ 75 __asm__ __volatile__ ( 76 "cld ; rep ; outsw " 77 : "=S" (addr), "=c" (count) 78 : "d"(port), "0"(addr), "1" (count) 79 ); 80} 81static inline void outsl(uint16_t port, const void *addr, unsigned long count) 82{ 83 __asm__ __volatile__ ( 84 "cld ; rep ; outsl " 85 : "=S" (addr), "=c" (count) 86 : "d"(port), "0"(addr), "1" (count) 87 ); 88} 89static inline void insb(uint16_t port, void *addr, unsigned long count) 90{ 91 __asm__ __volatile__ ( 92 "cld ; rep ; insb " 93 : "=D" (addr), "=c" (count) 94 : "d"(port), "0"(addr), "1" (count) 95 ); 96} 97static inline void insw(uint16_t port, void *addr, unsigned long count) 98{ 99 __asm__ __volatile__ ( 100 "cld ; rep ; insw " 101 : "=D" (addr), "=c" (count) 102 : "d"(port), "0"(addr), "1" (count) 103 ); 104} 105static inline void insl(uint16_t port, void *addr, unsigned long count) 106{ 107 __asm__ __volatile__ ( 108 "cld ; rep ; insl " 109 : "=D" (addr), "=c" (count) 110 : "d"(port), "0"(addr), "1" (count) 111 ); 112} 113static inline void pnp_write_config(unsigned char port, unsigned char value, unsigned char reg) 114{ 115 outb(reg, port); 116 outb(value, port +1); 117} 118static inline unsigned char pnp_read_config(unsigned char port, unsigned char reg) 119{ 120 outb(reg, port); 121 return inb(port +1); 122} 123static inline void pnp_set_logical_device(unsigned char port, int device) 124{ 125 pnp_write_config(port, device, 0x07); 126} 127static inline void pnp_set_enable(unsigned char port, int enable) 128{ 129 pnp_write_config(port, enable?0x1:0x0, 0x30); 130} 131static inline int pnp_read_enable(unsigned char port) 132{ 133 return !!pnp_read_config(port, 0x30); 134} 135static inline void pnp_set_iobase0(unsigned char port, unsigned iobase) 136{ 137 pnp_write_config(port, (iobase >> 8) & 0xff, 0x60); 138 pnp_write_config(port, iobase & 0xff, 0x61); 139} 140static inline void pnp_set_iobase1(unsigned char port, unsigned iobase) 141{ 142 pnp_write_config(port, (iobase >> 8) & 0xff, 0x62); 143 pnp_write_config(port, iobase & 0xff, 0x63); 144} 145static inline void pnp_set_irq0(unsigned char port, unsigned irq) 146{ 147 pnp_write_config(port, irq, 0x70); 148} 149static inline void pnp_set_irq1(unsigned char port, unsigned irq) 150{ 151 pnp_write_config(port, irq, 0x72); 152} 153static inline void pnp_set_drq(unsigned char port, unsigned drq) 154{ 155 pnp_write_config(port, drq & 0xff, 0x74); 156} 157static void hlt(void) 158{ 159 __builtin_hlt(); 160} 161typedef __builtin_div_t div_t; 162typedef __builtin_ldiv_t ldiv_t; 163typedef __builtin_udiv_t udiv_t; 164typedef __builtin_uldiv_t uldiv_t; 165static div_t div(int numer, int denom) 166{ 167 return __builtin_div(numer, denom); 168} 169static ldiv_t ldiv(long numer, long denom) 170{ 171 return __builtin_ldiv(numer, denom); 172} 173static udiv_t udiv(unsigned numer, unsigned denom) 174{ 175 return __builtin_udiv(numer, denom); 176} 177static uldiv_t uldiv(unsigned long numer, unsigned long denom) 178{ 179 return __builtin_uldiv(numer, denom); 180} 181int log2(int value) 182{ 183 184 return __builtin_bsr(value); 185} 186typedef unsigned device_t; 187static unsigned char pci_read_config8(device_t dev, unsigned where) 188{ 189 unsigned addr; 190 addr = dev | where; 191 outl(0x80000000 | (addr & ~3), 0xCF8); 192 return inb(0xCFC + (addr & 3)); 193} 194static unsigned short pci_read_config16(device_t dev, unsigned where) 195{ 196 unsigned addr; 197 addr = dev | where; 198 outl(0x80000000 | (addr & ~3), 0xCF8); 199 return inw(0xCFC + (addr & 2)); 200} 201static unsigned int pci_read_config32(device_t dev, unsigned where) 202{ 203 unsigned addr; 204 addr = dev | where; 205 outl(0x80000000 | (addr & ~3), 0xCF8); 206 return inl(0xCFC); 207} 208static void pci_write_config8(device_t dev, unsigned where, unsigned char value) 209{ 210 unsigned addr; 211 addr = dev | where; 212 outl(0x80000000 | (addr & ~3), 0xCF8); 213 outb(value, 0xCFC + (addr & 3)); 214} 215static void pci_write_config16(device_t dev, unsigned where, unsigned short value) 216{ 217 unsigned addr; 218 addr = dev | where; 219 outl(0x80000000 | (addr & ~3), 0xCF8); 220 outw(value, 0xCFC + (addr & 2)); 221} 222static void pci_write_config32(device_t dev, unsigned where, unsigned int value) 223{ 224 unsigned addr; 225 addr = dev | where; 226 outl(0x80000000 | (addr & ~3), 0xCF8); 227 outl(value, 0xCFC); 228} 229static device_t pci_locate_device(unsigned pci_id, device_t dev) 230{ 231 for(; dev <= ( ((( 255 ) & 0xFF) << 16) | ((( 31 ) & 0x1f) << 11) | ((( 7 ) & 0x7) << 8)) ; dev += ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ) { 232 unsigned int id; 233 id = pci_read_config32(dev, 0); 234 if (id == pci_id) { 235 return dev; 236 } 237 } 238 return (0xffffffffU) ; 239} 240 241 242 243 244 245static int uart_can_tx_byte(void) 246{ 247 return inb(1016 + 0x05 ) & 0x20; 248} 249static void uart_wait_to_tx_byte(void) 250{ 251 while(!uart_can_tx_byte()) 252 ; 253} 254static void uart_wait_until_sent(void) 255{ 256 while(!(inb(1016 + 0x05 ) & 0x40)) 257 ; 258} 259static void uart_tx_byte(unsigned char data) 260{ 261 uart_wait_to_tx_byte(); 262 outb(data, 1016 + 0x00 ); 263 264 uart_wait_until_sent(); 265} 266static void uart_init(void) 267{ 268 269 outb(0x0, 1016 + 0x01 ); 270 271 outb(0x01, 1016 + 0x02 ); 272 273 outb(0x80 | 3 , 1016 + 0x03 ); 274 outb((115200/ 115200 ) & 0xFF, 1016 + 0x00 ); 275 outb(((115200/ 115200 ) >> 8) & 0xFF, 1016 + 0x01 ); 276 outb(3 , 1016 + 0x03 ); 277} 278 279static void __console_tx_byte(unsigned char byte) 280{ 281 uart_tx_byte(byte); 282} 283static void __console_tx_nibble(unsigned nibble) 284{ 285 unsigned char digit; 286 digit = nibble + '0'; 287 if (digit > '9') { 288 digit += 39; 289 } 290 __console_tx_byte(digit); 291} 292static void __console_tx_char(int loglevel, unsigned char byte) 293{ 294 if (8 > loglevel) { 295 uart_tx_byte(byte); 296 } 297} 298static void __console_tx_hex8(int loglevel, unsigned char value) 299{ 300 if (8 > loglevel) { 301 __console_tx_nibble((value >> 4U) & 0x0fU); 302 __console_tx_nibble(value & 0x0fU); 303 } 304} 305static void __console_tx_hex16(int loglevel, unsigned short value) 306{ 307 if (8 > loglevel) { 308 __console_tx_nibble((value >> 12U) & 0x0fU); 309 __console_tx_nibble((value >> 8U) & 0x0fU); 310 __console_tx_nibble((value >> 4U) & 0x0fU); 311 __console_tx_nibble(value & 0x0fU); 312 } 313} 314static void __console_tx_hex32(int loglevel, unsigned int value) 315{ 316 if (8 > loglevel) { 317 __console_tx_nibble((value >> 28U) & 0x0fU); 318 __console_tx_nibble((value >> 24U) & 0x0fU); 319 __console_tx_nibble((value >> 20U) & 0x0fU); 320 __console_tx_nibble((value >> 16U) & 0x0fU); 321 __console_tx_nibble((value >> 12U) & 0x0fU); 322 __console_tx_nibble((value >> 8U) & 0x0fU); 323 __console_tx_nibble((value >> 4U) & 0x0fU); 324 __console_tx_nibble(value & 0x0fU); 325 } 326} 327static void __console_tx_string(int loglevel, const char *str) 328{ 329 if (8 > loglevel) { 330 unsigned char ch; 331 while((ch = *str++) != '\0') { 332 __console_tx_byte(ch); 333 } 334 } 335} 336static void print_emerg_char(unsigned char byte) { __console_tx_char(0 , byte); } 337static void print_emerg_hex8(unsigned char value){ __console_tx_hex8(0 , value); } 338static void print_emerg_hex16(unsigned short value){ __console_tx_hex16(0 , value); } 339static void print_emerg_hex32(unsigned int value) { __console_tx_hex32(0 , value); } 340static void print_emerg(const char *str) { __console_tx_string(0 , str); } 341static void print_alert_char(unsigned char byte) { __console_tx_char(1 , byte); } 342static void print_alert_hex8(unsigned char value) { __console_tx_hex8(1 , value); } 343static void print_alert_hex16(unsigned short value){ __console_tx_hex16(1 , value); } 344static void print_alert_hex32(unsigned int value) { __console_tx_hex32(1 , value); } 345static void print_alert(const char *str) { __console_tx_string(1 , str); } 346static void print_crit_char(unsigned char byte) { __console_tx_char(2 , byte); } 347static void print_crit_hex8(unsigned char value) { __console_tx_hex8(2 , value); } 348static void print_crit_hex16(unsigned short value){ __console_tx_hex16(2 , value); } 349static void print_crit_hex32(unsigned int value) { __console_tx_hex32(2 , value); } 350static void print_crit(const char *str) { __console_tx_string(2 , str); } 351static void print_err_char(unsigned char byte) { __console_tx_char(3 , byte); } 352static void print_err_hex8(unsigned char value) { __console_tx_hex8(3 , value); } 353static void print_err_hex16(unsigned short value){ __console_tx_hex16(3 , value); } 354static void print_err_hex32(unsigned int value) { __console_tx_hex32(3 , value); } 355static void print_err(const char *str) { __console_tx_string(3 , str); } 356static void print_warning_char(unsigned char byte) { __console_tx_char(4 , byte); } 357static void print_warning_hex8(unsigned char value) { __console_tx_hex8(4 , value); } 358static void print_warning_hex16(unsigned short value){ __console_tx_hex16(4 , value); } 359static void print_warning_hex32(unsigned int value) { __console_tx_hex32(4 , value); } 360static void print_warning(const char *str) { __console_tx_string(4 , str); } 361static void print_notice_char(unsigned char byte) { __console_tx_char(5 , byte); } 362static void print_notice_hex8(unsigned char value) { __console_tx_hex8(5 , value); } 363static void print_notice_hex16(unsigned short value){ __console_tx_hex16(5 , value); } 364static void print_notice_hex32(unsigned int value) { __console_tx_hex32(5 , value); } 365static void print_notice(const char *str) { __console_tx_string(5 , str); } 366static void print_info_char(unsigned char byte) { __console_tx_char(6 , byte); } 367static void print_info_hex8(unsigned char value) { __console_tx_hex8(6 , value); } 368static void print_info_hex16(unsigned short value){ __console_tx_hex16(6 , value); } 369static void print_info_hex32(unsigned int value) { __console_tx_hex32(6 , value); } 370static void print_info(const char *str) { __console_tx_string(6 , str); } 371static void print_debug_char(unsigned char byte) { __console_tx_char(7 , byte); } 372static void print_debug_hex8(unsigned char value) { __console_tx_hex8(7 , value); } 373static void print_debug_hex16(unsigned short value){ __console_tx_hex16(7 , value); } 374static void print_debug_hex32(unsigned int value) { __console_tx_hex32(7 , value); } 375static void print_debug(const char *str) { __console_tx_string(7 , str); } 376static void print_spew_char(unsigned char byte) { __console_tx_char(8 , byte); } 377static void print_spew_hex8(unsigned char value) { __console_tx_hex8(8 , value); } 378static void print_spew_hex16(unsigned short value){ __console_tx_hex16(8 , value); } 379static void print_spew_hex32(unsigned int value) { __console_tx_hex32(8 , value); } 380static void print_spew(const char *str) { __console_tx_string(8 , str); } 381static void console_init(void) 382{ 383 static const char console_test[] = 384 "\r\n\r\nLinuxBIOS-" 385 "1.1.4" 386 ".0Fallback" 387 " " 388 "Thu Oct 9 20:29:48 MDT 2003" 389 " starting...\r\n"; 390 print_info(console_test); 391} 392static void die(const char *str) 393{ 394 print_emerg(str); 395 do { 396 hlt(); 397 } while(1); 398} 399static void write_phys(unsigned long addr, unsigned long value) 400{ 401 asm volatile( 402 "movnti %1, (%0)" 403 : 404 : "r" (addr), "r" (value) 405 : 406 ); 407} 408static unsigned long read_phys(unsigned long addr) 409{ 410 volatile unsigned long *ptr; 411 ptr = (void *)addr; 412 return *ptr; 413} 414static void ram_fill(unsigned long start, unsigned long stop) 415{ 416 unsigned long addr; 417 418 print_debug("DRAM fill: "); 419 print_debug_hex32(start); 420 print_debug("-"); 421 print_debug_hex32(stop); 422 print_debug("\r\n"); 423 for(addr = start; addr < stop ; addr += 4) { 424 425 if (!(addr & 0xffff)) { 426 print_debug_hex32(addr); 427 print_debug("\r"); 428 } 429 write_phys(addr, addr); 430 }; 431 432 print_debug_hex32(addr); 433 print_debug("\r\nDRAM filled\r\n"); 434} 435static void ram_verify(unsigned long start, unsigned long stop) 436{ 437 unsigned long addr; 438 439 print_debug("DRAM verify: "); 440 print_debug_hex32(start); 441 print_debug_char('-'); 442 print_debug_hex32(stop); 443 print_debug("\r\n"); 444 for(addr = start; addr < stop ; addr += 4) { 445 unsigned long value; 446 447 if (!(addr & 0xffff)) { 448 print_debug_hex32(addr); 449 print_debug("\r"); 450 } 451 value = read_phys(addr); 452 if (value != addr) { 453 454 print_err_hex32(addr); 455 print_err_char(':'); 456 print_err_hex32(value); 457 print_err("\r\n"); 458 } 459 } 460 461 print_debug_hex32(addr); 462 print_debug("\r\nDRAM verified\r\n"); 463} 464void ram_check(unsigned long start, unsigned long stop) 465{ 466 int result; 467 468 print_debug("Testing DRAM : "); 469 print_debug_hex32(start); 470 print_debug("-"); 471 print_debug_hex32(stop); 472 print_debug("\r\n"); 473 ram_fill(start, stop); 474 ram_verify(start, stop); 475 print_debug("Done.\r\n"); 476} 477static int enumerate_ht_chain(unsigned link) 478{ 479 480 unsigned next_unitid, last_unitid; 481 int reset_needed = 0; 482 next_unitid = 1; 483 do { 484 uint32_t id; 485 uint8_t hdr_type, pos; 486 last_unitid = next_unitid; 487 id = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x00 ); 488 489 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || 490 (((id >> 16) & 0xffff) == 0xffff) || 491 (((id >> 16) & 0xffff) == 0x0000)) { 492 break; 493 } 494 hdr_type = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x0e ); 495 pos = 0; 496 hdr_type &= 0x7f; 497 if ((hdr_type == 0 ) || 498 (hdr_type == 1 )) { 499 pos = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x34 ); 500 } 501 while(pos != 0) { 502 uint8_t cap; 503 cap = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , pos + 0 ); 504 if (cap == 0x08 ) { 505 uint16_t flags; 506 flags = pci_read_config16(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , pos + 2 ); 507 if ((flags >> 13) == 0) { 508 unsigned count; 509 flags &= ~0x1f; 510 flags |= next_unitid & 0x1f; 511 count = (flags >> 5) & 0x1f; 512 pci_write_config16(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , pos + 2 , flags); 513 next_unitid += count; 514 break; 515 } 516 } 517 pos = pci_read_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , pos + 1 ); 518 } 519 } while((last_unitid != next_unitid) && (next_unitid <= 0x1f)); 520 return reset_needed; 521} 522static void enable_smbus(void) 523{ 524 device_t dev; 525 dev = pci_locate_device((((( 0x746b ) & 0xFFFF) << 16) | (( 0x1022 ) & 0xFFFF)) , 0); 526 if (dev == (0xffffffffU) ) { 527 die("SMBUS controller not found\r\n"); 528 } 529 uint8_t enable; 530 print_debug("SMBus controller enabled\r\n"); 531 pci_write_config32(dev, 0x58, 0x0f00 | 1); 532 enable = pci_read_config8(dev, 0x41); 533 pci_write_config8(dev, 0x41, enable | (1 << 7)); 534 535 outw(inw(0x0f00 + 0xe0 ), 0x0f00 + 0xe0 ); 536} 537static inline void smbus_delay(void) 538{ 539 outb(0x80, 0x80); 540} 541static int smbus_wait_until_ready(void) 542{ 543 unsigned long loops; 544 loops = (100*1000*10) ; 545 do { 546 unsigned short val; 547 smbus_delay(); 548 val = inw(0x0f00 + 0xe0 ); 549 if ((val & 0x800) == 0) { 550 break; 551 } 552 if(loops == ((100*1000*10) / 2)) { 553 outw(inw(0x0f00 + 0xe0 ), 554 0x0f00 + 0xe0 ); 555 } 556 } while(--loops); 557 return loops?0:-2; 558} 559static int smbus_wait_until_done(void) 560{ 561 unsigned long loops; 562 loops = (100*1000*10) ; 563 do { 564 unsigned short val; 565 smbus_delay(); 566 567 val = inw(0x0f00 + 0xe0 ); 568 if (((val & 0x8) == 0) | ((val & 0x437) != 0)) { 569 break; 570 } 571 } while(--loops); 572 return loops?0:-3; 573} 574static int smbus_read_byte(unsigned device, unsigned address) 575{ 576 unsigned char global_control_register; 577 unsigned char global_status_register; 578 unsigned char byte; 579 if (smbus_wait_until_ready() < 0) { 580 return -2; 581 } 582 583 584 585 outw(inw(0x0f00 + 0xe2 ) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), 0x0f00 + 0xe2 ); 586 587 outw(((device & 0x7f) << 1) | 1, 0x0f00 + 0xe4 ); 588 589 outb(address & 0xFF, 0x0f00 + 0xe8 ); 590 591 outw((inw(0x0f00 + 0xe2 ) & ~7) | (0x2), 0x0f00 + 0xe2 ); 592 593 594 outw(inw(0x0f00 + 0xe0 ), 0x0f00 + 0xe0 ); 595 596 outw(0, 0x0f00 + 0xe6 ); 597 598 outw((inw(0x0f00 + 0xe2 ) | (1 << 3)), 0x0f00 + 0xe2 ); 599 600 if (smbus_wait_until_done() < 0) { 601 return -3; 602 } 603 global_status_register = inw(0x0f00 + 0xe0 ); 604 605 byte = inw(0x0f00 + 0xe6 ) & 0xff; 606 if (global_status_register != (1 << 4)) { 607 return -1; 608 } 609 return byte; 610} 611static void smbus_write_byte(unsigned device, unsigned address, unsigned char val) 612{ 613 return; 614} 615struct mem_controller { 616 unsigned node_id; 617 device_t f0, f1, f2, f3; 618 uint8_t channel0[4]; 619 uint8_t channel1[4]; 620}; 621typedef __builtin_msr_t msr_t; 622static msr_t rdmsr(unsigned long index) 623{ 624 return __builtin_rdmsr(index); 625} 626static void wrmsr(unsigned long index, msr_t msr) 627{ 628 __builtin_wrmsr(index, msr.lo, msr.hi); 629} 630struct tsc_struct { 631 unsigned lo; 632 unsigned hi; 633}; 634typedef struct tsc_struct tsc_t; 635static tsc_t rdtsc(void) 636{ 637 tsc_t res; 638 asm ("rdtsc" 639 : "=a" (res.lo), "=d"(res.hi) 640 : 641 : 642 ); 643 return res; 644} 645void init_timer(void) 646{ 647 648 apic_write(0x320 , (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0)); 649 650 apic_write(0x3E0 , 0xB ); 651 652 apic_write(0x380 , 0xffffffff); 653} 654void udelay(unsigned usecs) 655{ 656 uint32_t start, value, ticks; 657 658 ticks = usecs * 200; 659 start = apic_read(0x390 ); 660 do { 661 value = apic_read(0x390 ); 662 } while((start - value) < ticks); 663 664} 665void mdelay(unsigned msecs) 666{ 667 unsigned i; 668 for(i = 0; i < msecs; i++) { 669 udelay(1000); 670 } 671} 672void delay(unsigned secs) 673{ 674 unsigned i; 675 for(i = 0; i < secs; i++) { 676 mdelay(1000); 677 } 678} 679int boot_cpu(void) 680{ 681 volatile unsigned long *local_apic; 682 unsigned long apic_id; 683 int bsp; 684 msr_t msr; 685 msr = rdmsr(0x1b); 686 bsp = !!(msr.lo & (1 << 8)); 687 return bsp; 688} 689static int cpu_init_detected(void) 690{ 691 unsigned long htic; 692 htic = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c ); 693 return !!(htic & (1<<6) ); 694} 695static int bios_reset_detected(void) 696{ 697 unsigned long htic; 698 htic = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c ); 699 return (htic & (1<<4) ) && !(htic & (1<<5) ); 700} 701static int cold_reset_detected(void) 702{ 703 unsigned long htic; 704 htic = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c ); 705 return !(htic & (1<<4) ); 706} 707static void distinguish_cpu_resets(unsigned node_id) 708{ 709 uint32_t htic; 710 device_t device; 711 device = ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 + node_id ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ; 712 htic = pci_read_config32(device, 0x6c ); 713 htic |= (1<<4) | (1<<5) | (1<<6) ; 714 pci_write_config32(device, 0x6c , htic); 715} 716static void set_bios_reset(void) 717{ 718 unsigned long htic; 719 htic = pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c ); 720 htic &= ~(1<<5) ; 721 pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) , 0x6c , htic); 722} 723static void print_debug_pci_dev(unsigned dev) 724{ 725 print_debug("PCI: "); 726 print_debug_hex8((dev >> 16) & 0xff); 727 print_debug_char(':'); 728 print_debug_hex8((dev >> 11) & 0x1f); 729 print_debug_char('.'); 730 print_debug_hex8((dev >> 8) & 7); 731} 732static void print_pci_devices(void) 733{ 734 device_t dev; 735 for(dev = ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ; 736 dev <= ( ((( 0 ) & 0xFF) << 16) | ((( 0x1f ) & 0x1f) << 11) | ((( 0x7 ) & 0x7) << 8)) ; 737 dev += ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ) { 738 uint32_t id; 739 id = pci_read_config32(dev, 0x00 ); 740 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || 741 (((id >> 16) & 0xffff) == 0xffff) || 742 (((id >> 16) & 0xffff) == 0x0000)) { 743 continue; 744 } 745 print_debug_pci_dev(dev); 746 print_debug("\r\n"); 747 } 748} 749static void dump_pci_device(unsigned dev) 750{ 751 int i; 752 print_debug_pci_dev(dev); 753 print_debug("\r\n"); 754 755 for(i = 0; i <= 255; i++) { 756 unsigned char val; 757 if ((i & 0x0f) == 0) { 758 print_debug_hex8(i); 759 print_debug_char(':'); 760 } 761 val = pci_read_config8(dev, i); 762 print_debug_char(' '); 763 print_debug_hex8(val); 764 if ((i & 0x0f) == 0x0f) { 765 print_debug("\r\n"); 766 } 767 } 768} 769static void dump_pci_devices(void) 770{ 771 device_t dev; 772 for(dev = ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ; 773 dev <= ( ((( 0 ) & 0xFF) << 16) | ((( 0x1f ) & 0x1f) << 11) | ((( 0x7 ) & 0x7) << 8)) ; 774 dev += ( ((( 0 ) & 0xFF) << 16) | ((( 0 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ) { 775 uint32_t id; 776 id = pci_read_config32(dev, 0x00 ); 777 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || 778 (((id >> 16) & 0xffff) == 0xffff) || 779 (((id >> 16) & 0xffff) == 0x0000)) { 780 continue; 781 } 782 dump_pci_device(dev); 783 } 784} 785static void dump_spd_registers(const struct mem_controller *ctrl) 786{ 787 int i; 788 print_debug("\r\n"); 789 for(i = 0; i < 4; i++) { 790 unsigned device; 791 device = ctrl->channel0[i]; 792 if (device) { 793 int j; 794 print_debug("dimm: "); 795 print_debug_hex8(i); 796 print_debug(".0: "); 797 print_debug_hex8(device); 798 for(j = 0; j < 256; j++) { 799 int status; 800 unsigned char byte; 801 if ((j & 0xf) == 0) { 802 print_debug("\r\n"); 803 print_debug_hex8(j); 804 print_debug(": "); 805 } 806 status = smbus_read_byte(device, j); 807 if (status < 0) { 808 print_debug("bad device\r\n"); 809 break; 810 } 811 byte = status & 0xff; 812 print_debug_hex8(byte); 813 print_debug_char(' '); 814 } 815 print_debug("\r\n"); 816 } 817 device = ctrl->channel1[i]; 818 if (device) { 819 int j; 820 print_debug("dimm: "); 821 print_debug_hex8(i); 822 print_debug(".1: "); 823 print_debug_hex8(device); 824 for(j = 0; j < 256; j++) { 825 int status; 826 unsigned char byte; 827 if ((j & 0xf) == 0) { 828 print_debug("\r\n"); 829 print_debug_hex8(j); 830 print_debug(": "); 831 } 832 status = smbus_read_byte(device, j); 833 if (status < 0) { 834 print_debug("bad device\r\n"); 835 break; 836 } 837 byte = status & 0xff; 838 print_debug_hex8(byte); 839 print_debug_char(' '); 840 } 841 print_debug("\r\n"); 842 } 843 } 844} 845 846static unsigned int cpuid(unsigned int op) 847{ 848 unsigned int ret; 849 unsigned dummy2,dummy3,dummy4; 850 asm volatile ( 851 "cpuid" 852 : "=a" (ret), "=b" (dummy2), "=c" (dummy3), "=d" (dummy4) 853 : "a" (op) 854 ); 855 return ret; 856} 857static int is_cpu_rev_a0(void) 858{ 859 return (cpuid(1) & 0xffff) == 0x0f10; 860} 861static int is_cpu_pre_c0(void) 862{ 863 return (cpuid(1) & 0xffef) < 0x0f48; 864} 865static void memreset_setup(void) 866{ 867 if (is_cpu_pre_c0()) { 868 869 outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), 0x0f00 + 0xc0 + 28); 870 871 outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), 0x0f00 + 0xc0 + 29); 872 } 873 else { 874 875 outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), 0x0f00 + 0xc0 + 29); 876 } 877} 878static void memreset(int controllers, const struct mem_controller *ctrl) 879{ 880 if (is_cpu_pre_c0()) { 881 udelay(800); 882 883 outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), 0x0f00 + 0xc0 + 28); 884 udelay(90); 885 } 886} 887static unsigned int generate_row(uint8_t node, uint8_t row, uint8_t maxnodes) 888{ 889 890 uint32_t ret=0x00010101; 891 static const unsigned int rows_2p[2][2] = { 892 { 0x00050101, 0x00010404 }, 893 { 0x00010404, 0x00050101 } 894 }; 895 if(maxnodes>2) { 896 print_debug("this mainboard is only designed for 2 cpus\r\n"); 897 maxnodes=2; 898 } 899 if (!(node>=maxnodes || row>=maxnodes)) { 900 ret=rows_2p[node][row]; 901 } 902 return ret; 903} 904static inline int spd_read_byte(unsigned device, unsigned address) 905{ 906 return smbus_read_byte(device, address); 907} 908 909static void coherent_ht_mainboard(unsigned cpus) 910{ 911} 912 913void cpu_ldtstop(unsigned cpus) 914{ 915 uint32_t tmp; 916 device_t dev; 917 unsigned cnt; 918 for(cnt=0; cnt<cpus; cnt++) { 919 920 pci_write_config8(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) ,0x81,0x23); 921 922 pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) ,0xd4,0x00000701); 923 924 pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) ,0xd8,0x00000000); 925 926 tmp=pci_read_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 2 ) & 0x7) << 8)) ,0x90); 927 pci_write_config32(( ((( 0 ) & 0xFF) << 16) | ((( 24 ) & 0x1f) << 11) | ((( 2 ) & 0x7) << 8)) ,0x90, tmp | (1<<24) ); 928 } 929} 930 931 932 933 934 935static void setup_resource_map(const unsigned int *register_values, int max) 936{ 937 int i; 938 print_debug("setting up resource map....\r\n"); 939 for(i = 0; i < max; i += 3) { 940 device_t dev; 941 unsigned where; 942 unsigned long reg; 943 dev = register_values[i] & ~0xff; 944 where = register_values[i] & 0xff; 945 reg = pci_read_config32(dev, where); 946 reg &= register_values[i+1]; 947 reg |= register_values[i+2]; 948 pci_write_config32(dev, where, reg); 949 } 950 print_debug("done.\r\n"); 951} 952static void setup_default_resource_map(void) 953{ 954 static const unsigned int register_values[] = { 955 956 957 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x44 ) & 0xFF)) , 0x0000f8f8, 0x00000000, 958 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x4C ) & 0xFF)) , 0x0000f8f8, 0x00000001, 959 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x54 ) & 0xFF)) , 0x0000f8f8, 0x00000002, 960 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x5C ) & 0xFF)) , 0x0000f8f8, 0x00000003, 961 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x64 ) & 0xFF)) , 0x0000f8f8, 0x00000004, 962 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x6C ) & 0xFF)) , 0x0000f8f8, 0x00000005, 963 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x74 ) & 0xFF)) , 0x0000f8f8, 0x00000006, 964 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x7C ) & 0xFF)) , 0x0000f8f8, 0x00000007, 965 966 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x40 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 967 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x48 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 968 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x50 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 969 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x58 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 970 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x60 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 971 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x68 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 972 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x70 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 973 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x78 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 974 975 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x84 ) & 0xFF)) , 0x00000048, 0x00000000, 976 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x8C ) & 0xFF)) , 0x00000048, 0x00000000, 977 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x94 ) & 0xFF)) , 0x00000048, 0x00000000, 978 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x9C ) & 0xFF)) , 0x00000048, 0x00000000, 979 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xA4 ) & 0xFF)) , 0x00000048, 0x00000000, 980 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xAC ) & 0xFF)) , 0x00000048, 0x00000000, 981 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xB4 ) & 0xFF)) , 0x00000048, 0x00000000, 982 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xBC ) & 0xFF)) , 0x00000048, 0x00ffff00, 983 984 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x80 ) & 0xFF)) , 0x000000f0, 0x00000000, 985 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x88 ) & 0xFF)) , 0x000000f0, 0x00000000, 986 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x90 ) & 0xFF)) , 0x000000f0, 0x00000000, 987 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x98 ) & 0xFF)) , 0x000000f0, 0x00000000, 988 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xA0 ) & 0xFF)) , 0x000000f0, 0x00000000, 989 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xA8 ) & 0xFF)) , 0x000000f0, 0x00000000, 990 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xB0 ) & 0xFF)) , 0x000000f0, 0x00000000, 991 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xB8 ) & 0xFF)) , 0x000000f0, 0x00fc0003, 992 993 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xC4 ) & 0xFF)) , 0xFE000FC8, 0x01fff000, 994 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xCC ) & 0xFF)) , 0xFE000FC8, 0x00000000, 995 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xD4 ) & 0xFF)) , 0xFE000FC8, 0x00000000, 996 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xDC ) & 0xFF)) , 0xFE000FC8, 0x00000000, 997 998 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xC0 ) & 0xFF)) , 0xFE000FCC, 0x00000003, 999 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xC8 ) & 0xFF)) , 0xFE000FCC, 0x00000000, 1000 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xD0 ) & 0xFF)) , 0xFE000FCC, 0x00000000,
1001 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xD8 ) & 0xFF)) , 0xFE000FCC, 0x00000000, 1002 1003 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xE0 ) & 0xFF)) , 0x0000FC88, 0xff000003, 1004 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xE4 ) & 0xFF)) , 0x0000FC88, 0x00000000, 1005 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xE8 ) & 0xFF)) , 0x0000FC88, 0x00000000, 1006 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0xEC ) & 0xFF)) , 0x0000FC88, 0x00000000, 1007 }; 1008 int max; 1009 max = sizeof(register_values)/sizeof(register_values[0]); 1010 setup_resource_map(register_values, max); 1011} 1012static void sdram_set_registers(const struct mem_controller *ctrl) 1013{ 1014 static const unsigned int register_values[] = { 1015 1016 1017 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x44 ) & 0xFF)) , 0x0000f8f8, 0x00000000, 1018 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x4C ) & 0xFF)) , 0x0000f8f8, 0x00000001, 1019 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x54 ) & 0xFF)) , 0x0000f8f8, 0x00000002, 1020 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x5C ) & 0xFF)) , 0x0000f8f8, 0x00000003, 1021 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x64 ) & 0xFF)) , 0x0000f8f8, 0x00000004, 1022 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x6C ) & 0xFF)) , 0x0000f8f8, 0x00000005, 1023 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x74 ) & 0xFF)) , 0x0000f8f8, 0x00000006, 1024 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x7C ) & 0xFF)) , 0x0000f8f8, 0x00000007, 1025 1026 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x40 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 1027 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x48 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 1028 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x50 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 1029 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x58 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 1030 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x60 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 1031 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x68 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 1032 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x70 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 1033 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x07) << 8) | (( 0x78 ) & 0xFF)) , 0x0000f8fc, 0x00000000, 1034 1035 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x40 ) & 0xFF)) , 0x001f01fe, 0x00000000, 1036 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x44 ) & 0xFF)) , 0x001f01fe, 0x00000000, 1037 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x48 ) & 0xFF)) , 0x001f01fe, 0x00000000, 1038 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x4C ) & 0xFF)) , 0x001f01fe, 0x00000000, 1039 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x50 ) & 0xFF)) , 0x001f01fe, 0x00000000, 1040 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x54 ) & 0xFF)) , 0x001f01fe, 0x00000000, 1041 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x58 ) & 0xFF)) , 0x001f01fe, 0x00000000, 1042 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x5C ) & 0xFF)) , 0x001f01fe, 0x00000000, 1043 1044 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x60 ) & 0xFF)) , 0xC01f01ff, 0x00000000, 1045 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x64 ) & 0xFF)) , 0xC01f01ff, 0x00000000, 1046 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x68 ) & 0xFF)) , 0xC01f01ff, 0x00000000, 1047 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x6C ) & 0xFF)) , 0xC01f01ff, 0x00000000, 1048 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x70 ) & 0xFF)) , 0xC01f01ff, 0x00000000, 1049 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x74 ) & 0xFF)) , 0xC01f01ff, 0x00000000, 1050 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x78 ) & 0xFF)) , 0xC01f01ff, 0x00000000, 1051 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x7C ) & 0xFF)) , 0xC01f01ff, 0x00000000, 1052 1053 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x80 ) & 0xFF)) , 0xffff8888, 0x00000000, 1054 1055 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x88 ) & 0xFF)) , 0xe8088008, 0x02522001 , 1056 1057 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x8c ) & 0xFF)) , 0xff8fe08e, (0 << 20)|(0 << 8)|(0 << 4)|(0 << 0), 1058 1059 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x90 ) & 0xFF)) , 0xf0000000, 1060 (4 << 25)|(0 << 24)| 1061 (0 << 23)|(0 << 22)|(0 << 21)|(0 << 20)| 1062 (1 << 19)|(0 << 18)|(1 << 17)|(0 << 16)| 1063 (2 << 14)|(0 << 13)|(0 << 12)| 1064 (0 << 11)|(0 << 10)|(0 << 9)|(0 << 8)| 1065 (0 << 3) |(0 << 1) |(0 << 0), 1066 1067 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x94 ) & 0xFF)) , 0xc180f0f0, 1068 (0 << 29)|(0 << 28)|(0 << 27)|(0 << 26)|(0 << 25)| 1069 (0 << 20)|(0 << 19)|(3 << 16)|(0 << 8)|(0 << 0), 1070 1071 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 2 ) & 0x07) << 8) | (( 0x98 ) & 0xFF)) , 0xfc00ffff, 0x00000000, 1072 1073 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x58 ) & 0xFF)) , 0xffe0e0e0, 0x00000000, 1074 1075 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x5C ) & 0xFF)) , 0x0000003e, 0x00000000, 1076 1077 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x60 ) & 0xFF)) , 0xffffff00, 0x00000000, 1078 1079 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x94 ) & 0xFF)) , 0xffff8000, 0x00000f70, 1080 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x90 ) & 0xFF)) , 0xffffff80, 0x00000002, 1081 ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 3 ) & 0x07) << 8) | (( 0x98 ) & 0xFF)) , 0x0000000f, 0x00068300, 1082 }; 1083 int i; 1084 int max; 1085 print_debug("setting up CPU"); 1086 print_debug_hex8(ctrl->node_id); 1087 print_debug(" northbridge registers\r\n"); 1088 max = sizeof(register_values)/sizeof(register_values[0]); 1089 for(i = 0; i < max; i += 3) { 1090 device_t dev; 1091 unsigned where; 1092 unsigned long reg; 1093 dev = (register_values[i] & ~0xff) - ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) + ctrl->f0; 1094 where = register_values[i] & 0xff; 1095 reg = pci_read_config32(dev, where); 1096 reg &= register_values[i+1]; 1097 reg |= register_values[i+2]; 1098 pci_write_config32(dev, where, reg); 1099 } 1100 print_debug("done.\r\n"); 1101} 1102static int is_dual_channel(const struct mem_controller *ctrl) 1103{ 1104 uint32_t dcl; 1105 dcl = pci_read_config32(ctrl->f2, 0x90 ); 1106 return dcl & (1<<16) ; 1107} 1108static int is_opteron(const struct mem_controller *ctrl) 1109{ 1110 1111 uint32_t nbcap; 1112 nbcap = pci_read_config32(ctrl->f3, 0xE8 ); 1113 return !!(nbcap & 0x0001 ); 1114} 1115static int is_registered(const struct mem_controller *ctrl) 1116{ 1117 1118 uint32_t dcl; 1119 dcl = pci_read_config32(ctrl->f2, 0x90 ); 1120 return !(dcl & (1<<18) ); 1121} 1122struct dimm_size { 1123 unsigned long side1; 1124 unsigned long side2; 1125}; 1126static struct dimm_size spd_get_dimm_size(unsigned device) 1127{ 1128 1129 struct dimm_size sz; 1130 int value, low; 1131 sz.side1 = 0; 1132 sz.side2 = 0; 1133 1134 value = spd_read_byte(device, 3); 1135 if (value < 0) goto out; 1136 sz.side1 += value & 0xf; 1137 value = spd_read_byte(device, 4); 1138 if (value < 0) goto out; 1139 sz.side1 += value & 0xf; 1140 value = spd_read_byte(device, 17); 1141 if (value < 0) goto out; 1142 sz.side1 += log2(value & 0xff); 1143 1144 value = spd_read_byte(device, 7); 1145 if (value < 0) goto out; 1146 value &= 0xff; 1147 value <<= 8; 1148 1149 low = spd_read_byte(device, 6); 1150 if (low < 0) goto out; 1151 value = value | (low & 0xff); 1152 sz.side1 += log2(value); 1153 1154 value = spd_read_byte(device, 5); 1155 if (value <= 1) goto out; 1156 1157 sz.side2 = sz.side1; 1158 value = spd_read_byte(device, 3); 1159 if (value < 0) goto out; 1160 if ((value & 0xf0) == 0) goto out; 1161 sz.side2 -= (value & 0x0f); 1162 sz.side2 += ((value >> 4) & 0x0f); 1163 value = spd_read_byte(device, 4); 1164 if (value < 0) goto out; 1165 sz.side2 -= (value & 0x0f); 1166 sz.side2 += ((value >> 4) & 0x0f); 1167 out: 1168 return sz; 1169} 1170static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index) 1171{ 1172 uint32_t base0, base1, map; 1173 uint32_t dch; 1174 if (sz.side1 != sz.side2) { 1175 sz.side2 = 0; 1176 } 1177 map = pci_read_config32(ctrl->f2, 0x80 ); 1178 map &= ~(0xf << (index + 4)); 1179 1180 1181 base0 = base1 = 0; 1182 1183 if (sz.side1 >= (25 +3)) { 1184 map |= (sz.side1 - (25 + 3)) << (index *4); 1185 base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1; 1186 } 1187 1188 if (sz.side2 >= (25 + 3)) { 1189 base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1; 1190 } 1191 1192 if (is_dual_channel(ctrl)) { 1193 base0 = (base0 << 1) | (base0 & 1); 1194 base1 = (base1 << 1) | (base1 & 1); 1195 } 1196 1197 base0 &= ~0x001ffffe; 1198 base1 &= ~0x001ffffe; 1199 1200 pci_write_config32(ctrl->f2, 0x40 + (((index << 1)+0)<<2), base0); 1201 pci_write_config32(ctrl->f2, 0x40 + (((index << 1)+1)<<2), base1); 1202 pci_write_config32(ctrl->f2, 0x80 , map); 1203 1204 1205 if (base0) { 1206 dch = pci_read_config32(ctrl->f2, 0x94 ); 1207 dch |= (1 << 26) << index; 1208 pci_write_config32(ctrl->f2, 0x94 , dch); 1209 } 1210} 1211static void spd_set_ram_size(const struct mem_controller *ctrl) 1212{ 1213 int i; 1214 1215 for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) { 1216 struct dimm_size sz; 1217 sz = spd_get_dimm_size(ctrl->channel0[i]); 1218 set_dimm_size(ctrl, sz, i); 1219 } 1220} 1221static void route_dram_accesses(const struct mem_controller *ctrl, 1222 unsigned long base_k, unsigned long limit_k) 1223{ 1224 1225 unsigned node_id; 1226 unsigned limit; 1227 unsigned base; 1228 unsigned index; 1229 unsigned limit_reg, base_reg; 1230 device_t device; 1231 node_id = ctrl->node_id; 1232 index = (node_id << 3); 1233 limit = (limit_k << 2); 1234 limit &= 0xffff0000; 1235 limit -= 0x00010000; 1236 limit |= ( 0 << 8) | (node_id << 0); 1237 base = (base_k << 2); 1238 base &= 0xffff0000; 1239 base |= (0 << 8) | (1<<1) | (1<<0); 1240 limit_reg = 0x44 + index; 1241 base_reg = 0x40 + index; 1242 for(device = ( ((( 0 ) & 0xFF) << 16) | ((( 0x18 ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ; device <= ( ((( 0 ) & 0xFF) << 16) | ((( 0x1f ) & 0x1f) << 11) | ((( 1 ) & 0x7) << 8)) ; device += ( ((( 0 ) & 0xFF) << 16) | ((( 1 ) & 0x1f) << 11) | ((( 0 ) & 0x7) << 8)) ) { 1243 pci_write_config32(device, limit_reg, limit); 1244 pci_write_config32(device, base_reg, base); 1245 } 1246} 1247static void set_top_mem(unsigned tom_k) 1248{ 1249 1250 if (!tom_k) { 1251 set_bios_reset(); 1252 print_debug("No memory - reset"); 1253 1254 pci_write_config8(( ((( 0 ) & 0xFF) << 16) | ((( 0x04 ) & 0x1f) << 11) | ((( 3 ) & 0x7) << 8)) , 0x41, 0xf1); 1255 1256 outb(0x0e, 0x0cf9); 1257 } 1258 1259 print_debug("RAM: 0x"); 1260 print_debug_hex32(tom_k); 1261 print_debug(" KB\r\n"); 1262 1263 msr_t msr; 1264 msr.lo = (tom_k & 0x003fffff) << 10; 1265 msr.hi = (tom_k & 0xffc00000) >> 22; 1266 wrmsr(0xC001001D , msr); 1267 1268 if (tom_k >= 0x003f0000) { 1269 tom_k = 0x3f0000; 1270 } 1271 msr.lo = (tom_k & 0x003fffff) << 10; 1272 msr.hi = (tom_k & 0xffc00000) >> 22; 1273 wrmsr(0xC001001A , msr); 1274} 1275static unsigned long interleave_chip_selects(const struct mem_controller *ctrl) 1276{ 1277 1278 static const uint32_t csbase_low[] = { 1279 (1 << (13 - 4)), 1280 (1 << (14 - 4)), 1281 (1 << (14 - 4)), 1282 (1 << (15 - 4)), 1283 (1 << (15 - 4)), 1284 (1 << (16 - 4)), 1285 (1 << (16 - 4)), 1286 }; 1287 uint32_t csbase_inc; 1288 int chip_selects, index; 1289 int bits; 1290 int dual_channel; 1291 unsigned common_size; 1292 uint32_t csbase, csmask; 1293 1294 chip_selects = 0; 1295 common_size = 0; 1296 for(index = 0; index < 8; index++) { 1297 unsigned size; 1298 uint32_t value; 1299 1300 value = pci_read_config32(ctrl->f2, 0x40 + (index << 2)); 1301 1302 1303 if (!(value & 1)) { 1304 continue; 1305 } 1306 chip_selects++; 1307 size = value >> 21; 1308 if (common_size == 0) { 1309 common_size = size; 1310 } 1311 1312 if (common_size != size) { 1313 return 0; 1314 } 1315 } 1316 1317 bits = log2(chip_selects); 1318 if (((1 << bits) != chip_selects) || (bits < 1) || (bits > 3)) { 1319 return 0; 1320 1321 } 1322 1323 if ((bits == 3) && (common_size == (1 << (32 - 3)))) { 1324 print_debug("8 4GB chip selects cannot be interleaved\r\n"); 1325 return 0; 1326 } 1327 1328 if (is_dual_channel(ctrl)) { 1329 csbase_inc = csbase_low[log2(common_size) - 1] << 1; 1330 } else { 1331 csbase_inc = csbase_low[log2(common_size)]; 1332 } 1333 1334 csbase = 0 | 1; 1335 csmask = (((common_size << bits) - 1) << 21); 1336 csmask |= 0xfe00 & ~((csbase_inc << bits) - csbase_inc); 1337 for(index = 0; index < 8; index++) { 1338 uint32_t value; 1339 value = pci_read_config32(ctrl->f2, 0x40 + (index << 2)); 1340 1341 if (!(value & 1)) { 1342 continue; 1343 } 1344 pci_write_config32(ctrl->f2, 0x40 + (index << 2), csbase); 1345 pci_write_config32(ctrl->f2, 0x60 + (index << 2), csmask); 1346 csbase += csbase_inc; 1347 } 1348 1349 print_debug("Interleaved\r\n"); 1350 1351 return common_size << (15 + bits); 1352} 1353static unsigned long order_chip_selects(const struct mem_controller *ctrl) 1354{ 1355 unsigned long tom; 1356 1357 1358 tom = 0; 1359 for(;;) { 1360 1361 unsigned index, canidate; 1362 uint32_t csbase, csmask; 1363 unsigned size; 1364 csbase = 0; 1365 canidate = 0; 1366 for(index = 0; index < 8; index++) { 1367 uint32_t value; 1368 value = pci_read_config32(ctrl->f2, 0x40 + (index << 2)); 1369 1370 if (!(value & 1)) { 1371 continue; 1372 } 1373 1374 1375 if (value <= csbase) { 1376 continue; 1377 } 1378 1379 1380 if (tom & (1 << (index + 24))) { 1381 continue; 1382 } 1383 1384 csbase = value; 1385 canidate = index; 1386 } 1387 1388 if (csbase == 0) { 1389 break; 1390 } 1391 1392 size = csbase >> 21; 1393 1394 tom |= (1 << (canidate + 24)); 1395 1396 csbase = (tom << 21) | 1; 1397 1398 tom += size; 1399 1400 csmask = ((size -1) << 21); 1401 csmask |= 0xfe00; 1402 1403 pci_write_config32(ctrl->f2, 0x40 + (canidate << 2), csbase); 1404 1405 pci_write_config32(ctrl->f2, 0x60 + (canidate << 2), csmask); 1406 1407 } 1408 1409 return (tom & ~0xff000000) << 15; 1410} 1411static void order_dimms(const struct mem_controller *ctrl) 1412{ 1413 unsigned long tom, tom_k, base_k; 1414 unsigned node_id; 1415 tom_k = interleave_chip_selects(ctrl); 1416 if (!tom_k) { 1417 tom_k = order_chip_selects(ctrl); 1418 } 1419 1420 base_k = 0; 1421 for(node_id = 0; node_id < ctrl->node_id; node_id++) { 1422 uint32_t limit, base; 1423 unsigned index; 1424 index = node_id << 3; 1425 base = pci_read_config32(ctrl->f1, 0x40 + index); 1426 1427 if ((base & 3) == 3) { 1428 limit = pci_read_config32(ctrl->f1, 0x44 + index); 1429 base_k = ((limit + 0x00010000) & 0xffff0000) >> 2; 1430 } 1431 } 1432 tom_k += base_k; 1433 route_dram_accesses(ctrl, base_k, tom_k); 1434 set_top_mem(tom_k); 1435} 1436static void disable_dimm(const struct mem_controller *ctrl, unsigned index) 1437{ 1438 print_debug("disabling dimm"); 1439 print_debug_hex8(index); 1440 print_debug("\r\n"); 1441 pci_write_config32(ctrl->f2, 0x40 + (((index << 1)+0)<<2), 0); 1442 pci_write_config32(ctrl->f2, 0x40 + (((index << 1)+1)<<2), 0); 1443} 1444static void spd_handle_unbuffered_dimms(const struct mem_controller *ctrl) 1445{ 1446 int i; 1447 int registered; 1448 int unbuffered; 1449 uint32_t dcl; 1450 unbuffered = 0; 1451 registered = 0; 1452 for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) { 1453 int value; 1454 value = spd_read_byte(ctrl->channel0[i], 21); 1455 if (value < 0) { 1456 disable_dimm(ctrl, i); 1457 continue; 1458 } 1459 1460 if (value & (1 << 1)) { 1461 registered = 1; 1462 } 1463 1464 else { 1465 unbuffered = 1; 1466 } 1467 } 1468 if (unbuffered && registered) { 1469 die("Mixed buffered and registered dimms not supported"); 1470 } 1471 if (unbuffered && is_opteron(ctrl)) { 1472 die("Unbuffered Dimms not supported on Opteron"); 1473 } 1474 dcl = pci_read_config32(ctrl->f2, 0x90 ); 1475 dcl &= ~(1<<18) ; 1476 if (unbuffered) { 1477 dcl |= (1<<18) ; 1478 } 1479 pci_write_config32(ctrl->f2, 0x90 , dcl); 1480} 1481static void spd_enable_2channels(const struct mem_controller *ctrl) 1482{ 1483 int i; 1484 uint32_t nbcap; 1485 1486 1487 static const unsigned addresses[] = { 1488 2, 1489 3, 1490 4, 1491 5, 1492 6, 1493 7, 1494 9, 1495 11, 1496 13, 1497 17, 1498 18, 1499 21, 1500 23, 1501 26, 1502 27, 1503 28, 1504 29, 1505 30, 1506 41, 1507 42, 1508 }; 1509 nbcap = pci_read_config32(ctrl->f3, 0xE8 ); 1510 if (!(nbcap & 0x0001 )) { 1511 return; 1512 } 1513 for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) { 1514 unsigned device0, device1; 1515 int value0, value1; 1516 int j; 1517 device0 = ctrl->channel0[i]; 1518 device1 = ctrl->channel1[i]; 1519 if (!device1) 1520 return; 1521 for(j = 0; j < sizeof(addresses)/sizeof(addresses[0]); j++) { 1522 unsigned addr; 1523 addr = addresses[j]; 1524 value0 = spd_read_byte(device0, addr); 1525 if (value0 < 0) { 1526 break; 1527 } 1528 value1 = spd_read_byte(device1, addr); 1529 if (value1 < 0) { 1530 return; 1531 } 1532 if (value0 != value1) { 1533 return; 1534 } 1535 } 1536 } 1537 print_debug("Enabling dual channel memory\r\n"); 1538 uint32_t dcl; 1539 dcl = pci_read_config32(ctrl->f2, 0x90 ); 1540 dcl &= ~(1<<19) ; 1541 dcl |= (1<<16) ; 1542 pci_write_config32(ctrl->f2, 0x90 , dcl); 1543} 1544struct mem_param { 1545 uint8_t cycle_time; 1546 uint8_t divisor; 1547 uint8_t tRC; 1548 uint8_t tRFC; 1549 uint32_t dch_memclk; 1550 uint16_t dch_tref4k, dch_tref8k; 1551 uint8_t dtl_twr; 1552 char name[9]; 1553}; 1554static const struct mem_param *get_mem_param(unsigned min_cycle_time) 1555{ 1556 static const struct mem_param speed[] = { 1557 { 1558 .name = "100Mhz\r\n", 1559 .cycle_time = 0xa0, 1560 .divisor = (10 <<1), 1561 .tRC = 0x46, 1562 .tRFC = 0x50, 1563 .dch_memclk = 0 << 20 , 1564 .dch_tref4k = 0x00 , 1565 .dch_tref8k = 0x08 , 1566 .dtl_twr = 2, 1567 }, 1568 { 1569 .name = "133Mhz\r\n", 1570 .cycle_time = 0x75, 1571 .divisor = (7<<1)+1, 1572 .tRC = 0x41, 1573 .tRFC = 0x4B, 1574 .dch_memclk = 2 << 20 , 1575 .dch_tref4k = 0x01 , 1576 .dch_tref8k = 0x09 , 1577 .dtl_twr = 2, 1578 }, 1579 { 1580 .name = "166Mhz\r\n", 1581 .cycle_time = 0x60, 1582 .divisor = (6<<1), 1583 .tRC = 0x3C, 1584 .tRFC = 0x48, 1585 .dch_memclk = 5 << 20 , 1586 .dch_tref4k = 0x02 , 1587 .dch_tref8k = 0x0A , 1588 .dtl_twr = 3, 1589 }, 1590 { 1591 .name = "200Mhz\r\n", 1592 .cycle_time = 0x50, 1593 .divisor = (5<<1), 1594 .tRC = 0x37, 1595 .tRFC = 0x46, 1596 .dch_memclk = 7 << 20 , 1597 .dch_tref4k = 0x03 , 1598 .dch_tref8k = 0x0B , 1599 .dtl_twr = 3, 1600 }, 1601 { 1602 .cycle_time = 0x00, 1603 }, 1604 }; 1605 const struct mem_param *param; 1606 for(param = &speed[0]; param->cycle_time ; param++) { 1607 if (min_cycle_time > (param+1)->cycle_time) { 1608 break; 1609 } 1610 } 1611 if (!param->cycle_time) { 1612 die("min_cycle_time to low"); 1613 } 1614 print_debug(param->name); 1615 return param; 1616} 1617static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl) 1618{ 1619 1620 const struct mem_param *param; 1621 unsigned min_cycle_time, min_latency; 1622 int i; 1623 uint32_t value; 1624 static const int latency_indicies[] = { 26, 23, 9 }; 1625 static const unsigned char min_cycle_times[] = { 1626 [0 ] = 0x50, 1627 [1 ] = 0x60, 1628 [2 ] = 0x75, 1629 [3 ] = 0xa0, 1630 }; 1631 value = pci_read_config32(ctrl->f3, 0xE8 ); 1632 min_cycle_time = min_cycle_times[(value >> 5 ) & 3 ]; 1633 min_latency = 2; 1634 1635 for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) { 1636 int new_cycle_time, new_latency; 1637 int index; 1638 int latencies; 1639 int latency; 1640 1641 new_cycle_time = 0xa0; 1642 new_latency = 5; 1643 latencies = spd_read_byte(ctrl->channel0[i], 18); 1644 if (latencies <= 0) continue; 1645 1646 latency = log2(latencies) -2; 1647 1648 for(index = 0; index < 3; index++, latency++) { 1649 int value; 1650 if ((latency < 2) || (latency > 4) || 1651 (!(latencies & (1 << latency)))) { 1652 continue; 1653 } 1654 value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]); 1655 if (value < 0) { 1656 continue; 1657 } 1658 1659 if ((value >= min_cycle_time) && (value < new_cycle_time)) { 1660 new_cycle_time = value; 1661 new_latency = latency; 1662 } 1663 } 1664 if (new_latency > 4){ 1665 continue; 1666 } 1667 1668 if (new_cycle_time > min_cycle_time) { 1669 min_cycle_time = new_cycle_time; 1670 } 1671 1672 if (new_latency > min_latency) { 1673 min_latency = new_latency; 1674 } 1675 } 1676 1677 1678 for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) { 1679 int latencies; 1680 int latency; 1681 int index; 1682 int value; 1683 int dimm; 1684 latencies = spd_read_byte(ctrl->channel0[i], 18); 1685 if (latencies <= 0) { 1686 goto dimm_err; 1687 } 1688 1689 latency = log2(latencies) -2; 1690 1691 for(index = 0; index < 3; index++, latency++) { 1692 if (!(latencies & (1 << latency))) { 1693 continue; 1694 } 1695 if (latency == min_latency) 1696 break; 1697 } 1698 1699 if ((latency != min_latency) || (index >= 3)) { 1700 goto dimm_err; 1701 } 1702 1703 1704 value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]); 1705 1706 1707 if (value <= min_cycle_time) { 1708 continue; 1709 } 1710 1711 dimm_err: 1712 disable_dimm(ctrl, i); 1713 } 1714 1715 param = get_mem_param(min_cycle_time); 1716 1717 value = pci_read_config32(ctrl->f2, 0x94 ); 1718 value &= ~(0x7 << 20 ); 1719 value |= param->dch_memclk; 1720 pci_write_config32(ctrl->f2, 0x94 , value); 1721 static const unsigned latencies[] = { 1 , 5 , 2 }; 1722 1723 value = pci_read_config32(ctrl->f2, 0x88 ); 1724 value &= ~(0x7 << 0 ); 1725 value |= latencies[min_latency - 2] << 0 ; 1726 pci_write_config32(ctrl->f2, 0x88 , value); 1727 1728 return param; 1729} 1730static int update_dimm_Trc(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1731{ 1732 unsigned clocks, old_clocks; 1733 uint32_t dtl; 1734 int value; 1735 value = spd_read_byte(ctrl->channel0[i], 41); 1736 if (value < 0) return -1; 1737 if ((value == 0) || (value == 0xff)) { 1738 value = param->tRC; 1739 } 1740 clocks = ((value << 1) + param->divisor - 1)/param->divisor; 1741 if (clocks < 7 ) { 1742 clocks = 7 ; 1743 } 1744 if (clocks > 22 ) { 1745 return -1; 1746 } 1747 dtl = pci_read_config32(ctrl->f2, 0x88 ); 1748 old_clocks = ((dtl >> 4 ) & 0xf ) + 7 ; 1749 if (old_clocks > clocks) { 1750 clocks = old_clocks; 1751 } 1752 dtl &= ~(0xf << 4 ); 1753 dtl |= ((clocks - 7 ) << 4 ); 1754 pci_write_config32(ctrl->f2, 0x88 , dtl); 1755 return 0; 1756} 1757static int update_dimm_Trfc(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1758{ 1759 unsigned clocks, old_clocks; 1760 uint32_t dtl; 1761 int value; 1762 value = spd_read_byte(ctrl->channel0[i], 42); 1763 if (value < 0) return -1; 1764 if ((value == 0) || (value == 0xff)) { 1765 value = param->tRFC; 1766 } 1767 clocks = ((value << 1) + param->divisor - 1)/param->divisor; 1768 if (clocks < 9 ) { 1769 clocks = 9 ; 1770 } 1771 if (clocks > 24 ) { 1772 return -1; 1773 } 1774 dtl = pci_read_config32(ctrl->f2, 0x88 ); 1775 old_clocks = ((dtl >> 8 ) & 0xf ) + 9 ; 1776 if (old_clocks > clocks) { 1777 clocks = old_clocks; 1778 } 1779 dtl &= ~(0xf << 8 ); 1780 dtl |= ((clocks - 9 ) << 8 ); 1781 pci_write_config32(ctrl->f2, 0x88 , dtl); 1782 return 0; 1783} 1784static int update_dimm_Trcd(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1785{ 1786 unsigned clocks, old_clocks; 1787 uint32_t dtl; 1788 int value; 1789 value = spd_read_byte(ctrl->channel0[i], 29); 1790 if (value < 0) return -1; 1791 clocks = (value + ((param->divisor & 0xff) << 1) -1)/((param->divisor & 0xff) << 1); 1792 if (clocks < 2 ) { 1793 clocks = 2 ; 1794 } 1795 if (clocks > 6 ) { 1796 return -1; 1797 } 1798 dtl = pci_read_config32(ctrl->f2, 0x88 ); 1799 old_clocks = ((dtl >> 12 ) & 0x7 ) + 0 ; 1800 if (old_clocks > clocks) { 1801 clocks = old_clocks; 1802 } 1803 dtl &= ~(0x7 << 12 ); 1804 dtl |= ((clocks - 0 ) << 12 ); 1805 pci_write_config32(ctrl->f2, 0x88 , dtl); 1806 return 0; 1807} 1808static int update_dimm_Trrd(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1809{ 1810 unsigned clocks, old_clocks; 1811 uint32_t dtl; 1812 int value; 1813 value = spd_read_byte(ctrl->channel0[i], 28); 1814 if (value < 0) return -1; 1815 clocks = (value + ((param->divisor & 0xff) << 1) -1)/((param->divisor & 0xff) << 1); 1816 if (clocks < 2 ) { 1817 clocks = 2 ; 1818 } 1819 if (clocks > 4 ) { 1820 return -1; 1821 } 1822 dtl = pci_read_config32(ctrl->f2, 0x88 ); 1823 old_clocks = ((dtl >> 16 ) & 0x7 ) + 0 ; 1824 if (old_clocks > clocks) { 1825 clocks = old_clocks; 1826 } 1827 dtl &= ~(0x7 << 16 ); 1828 dtl |= ((clocks - 0 ) << 16 ); 1829 pci_write_config32(ctrl->f2, 0x88 , dtl); 1830 return 0; 1831} 1832static int update_dimm_Tras(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1833{ 1834 unsigned clocks, old_clocks; 1835 uint32_t dtl; 1836 int value; 1837 value = spd_read_byte(ctrl->channel0[i], 30); 1838 if (value < 0) return -1; 1839 clocks = ((value << 1) + param->divisor - 1)/param->divisor; 1840 if (clocks < 5 ) { 1841 clocks = 5 ; 1842 } 1843 if (clocks > 15 ) { 1844 return -1; 1845 } 1846 dtl = pci_read_config32(ctrl->f2, 0x88 ); 1847 old_clocks = ((dtl >> 20 ) & 0xf ) + 0 ; 1848 if (old_clocks > clocks) { 1849 clocks = old_clocks; 1850 } 1851 dtl &= ~(0xf << 20 ); 1852 dtl |= ((clocks - 0 ) << 20 ); 1853 pci_write_config32(ctrl->f2, 0x88 , dtl); 1854 return 0; 1855} 1856static int update_dimm_Trp(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1857{ 1858 unsigned clocks, old_clocks; 1859 uint32_t dtl; 1860 int value; 1861 value = spd_read_byte(ctrl->channel0[i], 27); 1862 if (value < 0) return -1; 1863 clocks = (value + ((param->divisor & 0xff) << 1) - 1)/((param->divisor & 0xff) << 1); 1864 if (clocks < 2 ) { 1865 clocks = 2 ; 1866 } 1867 if (clocks > 6 ) { 1868 return -1; 1869 } 1870 dtl = pci_read_config32(ctrl->f2, 0x88 ); 1871 old_clocks = ((dtl >> 24 ) & 0x7 ) + 0 ; 1872 if (old_clocks > clocks) { 1873 clocks = old_clocks; 1874 } 1875 dtl &= ~(0x7 << 24 ); 1876 dtl |= ((clocks - 0 ) << 24 ); 1877 pci_write_config32(ctrl->f2, 0x88 , dtl); 1878 return 0; 1879} 1880static void set_Twr(const struct mem_controller *ctrl, const struct mem_param *param) 1881{ 1882 uint32_t dtl; 1883 dtl = pci_read_config32(ctrl->f2, 0x88 ); 1884 dtl &= ~(0x1 << 28 ); 1885 dtl |= (param->dtl_twr - 2 ) << 28 ; 1886 pci_write_config32(ctrl->f2, 0x88 , dtl); 1887} 1888static void init_Tref(const struct mem_controller *ctrl, const struct mem_param *param) 1889{ 1890 uint32_t dth; 1891 dth = pci_read_config32(ctrl->f2, 0x8c ); 1892 dth &= ~(0x1f << 8 ); 1893 dth |= (param->dch_tref4k << 8 ); 1894 pci_write_config32(ctrl->f2, 0x8c , dth); 1895} 1896static int update_dimm_Tref(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1897{ 1898 uint32_t dth; 1899 int value; 1900 unsigned tref, old_tref; 1901 value = spd_read_byte(ctrl->channel0[i], 3); 1902 if (value < 0) return -1; 1903 value &= 0xf; 1904 tref = param->dch_tref8k; 1905 if (value == 12) { 1906 tref = param->dch_tref4k; 1907 } 1908 dth = pci_read_config32(ctrl->f2, 0x8c ); 1909 old_tref = (dth >> 8 ) & 0x1f ; 1910 if ((value == 12) && (old_tref == param->dch_tref4k)) { 1911 tref = param->dch_tref4k; 1912 } else { 1913 tref = param->dch_tref8k; 1914 } 1915 dth &= ~(0x1f << 8 ); 1916 dth |= (tref << 8 ); 1917 pci_write_config32(ctrl->f2, 0x8c , dth); 1918 return 0; 1919} 1920static int update_dimm_x4(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1921{ 1922 uint32_t dcl; 1923 int value; 1924 int dimm; 1925 value = spd_read_byte(ctrl->channel0[i], 13); 1926 if (value < 0) { 1927 return -1; 1928 } 1929 dimm = i; 1930 dimm += 20 ; 1931 dcl = pci_read_config32(ctrl->f2, 0x90 ); 1932 dcl &= ~(1 << dimm); 1933 if (value == 4) { 1934 dcl |= (1 << dimm); 1935 } 1936 pci_write_config32(ctrl->f2, 0x90 , dcl); 1937 return 0; 1938} 1939static int update_dimm_ecc(const struct mem_controller *ctrl, const struct mem_param *param, int i) 1940{ 1941 uint32_t dcl; 1942 int value; 1943 value = spd_read_byte(ctrl->channel0[i], 11); 1944 if (value < 0) { 1945 return -1; 1946 } 1947 if (value != 2) { 1948 dcl = pci_read_config32(ctrl->f2, 0x90 ); 1949 dcl &= ~(1<<17) ; 1950 pci_write_config32(ctrl->f2, 0x90 , dcl); 1951 } 1952 return 0; 1953} 1954static int count_dimms(const struct mem_controller *ctrl) 1955{ 1956 int dimms; 1957 unsigned index; 1958 dimms = 0; 1959 for(index = 0; index < 8; index += 2) { 1960 uint32_t csbase; 1961 csbase = pci_read_config32(ctrl->f2, (0x40 + index << 2)); 1962 if (csbase & 1) { 1963 dimms += 1; 1964 } 1965 } 1966 return dimms; 1967} 1968static void set_Twtr(const struct mem_controller *ctrl, const struct mem_param *param) 1969{ 1970 uint32_t dth; 1971 unsigned clocks; 1972 clocks = 1; 1973 dth = pci_read_config32(ctrl->f2, 0x8c ); 1974 dth &= ~(0x1 << 0 ); 1975 dth |= ((clocks - 1 ) << 0 ); 1976 pci_write_config32(ctrl->f2, 0x8c , dth); 1977} 1978static void set_Trwt(const struct mem_controller *ctrl, const struct mem_param *param) 1979{ 1980 uint32_t dth, dtl; 1981 unsigned divisor; 1982 unsigned latency; 1983 unsigned clocks; 1984 clocks = 0; 1985 dtl = pci_read_config32(ctrl->f2, 0x88 ); 1986 latency = (dtl >> 0 ) & 0x7 ; 1987 divisor = param->divisor; 1988 if (is_opteron(ctrl)) { 1989 if (latency == 1 ) { 1990 if (divisor == ((6 << 0) + 0)) { 1991 1992 clocks = 3; 1993 } 1994 else if (divisor > ((6 << 0)+0)) { 1995 1996 clocks = 2; 1997 } 1998 } 1999 else if (latency == 5 ) { 2000 clocks = 3;
2001 } 2002 else if (latency == 2 ) { 2003 if (divisor == ((6 << 0)+0)) { 2004 2005 clocks = 4; 2006 } 2007 else if (divisor > ((6 << 0)+0)) { 2008 2009 clocks = 3; 2010 } 2011 } 2012 } 2013 else { 2014 if (is_registered(ctrl)) { 2015 if (latency == 1 ) { 2016 clocks = 2; 2017 } 2018 else if (latency == 5 ) { 2019 clocks = 3; 2020 } 2021 else if (latency == 2 ) { 2022 clocks = 3; 2023 } 2024 } 2025 else { 2026 if (latency == 1 ) { 2027 clocks = 3; 2028 } 2029 else if (latency == 5 ) { 2030 clocks = 4; 2031 } 2032 else if (latency == 2 ) { 2033 clocks = 4; 2034 } 2035 } 2036 } 2037 if ((clocks < 1 ) || (clocks > 6 )) { 2038 die("Unknown Trwt"); 2039 } 2040 2041 dth = pci_read_config32(ctrl->f2, 0x8c ); 2042 dth &= ~(0x7 << 4 ); 2043 dth |= ((clocks - 1 ) << 4 ); 2044 pci_write_config32(ctrl->f2, 0x8c , dth); 2045 return; 2046} 2047static void set_Twcl(const struct mem_controller *ctrl, const struct mem_param *param) 2048{ 2049 2050 uint32_t dth; 2051 unsigned clocks; 2052 if (is_registered(ctrl)) { 2053 clocks = 2; 2054 } else { 2055 clocks = 1; 2056 } 2057 dth = pci_read_config32(ctrl->f2, 0x8c ); 2058 dth &= ~(0x7 << 20 ); 2059 dth |= ((clocks - 1 ) << 20 ); 2060 pci_write_config32(ctrl->f2, 0x8c , dth); 2061} 2062static void set_read_preamble(const struct mem_controller *ctrl, const struct mem_param *param) 2063{ 2064 uint32_t dch; 2065 unsigned divisor; 2066 unsigned rdpreamble; 2067 divisor = param->divisor; 2068 dch = pci_read_config32(ctrl->f2, 0x94 ); 2069 dch &= ~(0xf << 8 ); 2070 rdpreamble = 0; 2071 if (is_registered(ctrl)) { 2072 if (divisor == ((10 << 1)+0)) { 2073 2074 rdpreamble = ((9 << 1)+ 0); 2075 } 2076 else if (divisor == ((7 << 1)+1)) { 2077 2078 rdpreamble = ((8 << 1)+0); 2079 } 2080 else if (divisor == ((6 << 1)+0)) { 2081 2082 rdpreamble = ((7 << 1)+1); 2083 } 2084 else if (divisor == ((5 << 1)+0)) { 2085 2086 rdpreamble = ((7 << 1)+0); 2087 } 2088 } 2089 else { 2090 int slots; 2091 int i; 2092 slots = 0; 2093 for(i = 0; i < 4; i++) { 2094 if (ctrl->channel0[i]) { 2095 slots += 1; 2096 } 2097 } 2098 if (divisor == ((10 << 1)+0)) { 2099 2100 if (slots <= 2) { 2101 2102 rdpreamble = ((9 << 1)+0); 2103 } else { 2104 2105 rdpreamble = ((14 << 1)+0); 2106 } 2107 }

