From 1453b2ec7fe961363320392cfff6d7e15bbb3cfe Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 17 Jan 2010 21:16:05 +0100 Subject: [PATCH] add extended regs support in bios_interrupt --- disk/i386/pc/biosdisk.c | 28 ++++----- include/grub/i386/pc/int.h | 18 +++--- kern/i386/pc/startup.S | 123 ++++++++++++++++++++++--------------- 3 files changed, 97 insertions(+), 72 deletions(-) diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index 0f75dba5f..92198e591 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -33,29 +33,29 @@ static int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap); static int grub_biosdisk_get_num_floppies (void) { - struct grub_cpu_int_registers regs; + struct grub_bios_int_registers regs; int drive; /* reset the disk system first */ - regs.ax = 0; - regs.dx = 0; + regs.eax = 0; + regs.edx = 0; regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_cpu_interrupt (0x13, ®s); + grub_bios_interrupt (0x13, ®s); for (drive = 0; drive < 2; drive++) { regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT | GRUB_CPU_INT_FLAGS_CARRY; - regs.dx = drive; + regs.edx = drive; /* call GET DISK TYPE */ - regs.ax = 0x1500; - grub_cpu_interrupt (0x13, ®s); + regs.eax = 0x1500; + grub_bios_interrupt (0x13, ®s); if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) break; /* check if this drive exists */ - if (!(regs.ax & 0x300)) + if (!(regs.eax & 0x300)) break; } @@ -71,16 +71,16 @@ static int grub_biosdisk_get_num_floppies (void) static int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) { - struct grub_cpu_int_registers regs; - regs.ax = ah << 8; + struct grub_bios_int_registers regs; + regs.eax = ah << 8; /* compute the address of disk_address_packet */ regs.ds = (((grub_addr_t) dap) & 0xffff0000) >> 4; - regs.si = (((grub_addr_t) dap) & 0xffff); - regs.dx = drive; + regs.esi = (((grub_addr_t) dap) & 0xffff); + regs.edx = drive; regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_cpu_interrupt (0x13, ®s); - return regs.ax >> 8; + grub_bios_interrupt (0x13, ®s); + return (regs.eax >> 8) & 0xff; } static int diff --git a/include/grub/i386/pc/int.h b/include/grub/i386/pc/int.h index b8cbe3260..e1c463925 100644 --- a/include/grub/i386/pc/int.h +++ b/include/grub/i386/pc/int.h @@ -21,17 +21,18 @@ #include -struct grub_cpu_int_registers +struct grub_bios_int_registers { - grub_uint16_t bx; + grub_uint32_t eax; grub_uint16_t es; - grub_uint16_t cx; - grub_uint16_t ax; - grub_uint16_t dx; grub_uint16_t ds; - grub_uint16_t di; grub_uint16_t flags; - grub_uint16_t si; + grub_uint16_t dummy; + grub_uint32_t ebx; + grub_uint32_t ecx; + grub_uint32_t edi; + grub_uint32_t esi; + grub_uint32_t edx; }; #define GRUB_CPU_INT_FLAGS_CARRY 0x1 @@ -45,6 +46,7 @@ struct grub_cpu_int_registers #define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800 #define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT -void EXPORT_FUNC (grub_cpu_interrupt) (grub_uint8_t intno, struct grub_cpu_int_registers *regs); +void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno, + struct grub_bios_int_registers *regs); #endif diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 815686502..cb6ef32a6 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -2068,73 +2068,96 @@ FUNCTION(grub_pxe_call) popl %ebp ret -FUNCTION(grub_cpu_interrupt) +FUNCTION(grub_bios_interrupt) pushl %ebp - pushl %esi - pushl %edi - pushl %ebx + pushl %ecx + pushl %eax pushl %edx + movb %al, intno - movl %edx, %esi + movl (%edx), %eax + movl %eax, LOCAL(bios_register_eax) + movw 4(%edx), %ax + movw %ax, LOCAL(bios_register_es) + movw 6(%edx), %ax + movw %ax, LOCAL(bios_register_ds) + movw 8(%edx), %ax + movw %ax, LOCAL(bios_register_flags) - movl 0(%esi), %ebx - movl 4(%esi), %ecx - movl 8(%esi), %edx - movl 12(%esi), %edi - movw 16(%esi), %si + movl 12(%edx), %ebx + movl 16(%edx), %ecx + movl 20(%edx), %edi + movl 24(%edx), %esi + movl 28(%edx), %edx call prot_to_real .code16 - movl %edi, %eax - shrl $16, %eax - push %ax - movl %ebx, %eax - shrl $16, %eax - movw %ax, %es - - movl %edx, %eax - shrl $16, %eax - movw %ax, %ds + mov %ds, %ax + push %ax - movl %ecx, %eax - shrl $16, %eax + /* movw imm16, %ax*/ + .byte 0xb8 +LOCAL(bios_register_es): + .short 0 + movw %ax, %es + /* movw imm16, %ax*/ + .byte 0xb8 +LOCAL(bios_register_ds): + .short 0 + movw %ax, %ds + /* movw imm16, %ax*/ + .byte 0xb8 +LOCAL(bios_register_flags): + .short 0 + push %ax popf + + /* movl imm32, %eax*/ + .byte 0x66, 0xb8 +LOCAL(bios_register_eax): + .long 0 + + /* int imm8. */ .byte 0xcd intno: .byte 0 + movl %eax, %cs:LOCAL(bios_register_eax) + movw %ds, %ax + movw %ax, %cs:LOCAL(bios_register_ds) + pop %ax + mov %ax, %ds pushf - andl $0xffff, %ebx - andl $0xffff, %ecx - andl $0xffff, %edx - andl $0xffff, %edi - - shll $16, %eax - orl %eax, %ecx - - movw %ds, %ax - shll $16, %eax - orl %eax, %edx - - pop %ax - shll $16, %eax - orl %eax, %edi + pop %ax + movw %ax, LOCAL(bios_register_flags) + mov %es, %ax + movw %ax, LOCAL(bios_register_es) DATA32 call real_to_prot .code32 - pushl %esi - movl 4(%esp), %esi - movl %ebx, 0(%esi) - movl %ecx, 4(%esi) - movl %edx, 8(%esi) - movl %edi, 12(%esi) - popl %eax - movw %ax, 16(%esi) - popl %eax - popl %ebx - popl %edi - popl %esi - popl %ebp + + popl %eax + + movl %ebx, 12(%eax) + movl %ecx, 16(%eax) + movl %edi, 20(%eax) + movl %esi, 24(%eax) + movl %edx, 28(%eax) + + movl %eax, %edx + + movl LOCAL(bios_register_eax), %eax + movl %eax, (%edx) + movw LOCAL(bios_register_es), %ax + movw %ax, 4(%edx) + movw LOCAL(bios_register_ds), %ax + movw %ax, 6(%edx) + movw LOCAL(bios_register_flags), %ax + movw %ax, 8(%edx) + + popl %eax + popl %ecx + popl %ebp ret