After working hard about two weeks, I can't init sdram successfully. I'll attach the raminit.inc please help me check what's wrong. I've contacted with intel, they wouldn't like to provide me red book. tks zhu
_______________________________ Do you Yahoo!? Declare Yourself - Register online to vote today! http://vote.yahoo.com
jmp intel_i845gv_out
general_pci_clear_set_byte: //0003981B: 660FCF bswap edi movl %edi, %ebp //0003981E: BF2498 mov di,09824 ; //00039821: E951FF jmp 000039775 -------- (3) CALLDI(general_pci_read_byte) //00039824: F6D7 not bh notb %bh //00039826: 22C7 and al,bh andb %bh, %al //00039828: F6D7 not bh notb %bh //0003982A: 0AC3 or al,bl orb %bl, %al //0003982C: BF3198 mov di,09831 ; //0003982F: EB96 jmps 0000397C7 -------- (4) CALLDI(general_pci_write_byte) //00039831: 660FCF bswap edi movl %ebp, %edi //00039834: FFE7 jmp di RETDI
gmch_clear_set_byte: //00039836: BA0000 mov dx,00000 ; movw $0x0000, %dx //00039839: EBE0 jmps 00003981B -------- (5) jmp general_pci_clear_set_byte ich4_clear_set_byte: //0003983B: BAF800 mov dx,000F8 ; movw $0x00F8, %dx //0003983E: EBDB jmps 00003981B -------- (6) jmp general_pci_clear_set_byte clear_byte: //00039840: 8AF8 mov bh,al movb %al, %bh //00039842: B300 mov bl,000 ; movb $0x00, %bl //00039844: EBD5 jmps 00003981B -------- (7) jmp general_pci_clear_set_byte set_byte: //00039846: 0FB6D8 movzx bx,al movzx %al, %bx //00039849: EBD0 jmps 00003981B -------- (8) jmp general_pci_clear_set_byte gmch_clear_byte: //0003984B: BA0000 mov dx,00000 ; movw $0x0000, %dx //0003984E: EBF0 jmps 000039840 -------- (5) jmp clear_byte ich4_clear_byte: //00039850: BAF800 mov dx,000F8 ; movw $0x00F8, %dx //00039853: EBEB jmps 000039840 -------- (6) jmp clear_byte gmch_set_byte: //00039855: BA0000 mov dx,00000 ;" " movw $0x0000, %dx //00039858: EBEC jmps 000039846 -------- (7) jmp set_byte ich4_pci_set_byte: //0003985A: BAF800 mov dx,000F8 ; movw $0x00F8, %dx //0003985D: EBE7 jmps 000039846 -------- (8) jmp set_byte
pci_read_dword: movw $0xCF8,%dx andl $0xfffffffc, %eax outl %eax, %dx movw $0xCFC, %dx inl %dx, %eax RETSP
pci_write_dword: movw $0xCF8,%dx andl $0xfffffffc,%eax outl %eax,%dx movw $0xCFC, %dx movl %ebx,%eax outl %eax, %dx RETSP
pci_read_word: movw %ax, %dx bswapl %edx movw $0x0CF8, %dx andl $0xfffffffc, %eax outl %eax, %dx bswapl %edx movw %dx, %ax bswapl %edx andw $0x02, %ax addw %ax, %dx addw $0x04, %dx inw %dx, %ax RETSP
pci_write_word: movw %ax, %dx bswapl %edx movw $0x0CF8, %dx andl $0xfffffffc, %eax outl %eax, %dx bswapl %edx movw %dx, %ax bswapl %edx andw $0x02, %ax addw %ax, %dx addw $0x04, %dx movw %bx, %ax outw %ax, %dx RETSP
pci_read_byte: movw %ax, %dx bswapl %edx movw $0x0CF8, %dx andl $0xfffffffc, %eax outl %eax, %dx bswapl %edx movw %dx, %ax bswapl %edx andw $0x03, %ax addw %ax, %dx addw $0x04, %dx inb %dx, %al RETSP
pci_write_byte: movw %ax, %dx bswapl %edx movw $0x0CF8, %dx andl $0xfffffffc, %eax outl %eax, %dx bswapl %edx movw %dx, %ax bswapl %edx andw $0x03, %ax addw %ax, %dx addw $0x04, %dx mov %bl, %al outb %al, %dx RETSP
ram_3cb60: bswap %edx movw $0x0DFB, %bx mulw %bx movw $0x03E8, %bx divw %bx orw %dx, %dx je no_c incw %ax no_c: movzx %ax, %ebx movw $0x0800, %dx movw $0x0001, %ax outw %ax, %dx
addb $0x08, %dl inl %dx, %eax andl $0x00FFFFFF, %eax addl %eax, %ebx subb $0x08, %dl 1: testl $0xFF000000, %ebx je test_out in_loop: inw %dx, %ax andw $0x01, %ax je in_loop outw %ax, %dx subl $0x01000000, %ebx jmp 1b test_out: addb $0x08, %dl 2: inl %dx, %eax andl $0x00FFFFFF, %eax cmpl %eax, %ebx jb 2b bswap %edx RETSP
#define DEBUG_RAM_CONFIG 3
/* DDR DIMM Mode register Definitions */
#define BURST_2 (1<<0) #define BURST_4 (2<<0) #define BURST_8 (3<<0)
#define BURST_SEQUENTIAL (0<<3) #define BURST_INTERLEAVED (1<<3)
#define CAS_2_0 (1 << 5) #define CAS_2_5 00
#define MODE_NORM (0 << 7) #define MODE_DLL_RESET (2 << 7) #define MODE_TEST (1 << 7)
#define BURST_LENGTH BURST_4 #define BURST_TYPE BURST_INTERLEAVED #define CAS_LATENCY CAS_2_5
#define MRS_VALUE (MODE_NORM | CAS_LATENCY | BURST_TYPE | BURST_LENGTH) #define EMRS_VALUE 0x000
#define MD_SHIFT 4
#define RAM_COMMAND_NONE 0x0 #define RAM_COMMAND_NOP 0x1 #define RAM_COMMAND_PRECHARGE 0x2 #define RAM_COMMAND_MRS 0x3 #define RAM_COMMAND_EMRS 0x4 #define RAM_COMMAND_CBR 0x6 #define RAM_COMMAND_NORMAL 0x7
#define RAM_CMD(command, offset) \ movl $(((offset) << (MD_SHIFT + 16))|((command << 4) & 0x70)), %ebx ; \ CALLSP(do_ram_command) #define RAM_NOP() RAM_CMD(RAM_COMMAND_NOP, 0) #define RAM_PRECHARGE() RAM_CMD(RAM_COMMAND_PRECHARGE, 0) #define RAM_CBR() RAM_CMD(RAM_COMMAND_CBR, 0) #define RAM_EMRS() RAM_CMD(RAM_COMMAND_EMRS, EMRS_VALUE)
ram_cas_latency: .byte CAS_2_5, CAS_2_0 ram_mrs: /* Read the cas latency setting */ movl $0x78, %eax PCI_READ_CONFIG_BYTE /* Transform it into the form expected by SDRAM */ shrl $4, %eax andl $3, %eax movb ram_cas_latency(%eax), %al shll $(16+MD_SHIFT), %eax orl %eax, %ebx orl $((MODE_NORM | BURST_TYPE | BURST_LENGTH) << (16+MD_SHIFT)), %ebx jmp do_ram_command
#define RAM_MRS(dll_reset) \ movl $((dll_reset << (8+MD_SHIFT+ 16))|((RAM_COMMAND_MRS <<4)& 0x70)), %ebx ; \ CALLSP(ram_mrs)
#define RAM_NORMAL() \ movl $0x7c, %eax ;\ PCI_READ_CONFIG_BYTE ;\ andl $0x8F, %eax ;\ orb $(RAM_COMMAND_NORMAL << 4), %al ;\ movl %eax, %edx ;\ movl $0x7c, %eax ;\ PCI_WRITE_CONFIG_BYTE
#define RAM_RESET_DDR_PTR() \ movl $0x88, %eax ;\ PCI_READ_CONFIG_BYTE ;\ orb $(1 << 4), %al ;\ movl %eax, %edx ;\ movl $0x88, %eax ;\ PCI_WRITE_CONFIG_BYTE ;\ movl $0x88, %eax ;\ PCI_READ_CONFIG_BYTE ;\ andb $~(1 << 4), %al ;\ movl %eax, %edx ;\ movl $0x88, %eax ;\ PCI_WRITE_CONFIG_BYTE
do_ram_command: #if DEBUG_RAM_CONFIG >= 2 movl %esp, %esi movl %ebx, %edi CONSOLE_DEBUG_TX_CHAR($'P') CONSOLE_DEBUG_TX_CHAR($':') CONSOLE_DEBUG_TX_HEX8(%bl) CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n') movl %edi, %ebx movl %esi, %esp #endif /* %ecx - initial address to read from */ /* Compute the offset */ movl %ebx, %ecx shrl $16, %ecx
1: /* Set the ram command */
CONSOLE_DEBUG_TX_CHAR($'Z') CONSOLE_DEBUG_TX_CHAR($':') movl $0x7c, %eax PCI_READ_CONFIG_BYTE movl %eax, %esi CONSOLE_DEBUG_TX_HEX8(%al) movl %esi, %eax andl $0x8F, %eax orb %bl, %al movl %eax, %esi
CONSOLE_DEBUG_TX_HEX8(%al) CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n')
movl %esi, %edx movl $0x7c, %eax PCI_WRITE_CONFIG_BYTE /* Assert the command to the memory */ #if DEBUG_RAM_CONFIG >= 2 movl %esp, %esi movl %ebx, %edi CONSOLE_DEBUG_TX_CHAR($'R') CONSOLE_DEBUG_TX_CHAR($':') CONSOLE_DEBUG_TX_HEX32(%ecx) CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n') movl %edi, %ebx movl %esi, %esp #endif CONSOLE_DEBUG_TX_CHAR($'S') CONSOLE_DEBUG_TX_CHAR($':')
movl $0x7c, %eax PCI_READ_CONFIG_BYTE movb %al, %bh CONSOLE_DEBUG_TX_HEX8(%bh) CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n') movl (%ecx), %eax CONSOLE_DEBUG_TX_CHAR($'T') CONSOLE_DEBUG_TX_CHAR($':')
CONSOLE_DEBUG_TX_HEX8(%al) CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n')
/* Go to the next base address */ addl $0x02000000, %ecx /* Increment the counter */ incb %bh
/* See if we are done */ cmpb $8, %bh jb 1b
3: /* The command has been sent to all dimms so get out */ RETSP
#define ENABLE_REFRESH() \ movl $0x7c, %eax ;\ PCI_READ_CONFIG_DWORD ;\ orl $(1 << 29), %eax ;\ movl %eax, %ecx ;\ mov $0x7c, %eax ;\ PCI_WRITE_CONFIG_DWORD
/* * Table: constant_register_values */ .p2align 3 constant_register_values: /* SVID - Subsystem Vendor Identification Register * 0x2c - 0x2d * [15:00] Subsytem Vendor ID (Indicates system board vendor) */ /* SID - Subsystem Identification Register * 0x2e - 0x2f * [15:00] Subsystem ID */ .long 0x2c, 0, (0x1849 << 0) | (0x2560 << 16) /* 40 - 4F */ .long 0x40, 0, (05 << 8) | (0xbc << 0 ) .long 0x44, 0, (0x41 << 0) | (0x20 << 8) | (0x10 << 16)|(0x20<<24) .long 0x48, 0, (0x04 << 0) | (0x01 << 8) .long 0x4c, 0, (0x1b << 0) | (0x08 << 8) | (0x10 << 16)
/* GC - Graphic Control Register */ /* 0x52 */ .long 0x52, 0, 0x00000044
/* DRB - DRAM Row Boundary Registers * 0x60 - 0x63 * An array of 8 byte registers, which hold the ending * memory address assigned to each pair of DIMMS, in 32MB * granularity. */ /* Conservatively say each row has 32MB of ram, we will fix this up later */ // .long 0x60, 0x00000000, (0x01 << 0) | (0x02 << 8) | (0x03 << 16) | (0x04 << 24) /* Aggresively say each row has max ram = 1G, we will fix this up later */ .long 0x60, 0x00000000, (0x08 << 0) | (0x08 << 8) | (0x08 << 16) | (0x08 << 24)
/* DRA - DRAM Row Attribute Register * 0x70 Row 0,1 * 0x71 Row 2,3 * [7:7] reserved * [6:4] Row Attributes for Odd numbered rows * 000 == 2KB * 001 == 4KB * 010 == 8KB * 011 == 16KB * Others == Reserved * [3:3] reserved * [2:0] Row Attributes for Even numbered rows * 000 == 2KB * 001 == 4KB * 010 == 8KB * 011 == 16KB (This page size appears broken) * Others == Reserved */ .long 0x70, 0x00000000, 0x00000002
/* DRT - DRAM Time Register * 0x78-0x7B * [31:18] Reserved * [17:15] * 000: infinite * 001: 0 * 010: 8 DRAM clocks * 011: 16 DRAM clocks * 100: 64 DRAM clocks * others: * [14:12] Reserved * [11] * 0 == 120us * 1 == reserved * [10:9] * 00 == 8 clocks * 01 == 7 clocks * 10 == 6 clocks * 11 == 5 clocks * [8:7] Reserved * [6:5] DDR CL * 00 == 2.5 * 01 == 2 * 10 == Reserved * 11 == Reserved * [4] Reserved * [3:2] RAS# to CAS# delay * 01 == 3 DRAM clocks * 10 == 2 DRAM Clocks * 11 == Reserved * [1:0] DRAM RAS# precharge * 00 == Reserved * 01 == 3 DRAM Clocks * 10 == 2 DRAM Clocks * 11 == Reserved */ #define DRT_CAS_2_5 (0<<5) #define DRT_CAS_2_0 (1<<5) #define DRT_CAS_MASK (3<<5)
#if CAS_LATENCY == CAS_2_5 #define DRT_CL DRT_CAS_2_5 #elif CAS_LATENCY == CAS_2_0 #define DRT_CL DRT_CAS_2_0 #endif
/* Most aggressive settings possible */ // .long 0x78, 0x00007190, (0x2b<<24)|(0x41<<16)|(0x82<<8)|0x05 .long 0x78, 0x00000000, (0x00<<24)|(0x00<<16)|(0x00<<8)|0x00
/* FIXME why was I attempting to set a reserved bit? */ /* 0x0100040f */
/* DRC - DRAM Contoller Mode Register * 0x7c * [31:30] Reserved * [29:29] Initialization Complete * 0 == Not Complete * 1 == Complete * [28:28] Dynamic Power-Down Mode Enable * 0 == disable * 1 == enable * [27:10] Reserved * [09:07] Refresh mode select * 000 == Reserved * 001 == Refresh interval 15.6 usec * 010 == Refresh interval 7.8 usec * 011 == Refresh interval 64 usec * 111 == Refresh interval 64 clocks * others == Reserved * [06:04] Mode Select (SMS) * 000 == Self Refresh Mode * 001 == NOP Command * 010 == All Banks Precharge * 011 == Mode Register Set * 100 == Extended Mode Register Set * 101 == Reserved * 110 == CBR Refresh * 111 == Normal Operation * [03:01] Reserved * [00:00] DRAM type(RO) * 0 == SDR * 1 == DDR */ // .long 0x7c, 0x0000007f, (0x20<<24)|(0xc0<<8)|(1 << 8)
/* 0x80 - 8B */ .long 0x80, 0, (00<<24)|(0xaf <<16)|(0x01<<8)|(0x29) .long 0x84, 0, 0xad .long 0x88, 0, 0x01
/* FDHC - Fixed DRAM Hole Control * 0x97 * [7:7] Hole_Enable * 0 == No memory Hole * 1 == Memory Hole from 15MB to 16MB * [6:0] Reserved * * PAM - Programmable Attribute Map * 0x90 [3:0] Reserved * 0x90 [7:4] 0xF0000 - 0xFFFFF * 0x91 [1:0] 0xC0000 - 0xC3FFF * 0x91 [5:4] 0xC4000 - 0xC7FFF * 0x92 [1:0] 0xC8000 - 0xCBFFF * 0x92 [5:4] 0xCC000 - 0xCFFFF * 0x93 [1:0] 0xD0000 - 0xD3FFF * 0x93 [5:4] 0xD4000 - 0xD7FFF * 0x94 [1:0] 0xD8000 - 0xDBFFF * 0x94 [5:4] 0xDC000 - 0xDFFFF * 0x95 [1:0] 0xE0000 - 0xE3FFF * 0x95 [5:4] 0xE4000 - 0xE7FFF * 0x96 [1:0] 0xE8000 - 0xEBFFF * 0x96 [5:4] 0xEC000 - 0xEFFFF * 00 == DRAM Disabled (All Access go to memory mapped I/O space) * 01 == Read Only (Reads to DRAM, Writes to memory mapped I/O space) * 10 == Write Only (Writes to DRAM, Reads to memory mapped I/O space) * 11 == Normal (All Access go to DRAM) */ .long 0x90, 0x00000000, 0x03311110 .long 0x94, 0x00000000, 0x00110000 .long 0x98, 0x0000ffff, 0x00000445 .long 0x9c, 0xff0000ff, 0x00380a00
constant_register_values_end:
/* * Routine: ram_set_registers * Arguments: none * Results: none * Trashed: %eax, %ebx, %ecx, %edx, %esi, %eflags * Effects: Do basic ram setup that does not depend on serial * presence detect information. * This sets PCI configuration registers to known good * values based on the table: * constant_register_values * Which are a triple of configuration regiser, mask, and value. * */ /* DDR RECOMP/SCOMP table */ .p2align 3
.p2align 3 ram_set_registers: movb $0xAD, %al outb %al, $0x80 #if DEBUG_RAM_CONFIG CALLSP(dumpnorth) #endif movl $constant_register_values, %ebx jmp ram_set_one_register_start ram_set_one_register: #if DEBUG_RAM_CONFIG movl %ebx, %esi CONSOLE_DEBUG_TX_CHAR($'C') CONSOLE_DEBUG_TX_CHAR($':') movl 0(%esi), %eax CONSOLE_DEBUG_TX_HEX32(%eax) CONSOLE_DEBUG_TX_CHAR($':') movl 4(%esi), %eax CONSOLE_DEBUG_TX_HEX32(%eax) CONSOLE_DEBUG_TX_CHAR($':') movl 8(%esi), %eax CONSOLE_DEBUG_TX_HEX32(%eax) CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n') movl %esi, %ebx #endif /* DEBUG_RAM_CONFIG */ movl 0(%ebx), %eax /* Read the original value to preserve the reserved bits */ PCI_READ_CONFIG_DWORD movl 4(%ebx), %edx /* Reserved bits mask */ andl %edx, %eax /* Preserve only the reserved bits */ movl 8(%ebx), %ecx /* Read the new values into %ecx */ notl %edx andl %edx, %ecx /* Keep only the unreserved bits */ orl %eax, %ecx /* Put the two sets of bits together */ movl 0(%ebx), %eax /* Refetch the address to write */ PCI_WRITE_CONFIG_DWORD addl $12, %ebx ram_set_one_register_start: cmpl $constant_register_values_end, %ebx jb ram_set_one_register #if DEBUG_RAM_CONFIG CALLSP(dumpnorth) #if DEBUG_RAM_CONFIG CALLSP(dumplpc) CALLSP(dumppcibridge) #endif
#endif RET_LABEL(ram_set_registers)
ram_3aada: movl %esp, %ebp
/* RAM NOP */ movb $0x7C, %al andl $0x000000ff, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) andb $0x8F, %al orb $0x10, %al movl %eax, %ebx movb $0x7C, %al andl $0x000000ff, %eax orl $0x80000000, %eax CALLSP(pci_write_dword) #if 0 movb $0x7C, %al andl $0x000000ff, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) outb %al, $0x80 #endif
#if 1 movb $0xeb, %al outb %al,$0x80 #endif
movl (%esi), %eax movb $0xec, %al outb %al, $0x80
movl $0x0C8, %eax CALLSP(ram_3cb60)
CONSOLE_DEBUG_TX_CHAR($'R') CONSOLE_DEBUG_TX_CHAR($'1') CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n')
/* All Banks Pre-Charge */ xorl %esi, %esi movb $0x7c, %al andl $0x000000ff, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) andb $0x8F, %al orb $0x20, %al movl %eax, %ebx movb $0x7c, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_write_dword) movl (%esi), %eax CONSOLE_DEBUG_TX_CHAR($'R') CONSOLE_DEBUG_TX_CHAR($'2') CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n')
/* EMRS */ movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) andb $0x8F, %al orb $0x40, %al mov %eax, %ebx movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_write_dword) movl (%esi), %eax CONSOLE_DEBUG_TX_CHAR($'R') CONSOLE_DEBUG_TX_CHAR($'3') CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n')
/* MRS */ movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) andb $0x8F, %al orb $0x30, %al movl %eax, %ebx movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_write_dword) addl $0x350, %esi orl $0x800, %esi movl (%esi), %eax andl $0xFE000000, %esi /* precharge */ movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) movb $0x8F, %al orb $0x20, %al movl %eax, %ebx movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_write_dword) movl (%esi), %eax /* CBR Refresh Enable */ movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) andb $0x8F, %al orb $0x60, %al movl %eax, %ebx movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_write_dword) movl (%esi), %eax movl (%esi), %eax movl (%esi), %eax movl (%esi), %eax movl (%esi), %eax movl (%esi), %eax movl (%esi), %eax movl (%esi), %eax addl $0x350, %esi movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) andb $0x8F, %al orb $0x30, %al movl %eax, %ebx movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_write_dword) movl (%esi), %eax andl $0xFE000000, %esi
movl %ebp, %esp RETSP
/* * Routine: sdram_read_paired_byte * Arguments: %esp return address * %bl device on the smbus to read from * %bh address on the smbus to read * Results: * zf clear * byte read in %al * On Error: * zf set * %eax trashed * * Preserved: %ebx, %esi, %edi * * Trashed: %eax, %ecx, %edx, %ebp, %esp, %eflags * Used: %eax, %ebx, %ecx, %edx, %esp, %eflags * * Effects: Reads two spd bytes from both ram channesl * and errors if they are not equal. * It then returns the equal result. */ spd_read_paired_byte: movl %esp, %ebp CALLSP(smbus_read_byte) setnz %cl movb %al, %ch /* zhu */ CONSOLE_INFO_TX_CHAR($'Z') CONSOLE_INFO_TX_CHAR($':') CONSOLE_INFO_TX_HEX8(%ch) CONSOLE_INFO_TX_CHAR($'\r') CONSOLE_INFO_TX_CHAR($'\n') movb %ch, %al /* Clear the zero flag */ testb %cl, %cl spd_verify_byte_out: movl %ebp, %esp RETSP
/* * Routine: spd_verify_dimms * Arguments: none * Results: none * Preserved: none * Trashed: %eax, %ebx, %ecx, %edx, %ebp, %esi, %edi, %esp, %eflags * Used: %eax, %ebx, %ecx, %edx, %ebp, %esi, %edi, %esp, %eflags * * Effects: * - Verify all interesting spd information * matches for both dimm channels. * - Additional error checks that can be easily done * here are computed as well, so I don't need to * worry about them later. */ spd_verify_dimms: movl $(SMBUS_MEM_DEVICE_START), %ebx spd_verify_dimm: /* Verify this is DDR SDRAM */ movb $2, %bh CALLSP(spd_read_paired_byte) jz spd_verify_next_dimm cmpb $7, %al jne invalid_dimm_type
/* Verify the row addresses */ movb $3, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb $0x0f, %al jz spd_invalid_data /* Column addresses */ movb $4, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb $0xf, %al jz spd_invalid_data
/* Physical Banks */ movb $5, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data cmp $1, %al jb spd_invalid_data cmp $2, %al ja spd_invalid_data
/* Module Data Width */ movb $7, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data cmpb $0, %al jne spd_invalid_data
movb $6, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data cmpb $64, %al je 1f cmpb $72, %al je 1f jmp spd_unsupported_data 1:
/* Cycle time at highest CAS latency CL=X */ movb $9, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data
/* SDRAM type */ movb $11, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data
/* Refresh Interval */ movb $12, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data /* SDRAM Width */ movb $13, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data andb $0x7f, %al cmpb $4, %al je 1f cmpb $8, %al je 1f jmp spd_unsupported_data 1:
/* Back-to-Back Random Column Accesses */ movb $15, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb %al, %al jz spd_invalid_data cmpb $4, %al ja spd_unsupported_data
/* Burst Lengths */ movb $16, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb $(1<<2), %al jz spd_unsupported_data
/* Logical Banks */ movb $17, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb %al, %al jz spd_invalid_data /* Supported CAS Latencies */ movb $18, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb $(1 << 1), %al /* CL 1.5 */ jnz 1f testb $(1 << 2), %al /* CL 2.0 */ jnz 1f testb $(1 << 3), %al /* CL 2.5 */ jnz 1f jmp spd_unsupported_data 1: /* Cycle time at Cas Latency (CLX - 0.5) */ movb $23, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data /* DRAM Minimum Clock Cycle when CL is Derated by One Clock*/ movb $25, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data
/* Cycle time at Cas Latency (CLX - 1.0) */ movb $26, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data /* tRP Row precharge time */ movb $27, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb $0xfc, %al jz spd_invalid_data
/* tRCD RAS to CAS */ movb $29, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb $0xfc, %al jz spd_invalid_data /* tRAS Activate to Precharge */ movb $30, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb %al, %al jz spd_invalid_data
/* Module Bank Density */ movb $31, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data testb $(1<<2), %al /* 16MB */ jnz spd_unsupported_data testb $(1<<3), %al jnz spd_unsupported_data /* 32MB */ /* Address and Command Hold Time After Clock */ movb $33, %bh CALLSP(spd_read_paired_byte) jz spd_missing_data
spd_verify_next_dimm: /* go to the next DIMM */ addb $(SMBUS_MEM_DEVICE_INC), %bl /* increment the smbus device */ cmpb $SMBUS_MEM_DEVICE_END, %bl jbe spd_verify_dimm spd_verify_dimms_out: RET_LABEL(spd_verify_dimms)
/* Estimate that SLOW_DOWN_IO takes about 50&76us*/ /* delay for 200us */
#define DO_DELAY \ movl $16, %edi ; \ 1: SLOW_DOWN_IO ; \ decl %edi ; \ jnz 1b
#define EXTRA_DELAY DO_DELAY
#define ERRFUNC(x, str) \ .section ".rom.data" ;\ x##_str: ;\ .string str ;\ .ascii str ;\ .previous ;\ x: ;\ movl $x##_str, %esi ;\ jmp mem_err
ERRFUNC(invalid_dimm_type, "Invalid dimm type") ERRFUNC(spd_missing_data, "Missing sdram spd data") ERRFUNC(spd_invalid_data, "Invalid sdram spd data") ERRFUNC(spd_unsupported_data, "Unsupported sdram spd value") ERRFUNC(unsupported_page_size, "Unsupported page size") ERRFUNC(sdram_presence_mismatch, "DIMM presence mismatch") ERRFUNC(sdram_value_mismatch, "spd data does not match") ERRFUNC(unsupported_refresh_rate, "Unsuported spd refresh rate") ERRFUNC(inconsistent_cas_latencies, "No cas latency supported by all dimms") ERRFUNC(unsupported_rcd, "Unsupported ras to cas delay") #undef ERRFUNC
.section ".rom.data" mem_err_err: .string "ERROR: " mem_err_pair: .string " on dimm pair " mem_err_byte: .string " spd byte " crlf: .string "\r\n" .previous mem_err: movl %ebx, %edi CONSOLE_ERR_TX_STRING($mem_err_err) CONSOLE_ERR_TX_STRING(%esi) CONSOLE_ERR_TX_STRING($mem_err_pair) movl %edi, %ebx subb $(SMBUS_MEM_DEVICE_START), %bl CONSOLE_ERR_TX_HEX8(%bl) CONSOLE_ERR_TX_STRING($mem_err_byte) movl %edi, %ebx CONSOLE_ERR_TX_HEX8(%bh) jmp mem_stop
mem_stop: CONSOLE_ERR_TX_STRING($crlf) 1: hlt /* stick here.. */ jmp 1b
intel_i845gv_out:
CALL_LABEL(spd_verify_dimms)
CALL_LABEL(ram_set_registers) DO_DELAY EXTRA_DELAY //00039EDB: 6633F6 xor esi,esi xorl %esi, %esi //00039EDE: 32C9 xor cl,cl xorb %cl, %cl //00039EE0: B060 mov al,060 ; movb $0x60, %al //00039EE2: 6625FF000000 and eax,0000000FF ; andl $0x000000FF, %eax //00039EE8: 660D00000080 or eax,080000000 ; orl $0x80000000, %eax //00039EEE: 660FCC bswap esp //00039EF1: BCF79E mov sp,09EF7 ; //00039EF4: E9DFFA jmp 0000399D6 -------- (1) //00039EF7: 660FCC bswap esp CALLSP(pci_read_dword) 2: //00039EFA: 38C8 cmp al,cl cmpb %cl, %al //00039EFC: 7412 je 000039F10 -------- (2) je 1f //00039EFE: 668BF8 mov edi,eax movl %eax, %edi //00039F01: 660FCC bswap esp //00039F04: BC0A9F mov sp,09F0A ; //00039F07: E9D00B jmp 00003AADA -------- (3) //00039F0A: 660FCC bswap esp CALLSP(ram_3aada) //00039F0D: 668BC7 mov eax,edi movl %edi, %eax 1: //00039F10: 8AC8 mov cl,al movb %al, %cl //00039F12: 6633F6 xor esi,esi xorl %esi, %esi //00039F15: 660FB6F1 movzx esi,cl movzx %cl, %esi //00039F19: 66C1E619 shl esi,019 ; shll $0x19, %esi //00039F1D: 66C1E808 shr eax,008 ; shrl $0x08, %eax //00039F21: 6683F800 cmp eax,000 ; cmpl $0x00, %eax //00039F25: 75D3 jne 000039EFA -------- (3) jne 2b
/* normal mode */ movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_read_dword) andb $0x8F, %al orb $0x70, %al movl %eax, %ebx movb $0x7C, %al andl $0x000000FF, %eax orl $0x80000000, %eax CALLSP(pci_write_dword)
CONSOLE_DEBUG_TX_CHAR($'E') CONSOLE_DEBUG_TX_CHAR($'N') CONSOLE_DEBUG_TX_CHAR($'\r') CONSOLE_DEBUG_TX_CHAR($'\n') hlt