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.comjmp 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