Support for the rcn dc1100s mainboard. The 694 files are probably wrong.

This commit is contained in:
Ronald G. Minnich 2001-11-03 00:22:28 +00:00
parent 756b831085
commit be3ebbe61f
9 changed files with 1107 additions and 0 deletions

View file

@ -0,0 +1,17 @@
arch i386
mainboardinit cpu/i386/entry16.inc
ldscript cpu/i386/entry16.lds
mainboardinit superio/via/vt82c686/setup_serial.inc
mainboardinit pc80/serial.inc
northbridge via/vt694
southbridge via/vt82c686
superio via/vt82c686
mainboardinit cpu/p6/earlymtrr.inc
option ENABLE_FIXED_AND_VARIABLE_MTRRS
option SUPERIO_DEVFN=0x88
object mainboard.o
keyboard pc80
cpu p5
cpu p6

View file

@ -0,0 +1,21 @@
# This will make a target directory of ./via
target dc1100s
# VIA test mainboard
mainboard rcn/dc1100s
option USE_DOC_MIL
docipl northbridge/via/vt694/ipl.S
# Enable Serial Console for debugging
option SERIAL_CONSOLE
# Enable MicroCode update and L2 Cache init for PII and PIII
option UPDATE_MICROCODE
option CONFIGURE_L2_CACHE
# Path to your kernel (vmlinux)
linux ~/src/bios/linux-2.4.0-rcn
option CMD_LINE='"root=/dev/hda1 single"'

View file

@ -0,0 +1,6 @@
void
mainboard_fixup()
{
void southbridge_fixup(void);
southbridge_fixup();
}

View file

@ -0,0 +1 @@
object northbridge.o

View file

@ -0,0 +1,50 @@
/*
v1.0: 02/15/2001: Program procedure to make workable and stable register settings:
(1) Initial registers: 0x40:0x48, 0x41:0x4d, 0x43:0x44, 0x44:0x04, 0x83:0x02, 0x3e:0x0c
v1.1: 02/15/2001:
(1) Initial registers: To add 0x3e:0x0c
(2) After initial: To add bus0, devfn0 0x84:0xc0
v1.2: 02/15/2001:
To set 0x13 register to 0xd8 value, thus it won't hang the system if enable graphic aperture(0x88 bit 2). But
I am not sure if it would take effect for graphic device. According to the result, the system won't hang and check
the register setting, that's right, they do set those values except the aperture base(0x13) has been changed to 0x84
which means the pci configure does the resource allocation. But why it won't start up the monitor???
*/
jmp ptp_afteram_set_registers
ptp_afteram_table:
.byte 0x40, 0x48
.byte 0x41, 0x4d
.byte 0x43, 0x44
.byte 0x44, 0x04
.byte 0x83, 0x02
.byte 0x3e, 0x0c
.byte 0x0 /* end of table */
ptp_afteram_set_registers:
/* standard x86 loop on table until done code */
/* assumes that: devfn is 8 (safe on anything we've seen) */
/* which means addresses are a byte */
/* address is first, then data */
movl $ptp_afteram_table, %esi
1:
/* zero out eax. This is a must right here. */
xor %eax, %eax
movb (%esi), %al
testb %al, %al
jz done_ptp_afteram_set_registers
inc %esi
orl $0x0800, %eax
movb (%esi), %dl
PCI_WRITE_CONFIG_BYTE
inc %esi
jmp 1b
done_ptp_afteram_set_registers:
CS_WRITE($0x13, $0xd8)
CS_WRITE($0x84, $0xc0)
CS_WRITE($0x80, $0x0f)
CS_WRITE($0x88, $0x02)
intel_chip_post_macro(0x99)

View file

