stage1: support 32-bit registers for BIOS calls
This commit is contained in:
parent
bbe3375b8a
commit
68f56352ad
2 changed files with 49 additions and 43 deletions
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
/* fn __do_bios_int(regs: &mut BiosIntRegs) -> u8 */
|
/* fn __do_bios_int(regs: &mut BiosIntRegs) -> u8 */
|
||||||
GLOBL __do_bios_int
|
GLOBL __do_bios_int
|
||||||
pushal // '1 v
|
pushal // '1 (4 -> 36)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move the `regs` parameter into %ebp. `call` pushes one longword
|
* Move the `regs` parameter into %ebp. `call` pushes one longword
|
||||||
|
@ -18,21 +18,24 @@ GLOBL __do_bios_int
|
||||||
*/
|
*/
|
||||||
mov 36(%esp), %ebp
|
mov 36(%esp), %ebp
|
||||||
/* now load all registers with their desired values */
|
/* now load all registers with their desired values */
|
||||||
mov (%ebp), %ax
|
mov 24(%ebp), %eax
|
||||||
mov 2(%ebp), %cx
|
push %eax /* %ds and %es */ // '2 (36 -> 40)
|
||||||
mov 4(%ebp), %dx
|
mov (%ebp), %eax
|
||||||
mov 6(%ebp), %bx
|
mov 4(%ebp), %ecx
|
||||||
mov 8(%ebp), %si
|
mov 8(%ebp), %edx
|
||||||
mov 10(%ebp), %di
|
mov 12(%ebp), %ebx
|
||||||
|
mov 16(%ebp), %esi
|
||||||
|
mov 20(%ebp), %edi
|
||||||
|
|
||||||
push %ebp // '2 v
|
push %eax // '3 (40 -> 44)
|
||||||
|
push %edx // '4 (44 -> 48)
|
||||||
push %eax // '3 v
|
|
||||||
push %edx // '4 v
|
|
||||||
call prot_to_real
|
call prot_to_real
|
||||||
.code16
|
.code16
|
||||||
pop %edx // '4 ^
|
pop %edx // '4 (44 <- 48)
|
||||||
pop %eax // '3 ^
|
pop %eax // '3 (40 <- 44)
|
||||||
|
|
||||||
|
pop %es // '2 (38 <- 40)
|
||||||
|
pop %ds // '2 (36 <- 38)
|
||||||
|
|
||||||
/* call that polymorphism! */
|
/* call that polymorphism! */
|
||||||
.byte 0xcd /* opcode for `int imm8` */
|
.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 */
|
/* be careful not to touch EFLAGS now because that's our return value */
|
||||||
|
|
||||||
push %eax // '3 v
|
push %ds // '2 (36 -> 38)
|
||||||
push %edx // '4 v
|
push %es // '2 (38 -> 40)
|
||||||
pushfl // '5 v
|
|
||||||
|
push %eax // '3 (40 -> 44)
|
||||||
|
push %edx // '4 (44 -> 48)
|
||||||
|
pushfl // '5 (48 -> 52)
|
||||||
call real_to_prot
|
call real_to_prot
|
||||||
.code32
|
.code32
|
||||||
popfl // '5 ^
|
popfl // '5 (48 <- 52)
|
||||||
pop %edx // '4 ^
|
pop %edx // '4 (44 <- 48)
|
||||||
pop %eax // '3 ^
|
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 %eax, (%ebp)
|
||||||
mov %cx, 2(%ebp)
|
pop %eax // '2 (36 <- 40)
|
||||||
mov %dx, 4(%ebp)
|
mov %eax, 24(%ebp)
|
||||||
mov %bx, 6(%ebp)
|
mov %ecx, 4(%ebp)
|
||||||
mov %si, 8(%ebp)
|
mov %edx, 8(%ebp)
|
||||||
mov %di, 10(%ebp)
|
mov %ebx, 12(%ebp)
|
||||||
|
mov %esi, 16(%ebp)
|
||||||
|
mov %edi, 20(%ebp)
|
||||||
|
|
||||||
popal // '1 ^
|
popal // '1 (4 <- 36)
|
||||||
setc %al
|
setc %al
|
||||||
/* this is not really required, but just in case */
|
/* this is not really required, but just in case */
|
||||||
movzbl %al, %eax
|
movzbl %al, %eax
|
||||||
ret
|
|
||||||
|
ret //'0 (0 <- 4)
|
||||||
END __do_bios_int
|
END __do_bios_int
|
||||||
|
|
|
@ -18,11 +18,6 @@ include_asm!("common.s");
|
||||||
|
|
||||||
// stage1 header containing its magic, size, checksum, and entry point
|
// stage1 header containing its magic, size, checksum, and entry point
|
||||||
include_asm!("header.s");
|
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
|
// main bootstrap routine that calls the rust entry point
|
||||||
include_asm!("boot.s");
|
include_asm!("boot.s");
|
||||||
|
@ -53,21 +48,22 @@ extern "C" {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone, Default)]
|
#[derive(Copy, Clone, Default)]
|
||||||
pub struct BiosIntRegs {
|
pub struct BiosIntRegs {
|
||||||
pub ax: u16,
|
pub eax: u32,
|
||||||
pub cx: u16,
|
pub ecx: u32,
|
||||||
pub dx: u16,
|
pub edx: u32,
|
||||||
pub bx: u16,
|
pub ebx: u32,
|
||||||
pub si: u16,
|
pub esi: u32,
|
||||||
pub di: u16,
|
pub edi: u32,
|
||||||
|
pub ds: u16,
|
||||||
|
pub es: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BiosResult = Result<BiosIntRegs, BiosIntRegs>;
|
pub type BiosResult = Result<BiosIntRegs, BiosIntRegs>;
|
||||||
|
|
||||||
/// Temporarily return to Real Mode and do a BIOS interrupt with the
|
/// Temporarily return to Real Mode and do a BIOS interrupt with the
|
||||||
/// specified register values. Returns `Ok` if the carry flag was
|
/// specified register values. Returns `Ok` if the carry flag was clear
|
||||||
/// clear after the interrupt, and `Err` if it was set. In either
|
/// after the interrupt, and `Err` if it was set. In either case, the
|
||||||
/// case, the wrapped value contains the state of the registers after
|
/// wrapped value contains the state of the registers after the interrupt.
|
||||||
/// the interrupt.
|
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in a new issue