summaryrefslogtreecommitdiff
path: root/util/ADLO/loader.s
diff options
context:
space:
mode:
authorStefan Reinauer <stepan@openbios.org>2006-10-14 21:35:30 +0000
committerStefan Reinauer <stepan@openbios.org>2006-10-14 21:35:30 +0000
commitc1c3fdc79fab5b0d1572ea8f606c280b2df9676c (patch)
tree5cb58e91d722314d36403928d37c374c97403dea /util/ADLO/loader.s
parent5ed51d19331945915d2a879d11d72a7d1a8751b7 (diff)
downloadcoreboot-c1c3fdc79fab5b0d1572ea8f606c280b2df9676c.tar.xz
add ADLO to v2
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2457 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'util/ADLO/loader.s')
-rw-r--r--util/ADLO/loader.s461
1 files changed, 461 insertions, 0 deletions
diff --git a/util/ADLO/loader.s b/util/ADLO/loader.s
new file mode 100644
index 0000000000..48b6ec3299
--- /dev/null
+++ b/util/ADLO/loader.s
@@ -0,0 +1,461 @@
+;*****************************************************
+; $Id: loader.s,v 1.1 2002/11/25 02:07:53 rminnich Exp $
+;*****************************************************
+USE32
+; code it is loaded into memory at 0x7C00
+;*****************************************************
+nop
+nop
+;*****************************************************
+; A) setup GDT, so that we do not depend on program
+; that loaded us for GDT.
+; Ex: LinuxBIOS and EtherBOOT use different GDT's.
+
+;-----------------------------------------------------
+; 0)
+
+cli
+
+;-----------------------------------------------------
+; I)
+
+lgdt [0x7C00+protected_gdt]
+
+;-----------------------------------------------------
+; II) setup CS
+
+jmp 0x08:0x7C00+newpgdt
+
+newpgdt: nop
+
+;-----------------------------------------------------
+; III) setup all other segments
+
+mov ax, #0x10
+mov ss, ax
+mov ds, ax
+mov es, ax
+mov fs, ax
+mov gs, ax
+
+;-----------------------------------------------------
+; IV)
+
+; not now
+;sti
+
+;*****************************************************
+nop
+nop
+;*****************************************************
+; B) shadow - ON (enable/read/write)
+
+mov eax, #0x80000070
+mov dx, #0x0cf8
+out dx, eax
+
+mov eax, #0xFFFFFFFF
+mov dx, #0x0cfc
+out dx, eax
+
+;*****************************************************
+nop
+nop
+;*****************************************************
+; C) copy -- boch bios
+
+; counter - 64kb.
+mov ecx, #0x10000
+
+; source - 0x8000 ( 0x7C00+0x400 = 0x8000 )
+mov ax, #0x10 ; src-segment - 2nd entry in GDT
+mov ds, ax
+mov eax, #0x8000 ; src-offset - 0x8000
+mov esi, eax
+
+; destination - 0xE0000
+mov ax, #0x10 ; dst-segment - 2nd entry in GDT
+mov es, ax
+mov eax, #0xF0000 ; dst-offset - 0xF0000
+mov edi, eax
+
+; clear direction flag
+cld
+
+; the copy
+rep
+ movsb
+
+;*****************************************************
+nop
+nop
+;*****************************************************
+; X) copy -- LinuxBIOS table into safe place.
+
+ ;; TODO.
+ ;; Q1 : what is the size of table.
+ ;; Q2 : where to copy?
+
+;*****************************************************
+nop
+nop
+;*****************************************************
+; E) shadow - OFF (write)
+
+mov eax, #0x80000070
+mov dx, #0x0cf8
+out dx, eax
+
+;mov eax, #0xFFFFFFFF
+mov eax, #0x0000FFFF
+mov dx, #0x0cfc
+out dx, eax
+
+;*****************************************************
+nop
+nop
+;*****************************************************
+; F) do a little prep work.
+
+;-----------------------------------------------------
+; I) disable cache
+
+; if you disable cache, GRUB's GFX mode will be VERY slow.
+; so DO NOT DISABLE
+
+;mov eax, cr0
+;or eax, #0x60000000
+;wbinvd
+;mov cr0, eax
+;wbinvd
+
+;-----------------------------------------------------
+; II) disable MTRR
+; clear the "E" (0x800) and "FE" (0x400) flags in
+; IA32_MTRRdefType register (0x2FF)
+
+;-----------------------
+
+;mov ECX,#0x2FF
+
+; select either of the two below
+; depending on if your compiler suports
+; {RD,WR}MSR or not
+;rdmsr
+; .byte 0x0F, 0x32
+
+;xor edx, edx
+; xor eax, eax
+;and eax, #0xFFFFF3FF
+
+; select either of the two below
+; depending on if your compiler suports
+; {RD,WR}MSR or not
+;wrmsr
+; .byte 0x0F, 0x30
+
+;-----------------------
+;; This is what PC BIOS is setting. -- P6STMT.
+; add VIDEO BIOS cacheable!!!!
+;-----------------------
+; Fixed Range C0--C8
+;mov ECX,#0x268
+;mov EDX,#0x05050505
+;mov EAX,#0x05050505
+;wrmsr
+;-----------------------
+; Fixed Range C8--CF
+;mov ECX,#0x269
+;mov EDX,#0x0
+;mov EAX,#0x05050505
+;wrmsr
+;-----------------------
+
+;-----------------------------------------------------
+; III) tell BOCHS' BIOS we want to boot from hdd.
+; 0x00 - floppy
+; 0x02 - hdd
+; In future there will be 'fd failover'option in bochs.
+
+mov al, #0x3d ;; cmos_reg
+out 0x70, al
+mov al, #0x02 ;; val (hdd)
+out 0x71, al
+
+;-----------------------------------------------------
+; IV) tell BOCHS' BIOS length of our mem block @ 1mb.
+; This is for Int 15 / EAX=E820
+; 119mb = 0x77 00 00 00
+; (this is for 128mb of ram)
+; (FIXME: this value is currently hard coded)
+; (it should be being passed from LinuxBIOS )
+
+; for WinFast 6300
+; 07 70 = 0770
+; 06 80 = 0770 - 00F0 << ALT (for unpatched bochs)
+
+; for P6STMT - 10kb less ram
+; 077F - 10 = 07 6F
+; 07 6F - 00 F0 = 06 7F
+
+mov al, #0x35 ;; cmos_reg
+out 0x70, al
+mov al, #0x06 ;; val
+out 0x71, al
+
+mov al, #0x34 ;; cmos_reg
+out 0x70, al
+mov al, #0x7F ;; val
+out 0x71, al
+
+mov al, #0x31 ;; cmos_reg
+out 0x70, al
+mov al, #0x00 ;; val
+out 0x71, al
+
+mov al, #0x30 ;; cmos_reg
+out 0x70, al
+mov al, #0x00 ;; val
+out 0x71, al
+
+;-----------------------------------------------------
+; V) tell BOCHS' BIOS we want to have LBA translation.
+; 0x00 - NONE
+; 0x01 - LBA <<<<
+; 0x02 - LARGE
+; 0x03 - R-CHS
+; In future there will be 'fd failover'option in bochs.
+
+mov al, #0x39 ;; cmos_reg
+out 0x70, al
+mov al, #0x01 ;; val (LBA)
+out 0x71, al
+
+;*****************************************************
+nop
+nop
+;*****************************************************
+; G) the switch -- protected to real mode
+
+; IASDM, Vol 3
+; (8-14) 8.8.2 Switching Back to Real-Address Mode
+
+;=====================================================
+; 1) disable interrupts
+
+cli
+
+;=====================================================
+nop
+;=====================================================
+; 2) paging
+
+;not enabled, so not applicable.
+
+;=====================================================
+; 3) setup CS segment limit (64kb)
+; I)
+
+lgdt [0x7C00+new_gdt]
+
+;-----------------------------------------------------
+; II)
+
+jmp 0x08:0x7C00+new64lim
+
+new64lim: nop
+
+;=====================================================
+nop
+;=====================================================
+; 4) setup all other segments
+
+mov ax, #0x10
+mov ss, ax
+mov ds, ax
+mov es, ax
+mov fs, ax
+mov gs, ax
+
+;=====================================================
+nop
+;=====================================================
+; 5) LIDT
+; I)
+
+; set up Real Mode IDT table (0...3FF)
+
+; for BOCH's BIOS the address 0xF000:0xFF53
+; cantains value 0xCF which is IRET opcode.
+
+; counter
+mov cx, #0xFF ;1024 bytes(255 interrupts)(4*255=0x3FF)
+
+; destination - 0x00000 = ES:EDI
+mov ax, #0x10 ; dst-segment - 2nd entry in GDT
+mov es, ax
+mov eax, #0x00000 ; dst-offset - 0x00000
+mov edi, eax
+
+; data to store -- 0xF000:FF53
+mov eax, #0xF000FF53
+
+; clear direction flag
+cld
+
+; the store
+rep
+ stosd
+
+;-----------------------------------------------------
+; II)
+; load interrupt descriptor table
+
+lidt [0x7C00+new_idt]
+
+;=====================================================
+nop
+nop
+;=====================================================
+; 6) clear the PE flag in CR0 register.
+; I)
+
+; switch to 16 bit segments
+mov ax, #0x20
+mov ss, ax
+mov ds, ax
+mov es, ax
+mov fs, ax
+mov gs, ax
+
+;-----------------------------------------------------
+; II)
+
+; switch to 16 bit CS
+
+jmp 0x018:0x7C00+new16bit
+
+USE16
+
+new16bit: nop
+
+;-----------------------------------------------------
+; III)
+; the switch
+
+;xor eax, eax
+
+mov eax, cr0
+and eax, #0xFFFFFFFE
+mov cr0, eax ;switch to RM
+
+;=====================================================
+nop
+nop
+;=====================================================
+; 7) far jump -- (to real mode address)
+
+jmp 0x0:0x7C00+realcs
+
+realcs: nop
+
+;=====================================================
+; 8) set all segment registers to 0's
+
+mov ax, #0x0
+mov ss, ax
+mov ds, ax
+mov es, ax
+mov fs, ax
+mov gs, ax
+
+;=====================================================
+; 9) re-enable interrupts
+
+sti
+
+;*****************************************************
+nop
+nop
+;*****************************************************
+; G) jump to BIOS.
+
+jmp 0xFFFF:0x0000
+;jmp 0xF000:0xFFF0
+
+;*****************************************************
+;*****************************************************
+nop
+nop
+nop
+nop
+;*****************************************************
+;*****************************************************
+
+USE32
+
+new_idt:
+dw 0x03ff ;; limit 15:00
+dw 0x0000 ;; base 15:00
+dw 0x0000 ;; base 23:16
+
+new_gdt:
+dw 0x0028 ;; limit 15:00
+dw 0x7C00+new_gdt_table ;; base 15:00
+dw 0x0000 ;; base 23:16
+
+protected_gdt:
+dw 0x0018 ;; limit 15:00
+dw 0x7C00+pmode_gdt_table ;; base 15:00
+dw 0x0000 ;; base 23:16
+
+;-----------------------------------------------------
+
+new_gdt_table:
+;// 1 2 3 4
+;//0
+dd 0x00000000
+dd 0x00000000
+
+;//8
+dd 0x0000ffff
+dd 0x00409E00
+
+;//10
+dd 0x0000ffff
+dd 0x00409200
+
+;//18
+dd 0x0000ffff
+dd 0x00009a00
+
+;//20
+dd 0x0000ffff
+dd 0x00009200
+
+;-------------------------
+
+pmode_gdt_table:
+;// 1 2 3 4
+;//0
+dd 0x00000000
+dd 0x00000000
+
+;//8
+dd 0x0000ffff
+dd 0x00CF9E00
+
+;//10
+dd 0x0000ffff
+dd 0x00CF9200
+
+;*****************************************************
+;*****************************************************
+; the file size must be 1024 bytes.
+
+
+.org 0x400-1
+; dd 0xdeadbeef
+db 0x0
+
+;*****************************************************