@ -0,0 +1,385 @@
#include "asm.h"
//#include <cpu/p5/macros.h>
#include "intel.h"
/*
*/
#define DOC_WIN_SEG 0xfe00
#define DOC_STACK_SEG 0x0400
#define SPL_RAM_SEG 0x8000
#define DOC_SPL_START_BLK 2 /* 0,1 for IPL */
#define DOC_SPL_SIZE_IN_PAGE 252 /* 1 page = 512 bytes, total 63kB */
/* wow, the usual way to to this hurts. So we do it our way:
* 32-bit test not needed.
*/
/*#include <cpu/p5/start32.inc>*/
.org 0x0
.code16
_start: jmp _realstart
/* initialize registers */
#define REG(a) a&0xfc, (a&0x3)|4
register_table:
.byte REG(0x78), 0x01
.byte REG(0x68), 0x00
.byte REG(0x6b), 0x00
.byte REG(0x58), 0x88
.byte REG(0x59), 0x88
.byte REG(0x5a), 0x08
.byte REG(0x5b), 0x10
.byte REG(0x5c), 0x10
.byte REG(0x5d), 0x10
.byte REG(0x5e), 0x10
.byte REG(0x5f), 0x10
.byte REG(0x56), 0x10
.byte REG(0x57), 0x10
.byte REG(0x60), 0xff
.byte REG(0x64), 0xee
.byte REG(0x65), 0xee
.byte REG(0x66), 0xee
.byte REG(0x69), 0x04
.byte REG(0x6a), 0x00
.byte REG(0x6c), 0x00
.byte REG(0x6d), 0x37
// This extra set is redundant, but needed below.
// LEAVE IT HERE.
.byte REG(0x6c), 0x0
.byte 0x0
_realstart:
// movb $0xaa,%al
// outb %al,$0x80
cli
movw %cs, %ax
movw %ax, %ds
movl $0x80008840, %eax
movw $0x0cf8, %dx
outl %eax,%dx
movb $0xfc,%dl
movb $0x54,%al
outb %al,%dx
// inl %dx, %eax
// orw $0x7f10, %ax
// outw %ax,%dx
//.code32
#define loop200 $0x5000
#define loop100 $0x2500
movl $0x80000000,%esp
ram_set_registers:
movw $register_table, %si
cld
1:
movl %esp, %eax
orb (%si), %al
testb %al, %al
jz done_ram_set_registers
andb $0xf8, %dl
outl %eax, %dx
inc %si
orb (%si), %dl
inc %si
movb (%si), %al
outb %al, %dx
// PCI_WRITE_CONFIG_BYTE
inc %si
jmp 1b
// movb $0xbb,%al
// outb %al,$0x80
done_ram_set_registers:
xorw %si, %si
// movl $0x4000000, %edi
/* begin to initialize*/
// I forget why we need this, but we do
movl $0xa55a5aa5, %ecx
movl %ecx, (%si)
// mov %ecx, (%edi)
// REMEMBER: 0xcf8 was set to 0x8000006c above. No need to set
// again!
// Also, remember: %edx has 0xcfc from the above loop!
// that is the correct value!
/* set NOP*/
#define WRITE_6c(unused,val) movb val, %al ; outb %al, %dx
WRITE_6c($0x6C, $0x01)
/* wait 200us*/
// You need to do the memory reference. That causes the nop cycle.
movw (%si), %cx
// mov (%edi), %ecx
DELAY(loop200)
/* set precharge */
WRITE_6c($0x6C, $0x02)
/* dummy reads*/
movw (%si), %cx
// mov (%edi), %ecx
/* set CBR*/
WRITE_6c($0x6C, $0x04)
/* do 8 reads and wait 100us between each - from via*/
movb $8, %bl
eightreads:
movw (%si), %cx
// mov (%edi), %ecx
DELAY(loop100)
dec %bl
cmpb $0, %bl
ja eightreads
/* set MRS*/
// 0x150 is cas2. We are now using 0x1d0, which is cas3
WRITE_6c($0x6c, $0x03)
movw $0x1d0, %di
movl (%di), %ecx
// movl $0x40001d0, %ecx
// movl (%ecx), %ecx
/* set to normal mode */
WRITE_6c($0x6C, $0x00)
movl $0x55aa55aa, %ecx
movl %ecx, (%si)
movl (%si), %ecx
// Set the refresh rate.
movb $0x68, %al
movb $0xf8, %dl
outl %eax, %dx
addw $7, %dx
movb $0x65, %al
outb %al, %dx
//CS_WRITE($0x6A, $0x65)
// enable multi-page open
inc %dl
movb $1, %al
outb %al, %dx
//CS_WRITE($0x6B, $0x01)
// movb $0xcc,%al
// outb %al,$0x80
/* now for flash ... */
/* NOTE: MUST NOT DESTROY %ecx! */
/* INPUT: %al, the register. %ecx, the write data */
/* Following code courtesy Ollie Lho: */
/*
* ipl.S: Initial Program Loader (IPL) for SiS 630 and M-System DoC Millennium
*
*
* 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. System Management Bus Specification Rev 1.1
* 3. PC SDRAM Serial Presence Detect (SPD) Specification Rev 1.2B
* 4. Booting From the DiskOnChip Millennium, M-Systems Application Note Ap-DOC-044
* APR-2000, 93-SR-001-44-7L REV. 1.0
*
* $Id$
*/
// .code16
#define DOC_WIN_SEG 0xfe00
#define DOC_STACK 0x04000
#define SPL_RAM 0x80000
#define DOC_SPL_START_BLK 2 /* 0,1 for IPL */
#define DOC_SPL_SIZE_IN_PAGE 252 /* 1 page = 512 bytes, total 63kB */
ipl_start:
//#if 0
/* stack and es already set. */
/* O.K. we have DRAM now, so set up STACK for CALL/RET */
movw $DOC_STACK_SEG, %ax
movw %ax, %ss
movw $SPL_RAM_SEG, %ax
movw %ax, %es
// movl $DOC_STACK_SEG, %esp # set %sp
//#endif
/* NOTE: in ollie's original code, %ds was at 0xfe00, i.e.
* 0xfe000, i.e. base of DoC. We have to adjust for that when
* we set %edi and %esi
*/
// movl $0x80008840,%eax
// mov $0xcf8,%dx
// outl %eax,%dx
// mov $0xfc,%dl
// inl %dx,%eax
movb $0xbb, %al
outb %al,$0x80
xorw %sp,%sp
xorw %dx,%dx
// movl $DOC_STACK, %esp # set %sp
// movl $SPL_RAM, %edx # start of RAM
// xorl %ecx, %ecx # clear %ecx
movw $0x800, %si # point %si to CDSN Data area
movw $0x1000,%di # point %di to CDSN Control area
movw $DOC_SPL_START_BLK, %bp # start page of LinuxBIOS
movb $0x0, %ds:0x03(%di)
movb $0x84,%ds:0x02(%di)
movb $0x84,%ds:0x02(%di)
call delay4nop
movb $0x85,%ds:0x02(%di)
movb $0x85,%ds:0x02(%di)
call delay4nop
read_next_page:
movw $0x1000, %di # point %di to CDSN Control area
movw $0x800, %si
flash_command:
movb $0x13, %ds:0x04(%di) # start command cycle
call delay4nop
movb $0x00, %ds:(%si) # issue flash command Read00
movb $0x00, %ds:0x1e(%di)
movb $0x11, %ds:0x04(%di)
movw %bp, %bx # %bp is current page number
flash_address:
shll $0x08, %ebx
movw $0x03, %cx # this one is DANGEROUS but I am
movb $0x15, %ds:0x04(%di) # start address cycle
call delay4nop
0:
movb %bl, %ds:(%si) # write address to CDSNIO
shrw $0x08, %bx # shift next address byte
loop 0b
movb $0x00, %ds:0x1e(%di)
movb $0x31, %ds:0x04(%di)
// call doc_cycle_end
call delay4nop
wait_for_flash_ready:
/* delay by reding NOP register before polling the FLASH READY bit,
this is inlined to save a call/ret pair */
doc_delay:
movb %ds:0x04(%di),%ah
movw $0x04, %cx # this one is DANGEROUS but I am
# sure the upper 3 bytes == 0x00
0:
movb %ds:0x20(%di), %al # read DOC NOP retisger
loop 0b # four times
testb $0x80,%ah # is flash ready ?
jz wait_for_flash_ready
movb %ds:0x1d(%di), %al # init read pipeline
movw $0x1ff, %cx # 1 page = 512 bytes
movw $0x800, %si # point %si to CDSN Data area
movw %dx, %di # restore saved current destination
rep movsb
movw $0x101f,%si
movsb
// call dely4nop
movw %di, %dx # save current destination
mov %bp,%di
sub $128,%di
shl $9,%di
movb %es:(%di),%al
out %al,$0x80
// DELAY(loop200)
// DELAY(loop200)
// mov $0xffff,%cx
//aa: loop aa
inc %di
movb %es:(%di),%al
out %al,$0x80
incw %bp # increse current page number
cmpw $128, %bp # moved 63 KB ??
jl read_next_page # no, read next page
sis630ipl_end:
# jmp to 8000:0000, where SPL
# (LinuxBIOS) starts in RAM
# ljmp $0x10,$0x8000
movb $0xdd, %al
outb %al,$0x80
jmp spl_vector
delay4nop:
movb %ds:0x20(%di),%al
movb %ds:0x20(%di),%al
movb %ds:0x20(%di),%al
movb %ds:0x20(%di),%al
ret
//doc_reset:
/* Input: AL = value write to DOC_CONTROL register
Clobberd: CX */
// movb %al, 0x02(%edi) # write DoC Control retister
// movb %al, 0x02(%edi) # twice
// ret # End of doc_reset
//doc_cycle_end:
// movb $0x00, 0x1e(%di) # flush write pepeline
// movb $0x31, 0x04(%di) # end command cycle
// ret
/* we don't need these. We only do I/O to MCR 0 */
#if 0
pci_write_dword:
mov $0,%ah
mov $0x80000000,%edx
or %ax,%dx
mov %edx,%eax
mov $0x0cf8,%dx
outl %eax,%dx
mov $0x0fc,%dl
mov %ecx, %eax
outl %eax,%dx
RETSP
pci_read_dword:
mov $0,%ah
mov $0x80000000,%edx
or %ax,%dx
mov %edx,%eax
mov $0x0cf8,%dx
outl %eax,%dx
mov $0x0fc,%dl
inl %dx, %eax
mov %eax, %ecx
RETSP
#endif
.org 0x01f0
reset_vector:
.byte 0xea #jump to fe00:0000, where IPL
.word 0x0000, DOC_WIN_SEG #starts in DoC
spl_vector:
// invd
// movb $0xdd,%al
// outb %al,$0x80
// jmpl $0x10, $0x80000
.byte 0xea
.word 0x0000, 0x8000
# jumpl $0x80000
# put this here to buy some room
pad: .byte 0,0,0,0,0,0

