I am porting LinuxBIOS to a board with an SIS 635 chipset. I started
with the 630 code and modified it according to the programmer's guide
and some SIS sample code, but RAM (DDR in this case) is not being
initialized. The relevant code is attached; can anyone offer hints about
what might be wrong?

Wes Felter
System Software Department
IBM Austin Research Lab
11400 Burnet Rd., Austin, TX 78758
Tel 512-838-7933
/*
 * 635_regs.inc:	Register Recommended Setting for SiS 635 [ABE][01]
 *
 *
 * Copyright 2000 Silicon Integrated Systems Corporation
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 * Reference:
 *	1. SiS 630 Specification
 *	2. SiS 630A1 Register Recommended Setting
 *	   Rev 0.97, Jan 7, 2000
 *
 * $Id: 635_regs.inc,v 1.5 2001/10/18 21:08:31 wes Exp $
 */

northbridge_init_table:
 	#	Reg.	Value
	/* generic PCI configuration space */
	.byte	0x04,	0x07	# Turn on Bus Master,
	.byte	0x05,	0x00	# Memory and I/O Space UNDOCUMENTED
	.byte	0x07,	0x02	# Clear status 1s clear UNDOCUMENTED
	.byte	0x0D,	0x20	# Master Latency Timer = 32 PCI CLCK

	/* Host Control Interface */

	.byte 0x50,	0xFF		# various FSB & PCI settings
	.byte	0x51,	0x07	# no MDA, no VGA, various other
	.byte	0x52,	0x71	# bus priorities
	.byte	0x53,	0x83	# PCI33 settings

	.byte 0x54,	0x03	# PCI66 settings
	.byte 0x55,	0x01	# CPU-Mem settings
	.byte 0x56,	0x88	# PCI33 lock timers
	.byte 0x57,	0x88	# PCI66 lock timers

	.byte 0x58,	0x00	# SDRAM timings (conservative)
	.byte 0x59,	0x29	# mem times: CAS 2

	.byte	0x5A,	0x38	# mem lead-off (non-std), bypass enable
	.byte	0x5B,	0x03	# read combine off, write combine on
						# p. 9
	.byte	0x5C,	0x00	# mem init cmd mode, MD/DQS (both non-std)
	.byte	0x5D,	0xD1	# mem refresh Q=12 (non-std),
						# mem clock=100, refresh cycle enable
	.byte	0x5E,	0x03	#  ahead refresh
	.byte	0x5F,	0x00	#  UNDOCUMENTED
	.byte	0x6A,	0x26	#  
						# p. 10
	.byte	0x6C,	0x20	# CKE (must) (non-std), ACPI on (non-std)

	/* SiS 630 specific registers. See SiS 630 Registers Recommended Setting */

#	.byte	0x70,0x00		#Disable C000-C7FF Shadow Read	
#	.byte	0x72,0x00		#Disable C000-C7FF Shadow Write 
#	.byte	0x71,0x9F		#Disable E000-FFFF Shadow Read	
#	.byte	0x73,0x1F		#Disable E000-FFFF Shadow Write 
	
	.byte	0x68,	0x01	# ACPI_IO_BASE UNDOCUMENTED
	.byte	0x69,	0x80	#  UNDOCUMENTED

	.byte	0x80,	0x22
	.byte	0x81,	0x02
	.byte	0x82,	0x30
	.byte	0x83,	0x03
	.byte	0x84,	0x15
	.byte	0x85,	0x00
	.byte	0x86,	0x80
	.byte	0x87,	0x01
	.byte	0x88,	0x20
	.byte	0x89,	0x04
	.byte	0x8A,	0x00
	.byte	0x8B,	0x04

						# p.12
	.byte	0x90,	0x00	# GART
	.byte	0x91,	0x00	# UNDOCUMENTED
	.byte	0x92,	0x00	# UNDOCUMENTED
	.byte	0x93,	0x00	#  UNDOCUMENTED
	.byte	0x94,	0x40	#  GART
	.byte	0x95,	0x01	#  GART
	.byte	0x96,	0x00	# UNDOCUMENTED
	.byte	0x97,	0x01	#  GART
	.byte	0x98,	0x00	#  GART
	.byte	0x99,	0x10	# docs incomplete
						# p.13
	.byte	0x9A,	0xbb	# strobe signal: DDR, 2.4ns (100MHz?)
	.byte	0x9B,	0x42	#  AGP TCLK, CPUCLK/SDCLK agressive

				#  I don't know what's up with these,
				#  since they were just programmed above:
	.byte	0x99,	0x20	# (must)
	.byte	0x9A,	0x52	# (must)
	.byte	0x9B,	0x42	# (must)

	.byte	0xA0,	0x42
	.byte	0xA1,	0x2A
	.byte	0xA2,	0x22

	.byte	0x9C,	0x00	# (must) double word MD signals hold time
	.byte	0x9D,	0x00	# (must) DQM/MA signals hold time
	.byte	0x9E,	0x00	# (must) CSA/CSB signals hold time
	.byte	0x9F,	0x10	# (must) CKE setup time (100MHz?)

	.byte	0xA3,	0x01
	.byte	0xA4,	0x02

	.byte	0xD0,	0x22
	.byte	0xD1,	0x02
	.byte	0xD2,	0x33
	.byte	0xD3,	0x00
	.byte	0xD4,	0x01
	.byte	0xD5,	0xFF
	.byte	0xD6,	0xFF
	.byte	0xD8,	0x60
	.byte	0xD9,	0x60
	.byte	0xDA,	0xAA
	.byte	0xDC,	0x00
	.byte	0xDD,	0x88

