/************************************************************************** MEMSIZE - Determine size of extended memory **************************************************************************/ unsigned int memsize ( void ) { struct { reg16_t ax; } PACKED in_stack; struct { reg16_t ax; reg16_t bx; reg16_t cx; reg16_t dx; reg16_t flags; } PACKED out_stack; int memsize; RM_FRAGMENT(rm_memsize, /* Some buggy BIOSes don't clear/set carry on pass/error of * e801h memory size call or merely pass cx,dx through without * changing them, so we set carry and zero cx,dx before call. */ "stc\n\t" "xorw %cx,%cx\n\t" "xorw %dx,%dx\n\t" "popw %ax\n\t" "int $0x15\n\t" "pushfw\n\t" "pushw %dx\n\t" "pushw %cx\n\t" "pushw %bx\n\t" "pushw %ax\n\t" ); /* Try INT 15,e801 first */ in_stack.ax.word = 0xe801; real_call ( rm_memsize, &in_stack, &out_stack ); if ( out_stack.flags.word & CF ) { /* INT 15,e801 not supported: try INT 15,88 */ in_stack.ax.word = 0x8800; memsize = real_call ( rm_memsize, &in_stack, &out_stack ); } else { /* Some BIOSes report extended memory via ax,bx rather * than cx,dx */ if ( (out_stack.cx.word==0) && (out_stack.dx.word==0) ) { /* Use ax,bx */ memsize = ( out_stack.bx.word<<6 ) + out_stack.ax.word; } else { /* Use cx,dx */ memsize = ( out_stack.dx.word<<6 ) + out_stack.cx.word; } } return memsize; }
/************************************************************************** BASEMEMSIZE - Get size of the conventional (base) memory **************************************************************************/ unsigned short basememsize ( void ) { RM_FRAGMENT(rm_basememsize, "int $0x12\n\t" ); return real_call ( rm_basememsize, NULL, NULL ); }
int vesa_set_vbe_mode(unsigned short mode) { unsigned int handle_irq = irq_lock(); irq_unmap(); int result = real_call(real_set_vbe_mode_id, mode); irq_remap(); irq_unlock(handle_irq); return result; }
struct vesa_vbe_mode_info* vesa_get_vbe_mode_info(unsigned short mode) { unsigned int handle_irq = irq_lock(); irq_unmap(); struct vesa_vbe_mode_info* result = (struct vesa_vbe_mode_info*)real_call(real_get_vbe_mode_info_id, mode); irq_remap(); irq_unlock(handle_irq); return result; }
int meme820 ( struct e820entry *buf, int count ) { struct { reg16_t flags; reg32_t eax; reg32_t ebx; struct e820entry entry; } PACKED stack; int index = 0; #ifdef VBOX RM_FRAGMENT(rm_meme820, "addw $6, %sp\n\t" /* skip flags, eax */ "popl %ebx\n\t" "pushw %ss\n\t" /* es:di = ss:sp */ "popw %es\n\t" "movw %sp, %di\n\t" "movl $0xe820, %eax\n\t" "movl $" STRINGIFY(SMAP) ", %edx\n\t" "movl $" STRINGIFY(E820ENTRY_SIZE) ", %ecx\n\t" "int $0x15\n\t" "pushl %ebx\n\t" "pushl %eax\n\t" "pushfw\n\t" ); #else /* !VBOX */ RM_FRAGMENT(rm_meme820, "addw $6, %sp\n\t" /* skip flags, eax */ "popl %ebx\n\t" "pushw %ss\n\t" /* es:di = ss:sp */ "popw %es\n\t" "movw %sp, %di\n\t" "movl $0xe820, %eax\n\t" "movl $" RM_STR(SMAP) ", %edx\n\t" "movl $" RM_STR(E820ENTRY_SIZE) ", %ecx\n\t" "int $0x15\n\t" "pushl %ebx\n\t" "pushl %eax\n\t" "pushfw\n\t" ); #endif /* !VBOX */ stack.ebx.dword = 0; /* 'EOF' marker */ while ( ( index < count ) && ( ( index == 0 ) || ( stack.ebx.dword != 0 ) ) ) { real_call ( rm_meme820, &stack, &stack ); if ( stack.eax.dword != SMAP ) return 0; if ( stack.flags.word & CF ) return 0; buf[index++] = stack.entry; } return index; }