View file

@ -0,0 +1,74 @@
#include <printk.h>
#include <pci.h>
#include <pciconf.h>
unsigned long sizeram()
{
unsigned long totalmem;
unsigned char bank, mem, prevmem;
// fix me later -- there are two more banks at 0x56 and 0x57
unsigned long firstbank = 0x5a, lastbank = 0x5f;
u8 sma_status, sma_size, sma_size_bits;
struct pci_dev *pcidev;
pcidev = pci_find_slot(0, PCI_DEVFN(0,0));
if (! pcidev)
return 0;
pci_read_config_byte(pcidev, 0xfb, &sma_status);
sma_size_bits = (sma_status >> 4) & 0x03;
if (sma_size_bits > 3)
sma_size = 0;
else
sma_size = 0x01 << sma_size_bits;
for(totalmem = mem = prevmem = 0, bank = firstbank;
bank <= lastbank; bank++) {
pci_read_config_byte(pcidev, bank, &mem);
// sanity check. If the mem value is < prevmem,
// that is an error, so skip this step.
if (mem < prevmem) {
printk_err("ERROR: bank 0x%x, mem 0x%x TOO SMALL\n",
bank, prevmem);
printk_err("Should be >= 0x%x\n", prevmem);
} else
totalmem += (mem - prevmem) * 8;
prevmem = mem;
}
totalmem -= sma_size;
totalmem *= 1024;
printk_info("sizeram: returning 0x%x KB\n", totalmem);
printk_info("sizeram: NOT returning 0x%x KB\n", totalmem);
printk_info("sizeram: there are still some SPD problems ... \n");
totalmem = 64 * 1024;
printk_info("sizeram: SO we return only 0x%x KB\n", totalmem);
#if 0
#endif
return totalmem;
}
/*
unsigned long sizeram()
{
return 0;
}
*/
#ifdef HAVE_FRAMEBUFFER
void framebuffer_on()
{
unsigned long devfn;
u16 command;
devfn = PCI_DEVFN(0, 1);
pcibios_read_config_word(0, devfn, 0x3e, &command);
command |= 0x08;
pcibios_write_config_word(0, devfn, 0x3e, command);
}
#endif