northbridge_init_table_end:
/* $Id: 635_mem_size.inc,v 1.5 2001/10/11 22:35:45 wes Exp $
 *
 * based on ctmemsize.inc from SIS
 */
#define EDOPATTERN	$0x055AA55AA
#define MPATTERN0	$0x012345678
#define MPATTERN1	$0x0FEDCBA98
#define IODELAY     jmp 1f; 1: # not sure if this is right
#define Fail_Value  $0xFF

Start_DRAM_Sizing:
		mov	$0x06C, %ah  # CKE output enable control Reg6C b5=1 
		CALL_SP(read_northbridge_register)
		or	$0x20, %al
		CALL_SP(write_northbridge_register)

	#************************************************* 
	# check H/W Trap for SDR/DDR Reg7C b2= 0:SDR 1:DDR  
	#************************************************* 

		mov	$0x07C, %ah
		CALL_SP(read_northbridge_register)
		test	$0x04, %al
		jnz	DDR_Device

SDR_Device:
		# should not be reached, since we do not have SDRAM
		jmp .Lhlt

DDR_Device:

		mov	$0x05C, %ah  # DDR MD/DQS input enable control Reg5C b1=1 
		CALL_SP(read_northbridge_register)
		or	$0x02, %al
		CALL_SP(write_northbridge_register)

		mov	$0x0A0, %ah
		CALL_SP(read_northbridge_register)
		or	 $0x40, %al			#S02 
		CALL_SP(write_northbridge_register)

		# FIXME: I dont know ACPI_BASE_IO_ADDR, so this is commented out
		#mov	ACPI_BASE_IO_ADDR+$0x056, %dx  # CKE Floating ACPI Reg56 b5=1 
		#in	%dx, %al
		#or	$0x20, %al
		#out	%al, %dx


		mov	$0x09A, %ah  # H/W recommand setting 
		CALL_SP(read_northbridge_register)			#ying 
		or	$0x10, %al			#ying 
		CALL_SP(write_northbridge_register)

		mov	$0x05C, %ah
		CALL_SP(read_northbridge_register)		   # Set REF Command 
		and	 $0x8F, %al
		or	$0x30, %al
		CALL_SP(write_northbridge_register)

		mov	 $0x10, %cl

Refresh_Loop:

		mov	$0x05C, %ah
		CALL_SP(read_northbridge_register)		   # Command Enable 
		or	$0x08, %al
		CALL_SP(write_northbridge_register)
		dec	%cl
		jnz Refresh_Loop


		mov	$0x05B, %ah  # One Page Mode Enable Reg5B b2=1 
		CALL_SP(read_northbridge_register)
		or	$0x04, %al
		CALL_SP(write_northbridge_register)

Test_DDR_Start:

      #**********************************************
      #	      tell Unbuffer DDR or Registered DDR      
      #********************************************** 
		mov	 $0x06D, %al		#Set Dram type is UnbDDR 
		CALL_SP(Assume_All_Dimms_Type)
		CALL_SP(Scan_All_Dimms)
		jnz	 End_Dram_Sizing	# clc-exists 

		mov	 $0x0ED, %al		#Set Dram type is RegDDR (not reached)
		CALL_SP(Assume_All_Dimms_Type)
		CALL_SP(Scan_All_Dimms)
		jnz	 End_Dram_Sizing	# clc-exists 

No_Dram:
		mov  $0x0DE, %al		#no memory device on any dimm
		out	%al, $0x80
		jmp .Lhlt

End_Dram_Sizing:

		mov	$0x05B, %ah  # Disable One Page Control 
		CALL_SP(read_northbridge_register)
		andb	$0x0FB, %al
		CALL_SP(write_northbridge_register)


		mov	$0x064, %ah
		CALL_SP(read_northbridge_register)
		mov	 %al, %bl

		#xchg	%bp, %sp
		jmp mem_size_end

# ********************************************************;
# Assume_All_Dimms_Type;
# Input: AL						 ;
# Output: Set NB 60h~63h by AL				 ;
# ********************************************************;
Assume_All_Dimms_Type:
		xchg	%esp, %ebp
		mov	$0x0, %cl
	43:
		mov $0x060, %ah
		addb	 %cl, %ah
		CALL_SP(write_northbridge_register) #clobbers eax, ebx, edx
		inc	%cl
		cmp	$0x4, %cl
		jb	43b
		xchg	%esp, %ebp
		RET_SP

#**************************************************************************;
# CheckSizeMemory							   ;
# 1. Check Memory Device on Dimm or not					   ;
# 2. Find out the physical MA Table					   ;
#**************************************************************************;
Scan_All_Dimms:

		mov	%esp, %ebp			#ying what does this do?
		ror $0x10, %ebx			#ying
		mov	$0x0, %esi	# dimm index

Check_Memory_Loop:

		mov	$0x01, %bl
		mov	%si, %cx
		shl	%cl, %bl
		mov $0x064, %ah	# DRAM Status Register
		mov	%bl, %al
		CALL_SP(write_northbridge_register)

		mov $0x05D, %ah  # Disable Refresh Cycle
		CALL_SP(read_northbridge_register)
		andb	$0x0FE, %al
		CALL_SP(write_northbridge_register)

    # ************************* ;
    #  Check If DDR is Plugged	;
    # ************************* ;

		mov $0x060, %ah
		mov $0x00, %edx     # I hope edx is not being used
		mov %ah, %dl        # add the DIMM number (%esi) to the register number
		add	%esi, %edx
		mov %dl, %ah
		CALL_SP(read_northbridge_register)
		test $0x040, %al		   # Reg.60~64 b6 = Switch of SDRAM/DDR
		jz	Check_SDRAM

		mov $0x05C, %ah
		CALL_SP(read_northbridge_register)
		and	$0x8F, %al
		or	$0x10, %al		   # PALL : Precharge ALL
		CALL_SP(write_northbridge_register)
		or	$0x08, %al		   # Command Enable
		CALL_SP(write_northbridge_register)

		mov $0x05C, %ah
		CALL_SP(read_northbridge_register)
		and	$0x8F, %al
		or	$0x40, %al		   # EMRS-N : DLL-Enable Normal
		CALL_SP(write_northbridge_register)
		or	$0x08, %al		   # Command Enable
		CALL_SP(write_northbridge_register)

		mov $0x05C, %ah
		CALL_SP(read_northbridge_register)
		and	$0x8F, %al
		or	$0x60, %al		   # DLL-Reset : DLL Reset
		CALL_SP(write_northbridge_register)
		or	$0x08, %al		   # Command Enable
		CALL_SP(write_northbridge_register)

	Check_SDRAM:

		mov $0x05C, %ah
		CALL_SP(read_northbridge_register)
		and	$0x8F, %al
		or	$0x10, %al		   # PALL : Precharge ALL
		CALL_SP(write_northbridge_register)
		or	$0x08, %al		   # Command Enable
		CALL_SP(write_northbridge_register)

		mov $0x05C, %ah
		CALL_SP(read_northbridge_register)
		and	$0x8F, %al
		or	$0x20, %al		   # MRS : Mode Register Set
		CALL_SP(write_northbridge_register)
		or	$0x08, %al		   # Command Enable
		CALL_SP(write_northbridge_register)

		mov $0x05C, %ah
		CALL_SP(read_northbridge_register)
		and	$0x8F, %al
		or	$0x30, %al		   # REF : Refresh
		CALL_SP(write_northbridge_register)
		or	$0x08, %al		   # Command Enable
		CALL_SP(write_northbridge_register)

		mov $0x05C, %ah
		CALL_SP(read_northbridge_register)
		and	$0x8F, %al
		or	$0x30, %al		   # REF : Refresh
		CALL_SP(write_northbridge_register)
		or	$0x08, %al		   # Command Enable
		CALL_SP(write_northbridge_register)

		mov $0x05D, %ah
		CALL_SP(read_northbridge_register)
		or	$0x01, %al		   # Enable Refresh Cycle
		CALL_SP(write_northbridge_register)

		CALL_SP(Check_Memory_Plugged_Or_Not)	# Check if Memory Plugged
		jc	No_Memory_Plugged_on_Dimm

		CALL_SP(Test_MA)		# Find out the real MA Type
						# al = Test_MA output
		cmp	Fail_Value, %al
		je	No_Memory_Plugged_on_Dimm

		mov	%al, %bl			# save al(MA-Type) to bl
		and	$0x0F, %bl			# clear higher 4-bits in bl

		CALL_SP(Test_Side)		# determine Single/Double Side
		jnz	Memory_Single_Side
		or	$0x20, %bl			# Set Double Side

