diff options
author | Juergen Beisert <jbe@pengutronix.de> | 2010-01-12 11:15:41 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-01-14 10:06:16 +0100 |
commit | 7dcc15e8197e647abc80b1d3298a91edd45a8c2d (patch) | |
tree | f0bb5981a61c989ce37d40554971b9adc49e2b3e /arch/x86/boot/bioscall.S | |
parent | 2bdd75bd02f3d214b285429be72b3a0eab4e9610 (diff) | |
download | barebox-7dcc15e8197e647abc80b1d3298a91edd45a8c2d.tar.gz barebox-7dcc15e8197e647abc80b1d3298a91edd45a8c2d.tar.xz |
Add functions to be able to boot with BIOSs help
These functions are special: They are running in the 16 bit real mode world
to bring up barebox on an x86 box.
Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/x86/boot/bioscall.S')
-rw-r--r-- | arch/x86/boot/bioscall.S | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/arch/x86/boot/bioscall.S b/arch/x86/boot/bioscall.S new file mode 100644 index 0000000000..84d2577eb6 --- /dev/null +++ b/arch/x86/boot/bioscall.S @@ -0,0 +1,99 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 2009 Intel Corporation; author H. Peter Anvin + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2 or (at your + * option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * "Glove box" for BIOS calls. Avoids the constant problems with BIOSes + * touching registers they shouldn't be. + */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + .file "bioscall.S" + .code16 + .section .boot.text.intcall, "ax" + + .globl intcall + .type intcall, @function +intcall: + /* Self-modify the INT instruction. Ugly, but works. */ + cmpb %al, 3f + je 1f + movb %al, 3f + jmp 1f /* Synchronize pipeline */ +1: + /* Save state */ + pushfl + pushw %fs + pushw %gs + pushal + + /* Copy input state to stack frame */ + subw $44, %sp + movw %dx, %si + movw %sp, %di + movw $11, %cx + rep; movsd + + /* Pop full state from the stack */ + popal + popw %gs + popw %fs + popw %es + popw %ds + popfl + + /* Actual INT */ + .byte 0xcd /* INT opcode */ +3: .byte 0 + + /* Push full state to the stack */ + pushfl + pushw %ds + pushw %es + pushw %fs + pushw %gs + pushal + + /* Re-establish C environment invariants */ + cld + movzwl %sp, %esp + movw %cs, %ax + movw %ax, %ds + movw %ax, %es + + /* Copy output state from stack frame */ + movw 68(%esp), %di /* Original %cx == 3rd argument */ + andw %di, %di + jz 4f + movw %sp, %si + movw $11, %cx + rep; movsd +4: addw $44, %sp + + /* Restore state and return */ + popal + popw %gs + popw %fs + popfl + retl + .size intcall, .-intcall + +/* ------------------------------------------------------------------------ */ + .code16 + .section .boot.text.die, "ax" + + .globl die + .type die, @function +die: + hlt + jmp die + .size die, .-die + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ |