mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
This now works enough to load linuxbios and jump to it!
This commit is contained in:
parent
42e38b5a3e
commit
9c56e39fcf
1 changed files with 151 additions and 167 deletions
|
@ -1,6 +1,6 @@
|
|||
#include <asm.h>
|
||||
#include <cpu/p5/macros.h>
|
||||
#include <intel.h>
|
||||
#include "asm.h"
|
||||
//#include <cpu/p5/macros.h>
|
||||
#include "intel.h"
|
||||
/*
|
||||
*/
|
||||
|
||||
|
@ -9,29 +9,16 @@
|
|||
#define SPL_RAM_SEG 0x8000
|
||||
|
||||
#define DOC_SPL_START_BLK 2 /* 0,1 for IPL */
|
||||
#define DOC_SPL_SIZE_IN_PAGE 126 /* 1 page = 512 bytes, total 63kB */
|
||||
#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 0xfe000
|
||||
.org 0x0
|
||||
.code16
|
||||
_start: jmp _realstart
|
||||
gdt: //GDT entry 0 (null segment)
|
||||
.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// GDT 1
|
||||
.word 0xffff, 0x0000 /* flat code segment */
|
||||
.byte 0x0, 0x9a, 0xcf, 0x0
|
||||
|
||||
.word 0xffff, 0x0000 /* flat data segment */
|
||||
.byte 0x0, 0x92, 0xcf, 0x0
|
||||
|
||||
gdtptr:
|
||||
.word 4*8-1
|
||||
.long gdt /* we know the offset */
|
||||
.long 0
|
||||
|
||||
/* initialize registers */
|
||||
#define REG(a) a&0xfc, (a&0x3)|4
|
||||
|
@ -62,106 +49,57 @@ register_table:
|
|||
.byte REG(0x6c), 0x0
|
||||
.byte 0x0
|
||||
_realstart:
|
||||
|
||||
// movb $0xaa,%al
|
||||
// outb %al,$0x80
|
||||
cli
|
||||
movw %cs, %ax
|
||||
movw %ax, %es
|
||||
|
||||
.byte 0x66 /* prefix */
|
||||
.byte 0x26
|
||||
.byte 0x0f, 0x01, 0x16 /* lgdt [es:offset]*/
|
||||
.word gdtptr - EXT(_start) /* offset in segment */
|
||||
|
||||
movl %cr0, %eax
|
||||
andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
|
||||
orl $0x60000001, %eax /* CD, NW, PE = 1 */
|
||||
movl %eax, %cr0
|
||||
|
||||
/* invalidate the cache */
|
||||
invd
|
||||
data32 ljmp $0x10, $.Lprotected
|
||||
|
||||
.Lprotected:
|
||||
.code32
|
||||
movw $0x18, %bx
|
||||
movw %bx, %es
|
||||
movw %bx, %ds
|
||||
/*
|
||||
movw %bx, %es
|
||||
movw %bx, %fs
|
||||
movw %bx, %gs
|
||||
movw %bx, %ss
|
||||
*/
|
||||
|
||||
// Registers
|
||||
// %esp holds the 0x80000000 pattern
|
||||
// %edx always hold $0xcf8
|
||||
// %esi holds 0
|
||||
// %edi holds 0x40000000
|
||||
// %bl is reused as needed.
|
||||
// store this constant in %esp
|
||||
movl $0x80000000, %esp
|
||||
/* make the flash writeable */
|
||||
/* select the south bridge, register 40 (base) */
|
||||
/* south bridge is device 7. 7 << 3 is 0x38 */
|
||||
movl %esp, %eax
|
||||
#define FLASHREG ((SUPERIO_DEVFN<<8) | 0x40)
|
||||
orw $FLASHREG, %ax
|
||||
mov $0xcf8,%dx
|
||||
outl %eax,%dx
|
||||
#if (SUPERIO_DEVFN == 0x88)
|
||||
mov $0xfc,%dl
|
||||
inl %dx,%eax
|
||||
/*
|
||||
For 8231:
|
||||
Please see databook revision 1.2, November 13, 2000. Page68.
|
||||
PCI to ISA bridge: Regx40[4]=1, Regx41[0-6]=1.
|
||||
*/
|
||||
orw $0x7f10, %ax
|
||||
outl %eax,%dx
|
||||
#endif
|
||||
#if (SUPERIO_DEVFN == 0x38)
|
||||
Please see databook revision 1.33, January 7, 2000. Page55
|
||||
and 56.
|
||||
PCI to ISA bridge: Regx40[0]=1 (write enable)
|
||||
Regx43[0-7]=1(all bits set to 1)
|
||||
|
||||
/* but 0x01 makes flash writeable. You need this for DoC */
|
||||
mov $0x0cfc,%dx
|
||||
inl %dx,%eax
|
||||
orl $0xc0000001, %eax
|
||||
outl %eax,%dx
|
||||
#endif
|
||||
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:
|
||||
movl $register_table, %esi
|
||||
movw $register_table, %si
|
||||
cld
|
||||
1:
|
||||
movl %esp, %eax
|
||||
orb (%esi), %al
|
||||
orb (%si), %al
|
||||
testb %al, %al
|
||||
jz done_ram_set_registers
|
||||
andb $0xf8, %dl
|
||||
outl %eax, %dx
|
||||
inc %esi
|
||||
orb (%esi), %dl
|
||||
inc %esi
|
||||
movb (%esi), %al
|
||||
|
||||
inc %si
|
||||
orb (%si), %dl
|
||||
inc %si
|
||||
movb (%si), %al
|
||||
outb %al, %dx
|
||||
// PCI_WRITE_CONFIG_BYTE
|
||||
inc %esi
|
||||
inc %si
|
||||
jmp 1b
|
||||
|
||||
// movb $0xbb,%al
|
||||
// outb %al,$0x80
|
||||
|
||||
done_ram_set_registers:
|
||||
xorl %esi, %esi
|
||||
movl $0x4000000, %edi
|
||||
xorw %si, %si
|
||||
// movl $0x4000000, %edi
|
||||
/* begin to initialize*/
|
||||
// I forget why we need this, but we do
|
||||
mov $0xa55a5aa5, %ecx
|
||||
mov %ecx, (%esi)
|
||||
mov %ecx, (%edi)
|
||||
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!
|
||||
|
@ -172,16 +110,16 @@ done_ram_set_registers:
|
|||
|
||||
/* wait 200us*/
|
||||
// You need to do the memory reference. That causes the nop cycle.
|
||||
mov (%esi), %ecx
|
||||
mov (%edi), %ecx
|
||||
movw (%si), %cx
|
||||
// mov (%edi), %ecx
|
||||
DELAY(loop200)
|
||||
|
||||
/* set precharge */
|
||||
WRITE_6c($0x6C, $0x02)
|
||||
|
||||
/* dummy reads*/
|
||||
mov (%esi), %ecx
|
||||
mov (%edi), %ecx
|
||||
movw (%si), %cx
|
||||
// mov (%edi), %ecx
|
||||
|
||||
/* set CBR*/
|
||||
WRITE_6c($0x6C, $0x04)
|
||||
|
@ -190,8 +128,8 @@ done_ram_set_registers:
|
|||
|
||||
movb $8, %bl
|
||||
eightreads:
|
||||
mov (%esi), %ecx
|
||||
mov (%edi), %ecx
|
||||
movw (%si), %cx
|
||||
// mov (%edi), %ecx
|
||||
DELAY(loop100)
|
||||
dec %bl
|
||||
cmpb $0, %bl
|
||||
|
@ -201,17 +139,17 @@ eightreads:
|
|||
// 0x150 is cas2. We are now using 0x1d0, which is cas3
|
||||
WRITE_6c($0x6c, $0x03)
|
||||
|
||||
movl $0x1d0, %ecx
|
||||
movl (%ecx), %ecx
|
||||
movl $0x40001d0, %ecx
|
||||
movl (%ecx), %ecx
|
||||
movw $0x1d0, %di
|
||||
movl (%di), %ecx
|
||||
// movl $0x40001d0, %ecx
|
||||
// movl (%ecx), %ecx
|
||||
|
||||
/* set to normal mode */
|
||||
WRITE_6c($0x6C, $0x00)
|
||||
|
||||
movl $0x55aa55aa, %ecx
|
||||
mov %ecx, (%esi)
|
||||
mov (%esi), %ecx
|
||||
movl %ecx, (%si)
|
||||
movl (%si), %ecx
|
||||
|
||||
// Set the refresh rate.
|
||||
movb $0x68, %al
|
||||
|
@ -226,7 +164,9 @@ eightreads:
|
|||
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 */
|
||||
|
@ -261,105 +201,145 @@ eightreads:
|
|||
*
|
||||
* $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 126 /* 1 page = 512 bytes, total 63kB */
|
||||
#define DOC_SPL_SIZE_IN_PAGE 252 /* 1 page = 512 bytes, total 63kB */
|
||||
|
||||
ipl_start:
|
||||
#if 0
|
||||
//#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
|
||||
// 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 $DOC_STACK, %esp # set %sp
|
||||
movl $SPL_RAM, %edx # start of RAM
|
||||
xorl %ecx, %ecx # clear %ecx
|
||||
movl $0xfe800, %esi # point %si to CDSN Data area
|
||||
movl $0xff000, %edi # point %di to CDSN Control area
|
||||
movl $DOC_SPL_START_BLK, %ebp # start page of LinuxBIOS
|
||||
|
||||
movb $0x84, %al # Reset DOC Millennium
|
||||
call doc_reset
|
||||
|
||||
movb $0x85, %al # Turn into Normal Mode
|
||||
call doc_reset
|
||||
|
||||
// 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:
|
||||
movl $0xff000, %edi # point %di to CDSN Control area
|
||||
|
||||
movw $0x1000, %di # point %di to CDSN Control area
|
||||
movw $0x800, %si
|
||||
flash_command:
|
||||
movb $0x03, 0x04(%edi) # start command cycle
|
||||
movb $0x00, (%esi) # issue flash command Read00
|
||||
call doc_cycle_end
|
||||
|
||||
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
|
||||
movb $0x03, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
movw $0x03, %cx # this one is DANGEROUS but I am
|
||||
|
||||
movb $0x05, 0x04(%edi) # start address cycle
|
||||
movb $0x15, %ds:0x04(%di) # start address cycle
|
||||
call delay4nop
|
||||
0:
|
||||
movb %bl, (%esi) # write address to CDSNIO
|
||||
movb %bl, %ds:(%si) # write address to CDSNIO
|
||||
shrw $0x08, %bx # shift next address byte
|
||||
loop 0b
|
||||
|
||||
call doc_cycle_end
|
||||
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 $0x04, %cl # this one is DANGEROUS but I am
|
||||
movb %ds:0x04(%di),%ah
|
||||
movw $0x04, %cx # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
0:
|
||||
movb 0x20(%edi), %al # read DOC NOP retisger
|
||||
movb %ds:0x20(%di), %al # read DOC NOP retisger
|
||||
loop 0b # four times
|
||||
|
||||
testb $0x80, 0x04(%edi) # is flash ready ?
|
||||
testb $0x80,%ah # is flash ready ?
|
||||
jz wait_for_flash_ready
|
||||
|
||||
movb 0x1d(%edi), %al # init read pipeline
|
||||
movw $0x100, %cx # 1 page = 512 bytes
|
||||
movl $0xfe800, %esi # point %si to CDSN Data area
|
||||
movl %edx, %edi # restore saved current destination
|
||||
rep
|
||||
movsw
|
||||
|
||||
movl %edi, %edx # save current destination
|
||||
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
|
||||
|
||||
doc_reset:
|
||||
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
|
||||
// movb %al, 0x02(%edi) # write DoC Control retister
|
||||
// movb %al, 0x02(%edi) # twice
|
||||
// ret # End of doc_reset
|
||||
|
||||
doc_cycle_end:
|
||||
movb $0x00, 0x1e(%edi) # flush write pepeline
|
||||
movb $0x01, 0x04(%edi) # end command cycle
|
||||
ret
|
||||
//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 */
|
||||
|
@ -388,14 +368,18 @@ pci_read_dword:
|
|||
RETSP
|
||||
#endif
|
||||
|
||||
.org 0xfe1f0
|
||||
.org 0x01f0
|
||||
reset_vector:
|
||||
.byte 0xea #jump to fe00:0000, where IPL
|
||||
.word 0x0000, DOC_WIN_SEG #starts in DoC
|
||||
.code32
|
||||
|
||||
spl_vector:
|
||||
invd
|
||||
jmpl $0x10, $0x80000
|
||||
// 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
|
||||
pad: .byte 0,0,0,0,0,0
|
||||
|
|
Loading…
Add table
Reference in a new issue