Memory_Single_Side:

		mov $0x060, %ah
		mov $0x00, %edx     # I hope edx is not being used
		mov %ah, %dl        # add the DIMM number (%esi) to the register number
		add	%esi, %edx
		mov %dl, %ah
		CALL_SP(read_northbridge_register)
		and	$0xC0, %al		# reserve Reg60~63 bit-7,6
		or	%bl, %al
		CALL_SP(write_northbridge_register)

		mov	$0x1, %bx
		mov	%si, %cx
		shl	%cl, %bx
		ror	$0x10, %esi
		or	%bx, %si
		rol	$0x10, %esi

No_Memory_Plugged_on_Dimm:

		mov $0x05C, %ah
		CALL_SP(read_northbridge_register)
		and	$0x8F, %al
		or	$0x10, %al		   # PALL : Precharge ALL
		CALL_SP(write_northbridge_register)
		or	$0x08, %al		   # Command Enable
		CALL_SP(write_northbridge_register)

		inc	%si
		cmp	$0x4, %si
		jae	All_Dimms_Determined
		jmp    Check_Memory_Loop

All_Dimms_Determined:
		ror	$0x10, %esi
		mov	$0x64, %cx
		mov	%si, %ax
		CALL_SP(write_northbridge_register)
		ror	$0x10, %ebx		#ying
		mov	%ebp, %esp		#ying	Avoid to destroy return address

		cmp	$0x0, %al			#Set Flag
		RET_SP

# ********************************************************;
# Check_Memory_Plugged_Or_Not				 ;
# stc : no memory device on dimm			 ;
# clc : memory device on dimm				 ;
# ********************************************************;
Check_Memory_Plugged_Or_Not:
	movl	MPATTERN0, %es:0x4	#write memory
	IODELAY
	movl	EDOPATTERN, %es:0x8	#clear bus
	IODELAY
	movl	EDOPATTERN, %es:0x8	#clear bus
	IODELAY
	movl	EDOPATTERN, %es:0x8	#clear bus
	IODELAY
	movl	EDOPATTERN, %es:0x8	#clear bus
	IODELAY
	movl	EDOPATTERN, %es:0x8	#clear bus
	IODELAY
	movl	EDOPATTERN, %es:0x8	#clear bus
	IODELAY
	movl	EDOPATTERN, %es:0x8	#clear bus
	IODELAY
	movl	EDOPATTERN, %es:0x8	#clear bus
	IODELAY

	cmpl	MPATTERN0, %es:0x04	#memory exist?
	je	44f
	stc	# not exist
	RET_SP
44:
	clc	# exist
	RET_SP

# **************************************************** ;
# Test_Side : Decide Single/Double Side		       ;
#						       ;
#						       ;
# **************************************************** ;
Test_Side:
	mov	$0x79999990, %edi		# write 2048M-16
	movl	MPATTERN1, %es:(%edi)
	IODELAY
	movl	EDOPATTERN, %es:0x8(%edi)
	IODELAY
	cmpl	MPATTERN1, %es:(%edi)
	RET_SP

#define MA_1_11_08  $0x0
#define MA_1_13_08	$0x1
#define MA_2_12_08	$0x2
#define MA_2_13_08	$0x3
#define MA_1_11_09	$0x4
#define MA_1_13_09	$0x5
#define MA_2_12_09	$0x6
#define MA_2_13_09	$0x7
#define MA_1_11_10	$0x8
#define MA_1_13_10	$0x9
#define MA_2_12_10	$0xa
#define MA_2_13_10	$0xb
#define MA_2_11_08	$0xc
#define MA_2_13_12	$0xd
#define MA_2_12_11	$0xe
#define MA_2_13_11	$0xf

Test_MA:
		xor	%edi, %edi
		movl	MPATTERN0, %es:(%edi)

	#; Test COLUMN AD16
		cmpl	MPATTERN0, %es:0x10000(%edi)
		jne	Four_Banks

