X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fromlayout.S;h=9f0541a7c00b41c23c5bc9e083058c4813281158;hb=ed12849c9b06e371f11596a32da5997c96d9bc95;hp=c9cc6ef5dcf33142eaa664266bc4d22e8ed7e9ca;hpb=f076a3eeb9a0185b06a2abbba8c798a7761b2bdf;p=seabios.git diff --git a/src/romlayout.S b/src/romlayout.S index c9cc6ef..9f0541a 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -7,8 +7,18 @@ #include "config.h" +#define PROTECTED_MODE_CS (2 << 3) // 0x10 +#define PROTECTED_MODE_DS (3 << 3) // 0x18 +#define REAL_MODE_CS (4 << 3) // 0x20 +#define REAL_MODE_DS (5 << 3) // 0x28 + .code16gcc - .text + + +/**************************************************************** + * Include of 16bit C code + ****************************************************************/ + .globl bios16c_start, bios16c_end bios16c_start: .include "out/blob.proc.16.s" @@ -16,21 +26,39 @@ bios16c_start: bios16c_end: +/**************************************************************** + * POST handler + ****************************************************************/ + + // Macro to reset the 16bit stack + // Clobbers %ax + .macro RESET_STACK + xorw %ax, %ax + movw %ax, %ss + movl $ CONFIG_STACK_OFFSET , %esp + .endm + .org 0xe05b - .globl _start -_start: .globl post16 post16: + // init the stack pointer + RESET_STACK - // Entry point of rombios32 code - the actual instruction is - // altered later in the build process. + // Set entry point of rombios32 code - the actual address + // is altered later in the build process. .globl set_entry32 set_entry32: - mov $0xf0000000, %ebx + pushl $0xf0000000 - // init the stack pointer - movl $ CONFIG_STACK32_OFFSET , %esp + // Fall through to transition32 function below + +/**************************************************************** + * Call trampolines + ****************************************************************/ + +// Place CPU into 32bit mode from 16bit mode. +// Clobbers: %eax, flags, stack registers, cr0, idt/gdt transition32: // Disable irqs cli @@ -50,12 +78,13 @@ transition32: movl %eax, %cr0 // start protected mode code - .word 0xea66, 1f, 0x000f, 0x0010 // ljmpl $0x10, $(post32 | 0xf0000) + // ljmpl $PROTECTED_MODE_CS, $(1f | 0xf0000) + .word 0xea66, 1f, 0x000f, PROTECTED_MODE_CS .code32 1: // init data segments - movl $0x18, %eax + movl $PROTECTED_MODE_DS, %eax movw %ax, %ds movw %ax, %es movw %ax, %ss @@ -65,25 +94,22 @@ transition32: cld - jmp *%ebx - - .code16gcc + retl -// We need a copy of this string, but we are not actually a PnP BIOS, -// so make sure it is *not* aligned, so OSes will not see it if they -// scan. - .align 2 - .byte 0 -pnp_string: - .ascii "$PnP" +// Call a 16bit function from 32bit mode. +// %eax = address of struct bregs +// Clobbers: all gp registers, flags, stack registers, cr0, idt/gdt + .globl __call16_from32 +__call16_from32: + pushl %eax -// Return from 32bit code to 16bit code - must pass in destination -// code segment,offset (%ebx) and the return stack position (%esp). + // Jump to 16bit mode + ljmp $REAL_MODE_CS, $1f - .globl call16 -call16: + .code16gcc +1: // restore data segment limits to 0xffff - movw $0x28, %ax + movw $REAL_MODE_DS, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss @@ -96,43 +122,84 @@ call16: movl %eax, %cr0 // far jump to flush CPU queue after transition to real mode - ljmpw $0xf000, $1f -1: + ljmpw $0xf000, $2f + +2: // restore IDT to normal real-mode defaults lidt %cs:rmode_IDT_info - // Setup segment registers + // Clear segment registers xorw %ax, %ax - movw %ax, %ds movw %ax, %fs movw %ax, %gs - movw $0xf000, %ax movw %ax, %es - lea pnp_string, %di - movw $ CONFIG_STACK16_SEGMENT , %ax - movw %ax, %ss - movl %esp, %eax - movl $ CONFIG_STACK16_OFFSET , %esp + movw %ax, %ds + movw %ax, %ss // Assume stack is in segment 0 - // Save info - pushl %eax - pushl %ebx - movl %esp, %ebp + popl %eax + pushl $transition32 + + // Fall through to __call16 - lcallw %ss:*(%bp) - // Restore stack and jump back to 32bit mode. +// Call a 16bit function from 16bit mode with a specified cpu register state +// %eax = address of struct bregs +// Clobbers: all gp registers, es + .globl __call16 +__call16: + // Save eax + pushl %eax + + // Setup for iretw call + pushw $0xf000 + pushw $1f // return point + pushw 0x28(%eax) // flags + pushl 0x24(%eax) // CS:IP + + // Load calling registers. + movl 0x04(%eax), %edi + movl 0x08(%eax), %esi + movl 0x0c(%eax), %ebp + movl 0x14(%eax), %ebx + movl 0x18(%eax), %edx + movl 0x1c(%eax), %ecx + movw 0x02(%eax), %es // XXX - should load %ds too + movl 0x20(%eax), %eax + + // Invoke call + iretw // XXX - just do a lcalll +1: + // Store flags, eax, ecx + pushfw + pushl %eax + movl 0x06(%esp), %eax + movl %ecx, %ss:0x1c(%eax) // Save %ecx + movw %ss, %cx + movw %cx, %ds // Restore %ds == %ss + popl %ecx + movl %ecx, 0x20(%eax) // Save %eax + popw %cx + movw %cx, 0x28(%eax) // Save flags + + // Store remaining registers + movw %es, 0x02(%eax) + movl %edi, 0x04(%eax) + movl %esi, 0x08(%eax) + movl %ebp, 0x0c(%eax) + movl %ebx, 0x14(%eax) + movl %edx, 0x18(%eax) + + // Remove %eax popl %eax - popl %esp - // Resume point of rombios32 code - the actual instruction is - // altered later in the build process. - .globl set_resume32 -set_resume32: - mov $0xf0000000, %ebx + cld + + retl - jmp transition32 +/**************************************************************** + * GDT and IDT tables + ****************************************************************/ // Protected mode IDT descriptor // @@ -145,8 +212,7 @@ set_resume32: // Set limit to 0 pmode_IDT_info: .word 0x0000 // limit 15:00 - .word 0x0000 // base 15:00 - .byte 0x0f // base 23:16 + .long 0xf0000 // base 16:47 // Real mode IDT descriptor // @@ -155,53 +221,121 @@ pmode_IDT_info: // limit = 03ff rmode_IDT_info: .word 0x03ff // limit 15:00 - .word 0x0000 // base 15:00 - .byte 0x00 // base 23:16 + .long 0 // base 16:47 rombios32_gdt_48: .word 0x30 .word rombios32_gdt .word 0x000f + .balign 8 rombios32_gdt: .word 0, 0, 0, 0 .word 0, 0, 0, 0 - .word 0xffff, 0, 0x9b00, 0x00cf // 32 bit flat code segment (0x10) - .word 0xffff, 0, 0x9300, 0x00cf // 32 bit flat data segment (0x18) - .word 0xffff, 0, 0x9b0f, 0x0000 // 16 bit code segment base=0xf0000 limit=0xffff - .word 0xffff, 0, 0x9300, 0x0000 // 16 bit data segment base=0x0 limit=0xffff - - + // 32 bit flat code segment (PROTECTED_MODE_CS) + .word 0xffff, 0, 0x9b00, 0x00cf + // 32 bit flat data segment (PROTECTED_MODE_DS) + .word 0xffff, 0, 0x9300, 0x00cf + // 16 bit code segment base=0xf0000 limit=0xffff (REAL_MODE_CS) + .word 0xffff, 0, 0x9b0f, 0x0000 + // 16 bit data segment base=0x0 limit=0xffff (REAL_MODE_DS) + .word 0xffff, 0, 0x9300, 0x0000 + + +/**************************************************************** + * Interrupt entry points + ****************************************************************/ + + // Call a C function - this does the minimal work necessary to + // call into C. It sets up %ds, backs up %es, and backs up + // those registers that are call clobbered by the C compiler. .macro ENTRY cfunc + cld + pushl %eax + pushl %ecx + pushl %edx + pushw %es + pushw %ds + movw %ss, %ax + movw %ax, %ds + calll \cfunc + popw %ds + popw %es + popl %edx + popl %ecx + popl %eax + .endm + + // Call a C function with current register list as an + // argument. This backs up the registers and sets %eax + // to point to the backup. On return, the registers are + // restored from the structur. + .macro ENTRY_ARG cfunc + cld pushal pushw %es pushw %ds movw %ss, %ax movw %ax, %ds - mov %esp, %eax - call \cfunc + movzwl %sp, %esp + movl %esp, %eax + calll \cfunc popw %ds popw %es popal .endm + // Define an entry point for an interrupt (no args passed). .macro IRQ_ENTRY num .globl entry_\num entry_\num : + cli // In case something far-calls instead of using "int" ENTRY handle_\num iretw .endm + // Define an entry point for an interrupt (can read/modify args). + .macro IRQ_ENTRY_ARG num + .globl entry_\num + entry_\num : + cli // In case something far-calls instead of using "int" + ENTRY_ARG handle_\num + iretw + .endm + + // APM trampolines + .globl apm16protected_entry +apm16protected_entry: + pushfw // save flags + pushl %eax // dummy + ENTRY_ARG handle_1553 + addw $4, %sp // pop dummy + popfw // restore flags + lretw + + .code32 + .globl apm32protected_entry +apm32protected_entry: + pushfw // save flags + pushw %cs // Setup for long jump to 16bitmode + incw (%esp) + pushw 1f + lcallw *(%esp) + addl $4, %esp // pop call address + popfw + lretl + .code16gcc +1: // 16bit entry point for apm32 code. + ENTRY_ARG handle_1553 + lretw .org 0xe2c3 IRQ_ENTRY nmi - IRQ_ENTRY 13 - IRQ_ENTRY 19 - IRQ_ENTRY 12 - IRQ_ENTRY 11 + IRQ_ENTRY_ARG 13 + IRQ_ENTRY_ARG 12 + IRQ_ENTRY_ARG 11 IRQ_ENTRY 76 - IRQ_ENTRY 18 IRQ_ENTRY 1c IRQ_ENTRY 70 IRQ_ENTRY 74 @@ -224,52 +358,85 @@ rombios32_gdt: // XXX - Baud Rate Generator Table .org 0xe739 - IRQ_ENTRY 14 + IRQ_ENTRY_ARG 14 + + // int 18/19 are special - they reset the stack and do not return. + .globl entry_19 +entry_19: + RESET_STACK + ENTRY handle_19 + + .globl entry_18 +entry_18: + RESET_STACK + ENTRY handle_18 + + // IRQ trampolines + .macro IRQ_TRAMPOLINE num + .globl irq_trampoline_0x\num + irq_trampoline_0x\num : + int $0x\num + lretw + .endm + + IRQ_TRAMPOLINE 02 + IRQ_TRAMPOLINE 10 + IRQ_TRAMPOLINE 13 + IRQ_TRAMPOLINE 15 + IRQ_TRAMPOLINE 18 + IRQ_TRAMPOLINE 19 + IRQ_TRAMPOLINE 1c + IRQ_TRAMPOLINE 4a .org 0xe82e - IRQ_ENTRY 16 + IRQ_ENTRY_ARG 16 .org 0xe987 IRQ_ENTRY 09 .org 0xec59 - IRQ_ENTRY 40 + IRQ_ENTRY_ARG 40 .org 0xef57 IRQ_ENTRY 0e .org 0xefc7 - // XXX - Diskette Controller Parameter Table +.include "out/floppy_dbt.proc.16.s" + .text .org 0xefd2 - IRQ_ENTRY 17 + IRQ_ENTRY_ARG 17 .org 0xf045 // XXX int 10 iretw .org 0xf065 - IRQ_ENTRY 10 + IRQ_ENTRY_ARG 10 .org 0xf0a4 // XXX int 1D iretw + .globl freespace2_start, freespace2_end +freespace2_start: + .org 0xf841 +freespace2_end: jmp entry_12 .org 0xf84d jmp entry_11 .org 0xf859 - IRQ_ENTRY 15 + IRQ_ENTRY_ARG 15 .org 0xfa6e .include "out/font.proc.16.s" .text .org 0xfe6e - IRQ_ENTRY 1a + IRQ_ENTRY_ARG 1a .org 0xfea5 IRQ_ENTRY 08 @@ -287,7 +454,7 @@ dummy_iret_handler: iretw .org 0xff54 - IRQ_ENTRY 05 + IRQ_ENTRY_ARG 05 .org 0xfff0 // Power-up Entry Point ljmpw $0xf000, $post16 @@ -297,8 +464,7 @@ dummy_iret_handler: .ascii "06/23/99" .org 0xfffe - // model byte 0xFC = AT - .byte 0xfc + .byte CONFIG_MODEL_ID .byte 0x00 .end