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
        

Reply via email to