View file

@ -0,0 +1,171 @@
/*
This software and ancillary information (herein called SOFTWARE )
called LinuxBIOS is made available under the terms described
here. The SOFTWARE has been approved for release with associated
LA-CC Number 00-34 . Unless otherwise indicated, this SOFTWARE has
been authored by an employee or employees of the University of
California, operator of the Los Alamos National Laboratory under
Contract No. W-7405-ENG-36 with the U.S. Department of Energy. The
U.S. Government has rights to use, reproduce, and distribute this
SOFTWARE. The public may copy, distribute, prepare derivative works
and publicly display this SOFTWARE without charge, provided that this
Notice and any statement of authorship are reproduced on all copies.
Neither the Government nor the University makes any warranty, express
or implied, or assumes any liability or responsibility for the use of
this SOFTWARE. If SOFTWARE is modified to produce derivative works,
such modified SOFTWARE should be clearly marked, so as not to confuse
it with the version available from LANL.
*/
/* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
* rminnich@lanl.gov
*/
#define loop200 $0x5000
#define loop100 $0x2500
/*; new code... pulled from via stuff.*/
/* initialize registers */
// memory clk enable. We are not using ECC
CS_WRITE($0x78, $0x01)
// dram control, see the book.
CS_WRITE($0x68, $0x00)
// dram control, see the book.
CS_WRITE($0x6B, $0x00)
// 64/128 MB dram
CS_WRITE($0x58, $0x88)
// 64/128 MB dram
CS_WRITE($0x59, $0x88)
// bank 0 ends at 64 MB
CS_WRITE($0x5A, $0x08)
// bank 1 ends at 64 MB
CS_WRITE($0x5B, $0x10)
// bank 2 ends at 64 MB
CS_WRITE($0x5C, $0x10)
// bank 2 ends at 64 MB
CS_WRITE($0x5D, $0x10)
// bank 2 ends at 64 MB
CS_WRITE($0x5E, $0x10)
// bank 2 ends at 64 MB
CS_WRITE($0x5F, $0x10)
// SDRAM in all banks
CS_WRITE($0x60, $0xFF)
// DRAM timing. I'm suspicious of this
// This is for all banks, 64 is 0,1. 65 is 2,3. 66 is 4,5.
// ras precharge 4T, RAS pulse 5T, CAS 2T
// as per the note below, we change to cas 3 2000/8/31
// cas2 is 0xd6, cas3 is 0xe6
// we're also backing off write pulse width to 2T, so result is 0xee
CS_WRITE($0x64, $0xee)
CS_WRITE($0x65, $0xee)
CS_WRITE($0x66, $0xee)
// dram frequency select. We set 66/66.
// no 256 m, enable 4K pages for 64M dram.
CS_WRITE($0x69, $0x04)
// refresh counter, disabled.
CS_WRITE($0x6A, $0x00)
// clkenable configuration. Not sure this is right!
CS_WRITE($0x6C, $0x00)
// dram read latch delay of 1 ns, MD drive 8 mA,
// high drive strength on MA[2: 13], we#, cas#, ras#
// As per Cindy Lee, set to 0x37, not 0x57
CS_WRITE($0x6D, $0x37)
/* begin to initialize*/
// I forget why we need this, but we do
mov $0xa55a5aa5, %eax
mov %eax, 0
mov %eax, 0x4000000
/* set NOP*/
CS_WRITE($0x6C, $0x01)
/* wait 200us*/
// You need to do the memory reference. That causes the nop cycle.
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop200)
/* set precharge */
CS_WRITE($0x6C, $0x02)
/* dummy reads*/
mov 0x0, %eax
mov 0x4000000, %eax
/* set CBR*/
CS_WRITE($0x6C, $0x04)
/* do 8 reads and wait 100us between each - from via*/
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop100)
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop100)
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop100)
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop100)
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop100)
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop100)
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop100)
mov 0x0, %eax
mov 0x4000000, %eax
DELAY(loop100)
/* set MRS*/
// 0x150 is cas2. We are now using 0x1d0, which is cas3
CS_WRITE($0x6c, $0x03)
movl $0x1d0, %ecx
movl (%ecx), %eax
movl $0x40001d0, %ecx
movl (%ecx), %eax
/* set to normal mode */
CS_WRITE($0x6C, $0x00)
movl $0x55aa55aa, %eax
mov %eax, 0x0
mov 0x0, %eax
// Set the refresh rate.
CS_WRITE($0x6A, $0x65)
// enable multi-page open
CS_WRITE($0x6B, $0x01)
/* From Mike Fan:
Hi all:
If you are porting PM133, then you have to set DRAM Row Ending Address.
You did not set Rx56 and Rx57 in intel_pm133ram.S.
That register setting is like Rx5A~Rx5F.
Maybe could fix the mem wrapping issue.
(from Ron Minnich)
My manual says these are non-cacheable region registers.
(Turns out the manual is wrong. However, this did not help.
2000/8/31 8:49 am I am setting all dram to cas3, and if that fails,
I'll be trying some of Cindy's other recommendations.
DRAM is currently CAS2. Symptom is an explosion in free_all_bootmem_core,
In the loop where it is freeing bootmem alloc pages from low mem.
2000/8/31: 10:57 No change, Linux still crashes. We'll try Cindy Lee's recommendation
RE Register 0x6d, set it to 0x37. All our other settings conform to her
other recommendations. We also need to see whether we should be setting
Fixed MTRRs, but that seems unlikely.
2000/8/31: 5:56 PM. No significant change. We're going to try to use 1 cycle writes
instead of 2. None of this feels like it is the real problem. Fixed MTRRs
helped a tiny bit. We can get to schedule() before we crash, but only
if we set a breakpoint after the first loop in free_all_bootmem_core
*/
CS_WRITE($0x56, $0x10)
CS_WRITE($0x57, $0x10)

