stage1: support 32-bit registers for BIOS calls

main
anna 12 months ago
parent bbe3375b8a
commit 68f56352ad
Signed by: fef
GPG Key ID: 2585C2DC6D79B485

@ -9,7 +9,7 @@
*/
/* fn __do_bios_int(regs: &mut BiosIntRegs) -> u8 */
GLOBL __do_bios_int
pushal // '1 v
pushal // '1 (4 -> 36)
/*
* Move the `regs` parameter into %ebp. `call` pushes one longword
@ -18,21 +18,24 @@ GLOBL __do_bios_int
*/
mov 36(%esp), %ebp
/* now load all registers with their desired values */
mov (%ebp), %ax
mov 2(%ebp), %cx
mov 4(%ebp), %dx
mov 6(%ebp), %bx
mov 8(%ebp), %si
mov 10(%ebp), %di
mov 24(%ebp), %eax
push %eax /* %ds and %es */ // '2 (36 -> 40)
mov (%ebp), %eax
mov 4(%ebp), %ecx
mov 8(%ebp), %edx
mov 12(%ebp), %ebx
mov 16(%ebp), %esi
mov 20(%ebp), %edi
push %ebp // '2 v
push %eax // '3 v
push %edx // '4 v
push %eax // '3 (40 -> 44)
push %edx // '4 (44 -> 48)
call prot_to_real
.code16
pop %edx // '4 ^
pop %eax // '3 ^
pop %edx // '4 (44 <- 48)
pop %eax // '3 (40 <- 44)
pop %es // '2 (38 <- 40)
pop %ds // '2 (36 <- 38)
/* call that polymorphism! */
.byte 0xcd /* opcode for `int imm8` */
@ -41,27 +44,34 @@ GLOBL __bios_int_number, object
/* be careful not to touch EFLAGS now because that's our return value */
push %eax // '3 v
push %edx // '4 v
pushfl // '5 v
push %ds // '2 (36 -> 38)
push %es // '2 (38 -> 40)
push %eax // '3 (40 -> 44)
push %edx // '4 (44 -> 48)
pushfl // '5 (48 -> 52)
call real_to_prot
.code32
popfl // '5 ^
pop %edx // '4 ^
pop %eax // '3 ^
popfl // '5 (48 <- 52)
pop %edx // '4 (44 <- 48)
pop %eax // '3 (40 <- 44)
pop %ebp // '2 ^
/* the BIOS call might have trashed %ebp, restore it */
mov 40(%esp), %ebp
mov %ax, (%ebp)
mov %cx, 2(%ebp)
mov %dx, 4(%ebp)
mov %bx, 6(%ebp)
mov %si, 8(%ebp)
mov %di, 10(%ebp)
mov %eax, (%ebp)
pop %eax // '2 (36 <- 40)
mov %eax, 24(%ebp)
mov %ecx, 4(%ebp)
mov %edx, 8(%ebp)
mov %ebx, 12(%ebp)
mov %esi, 16(%ebp)
mov %edi, 20(%ebp)
popal // '1 ^
popal // '1 (4 <- 36)
setc %al
/* this is not really required, but just in case */
movzbl %al, %eax
ret
ret //'0 (0 <- 4)
END __do_bios_int

@ -18,11 +18,6 @@ include_asm!("common.s");
// stage1 header containing its magic, size, checksum, and entry point
include_asm!("header.s");
extern "C" {
pub static _stage1_magic: u16;
pub static _stage1_len: u16;
pub static _stage1_csum: u32;
}
// main bootstrap routine that calls the rust entry point
include_asm!("boot.s");
@ -53,21 +48,22 @@ extern "C" {
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct BiosIntRegs {
pub ax: u16,
pub cx: u16,
pub dx: u16,
pub bx: u16,
pub si: u16,
pub di: u16,
pub eax: u32,
pub ecx: u32,
pub edx: u32,
pub ebx: u32,
pub esi: u32,
pub edi: u32,
pub ds: u16,
pub es: u16,
}
pub type BiosResult = Result<BiosIntRegs, BiosIntRegs>;
/// Temporarily return to Real Mode and do a BIOS interrupt with the
/// specified register values. Returns `Ok` if the carry flag was
/// clear after the interrupt, and `Err` if it was set. In either
/// case, the wrapped value contains the state of the registers after
/// the interrupt.
/// specified register values. Returns `Ok` if the carry flag was clear
/// after the interrupt, and `Err` if it was set. In either case, the
/// wrapped value contains the state of the registers after the interrupt.
///
/// ## Safety
///

Loading…
Cancel
Save