seperate out doc mil and std flash code from ipl.S
This commit is contained in:
parent
84912b0c25
commit
134a85d26d
6 changed files with 333 additions and 378 deletions
|
|
@ -32,11 +32,14 @@
|
|||
#include "ipl.h"
|
||||
|
||||
#define SIS550_BUG
|
||||
.code16
|
||||
|
||||
#ifdef STD_FLASH
|
||||
.org 0xfe00
|
||||
#endif
|
||||
|
||||
#undef SIZE_ALL
|
||||
#define REALLY_COMPACT
|
||||
|
||||
.code16
|
||||
|
||||
sis630spd_start:
|
||||
cli # Disables the maskable
|
||||
|
|
@ -61,7 +64,7 @@ lpc_init_complete:
|
|||
|
||||
#ifdef SIZE_ALL
|
||||
xorw %bx, %bx # clear %fs, %fs is used as "bitmap" of
|
||||
movw %bx, %fs # install DIMM slot
|
||||
movw %bx, %fs # installed DIMM slot
|
||||
#endif /* SIZE_ALL */
|
||||
|
||||
spd_sizing_start:
|
||||
|
|
@ -211,87 +214,23 @@ init_sdram:
|
|||
jmp init_sdram
|
||||
|
||||
init_complete:
|
||||
|
||||
sis630ipl_start:
|
||||
/* 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
|
||||
xorw %sp, %sp # clear %sp
|
||||
|
||||
xorl %esp, %esp # clear %sp
|
||||
xorw %dx, %dx # clear %dx, start of RAM
|
||||
movw $0x800, %si # point %si to CDSN Data area
|
||||
movw $0x1000, %di # point %di to CDSN Control area
|
||||
movw $DOC_SPL_START_PAGE, %bp # start page of LinuxBIOS
|
||||
|
||||
movb $0x84, %al # Reset DOC Millennium
|
||||
call doc_reset
|
||||
|
||||
movb $0x85, %al # Turn into Normal Mode
|
||||
call doc_reset
|
||||
|
||||
read_next_page:
|
||||
movw $0x1000, %di # point %di to CDSN Control area
|
||||
|
||||
flash_command:
|
||||
movb $0x03, 0x04(%di) # start command cycle
|
||||
movb $0x00, (%si) # issue flash command Read00
|
||||
call doc_cycle_end
|
||||
|
||||
movw %bp, %bx # %bp is current page number
|
||||
|
||||
|
||||
flash_address:
|
||||
#ifndef SIS550_BUG
|
||||
shll $0x08, %ebx
|
||||
movb $0x01, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
|
||||
movb $0x05, 0x04(%di) # start address cycle
|
||||
0:
|
||||
movb %bl, (%si) # write address to CDSNIO
|
||||
shrw $0x08, %bx # shift next address byte
|
||||
loop 0b
|
||||
|
||||
#else /* SIS550_BUG */
|
||||
|
||||
movb $0x05, 0x04(%di) # start address cycle
|
||||
|
||||
movb $0x00, (%si)
|
||||
movw %bp, %bx
|
||||
movb %bl, (%si)
|
||||
movb $0x00, (%si)
|
||||
#ifdef STD_FLASH
|
||||
#include "rom/std_flash.inc"
|
||||
#else /* !STD_FLASH */
|
||||
#if defined(USE_DOC_MIL) || defined(USE_DOC_2000_TSOP)
|
||||
# include "rom/doc_mil.inc"
|
||||
#else defined(USE_DOC_MIL_PLUS)
|
||||
# include "rom/doc_mil_plus.inc"
|
||||
#endif
|
||||
|
||||
call doc_cycle_end
|
||||
|
||||
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 $0x04, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
0:
|
||||
movb 0x20(%di), %al # read DOC NOP retisger
|
||||
loop 0b # four times
|
||||
|
||||
testb $0x80, 0x04(%di) # is flash ready ?
|
||||
jz wait_for_flash_ready
|
||||
|
||||
movb 0x1d(%di), %al # init read pipeline
|
||||
|
||||
movw $0x100, %cx # 1 page = 512 bytes
|
||||
movw $0x800, %si # point %si to CDSN Data area
|
||||
movw %dx, %di # restore saved current destination
|
||||
rep
|
||||
movsw
|
||||
|
||||
movw %di, %dx # save current destination
|
||||
incw %bp # increse current page number
|
||||
cmpw $(DOC_SPL_START_PAGE + DOC_SPL_SIZE_IN_PAGE), %bp
|
||||
# moved enough data ??
|
||||
jl read_next_page # no, read next page
|
||||
#endif /* STD_FLASH */
|
||||
|
||||
sis630ipl_end:
|
||||
jmp spl_vector # jump to SPL vector
|
||||
|
|
@ -326,7 +265,7 @@ write_common:
|
|||
read_spd:
|
||||
/* Input: AH = 05h, AL = byte number of SPD to be read.
|
||||
Output: BL = The value of specified SPD byte. */
|
||||
movb $0x05, %ah
|
||||
movb $0x05, %ah # set SMB Command == byte address
|
||||
CALL_BP(sis_set_smbus)
|
||||
|
||||
movw $0x0312, %ax # Start, R/W byte Data
|
||||
|
|
@ -347,7 +286,7 @@ read_spd_fail:
|
|||
|
||||
sis_get_smbus:
|
||||
/* Input: AH - register index.
|
||||
Output: AL - register value. */
|
||||
Output: BL - register value. */
|
||||
addb %ah, %dl # read SMBus byte 0
|
||||
inb %dx, %al
|
||||
movb %al, %bl # return result in BL
|
||||
|
|
@ -364,18 +303,6 @@ sis_set_smbus:
|
|||
outb %al, %dx
|
||||
RET_BP # End of sis_set_smbus
|
||||
|
||||
doc_reset:
|
||||
/* Input: AL = value write to DOC_CONTROL register
|
||||
Clobberd: CX */
|
||||
movb %al, 0x02(%di) # write DoC Control retister
|
||||
movb %al, 0x02(%di) # twice
|
||||
ret # End of doc_reset
|
||||
|
||||
doc_cycle_end:
|
||||
movb $0x00, 0x1e(%di) # flush write pepeline
|
||||
movb $0x01, 0x04(%di) # end command cycle
|
||||
ret
|
||||
|
||||
sdram_type_bank_1:
|
||||
# Column Number 8 9 10 11 Row Number
|
||||
.byte 0b0000, 0b0100, 0b1000, 0xff # 11
|
||||
|
|
@ -420,15 +347,31 @@ pci_init_table:
|
|||
.word 0x5201 # Refresh Cycle Enable
|
||||
.word 0x0000 /* Null, End of table */
|
||||
|
||||
.org 0x01f0
|
||||
#ifdef STD_FLASH
|
||||
.org 0xfff0
|
||||
reset_vector:
|
||||
.byte 0xea # jmp to f000:fe00, where IPL
|
||||
.word 0xfe00, 0xf000 # starts in Standard Flash
|
||||
#else /* !STD_FLASH i.e. DoC Mil */
|
||||
#if defined(USE_DOC_MIL)
|
||||
.org 0x1f0
|
||||
#elif defined(USE_DOC_2000_TSOP) || defined(USE_DOC_MIL_PLUS)
|
||||
.org 0x3f0
|
||||
#endif
|
||||
reset_vector:
|
||||
.byte 0xea # jmp to fe00:0000, where IPL
|
||||
.word 0x0000, DOC_WIN_SEG # starts in DoC
|
||||
#endif /* STD_FLASH */
|
||||
|
||||
spl_vector:
|
||||
.byte 0xea # jmp to 8000:0000, where SPL
|
||||
.word 0x0000, SPL_RAM_SEG # (LinuxBIOS) starts in RAM
|
||||
|
||||
.org 0x01ff
|
||||
#if defined(USE_DOC_MIL)
|
||||
.org 0x1ff
|
||||
#elif defined(USE_DOC_2000_TSOP) || defined(USE_DOC_MIL_PLUS)
|
||||
.org 0x3ff
|
||||
#endif
|
||||
|
||||
end:
|
||||
hlt
|
||||
|
|
|
|||
|
|
@ -16,14 +16,107 @@ static char rcsid[] =
|
|||
#include <subr.h>
|
||||
#include <pci.h>
|
||||
#include <pci_ids.h>
|
||||
#include <arch/io.h>
|
||||
#include <cpu/p5/io.h>
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define BYTE sizeof(u8)
|
||||
#define WORD sizeof(u16)
|
||||
#define DBLE sizeof(u32)
|
||||
#define IDE_REG_EXTENDED_OFFSET (0x200u)
|
||||
#define IDE_REG_SECTOR_COUNT(base) ((base) + 2u)
|
||||
#define IDE_REG_CONTROL(base) ((base) + IDE_REG_EXTENDED_OFFSET + 6u)
|
||||
#define IDE_BASE1 (0x1F0u) /* primary controller */
|
||||
#define ASIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
typedef struct {
|
||||
u8 size;
|
||||
u8 regno;
|
||||
u32 andval;
|
||||
u32 orval;
|
||||
} initreg_t;
|
||||
|
||||
static const initreg_t ide_init[] = {
|
||||
/*
|
||||
* BUS(0), DEVICE(0), FUNCTION(1): IDE Interface. Bridge
|
||||
*/
|
||||
/* SIZE REG AND-MASK OR-MASK */
|
||||
{ WORD, 0x04, 0x00, 0x0007 }, /* Command Register. sets mem+ */
|
||||
{ WORD, 0x06, 0x00, 0x3000 }, /* Status reg, clear aborts. */
|
||||
{ WORD, 0x09, 0x0A, 0x00 }, /* Programming interface = Compatible mode. */
|
||||
{ BYTE, 0x0D, 0x00, 0x10 }, /* Latency Timer */
|
||||
/* We let the pci enumerator assign these. */
|
||||
// { DBLE, 0x10, 0x0, 0x1F1 }, /* Primary channel base addr. */
|
||||
// { DBLE, 0x14, 0x0, 0x3F5 }, /* Primary channel control base addr. */
|
||||
// { DBLE, 0x18, 0x0, 0x171 }, /* Secondary channel base addr. */
|
||||
// { DBLE, 0x1C, 0x0, 0x375 }, /* Secondary channel control base addr. */
|
||||
// { DBLE, 0x20, 0x0, 0x4001 }, /* Control register base addr. */
|
||||
{ WORD, 0x2C, 0x00, 0x1039 }, /* Subsystem vendor ID. */
|
||||
{ WORD, 0x2E, 0x00, 0x5513 }, /* Subsystem ID. */
|
||||
{ BYTE, 0x3c, 0x00, 0x0e }, /* reserved don't do this, sets irq 14 */
|
||||
{ BYTE, 0x40, 0x00, 0x01 }, /* Primary master data recovery time. 1 PCICLK */
|
||||
{ BYTE, 0x41, 0x00, 0xb3 }, /* Primary master data active time. UDMA Mode 2 */
|
||||
{ BYTE, 0x42, 0x00, 0x00 }, /* Primary slave data recovery time. */
|
||||
{ BYTE, 0x43, 0x00, 0x00 }, /* Primary slave data active time. */
|
||||
{ BYTE, 0x44, 0x00, 0x00 }, /* Secondary master data recovery time. */
|
||||
{ BYTE, 0x45, 0x00, 0x00 }, /* Secondary master data active time. */
|
||||
{ BYTE, 0x46, 0x00, 0x00 }, /* Secondary slave data recovery time. */
|
||||
{ BYTE, 0x47, 0x00, 0x00 }, /* Secondary slave data active time. */
|
||||
{ BYTE, 0x48, 0x00, 0x05 }, /* Read/Write FIFO Threshold = 1/4 */
|
||||
{ BYTE, 0x4A, 0x40, 0xe2 }, /* Enable Bus Master, Fast postwrite, IDE 0 */
|
||||
{ BYTE, 0x4B, 0x00, 0x11 }, /* Enable Postwrite and Prefech for IDE0, Master */
|
||||
{ WORD, 0x4C, 0x00, 0x0200 }, /* Prefetch count of primary. */
|
||||
{ WORD, 0x4E, 0x00, 0x0200 }, /* Prefetch count of secondary. */
|
||||
{ BYTE, 0x52, 0xFF, 0x14 } /* Miscelaneous control (Only Doc). */
|
||||
};
|
||||
|
||||
void ide_fixup(void)
|
||||
{
|
||||
volatile int delay;
|
||||
struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513,
|
||||
(void *) NULL);
|
||||
int i;
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
|
||||
int initlen = ASIZE(ide_init);
|
||||
const initreg_t * inittab = ide_init;
|
||||
|
||||
printk_info ("Entering the initregs process\n");
|
||||
|
||||
for (i = 0; i < initlen; ++i) {
|
||||
u16 regno = inittab[i].regno;
|
||||
switch (inittab[i].size) {
|
||||
case BYTE:
|
||||
pci_read_config_byte(dev, regno, &val8);
|
||||
val8 = (val8 & inittab[i].andval) | inittab[i].orval;
|
||||
pci_write_config_byte(dev, regno, val8);
|
||||
break;
|
||||
case WORD:
|
||||
pci_read_config_word(dev, regno, &val16);
|
||||
val16 = (val16 & inittab[i].andval) | inittab[i].orval;
|
||||
pci_write_config_word(dev, regno, val16);
|
||||
break;
|
||||
case DBLE:
|
||||
pci_read_config_dword(dev, regno, &val32);
|
||||
val32 = (val32 & inittab[i].andval) | inittab[i].orval;
|
||||
break;
|
||||
|
||||
default:
|
||||
outb_p(0xEE,0x80);
|
||||
while(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_on()
|
||||
{
|
||||
u8 regval;
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
/* turn on sis550 keyboard/mouse controller */
|
||||
void pc_keyboard_init(void);
|
||||
/* turn on sis630 keyboard/mouse controller */
|
||||
pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, (void *)NULL);
|
||||
if (pcidev != NULL) {
|
||||
/* Register 0x47, Keyboard Controller */
|
||||
|
|
@ -175,6 +268,7 @@ final_southbridge_fixup()
|
|||
|
||||
serial_irq_fixedup();
|
||||
acpi_fixup();
|
||||
ide_fixup();
|
||||
|
||||
/* Delay transaction, experimental */
|
||||
south_fixup();
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ sis630spd_start:
|
|||
movw $0x7550, %ax # Store ACPI Base Address.
|
||||
CALL_SP(write_lpc_register) # (for use of SMBus)
|
||||
|
||||
movw $0x5501, %ax # Mode# enable, this bit
|
||||
movw $0x5501, %ax # MDOE# enable, this bit
|
||||
CALL_SP(write_pci_register) # should be set before sizing.
|
||||
|
||||
#ifdef SIZE_ALL
|
||||
|
|
@ -214,88 +214,17 @@ sis630ipl_start:
|
|||
movw %ax, %ss
|
||||
movw $SPL_RAM_SEG, %ax
|
||||
movw %ax, %es
|
||||
xorw %sp, %sp # clear %sp
|
||||
|
||||
#ifdef STD_FLASH
|
||||
movw $0xf000, %ax
|
||||
movw %ax, %ds
|
||||
xorw %sp, %sp # clear %sp
|
||||
xorw %si, %si
|
||||
xorw %di, %di
|
||||
movw $0xffff, %cx
|
||||
rep
|
||||
movsb
|
||||
|
||||
movw $DOC_WIN_SEG, %ax
|
||||
movw %ax, %ds
|
||||
#include "rom/std_flash.inc"
|
||||
#else /* !STD_FLASH */
|
||||
movw $sis950_init_table, %si # unlock SiS 950 LPC
|
||||
movw $0x05, %cx # select Clock Selection
|
||||
movw $0x2e, %dx # and Flash ROM I/F
|
||||
rep
|
||||
outsb
|
||||
movb $0xfd, %al # enable write, CLKIN = 24 MHZ
|
||||
outb %al, $0x2f
|
||||
|
||||
xorw %sp, %sp # clear %sp
|
||||
xorw %dx, %dx # clear %dx, start of RAM
|
||||
movw $0x800, %si # point %si to CDSN Data area
|
||||
movw $0x1000, %di # point %di to CDSN Control area
|
||||
movw $DOC_SPL_START_PAGE, %bp # start page of LinuxBIOS
|
||||
|
||||
movb $0x84, %al # Reset DOC Millennium
|
||||
call doc_reset
|
||||
|
||||
movb $0x85, %al # Turn into Normal Mode
|
||||
call doc_reset
|
||||
|
||||
read_next_page:
|
||||
movw $0x1000, %di # point %di to CDSN Control area
|
||||
|
||||
flash_command:
|
||||
movb $0x03, 0x04(%di) # start command cycle
|
||||
movb $0x00, (%si) # issue flash command Read00
|
||||
call doc_cycle_end
|
||||
|
||||
movw %bp, %bx # %bp is current page number
|
||||
|
||||
flash_address:
|
||||
shll $0x08, %ebx
|
||||
movb $0x03, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
|
||||
movb $0x05, 0x04(%di) # start address cycle
|
||||
0:
|
||||
movb %bl, (%si) # write address to CDSNIO
|
||||
shrw $0x08, %bx # shift next address byte
|
||||
loop 0b
|
||||
|
||||
call doc_cycle_end
|
||||
|
||||
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 $0x04, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
0:
|
||||
movb 0x20(%di), %al # read DOC NOP retisger
|
||||
loop 0b # four times
|
||||
|
||||
testb $0x80, 0x04(%di) # is flash ready ?
|
||||
jz wait_for_flash_ready
|
||||
|
||||
movb 0x1d(%di), %al # init read pipeline
|
||||
movw $0x100, %cx # 1 page = 512 bytes
|
||||
movw $0x800, %si # point %si to CDSN Data area
|
||||
movw %dx, %di # restore saved current destination
|
||||
rep
|
||||
movsw
|
||||
|
||||
movw %di, %dx # save current destination
|
||||
incw %bp # increse current page number
|
||||
cmpw $(DOC_SPL_START_PAGE + DOC_SPL_SIZE_IN_PAGE), %bp
|
||||
# moved enough data ??
|
||||
jl read_next_page # no, read next page
|
||||
#include "unlock_flash.inc"
|
||||
#if defined(USE_DOC_MIL) || defined(USE_DOC_2000_TSOP)
|
||||
# include "rom/doc_mil.inc"
|
||||
#else defined(USE_DOC_MIL_PLUS)
|
||||
# include "rom/doc_mil_plus.inc"
|
||||
#endif
|
||||
#endif /* STD_FLASH */
|
||||
|
||||
sis630ipl_end:
|
||||
|
|
@ -369,18 +298,6 @@ sis_set_smbus:
|
|||
outb %al, %dx
|
||||
RET_BP # End of sis_set_smbus
|
||||
|
||||
doc_reset:
|
||||
/* Input: AL = value write to DOC_CONTROL register
|
||||
Clobberd: CX */
|
||||
movb %al, 0x02(%di) # write DoC Control retister
|
||||
movb %al, 0x02(%di) # twice
|
||||
ret # End of doc_reset
|
||||
|
||||
doc_cycle_end:
|
||||
movb $0x00, 0x1e(%di) # flush write pepeline
|
||||
movb $0x01, 0x04(%di) # end command cycle
|
||||
ret
|
||||
|
||||
sdram_type_bank_1:
|
||||
# Column Number 8 9 10 11 Row Number
|
||||
.byte 0b0000, 0b0100, 0b1000, 0xff # 11
|
||||
|
|
@ -412,7 +329,11 @@ reset_vector:
|
|||
.byte 0xea # jmp to f000:fe00, where IPL
|
||||
.word 0xfe00, 0xf000 # starts in Standard Flash
|
||||
#else /* !STD_FLASH i.e. DoC Mil */
|
||||
#if defined(USE_DOC_MIL)
|
||||
.org 0x1f0
|
||||
#elif defined(USE_DOC_2000_TSOP) || defined(USE_DOC_MIL_PLUS)
|
||||
.org 0x3f0
|
||||
#endif
|
||||
reset_vector:
|
||||
.byte 0xea # jmp to fe00:0000, where IPL
|
||||
.word 0x0000, DOC_WIN_SEG # starts in DoC
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@ static char rcsid[] =
|
|||
|
||||
#include <types.h>
|
||||
|
||||
/*
|
||||
* Something in the pci enumerator appears to be hosing
|
||||
* values in the ide pci space. This is a temp workaround.
|
||||
*/
|
||||
#define BYTE sizeof(u8)
|
||||
#define WORD sizeof(u16)
|
||||
#define DBLE sizeof(u32)
|
||||
|
|
@ -33,101 +29,88 @@ static char rcsid[] =
|
|||
#define IDE_BASE1 (0x1F0u) /* primary controller */
|
||||
#define ASIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
|
||||
void ide_fixup(void) {
|
||||
volatile int delay;
|
||||
struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, (void *)NULL);
|
||||
int i;
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
|
||||
typedef struct {
|
||||
u8 size;
|
||||
u8 regno;
|
||||
u32 andval;
|
||||
u32 orval;
|
||||
u8 size;
|
||||
u8 regno;
|
||||
u32 andval;
|
||||
u32 orval;
|
||||
} initreg_t;
|
||||
|
||||
static const initreg_t ide_init[] = {
|
||||
/*
|
||||
* BUS(0), DEVICE(0), FUNCTION(1): IDE Interface. Bridge
|
||||
*/
|
||||
/*SIZE REG AND-MASK OR-MASK */
|
||||
{ WORD, 0x04, 0x0, 0x0007 }, /* Command Register. sets mem+ */
|
||||
{ WORD, 0x06, 0x0, 0x3000 }, /* Status reg, clear aborts. */
|
||||
{ WORD, 0x09, 0x0A, 0x00 }, /* Programming interface = Compatible mode. */
|
||||
{ BYTE, 0x0D, 0x0, 0x10 }, /* Latency Timer */
|
||||
/* We let the pci enumerator assign these. */
|
||||
// { DBLE, 0x10, 0x0, 0x1F1 }, /* Primary channel base addr. */
|
||||
// { DBLE, 0x14, 0x0, 0x3F5 }, /* Primary channel control base addr. */
|
||||
// { DBLE, 0x18, 0x0, 0x171 }, /* Secondary channel base addr. */
|
||||
// { DBLE, 0x1C, 0x0, 0x375 }, /* Secondary channel control base addr. */
|
||||
// { DBLE, 0x20, 0x0, 0x4001 }, /* Control register base addr. */
|
||||
{ WORD, 0x2C, 0x0, 0x1039 }, /* Subsystem vendor ID. */
|
||||
{ WORD, 0x2E, 0x0, 0x5513 }, /* Subsystem ID. */
|
||||
{ BYTE, 0x3c, 0x0, 0x0e }, /* reserved don't do this, sets irq 14 */
|
||||
{ BYTE, 0x40, 0x00, 0x01 }, /* Primary master data recovery time. */
|
||||
{ BYTE, 0x41, 0x00, 0xb3 }, /* Primary master data active time. UDMA */
|
||||
{ BYTE, 0x42, 0x00, 0x00 }, /* Primary slave data recovery time. */
|
||||
{ BYTE, 0x43, 0x00, 0x00 }, /* Primary slave data active time. */
|
||||
{ BYTE, 0x44, 0x00, 0x00 }, /* Secondary master data recovery time. */
|
||||
{ BYTE, 0x45, 0x00, 0x00 }, /* Secondary master data active time. */
|
||||
{ BYTE, 0x46, 0x00, 0x00 }, /* Secondary slave data recovery time. */
|
||||
{ BYTE, 0x47, 0x00, 0x00 }, /* Secondary slave data active time. */
|
||||
{ BYTE, 0x48, 0x00, 0x05 }, /* Ide status */
|
||||
{ BYTE, 0x4A, 0x40, 0xe6 }, /* Ide general control 0 was 0x62 */
|
||||
{ BYTE, 0x4B, 0x00, 0x11 }, /* Ide general control 1 */
|
||||
{ WORD, 0x4C, 0x00, 0x0200}, /* prefetch of primary. */
|
||||
{ WORD, 0x4E, 0x00, 0x0200} /* prefetch of secondary. */
|
||||
//{ BYTE, 0x48, 0x00, 0x33 }, /* Ide status */
|
||||
//{ BYTE, 0x4A, 0x00, 0xe2 }, /* Ide general control 0 was 0x62 */
|
||||
//{ BYTE, 0x4B, 0x00, 0x00 } /* Ide general control 1 */
|
||||
/* The following register has recommended setting of 0x41 in 630 programming guide,
|
||||
* But no documentation in the manual. It looks identical to the same register in the
|
||||
* 530.
|
||||
*/
|
||||
,
|
||||
{ BYTE, 0x52, 0xFF, 0x14 } /* Miscelaneous control (Only Doc). */
|
||||
};
|
||||
int initlen=ASIZE(ide_init);
|
||||
const initreg_t * inittab = ide_init;
|
||||
static const initreg_t ide_init[] = {
|
||||
/*
|
||||
* BUS(0), DEVICE(0), FUNCTION(1): IDE Interface. Bridge
|
||||
*/
|
||||
/* SIZE REG AND-MASK OR-MASK */
|
||||
{ WORD, 0x04, 0x00, 0x0007 }, /* Command Register. sets mem+ */
|
||||
{ WORD, 0x06, 0x00, 0x3000 }, /* Status reg, clear aborts. */
|
||||
{ WORD, 0x09, 0x0A, 0x00 }, /* Programming interface = Compatible mode. */
|
||||
{ BYTE, 0x0D, 0x00, 0x10 }, /* Latency Timer */
|
||||
/* We let the pci enumerator assign these. */
|
||||
// { DBLE, 0x10, 0x0, 0x1F1 }, /* Primary channel base addr. */
|
||||
// { DBLE, 0x14, 0x0, 0x3F5 }, /* Primary channel control base addr. */
|
||||
// { DBLE, 0x18, 0x0, 0x171 }, /* Secondary channel base addr. */
|
||||
// { DBLE, 0x1C, 0x0, 0x375 }, /* Secondary channel control base addr. */
|
||||
// { DBLE, 0x20, 0x0, 0x4001 }, /* Control register base addr. */
|
||||
{ WORD, 0x2C, 0x00, 0x1039 }, /* Subsystem vendor ID. */
|
||||
{ WORD, 0x2E, 0x00, 0x5513 }, /* Subsystem ID. */
|
||||
{ BYTE, 0x3c, 0x00, 0x0e }, /* reserved don't do this, sets irq 14 */
|
||||
{ BYTE, 0x40, 0x00, 0x01 }, /* Primary master data recovery time. 1 PCICLK */
|
||||
{ BYTE, 0x41, 0x00, 0xb3 }, /* Primary master data active time. UDMA Mode 2 */
|
||||
{ BYTE, 0x42, 0x00, 0x00 }, /* Primary slave data recovery time. */
|
||||
{ BYTE, 0x43, 0x00, 0x00 }, /* Primary slave data active time. */
|
||||
{ BYTE, 0x44, 0x00, 0x00 }, /* Secondary master data recovery time. */
|
||||
{ BYTE, 0x45, 0x00, 0x00 }, /* Secondary master data active time. */
|
||||
{ BYTE, 0x46, 0x00, 0x00 }, /* Secondary slave data recovery time. */
|
||||
{ BYTE, 0x47, 0x00, 0x00 }, /* Secondary slave data active time. */
|
||||
{ BYTE, 0x48, 0x00, 0x05 }, /* Read/Write FIFO Threshold = 1/4 */
|
||||
{ BYTE, 0x4A, 0x40, 0xe2 }, /* Enable Bus Master, Fast postwrite, IDE 0 */
|
||||
{ BYTE, 0x4B, 0x00, 0x11 }, /* Enable Postwrite and Prefech for IDE0, Master */
|
||||
{ WORD, 0x4C, 0x00, 0x0200 }, /* Prefetch count of primary. */
|
||||
{ WORD, 0x4E, 0x00, 0x0200 }, /* Prefetch count of secondary. */
|
||||
{ BYTE, 0x52, 0xFF, 0x14 } /* Miscelaneous control (Only Doc). */
|
||||
};
|
||||
|
||||
void ide_fixup(void)
|
||||
{
|
||||
volatile int delay;
|
||||
struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513,
|
||||
(void *) NULL);
|
||||
int i;
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
|
||||
int initlen = ASIZE(ide_init);
|
||||
const initreg_t * inittab = ide_init;
|
||||
|
||||
printk_info ("Entering the initregs process\n");
|
||||
|
||||
for (i = 0; i < initlen; ++i) {
|
||||
u16 regno = inittab[i].regno;
|
||||
switch (inittab[i].size) {
|
||||
case BYTE:
|
||||
pci_read_config_byte(dev, regno, &val8);
|
||||
val8 = (val8 & inittab[i].andval) | inittab[i].orval;
|
||||
pci_write_config_byte(dev, regno, val8);
|
||||
break;
|
||||
case WORD:
|
||||
pci_read_config_word(dev, regno, &val16);
|
||||
val16 = (val16 & inittab[i].andval) | inittab[i].orval;
|
||||
pci_write_config_word(dev, regno, val16);
|
||||
break;
|
||||
case DBLE:
|
||||
pci_read_config_dword(dev, regno, &val32);
|
||||
val32 = (val32 & inittab[i].andval) | inittab[i].orval;
|
||||
break;
|
||||
|
||||
default:
|
||||
outb_p(0xEE,0x80);
|
||||
while(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printk_info ("Entering the initregs process\n");
|
||||
|
||||
for (i = 0; i < initlen; ++i) {
|
||||
u16 regno = inittab[i].regno;
|
||||
switch (inittab[i].size) {
|
||||
case BYTE:
|
||||
pci_read_config_byte(dev, regno, &val8);
|
||||
val8 = (val8 & inittab[i].andval) | inittab[i].orval;
|
||||
pci_write_config_byte(dev, regno, val8);
|
||||
break;
|
||||
case WORD:
|
||||
pci_read_config_word(dev, regno, &val16);
|
||||
val16 = (val16 & inittab[i].andval) | inittab[i].orval;
|
||||
pci_write_config_word(dev, regno, val16);
|
||||
break;
|
||||
case DBLE:
|
||||
pci_read_config_dword(dev, regno, &val32);
|
||||
val32 = (val32 & inittab[i].andval) | inittab[i].orval;
|
||||
break;
|
||||
|
||||
default:
|
||||
outb_p(0xEE,0x80);
|
||||
while(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void keyboard_on()
|
||||
{
|
||||
u8 regval;
|
||||
|
|
@ -145,7 +128,6 @@ void keyboard_on()
|
|||
pc_keyboard_init();
|
||||
}
|
||||
|
||||
|
||||
void nvram_on()
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
|
|
|
|||
|
|
@ -117,11 +117,11 @@ check_row_column:
|
|||
jl no_sdram
|
||||
#endif /* SAFTY_CHECK */
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
subb $0x0b, %ch # row = row - 11
|
||||
shlb $0x02, %ch # row * 4
|
||||
|
||||
addb %ch, %cl # column + row *4
|
||||
addb %ch, %cl # column + row * 4
|
||||
movzbw %cl, %bx # Get the SDRAM type.
|
||||
|
||||
addw %bx, %si # sdram_type_bank[column + row * 4]
|
||||
|
|
@ -214,88 +214,17 @@ sis730ipl_start:
|
|||
movw %ax, %ss
|
||||
movw $SPL_RAM_SEG, %ax
|
||||
movw %ax, %es
|
||||
xorw %sp, %sp # clear %sp
|
||||
|
||||
#ifdef STD_FLASH
|
||||
movw $0xf000, %ax
|
||||
movw %ax, %ds
|
||||
xorw %sp, %sp # clear %sp
|
||||
xorw %si, %si
|
||||
xorw %di, %di
|
||||
movw $0xffff, %cx
|
||||
rep
|
||||
movsb
|
||||
|
||||
movw $DOC_WIN_SEG, %ax
|
||||
movw %ax, %ds
|
||||
#include "rom/std_flash.inc"
|
||||
#else /* !STD_FLASH */
|
||||
movw $sis950_init_table, %si # unlock SiS 950 LPC
|
||||
movw $0x05, %cx # select Clock Selection
|
||||
movw $0x2e, %dx # and Flash ROM I/F
|
||||
rep
|
||||
outsb
|
||||
movb $0xfd, %al # enable write, CLKIN = 24 MHZ
|
||||
outb %al, $0x2f
|
||||
|
||||
xorw %sp, %sp # clear %sp
|
||||
xorw %dx, %dx # clear %dx, start of RAM
|
||||
movw $0x800, %si # point %si to CDSN Data area
|
||||
movw $0x1000, %di # point %di to CDSN Control area
|
||||
movw $DOC_SPL_START_PAGE, %bp # start page of LinuxBIOS
|
||||
|
||||
movb $0x84, %al # Reset DOC Millennium
|
||||
call doc_reset
|
||||
|
||||
movb $0x85, %al # Turn into Normal Mode
|
||||
call doc_reset
|
||||
|
||||
read_next_page:
|
||||
movw $0x1000, %di # point %di to CDSN Control area
|
||||
|
||||
flash_command:
|
||||
movb $0x03, 0x04(%di) # start command cycle
|
||||
movb $0x00, (%si) # issue flash command Read00
|
||||
call doc_cycle_end
|
||||
|
||||
movw %bp, %bx # %bp is current page number
|
||||
|
||||
flash_address:
|
||||
shll $0x08, %ebx
|
||||
movb $0x03, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
|
||||
movb $0x05, 0x04(%di) # start address cycle
|
||||
0:
|
||||
movb %bl, (%si) # write address to CDSNIO
|
||||
shrw $0x08, %bx # shift next address byte
|
||||
loop 0b
|
||||
|
||||
call doc_cycle_end
|
||||
|
||||
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 $0x04, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
0:
|
||||
movb 0x20(%di), %al # read DOC NOP retisger
|
||||
loop 0b # four times
|
||||
|
||||
testb $0x80, 0x04(%di) # is flash ready ?
|
||||
jz wait_for_flash_ready
|
||||
|
||||
movb 0x1d(%di), %al # init read pipeline
|
||||
movw $0x100, %cx # 1 page = 512 bytes
|
||||
movw $0x800, %si # point %si to CDSN Data area
|
||||
movw %dx, %di # restore saved current destination
|
||||
rep
|
||||
movsw
|
||||
|
||||
movw %di, %dx # save current destination
|
||||
incw %bp # increse current page number
|
||||
cmpw $(DOC_SPL_START_PAGE + DOC_SPL_SIZE_IN_PAGE), %bp
|
||||
# moved enough data ??
|
||||
jl read_next_page # no, read next page
|
||||
#include "unlock_flash.inc"
|
||||
#if defined(USE_DOC_MIL) || defined(USE_DOC_2000_TSOP)
|
||||
# include "rom/doc_mil.inc"
|
||||
#else defined(USE_DOC_MIL_PLUS)
|
||||
# include "rom/doc_mil_plus.inc"
|
||||
#endif
|
||||
#endif /* STD_FLASH */
|
||||
|
||||
sis730ipl_end:
|
||||
|
|
@ -331,7 +260,7 @@ write_common:
|
|||
read_spd:
|
||||
/* Input: AH = 05h, AL = byte number of SPD to be read.
|
||||
Output: BL = The value of specified SPD byte. */
|
||||
movb $0x05, %ah
|
||||
movb $0x05, %ah # set SMB Command == byte address
|
||||
CALL_BP(sis_set_smbus)
|
||||
|
||||
movw $0x0312, %ax # Start, R/W byte Data
|
||||
|
|
@ -352,7 +281,7 @@ read_spd_fail:
|
|||
|
||||
sis_get_smbus:
|
||||
/* Input: AH - register index.
|
||||
Output: AL - register value. */
|
||||
Output: BL - register value. */
|
||||
addb %ah, %dl # read SMBus byte 0
|
||||
inb %dx, %al
|
||||
movb %al, %bl # return result in BL
|
||||
|
|
@ -369,18 +298,6 @@ sis_set_smbus:
|
|||
outb %al, %dx
|
||||
RET_BP # End of sis_set_smbus
|
||||
|
||||
doc_reset:
|
||||
/* Input: AL = value write to DOC_CONTROL register
|
||||
Clobberd: CX */
|
||||
movb %al, 0x02(%di) # write DoC Control retister
|
||||
movb %al, 0x02(%di) # twice
|
||||
ret # End of doc_reset
|
||||
|
||||
doc_cycle_end:
|
||||
movb $0x00, 0x1e(%di) # flush write pepeline
|
||||
movb $0x01, 0x04(%di) # end command cycle
|
||||
ret
|
||||
|
||||
sdram_type_bank_1:
|
||||
# Column Number 8 9 10 11 Row Number
|
||||
.byte 0b0000, 0b0100, 0b1000, 0xff # 11
|
||||
|
|
@ -420,7 +337,11 @@ reset_vector:
|
|||
.byte 0xea # jmp to f000:fe00, where IPL
|
||||
.word 0xfe00, 0xf000 # starts in Standard Flash
|
||||
#else /* !STD_FLASH i.e. DoC Mil */
|
||||
#if defined(USE_DOC_MIL)
|
||||
.org 0x1f0
|
||||
#elif defined(USE_DOC_2000_TSOP) || defined(USE_DOC_MIL_PLUS)
|
||||
.org 0x3f0
|
||||
#endif
|
||||
reset_vector:
|
||||
.byte 0xea # jmp to fe00:0000, where IPL
|
||||
.word 0x0000, DOC_WIN_SEG # starts in DoC
|
||||
|
|
|
|||
|
|
@ -18,6 +18,99 @@ static char rcsid[] =
|
|||
#include <pci_ids.h>
|
||||
#include <cpu/p5/io.h>
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define BYTE sizeof(u8)
|
||||
#define WORD sizeof(u16)
|
||||
#define DBLE sizeof(u32)
|
||||
#define IDE_REG_EXTENDED_OFFSET (0x200u)
|
||||
#define IDE_REG_SECTOR_COUNT(base) ((base) + 2u)
|
||||
#define IDE_REG_CONTROL(base) ((base) + IDE_REG_EXTENDED_OFFSET + 6u)
|
||||
#define IDE_BASE1 (0x1F0u) /* primary controller */
|
||||
#define ASIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
typedef struct {
|
||||
u8 size;
|
||||
u8 regno;
|
||||
u32 andval;
|
||||
u32 orval;
|
||||
} initreg_t;
|
||||
|
||||
static const initreg_t ide_init[] = {
|
||||
/*
|
||||
* BUS(0), DEVICE(0), FUNCTION(1): IDE Interface. Bridge
|
||||
*/
|
||||
/* SIZE REG AND-MASK OR-MASK */
|
||||
{ WORD, 0x04, 0x00, 0x0007 }, /* Command Register. sets mem+ */
|
||||
{ WORD, 0x06, 0x00, 0x3000 }, /* Status reg, clear aborts. */
|
||||
{ WORD, 0x09, 0x0A, 0x00 }, /* Programming interface = Compatible mode. */
|
||||
{ BYTE, 0x0D, 0x00, 0x10 }, /* Latency Timer */
|
||||
/* We let the pci enumerator assign these. */
|
||||
// { DBLE, 0x10, 0x0, 0x1F1 }, /* Primary channel base addr. */
|
||||
// { DBLE, 0x14, 0x0, 0x3F5 }, /* Primary channel control base addr. */
|
||||
// { DBLE, 0x18, 0x0, 0x171 }, /* Secondary channel base addr. */
|
||||
// { DBLE, 0x1C, 0x0, 0x375 }, /* Secondary channel control base addr. */
|
||||
// { DBLE, 0x20, 0x0, 0x4001 }, /* Control register base addr. */
|
||||
{ WORD, 0x2C, 0x00, 0x1039 }, /* Subsystem vendor ID. */
|
||||
{ WORD, 0x2E, 0x00, 0x5513 }, /* Subsystem ID. */
|
||||
{ BYTE, 0x3c, 0x00, 0x0e }, /* reserved don't do this, sets irq 14 */
|
||||
{ BYTE, 0x40, 0x00, 0x01 }, /* Primary master data recovery time. 1 PCICLK */
|
||||
{ BYTE, 0x41, 0x00, 0xb3 }, /* Primary master data active time. UDMA Mode 2 */
|
||||
{ BYTE, 0x42, 0x00, 0x00 }, /* Primary slave data recovery time. */
|
||||
{ BYTE, 0x43, 0x00, 0x00 }, /* Primary slave data active time. */
|
||||
{ BYTE, 0x44, 0x00, 0x00 }, /* Secondary master data recovery time. */
|
||||
{ BYTE, 0x45, 0x00, 0x00 }, /* Secondary master data active time. */
|
||||
{ BYTE, 0x46, 0x00, 0x00 }, /* Secondary slave data recovery time. */
|
||||
{ BYTE, 0x47, 0x00, 0x00 }, /* Secondary slave data active time. */
|
||||
{ BYTE, 0x48, 0x00, 0x05 }, /* Read/Write FIFO Threshold = 1/4 */
|
||||
{ BYTE, 0x4A, 0x40, 0xe2 }, /* Enable Bus Master, Fast postwrite, IDE 0 */
|
||||
{ BYTE, 0x4B, 0x00, 0x11 }, /* Enable Postwrite and Prefech for IDE0, Master */
|
||||
{ WORD, 0x4C, 0x00, 0x0200 }, /* Prefetch count of primary. */
|
||||
{ WORD, 0x4E, 0x00, 0x0200 }, /* Prefetch count of secondary. */
|
||||
{ BYTE, 0x52, 0xFF, 0x14 } /* Miscelaneous control (Only Doc). */
|
||||
};
|
||||
|
||||
void ide_fixup(void)
|
||||
{
|
||||
volatile int delay;
|
||||
struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513,
|
||||
(void *) NULL);
|
||||
int i;
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
|
||||
int initlen = ASIZE(ide_init);
|
||||
const initreg_t * inittab = ide_init;
|
||||
|
||||
printk_info ("Entering the initregs process\n");
|
||||
|
||||
for (i = 0; i < initlen; ++i) {
|
||||
u16 regno = inittab[i].regno;
|
||||
switch (inittab[i].size) {
|
||||
case BYTE:
|
||||
pci_read_config_byte(dev, regno, &val8);
|
||||
val8 = (val8 & inittab[i].andval) | inittab[i].orval;
|
||||
pci_write_config_byte(dev, regno, val8);
|
||||
break;
|
||||
case WORD:
|
||||
pci_read_config_word(dev, regno, &val16);
|
||||
val16 = (val16 & inittab[i].andval) | inittab[i].orval;
|
||||
pci_write_config_word(dev, regno, val16);
|
||||
break;
|
||||
case DBLE:
|
||||
pci_read_config_dword(dev, regno, &val32);
|
||||
val32 = (val32 & inittab[i].andval) | inittab[i].orval;
|
||||
break;
|
||||
|
||||
default:
|
||||
outb_p(0xEE,0x80);
|
||||
while(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_on()
|
||||
{
|
||||
u8 regval;
|
||||
|
|
@ -282,6 +375,7 @@ final_southbridge_fixup()
|
|||
apc_fixup();
|
||||
serial_irq_fixedup();
|
||||
acpi_fixup();
|
||||
ide_fixup();
|
||||
|
||||
printk_debug("Southbridge fixup done for SIS 503\n");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue