129 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  *  GRUB  --  GRand Unified Bootloader
 | |
|  *  Copyright (C) 2009  Free Software Foundation, Inc.
 | |
|  *
 | |
|  *  GRUB 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 3 of the License, or
 | |
|  *  (at your option) any later version.
 | |
|  *
 | |
|  *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #include <grub/symbol.h>
 | |
| 
 | |
| 
 | |
| 	.p2align	4	/* force 16-byte alignment */
 | |
| VARIABLE(grub_linux_trampoline_start)
 | |
| 	cli
 | |
| 	/* %rdi contains protected memory start and %rsi
 | |
| 	contains real memory start. */
 | |
| 
 | |
| 	mov %rsi, %rbx
 | |
| 
 | |
| 	call base
 | |
| base:
 | |
| 	pop %rsi
 | |
| 
 | |
| #ifdef APPLE_CC
 | |
| 	lea (cont1 - base) (%esi, 1), %rax
 | |
| 	mov %eax, (jump_vector - base) (%esi, 1)
 | |
| 
 | |
| 	lea (gdt - base) (%esi, 1), %rax
 | |
| 	mov %rax, (gdtaddr - base) (%esi, 1)
 | |
| 
 | |
| 	/* Switch to compatibility mode. */
 | |
| 
 | |
| 	lidt (idtdesc - base) (%esi, 1)
 | |
| 	lgdt (gdtdesc - base) (%esi, 1)
 | |
| 
 | |
| 	/* Update %cs. Thanks to David Miller for pointing this mistake out. */
 | |
| 	ljmp *(jump_vector - base) (%esi, 1)
 | |
| #else
 | |
| 	lea (cont1 - base) (%rsi, 1), %rax
 | |
| 	mov %eax, (jump_vector - base) (%rsi, 1)
 | |
| 
 | |
| 	lea (gdt - base) (%rsi, 1), %rax
 | |
| 	mov %rax, (gdtaddr - base) (%rsi, 1)
 | |
| 
 | |
| 	/* Switch to compatibility mode. */
 | |
| 
 | |
| 	lidt (idtdesc - base) (%rsi, 1)
 | |
| 	lgdt (gdtdesc - base) (%rsi, 1)
 | |
| 
 | |
| 	/* Update %cs. Thanks to David Miller for pointing this mistake out. */
 | |
| 	ljmp *(jump_vector - base) (%rsi, 1)
 | |
| #endif
 | |
| 
 | |
| cont1:
 | |
| 	.code32
 | |
| 
 | |
| 	/* Update other registers. */
 | |
| 	mov $0x18, %eax
 | |
| 	mov %eax, %ds
 | |
| 	mov %eax, %es
 | |
| 	mov %eax, %fs
 | |
| 	mov %eax, %gs
 | |
| 	mov %eax, %ss
 | |
| 
 | |
| 	/* Disable paging. */
 | |
| 	mov %cr0, %eax
 | |
| 	and $0x7fffffff, %eax
 | |
| 	mov %eax, %cr0
 | |
| 
 | |
| 	/* Disable amd64. */
 | |
| 	mov $0xc0000080, %ecx
 | |
| 	rdmsr
 | |
| 	and $0xfffffeff, %eax
 | |
| 	wrmsr
 | |
| 
 | |
| 	/* Turn off PAE. */
 | |
| 	movl %cr4, %eax
 | |
| 	and $0xffffffcf, %eax
 | |
| 	mov %eax, %cr4
 | |
| 
 | |
| 	jmp cont2
 | |
| cont2:
 | |
| 	.code32
 | |
| 
 | |
| 	mov %ebx, %esi
 | |
| 
 | |
| 	jmp *%edi
 | |
| 
 | |
| 	/* GDT. */
 | |
| 	.p2align 4
 | |
| gdt:
 | |
| 	/* NULL.  */
 | |
| 	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 | |
| 
 | |
| 	/* Reserved.  */
 | |
| 	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 | |
| 
 | |
| 	/* Code segment.  */
 | |
| 	.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
 | |
| 
 | |
| 	/* Data segment.  */
 | |
| 	.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
 | |
| 
 | |
| gdtdesc:
 | |
| 	.word 31
 | |
| gdtaddr:
 | |
| 	.quad gdt
 | |
| 
 | |
| idtdesc:
 | |
| 	.word 0
 | |
| idtaddr:
 | |
| 	.quad 0
 | |
| 
 | |
| 	.p2align 4
 | |
| jump_vector:
 | |
| 	/* Jump location. Is filled by the code */
 | |
| 	.long 0
 | |
| 	.long 0x10
 | |
| VARIABLE(grub_linux_trampoline_end)
 |