git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2457 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
		
			
				
	
	
		
			462 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			462 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| ;*****************************************************
 | |
| ; $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
 | |
| 
 | |
| ;*****************************************************
 |