View file

@ -0,0 +1,382 @@
/*
v1.0: 02/14/2001: Program procedure to make workable and stable register settings:
(1) Initial registers: 0x68:0x00, 0x6a:0x00, 0x6b:0x00, 0x6c:0x00,
0x64:0xe4, 0x65:0xe4, 0x66:0xe4, 0x50:0xfe,
0xf8:0x22, 0xf9:0x42, 0xfb:0xb0, 0x6d:0x01,
0x60:0xff, 0x58:0x40, 0x59:0x00, 0x5a:0x20,
0x5b:0x40, 0x5c:0x60, 0x5d:0x80, 0x5e:0xa0,
0x5f:0xc0, 0x56:0xe0, 0x57:0xff
(2) When SPD routine: Changed 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f
(3) After SPD, the special register setting:
(i) First to write: 0x56--0x57:(0x5f), 0x6a:65
(ii) Second to write: 0x6b:0x01, 0x78:0x01, 0x58:0x80, 0x6d:0x21
v1.1: 02/14/2001: To add:
(1) Initial registers: 0x51:0xdf, 0x52:0xc8, 0x53:0x98, 0x64:0xe6, 0x65:0xe6, 0x66:0xe6
(2) After SPD, the special register setting:
(i) First to write: or 0x68:0x01-->0x68:0x41, or 0x69:0x00-->0x69:0x2c
(i) Second to write: 0x6d:0x21-->0x6d:0x57i
TO TEST: To change 0x64:0xe4 to 0x64:0x12, 0x65:0xe4 to 0x65:0xe6, 0x66:0xe4 to 0x66:0xe6
Result: fail!! It will cause too many errors message.
SDRAM verify:
00000000:0005ff80
00000004:0005ff84
00000008:00000000
0000000c:00000004
00000010:00000008
00000014:0000000c
00000018:00000010
0000001c:00000014
00000020:0005ff80
00000024:0005ffa4
.................
.................
Too many errors.
v1.2: 02/14/2001: To modify:
(1) Initial register: 0x6b:0x00--> 0x6b:0x2d
(2) After SPD, the special register setting:
(i) Second to modify: or 0x6b:0x2d-->0x6b:0x2f, or 0x6c:0x00-->0x08
v1.3: 02/04/2001: To add:
(1) Initial registers: 0x71:0x08, 0x75:0x80, 0x76:0x80, 0x79:0xf0, 0x7f:0x04
v1.4: 02/04/2001: To modify:
(1) After SPD, set registers:
(1) Second to write and modify: 0x70:0xc0, or 0x71:08-->0x71:88, 0x72:ec, 0x73:0c, 0x74:0x0e,
or 0x75:0x80-->0x75:0x81, or 0x76:0x80-->0x76:0xd6, or 0x79:0xf0-->0x79:0xf4, 0x7a:0x01
v1.5: 02/15/2001: To modify and add:
(1) Initial register: 0x81:0xc3
To add ptp table(bus0, devfn08) and program: 0x1c:0xf0, 0x20:0xf0, 0x21:0xff, 0x24:0xf0, 0x25:0xff, 0x34:0x80
(2) After SPD, set registers:
(1) Second to write: 0x0d:0x08, 0xac:0x6e
*/
/* SPD ram init */
#define PM_DEVFN CONFIG_ADDR(0, PM_DEVICE, 0)
#define DRAM_CONFIG_PORT 0x5a
#define REGISTERED_DRAM_REGISTER $0x69
#define LAST_SMBUS_MEM_DEVICE SMBUS_MEM_DEVICE_2
jmp raminitspd_end
/* table of settings for initial registers */
register_table:
/* no memory clock enable -- overridden by SPD, we hope */
// .byte 0x78, 0x1
/* safe initial values ... */
.byte 0x68, 0x0
.byte 0x6a, 0x0 /* disable refresh */
// .byte 0x6b, 0x0
.byte 0x6b, 0x2d
.byte 0x6c, 0x0 /* disable ECC for start */
// .byte 0x6d, 0x37 /* as per Cindy Lee, ... */
// .byte 0x64, 0xe4 /* slowest ram setting. banks 0, 1 */
// .byte 0x65, 0xe4 /* banks 2, 3*/
// .byte 0x66, 0xe4 /* banks 4, 5 */
.byte 0x64, 0xe6
.byte 0x65, 0xe6
.byte 0x66, 0xe6
.byte 0x50, 0xfe
.byte 0x51, 0xdf
.byte 0x52, 0xc8
.byte 0x53, 0x98
.byte 0xf8, 0x22
.byte 0xf9, 0x42
.byte 0xfb, 0xb0
/* we tried increasing the drive, but that did not help or hurt.
* We will leave it at low drive for now, however.
*/
#if 1
/* the standard BIOS goes for 0x5f here, which is very high drive.
* Try it out. RGM 1/26/1 */
/* LOW DRIVE */
// .byte 0x6d, 0x5 /* 0x4 = 24 ma on ma[2:13],we#, 24ma on ras# */
.byte 0x6d, 0x1
#else
/* HIGH DRIVE */
.byte 0x6d, 0x5f /* 0x4 = 24 ma on ma[2:13],we#, 24ma on ras# */
#endif
.byte 0x60, 0xff /* sdram in ALL banks. It's all we do. */
/* set these to 0xee (128 MB VC SDRAM). In our working code we set to
* 0x88, but VIA code recommends 0xee. Since we are SPD, in the end,
* this initial setting will be over-ridden by SPD probe values.
* leave at 88 for now -- deal with this mess later
*/
// .byte 0x58, 0x88
// .byte 0x59, 0x88
.byte 0x58, 0x40
.byte 0x59, 0x00
/* size the banks at max, they will be resized later. */
.byte 0x5a, 0x20
.byte 0x5b, 0x40
.byte 0x5c, 0x60
.byte 0x5d, 0x80
.byte 0x5e, 0xa0
.byte 0x5f, 0xc0
.byte 0x56, 0xe0
.byte 0x57, 0xff
.byte 0x71, 0x08
.byte 0x75, 0x80
.byte 0x76, 0x80
.byte 0x79, 0xf0
.byte 0x81, 0xc3
.byte 0x0 /* end of table */
ptp_table:
.byte 0x1c, 0xf0
.byte 0x20, 0xf0
.byte 0x21, 0xff
.byte 0x24, 0xf0
.byte 0x25, 0xff
.byte 0x34, 0x80
.byte 0x0
ram_set_registers:
/* standard x86 loop on table until done code */
/* assumes that: devfn is 0 (safe on anything we've seen) */
/* which means addresses are a byte */
/* address is first, then data */
movl $register_table, %esi
1:
/* zero out eax. This is a must right here. */
xor %eax, %eax
movb (%esi), %al
testb %al, %al
// jz done_ram_set_registers
jz ptp
inc %esi
movb (%esi), %dl
PCI_WRITE_CONFIG_BYTE
inc %esi
jmp 1b
ptp: movl $ptp_table, %esi
2:
/* zero out eax. This is a must right here. */
xor %eax, %eax
movb (%esi), %al
testb %al, %al
jz done_ram_set_registers
inc %esi
orl $0x0800, %eax
movb (%esi), %dl
PCI_WRITE_CONFIG_BYTE
inc %esi
jmp 2b
// I forget why we need this, but we do
mov $0xa55a5aa5, %eax
mov %eax, 0
mov %eax, 0x4000000
intel_chip_post_macro(0x01)
done_ram_set_registers: RET_LABEL(ram_set_registers)
ram_set_spd_registers:
CALL_LABEL(enable_smbus)
intel_chip_post_macro(0x02)
CALL_LABEL(setup_smbus)
intel_chip_post_macro(0x03)
CALL_LABEL(spd_set_drb)
intel_chip_post_macro(0x04)
CALL_LABEL(spd_set_dramc)
intel_chip_post_macro(0x05)
/* CALL_LABEL(spd_set_rps)*/
/* CALL_LABEL(spd_set_sdramc)*/
/* CALL_LABEL(spd_set_pgpol)*/
/* CALL_LABEL(spd_set_nbxcfg)*/
spd_set_rps_done:
spd_set_pgpol_done:
spd_set_nbxcfg_done:
RET_LABEL(ram_set_spd_registers)
#define SMBUS_IO_BASE 0xf00
#define REGISTERED_DRAM $0x2
#define NONREGISTERED_DRAM $0
#define REGISTER_DRAM_REGISTER $0x69
#define RAM_READ 0x0400
#define DIMM0_BASE \
intel_chip_post_macro(0x06) ; \
xorl %eax, %eax
#define DIMM_BASE(n) \
intel_chip_post_macro(0x07) ; \
movl $(0x5a + ((n) -1)), %eax ; \
PCI_READ_CONFIG_BYTE ; \
andl $0xFF, %eax ; \
shll $23, %eax ; \
#define DIMM_READ \
addl %ebx, %eax ; \
movl (%eax), %edx /* end it here -- see if that fixes */
#if 0
xorl $0xdff8, %eax ; \
movl (%eax), %edx
#endif
#define DIMM0_READ DIMM0_BASE ; DIMM_READ
#define DIMM1_READ DIMM_BASE(1) ; DIMM_READ
#define DIMM2_READ DIMM_BASE(2) ; DIMM_READ
#define DIMM3_READ DIMM_BASE(3) ; DIMM_READ
#define DIMM4_READ DIMM_BASE(4) ; DIMM_READ
#define DIMM5_READ DIMM_BASE(5) ; DIMM_READ
#define DIMM6_READ DIMM_BASE(6) ; DIMM_READ
#define DIMM7_READ DIMM_BASE(7) ; DIMM_READ
#define DIMMS_READ_EBX_OFFSET \
intel_chip_post_macro(0x08) ; \
DIMM0_READ ; \
intel_chip_post_macro(0x09) ; \
DIMM1_READ ; \
intel_chip_post_macro(0x0a) ; \
DIMM2_READ ; \
intel_chip_post_macro(0x0b) ; \
DIMM3_READ ; \
intel_chip_post_macro(0x0c) ; \
DIMM4_READ ; \
intel_chip_post_macro(0x0d) ; \
DIMM5_READ ; \
intel_chip_post_macro(0x0e) ; \
DIMM6_READ ; \
intel_chip_post_macro(0x0f) ; \
DIMM7_READ
#define DIMMS_READ(offset) \
movl $offset, %ebx ; \
DIMMS_READ_EBX_OFFSET
#define RAM_COMMAND_NONE 0x0
#define RAM_COMMAND_NOP 0x1
#define RAM_COMMAND_PRECHARGE 0x2
#define RAM_COMMAND_MRS 0x3
#define RAM_COMMAND_CBR 0x4
#define SET_RAM_COMMAND(command) \
intel_chip_post_macro(0x20) ; \
movl $0x6c, %eax ; \
PCI_READ_CONFIG_BYTE ; \
andl $0x18, %eax ; \
orl $(command), %eax ; \
movl %eax, %edx ; \
movl $0x6c, %eax ; \
PCI_WRITE_CONFIG_BYTE
// fix me later. Have to have ram in slot 0, and we only test cas3 or 2
#define COMPUTE_CAS_MODE \
intel_chip_post_macro(0x21) ; \
movl $0x64, %eax ; \
PCI_READ_CONFIG_BYTE ; \
andl $0x20, %eax ; \
xorl $0x20, %eax ; \
shrl $1, %eax ; \
orl $0x2a, %eax ; \
#define SET_RAM_MODE_REGISTER \
SET_RAM_COMMAND(RAM_COMMAND_MRS) ; \
COMPUTE_CAS_MODE ; \
shll $3, %eax ; \
/* FIX ME -- set to cas3 no matter what for now */ ; \
movl $0x1d0, %eax; \
movl %eax, %ebx ; \
DIMMS_READ_EBX_OFFSET
#define ASSERT_RAM_COMMAND() DIMMS_READ(RAM_READ)
#define ASSERT_MRS_RAM_COMMAND(mode) DIMMS_READ(mode)
#define USE_SPD 1
#if ! USE_SPD
#define ENABLE_REFRESH() CS_BIS_BYTE(0x57, 0x1)
#else /* USE_SPD */
#define ENABLE_REFRESH() CALL_LABEL(spd_enable_refresh)
#endif
#define FIRST_NORMAL_REFERENCE() \
intel_chip_post_macro(0x22) ; \
movl $0x55aa55aa, %eax; \
mov %eax, 0x0; \
mov 0x0, %eax;
// should also read 0x5f and write that to 0x56 and 0x57
#define SPECIAL_FINISHUP() \
intel_chip_post_macro(0x23) ; \
/* enable multi-page open */; \
CS_READ($0x6B) ; \
movb %al, %dl ; \
orb $0x02, %dl ; \
movl $0x6b, %eax ; \
PCI_WRITE_CONFIG_BYTE ; \
CS_READ($0x6c) ; \
movb %al, %dl ; \
orb $0x08, %dl ; \
movl $0x6c, %eax ; \
PCI_WRITE_CONFIG_BYTE ; \
CS_WRITE($0x78, $0x01) ; \
movb $0x80, %dl; \
movl $0x58, %eax; \
PCI_WRITE_CONFIG_BYTE; \
CS_WRITE($0x6d, $0x57) ; \
CS_WRITE($0x70, $0xc0) ; \
CS_READ($0x71) ; \
movb %al, %dl ; \
orb $0x80, %dl ; \
movl $0x71, %eax ; \
PCI_WRITE_CONFIG_BYTE ; \
CS_WRITE($0x72, $0xec) ; \
CS_WRITE($0x73, $0x0c) ; \
CS_WRITE($0x74, $0x0e) ; \
CS_READ($0x75) ; \
movb %al, %dl ; \
orb $0x01, %dl ; \
movl $0x75, %eax ; \
PCI_WRITE_CONFIG_BYTE ; \
CS_READ($0x76) ; \
movb %al, %dl ; \
orb $0x52, %dl ; \
movl $0x76, %eax ; \
PCI_WRITE_CONFIG_BYTE ; \
CS_READ($0x79) ; \
movb %al, %dl ; \
orb $0x04, %dl ; \
movl $0x79, %eax ; \
PCI_WRITE_CONFIG_BYTE ; \
CS_WRITE($0x7a, $0x01) ; \
CS_WRITE($0x0d, $0x08) ; \
CS_WRITE($0xac, $0x6e)
// CS_WRITE($0x6d, $0x21) ; \
// CS_WRITE($0x84, $0xc0)
spd_enable_refresh:
intel_chip_post_macro(0x24) ; \
// just set it for now.
CS_WRITE($0x6A, $0x65)
CS_READ($0x5f)
movb %al, %dl
movl $0x56, %eax
PCI_WRITE_CONFIG_BYTE
CS_READ($0x5f)
movb %al, %dl
movl $0x57, %eax
PCI_WRITE_CONFIG_BYTE
CS_READ($0x68)
movb %al, %dl
orb $0x40, %dl
movl $0x68, %eax
PCI_WRITE_CONFIG_BYTE
CS_READ($0x69)
movb %al, %dl
orb $0x2c, %dl
movl $0x69, %eax
PCI_WRITE_CONFIG_BYTE
RET_LABEL(spd_enable_refresh)
raminitspd_end: