diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index d7cad05f..df71a9d7 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -41,8 +41,6 @@ FILE_LICENCE ( GPL2_OR_LATER ) /* Image compression enabled */ #define COMPRESS 1 -#define CR0_PE 1 - /***************************************************************************** * Utility function: print character (with LF -> LF,CR translation) * @@ -232,126 +230,6 @@ print_kill_line: ret .size print_kill_line, . - print_kill_line -/**************************************************************************** - * flatten_real_mode (real-mode far call) - * - * Set up 4GB segment limits - * - * Parameters: - * none - * Returns: - * none - * Corrupts: - * none - **************************************************************************** - */ -#ifndef KEEP_IT_REAL - - /* GDT for protected-mode calls */ - .section ".text16.early.data", "aw", @progbits - .align 16 -flatten_gdt: -flatten_gdt_limit: .word flatten_gdt_length - 1 -flatten_gdt_base: .long 0 - .word 0 /* padding */ -flatten_cs: /* 16-bit protected-mode flat code segment */ - .equ FLAT_CS, flatten_cs - flatten_gdt - .word 0xffff, 0 - .byte 0, 0x9b, 0x8f, 0 -flatten_ss: /* 16-bit protected-mode flat stack segment */ - .equ FLAT_SS, flatten_ss - flatten_gdt - .word 0xffff, 0 - .byte 0, 0x93, 0x8f, 0 -flatten_gdt_end: - .equ flatten_gdt_length, . - flatten_gdt - .size flatten_gdt, . - flatten_gdt - - .section ".text16.early.data", "aw", @progbits - .align 16 -flatten_saved_gdt: - .long 0, 0 - .size flatten_saved_gdt, . - flatten_saved_gdt - - .section ".text16.early", "awx", @progbits - .code16 -flatten_real_mode: - /* Preserve registers and flags */ - pushfl - pushl %eax - pushw %si - pushw %gs - pushw %fs - pushw %es - pushw %ds - pushw %ss - - /* Set %ds for access to .text16.early.data variables */ - pushw %cs - popw %ds - - /* Preserve original GDT */ - sgdt flatten_saved_gdt - - /* Set up GDT bases */ - xorl %eax, %eax - movw %cs, %ax - shll $4, %eax - addl $flatten_gdt, %eax - movl %eax, flatten_gdt_base - movw %cs, %ax - movw $flatten_cs, %si - call set_seg_base - movw %ss, %ax - movw $flatten_ss, %si - call set_seg_base - - /* Switch temporarily to protected mode and set segment registers */ - pushw %cs - pushw $2f - cli - data32 lgdt flatten_gdt - movl %cr0, %eax - orb $CR0_PE, %al - movl %eax, %cr0 - ljmp $FLAT_CS, $1f -1: movw $FLAT_SS, %ax - movw %ax, %ss - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movl %cr0, %eax - andb $0!CR0_PE, %al - movl %eax, %cr0 - lret -2: /* lret will ljmp to here */ - - /* Restore GDT, registers and flags */ - data32 lgdt flatten_saved_gdt - popw %ss - popw %ds - popw %es - popw %fs - popw %gs - popw %si - popl %eax - popfl - lret - .size flatten_real_mode, . - flatten_real_mode - - .section ".text16.early", "awx", @progbits - .code16 -set_seg_base: - rolw $4, %ax - movw %ax, 2(%si) - andw $0xfff0, 2(%si) - movb %al, 4(%si) - andb $0x0f, 4(%si) - ret - .size set_seg_base, . - set_seg_base - -#endif /* KEEP_IT_REAL */ - /**************************************************************************** * copy_bytes * diff --git a/src/arch/i386/transitions/libflat.S b/src/arch/i386/transitions/libflat.S new file mode 100644 index 00000000..9cb4c8af --- /dev/null +++ b/src/arch/i386/transitions/libflat.S @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2010 Michael Brown . + * + * This program 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 2 of the + * License, or any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ) + + .arch i386 + +#define CR0_PE 1 + +/**************************************************************************** + * flatten_real_mode (real-mode far call) + * + * Set up 4GB segment limits + * + * Parameters: + * none + * Returns: + * none + * Corrupts: + * none + **************************************************************************** + */ + /* GDT for protected-mode calls */ + .section ".text16.early.data", "aw", @progbits + .align 16 +flatten_gdt: +flatten_gdt_limit: .word flatten_gdt_length - 1 +flatten_gdt_base: .long 0 + .word 0 /* padding */ +flatten_cs: /* 16-bit protected-mode flat code segment */ + .equ FLAT_CS, flatten_cs - flatten_gdt + .word 0xffff, 0 + .byte 0, 0x9b, 0x8f, 0 +flatten_ss: /* 16-bit protected-mode flat stack segment */ + .equ FLAT_SS, flatten_ss - flatten_gdt + .word 0xffff, 0 + .byte 0, 0x93, 0x8f, 0 +flatten_gdt_end: + .equ flatten_gdt_length, . - flatten_gdt + .size flatten_gdt, . - flatten_gdt + + .section ".text16.early.data", "aw", @progbits + .align 16 +flatten_saved_gdt: + .long 0, 0 + .size flatten_saved_gdt, . - flatten_saved_gdt + + .section ".text16.early", "awx", @progbits + .code16 + .globl flatten_real_mode +flatten_real_mode: + /* Preserve registers and flags */ + pushfl + pushl %eax + pushw %si + pushw %gs + pushw %fs + pushw %es + pushw %ds + pushw %ss + + /* Set %ds for access to .text16.early.data variables */ + pushw %cs + popw %ds + + /* Preserve original GDT */ + sgdt flatten_saved_gdt + + /* Set up GDT bases */ + xorl %eax, %eax + movw %cs, %ax + shll $4, %eax + addl $flatten_gdt, %eax + movl %eax, flatten_gdt_base + movw %cs, %ax + movw $flatten_cs, %si + call set_seg_base + movw %ss, %ax + movw $flatten_ss, %si + call set_seg_base + + /* Switch temporarily to protected mode and set segment registers */ + pushw %cs + pushw $2f + cli + data32 lgdt flatten_gdt + movl %cr0, %eax + orb $CR0_PE, %al + movl %eax, %cr0 + ljmp $FLAT_CS, $1f +1: movw $FLAT_SS, %ax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movl %cr0, %eax + andb $0!CR0_PE, %al + movl %eax, %cr0 + lret +2: /* lret will ljmp to here */ + + /* Restore GDT, registers and flags */ + data32 lgdt flatten_saved_gdt + popw %ss + popw %ds + popw %es + popw %fs + popw %gs + popw %si + popl %eax + popfl + lret + .size flatten_real_mode, . - flatten_real_mode + + .section ".text16.early", "awx", @progbits + .code16 +set_seg_base: + rolw $4, %ax + movw %ax, 2(%si) + andw $0xfff0, 2(%si) + movb %al, 4(%si) + andb $0x0f, 4(%si) + ret + .size set_seg_base, . - set_seg_base