#*********************************
	#; Start 2Banks Device Sizing
	#; Test Row AD26
		cmpl	MPATTERN0, %es:0x4000000(%edi)
		jne	 Test_Column_09

	#; Column => 8
	#; Test Column AD11
		cmpl	MPATTERN0, %es:0x800(%edi)
		je	 Set_MA_1_11_08_Type

	#; Test Column AD12
		cmpl	MPATTERN0, %es:0x1000(%edi)
		jne	 Set_MA_1_11_10_Type

		cmpl	MPATTERN0, %es:0x8000(%edi)	#Error check
		je	Error_MA_Type

		mov	MA_1_11_09, %al
		RET_SP

Set_MA_1_11_10_Type:
		mov	MA_1_11_10, %al
		RET_SP

Set_MA_1_11_08_Type:
		cmpl	MPATTERN0, %es:0x8000(%edi)	#Error check
		je	 Error_MA_Type
		mov	MA_1_11_08, %al
		RET_SP

#*********************************
Test_Column_09:
	#; Test Row AD 12
		cmpl	MPATTERN0, %es:0x1000(%edi)
		jne	 Set_MA_1_13_10_Type

	#; Column => 08
	#; Test Row AD11
		cmpl	MPATTERN0, %es:0x800(%edi)
		jne	 Set_MA_1_13_09_Type

		cmpl	MPATTERN0, %es:0x8000000(%edi)	#Error check
		je	 Error_MA_Type

		mov	MA_1_13_08, %al
		RET_SP

Set_MA_1_13_09_Type:
		mov	MA_1_13_09, %al
		RET_SP

Set_MA_1_13_10_Type:
		mov	MA_1_13_10, %al
		RET_SP

#*********************************
Error_MA_Type:
		mov	Fail_Value, %al
		RET_SP
#*********************************
Four_Banks:
	#; Start 4Banks Device Sizing
	#; Test Column AD12
		cmpl	MPATTERN0, %es:0x1000(%edi)
		jne	 Test_Column_13

	#; Column => 8
	#; Test Row AD11
		cmpl	MPATTERN0, %es:0x800(%edi)
		je	 Test_Row_13

	#; Row => 14
	#; Test Row AD27
		cmpl	MPATTERN0, %es:0x8000000(%edi)
		jne Set_MA_2_13_09_Type

		cmpl	MPATTERN0, %es:0x4000000(%edi)	#Error check
		je Error_MA_Type

		mov	MA_2_12_09, %al
		RET_SP

Set_MA_2_13_09_Type:
		mov	MA_2_13_09, %al
		RET_SP

#*********************************
Test_Row_13:
	#; Row => 13
	#; Test Row AD26
		cmpl	MPATTERN0, %es:0x4000000(%edi)
		je Set_MA_2_11_08_Type

	#; Row => 14
	#; Test Row AD27
		cmpl	MPATTERN0, %es:0x8000000(%edi)
		jne Set_MA_2_13_08_Type

		cmpl	MPATTERN0, %es:0x10000(%edi)	#Error check
		je Error_MA_Type

		mov	MA_2_12_08, %al
		RET_SP

Set_MA_2_13_08_Type:
		mov	MA_2_13_08, %al
		RET_SP

Set_MA_2_11_08_Type:
		cmpl	MPATTERN0, %es:0x10000(%edi)	#Error check
		je	Error_MA_Type

		mov	MA_2_11_08, %al
		RET_SP

#*********************************
Test_Column_13:
	#; Test Column AD13
		cmpl	MPATTERN0, %es:0x2000(%edi)
		jne Test_Column_14

	#; Row => 14
	#; Test Row AD27
		cmpl	MPATTERN0, %es:0x8000000(%edi)
		jne Set_MA_2_13_10_Type

		cmpl	MPATTERN0, %es:0x4000000(%edi)	#Error check
		je	Error_MA_Type

		mov	MA_2_12_10, %al
		RET_SP

Set_MA_2_13_10_Type:
		mov	MA_2_13_10, %al
		RET_SP

#*********************************
Test_Column_14:
	#; Test Column AD14
		cmpl	MPATTERN0, %es:0x4000(%edi)
		jne Set_MA_2_13_12_Type

	#; Row => 14
	#; Test Row AD27
		cmpl	MPATTERN0, %es:0x8000000(%edi)
		jne Set_MA_2_13_11_Type

		cmpl	MPATTERN0, %es:0x4000000(%edi)	#Error check
		je	Error_MA_Type

		mov	MA_2_12_11, %al
		RET_SP

Set_MA_2_13_11_Type:
		mov	MA_2_13_11, %al
		RET_SP

Set_MA_2_13_12_Type:
		mov	MA_2_13_12, %al
		RET_SP

mem_size_end:

Reply via email to