diff options
Diffstat (limited to 'contrib/baremetal/startmpcc.S')
-rw-r--r-- | contrib/baremetal/startmpcc.S | 756 |
1 files changed, 0 insertions, 756 deletions
diff --git a/contrib/baremetal/startmpcc.S b/contrib/baremetal/startmpcc.S deleted file mode 100644 index 07486ce5..00000000 --- a/contrib/baremetal/startmpcc.S +++ /dev/null @@ -1,756 +0,0 @@ -/* #defines because ljmp wants a number, probably gas bug */ -/* .equ KERN_CODE_SEG,_pmcs-_gdt */ -#define KERN_CODE_SEG 0x08 - .equ KERN_DATA_SEG,_pmds-_gdt -/* .equ REAL_CODE_SEG,_rmcs-_gdt */ -#define REAL_CODE_SEG 0x18 - .equ REAL_DATA_SEG,_rmds-_gdt - .equ CR0_PE,1 - -#ifdef GAS291 -#define DATA32 data32; -#define ADDR32 addr32; -#define LJMPI(x) ljmp x -#else -#define DATA32 data32 -#define ADDR32 addr32 -/* newer GAS295 require #define LJMPI(x) ljmp *x */ -#define LJMPI(x) ljmp x -#endif - -#define PIC1_VBS 0x08 /* PIC1 interrupts start at vector 64 */ -#define PIC2_VBS 0x70 /* PIC1 interrupts start at vector 112 */ - -/* - * NOTE: if you write a subroutine that is called from C code (gcc/egcs), - * then you only have to take care of %ebx, %esi, %edi and %ebp. These - * registers must not be altered under any circumstance. All other registers - * may be clobbered without any negative side effects. If you don't follow - * this rule then you'll run into strange effects that only occur on some - * gcc versions (because the register allocator may use different registers). - * - * All the data32 prefixes for the ljmp instructions are necessary, because - * the assembler emits code with a relocation address of 0. This means that - * all destinations are initially negative, which the assembler doesn't grok, - * because for some reason negative numbers don't fit into 16 bits. The addr32 - * prefixes are there for the same reasons, because otherwise the memory - * references are only 16 bit wide. Theoretically they are all superfluous. - * One last note about prefixes: the data32 prefixes on all call _real_to_prot - * instructions could be removed if the _real_to_prot function is changed to - * deal correctly with 16 bit return addresses. I tried it, but failed. - */ - -/************************************************************************** -START - Where all the fun begins.... -**************************************************************************/ -/* this must be the first thing in the file because we enter from the top */ - .global _start - .code32 -_start: - cli - - /* load new IDT and GDT */ - lgdt gdtarg - lidt Idt_Reg - /* flush prefetch queue, and reload %cs:%eip */ - ljmp $KERN_CODE_SEG,$1f -1: - - /* reload other segment registers */ - movl $KERN_DATA_SEG,%eax - movl %eax,%ds - movl %eax,%es - movl %eax,%ss - movl $stktop,%esp - - /* program the PITs in order to stop them */ - mov $0x30,%al - out %al,$0x43 - out %al,$0x40 - mov $0x70,%al - out %al,$0x43 - out %al,$0x41 - mov $0xf0,%al - out %al,$0x43 - out %al,$0x42 - - call main - /* fall through */ - - .globl exit -exit: -2: - ljmp $KERN_CODE_SEG,$2b - -/************************************************************************** -MEMSIZE - Determine size of extended memory -**************************************************************************/ - .globl memsize -memsize: -#if 0 - pushl %ebx - pushl %esi - pushl %edi - call _prot_to_real - .code16 - movw $0xe801,%ax - stc - int $0x15 - jc 1f - andl $0xffff,%eax - andl $0xffff,%ebx - shll $6,%ebx - addl %ebx,%eax - jmp 2f -1: - movw $0x8800,%ax - int $0x15 - andl $0xffff,%eax -2: - movl %eax,%esi - DATA32 call _real_to_prot - .code32 - movl %esi,%eax - popl %edi - popl %esi - popl %ebx -#else - mov $32768,%eax -#endif - ret - -/************************************************************************** -XSTART - Transfer control to the kernel just loaded -**************************************************************************/ - .code16 - - .globl _int08_handler -_int08_handler: - movb $0x20, %al - outb %al, $0x20 - iret - - .globl _int10_handler -_int10_handler: - cmp $0x3, %ah - jnz _int10_04 - mov $0x0, %dx - mov $0x0, %cx - iret -_int10_04: - cmp $0x4, %ah - jnz _int10_05 - mov $0x0, %ah - iret -_int10_05: - cmp $0x5, %ah - jnz _int10_08 - mov $0x0, %al - iret -_int10_08: - cmp $0x8, %ah - jnz _int10_0D - mov $0x20, %al - mov $0x7, %ah - iret -_int10_0D: - cmp $0xD, %ah - jnz _int10_0F - mov $0x0, %al - iret -_int10_0F: - cmp $0xF, %ah - jnz _int10_XX - mov $0xb, %al - mov $80, %ah - mov $0, %bh -_int10_XX: - iret - - .globl _int11_handler -_int11_handler: - mov $0x22, %ax - iret - - .globl _int12_handler -_int12_handler: - mov $640, %ax - iret - - .globl _int13_handler -_int13_handler: - clc - mov $0, %ah - iret - - .globl _int14_handler -_int14_handler: - iret - - .globl _int15_handler -_int15_handler: - cmp $0xe801,%ax - jz _int15_008 - cmp $0x0, %ah - jz _int15_000 - cmp $0x1, %ah - jz _int15_000 - cmp $0x2, %ah - jz _int15_000 - cmp $0x3, %ah - jz _int15_000 - cmp $0xf, %ah - jz _int15_000 - cmp $0x21, %ah - jz _int15_000 - cmp $0x40, %ah - jz _int15_000 - cmp $0x41, %ah - jz _int15_000 - cmp $0x42, %ah - jz _int15_000 - cmp $0x43, %ah - jz _int15_000 - cmp $0x44, %ah - jz _int15_000 - cmp $0x80, %ah - jz _int15_001 - cmp $0x81, %ah - jz _int15_001 - cmp $0x82, %ah - jz _int15_002 - cmp $0x83, %ah - jz _int15_003 - cmp $0x84, %ah - jz _int15_000 - cmp $0x85, %ah - jz _int15_004 - cmp $0x86, %ah - jz _int15_003 - cmp $0x87, %ah - jz _int15_005 - cmp $0x88, %ah - jz _int15_006 - cmp $0x89, %ah - jz _int15_005 - cmp $0x90, %ah - jz _int15_007 - cmp $0xc0, %ah - jz _int15_000 - cmp $0xc1, %ah - jz _int15_000 - cmp $0xc2, %ah - jz _int15_000 - cmp $0xc3, %ah - jz _int15_000 - cmp $0xc4, %ah - jz _int15_000 - iret - -_int15_000: - mov $0x86, %ah - stc - iret - -_int15_001: - mov $0, %bx - mov $0, %cx - iret - -_int15_002: - mov $0, %bx - iret - -_int15_003: - clc - iret - -_int15_004: - mov $0, %al - iret - -_int15_005: - mov $0, %ah - clc - cmp $0, %ah - iret - -_int15_006: - mov $0xf000, %ax - iret - -_int15_007: - stc - iret - -_int15_008: - clc - mov $1024, %dx /* dx -> extended memory size (in 64K chuncks) */ - mov $640, %cx /* cx -> conventional memory size (in 1 Kbytes chuncks) */ - iret - - .globl _int16_handler -_int16_handler: - cmp $0x0, %ah - jnz _int16_01 - mov $0x20, %al - mov $0x39, %ah - iret -_int16_01: - cmp $0x1, %ah - jnz _int16_02 - iret -_int16_02: - cmp $0x2, %ah - jnz _int16_05 - mov $0, %al - iret -_int16_05: - cmp $0x5, %ah - jnz _int16_10 - mov $0, %al - iret -_int16_10: - cmp $0x10, %ah - jnz _int16_11 - mov $0x20, %al - mov $0x39, %ah - iret -_int16_11: - cmp $0x11, %ah - jnz _int16_12 - iret -_int16_12: - cmp $0x12, %ah - jnz _int16_XX - mov $0, %ax - iret -_int16_XX: - iret - - .globl _int17_handler -_int17_handler: - mov $0xd0, %ah - iret - - .globl _int19_handler -_int19_handler: - hlt - iret - - .globl _int1A_handler -_int1A_handler: - stc - iret - - .code32 - .globl xstart -xstart: - /* reprogram the PICs so that interrupt are masked */ - movb $0x11,%al /* ICW1 [ICW4 NEEDED, EDGE TRIGGERED]*/ - outb %al,$0x20 - movb $PIC1_VBS, %al - outb %al,$0x21 - movb $0x4,%al - outb %al,$0x21 - movb $0x1,%al - outb %al,$0x21 - movb $0xff,%al - outb %al,$0x21 - - movb $0x11,%al /* ICW1 [ICW4 NEEDED, EDGE TRIGGERED]*/ - outb %al,$0xa0 - movb $PIC2_VBS, %al - outb %al,$0xa1 - movb $0x2,%al - outb %al,$0xa1 - movb $0x1,%al - outb %al,$0xa1 - movb $0xff,%al - outb %al,$0xa1 - - pushl %ebp - movl %esp,%ebp - pushl %ebx - pushl %esi - pushl %edi - movl 8(%ebp),%eax - movl %eax,_execaddr - movl 12(%ebp),%ebx - movl 16(%ebp),%ecx /* bootp record (32bit pointer) */ - addl $28,%ecx /* ip, udp header */ - shll $12,%ecx - shrw $12,%cx - call _prot_to_real - .code16 -/* MP: add int10 handler */ - push %eax - push %ebx - push %es - mov $0,%ax - mov %ax,%es - mov %cs,%ax - shl $16,%eax - - ADDR32 mov $(_int08_handler-_start),%ax - mov $0x20,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int10_handler-_start),%ax - mov $0x40,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int11_handler-_start),%ax - mov $0x44,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int12_handler-_start),%ax - mov $0x48,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int13_handler-_start),%ax - mov $0x4c,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int14_handler-_start),%ax - mov $0x50,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int15_handler-_start),%ax - mov $0x54,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int16_handler-_start),%ax - mov $0x58,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int17_handler-_start),%ax - mov $0x5c,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int19_handler-_start),%ax - mov $0x64,%ebx - mov %eax,%es:(%bx) - - ADDR32 mov $(_int1A_handler-_start),%ax - mov $0x68,%ebx - mov %eax,%es:(%bx) - - pop %es - pop %ebx - pop %eax -/* */ - pushl %ecx /* bootp record */ - pushl %ebx /* file header */ - movl $((RELOC<<12)+(1f-RELOC)),%eax - pushl %eax - ADDR32 LJMPI(_execaddr-_start) -1: - addw $8,%sp /* XXX or is this 10 in case of a 16bit "ret" */ - DATA32 call _real_to_prot - .code32 - popl %edi - popl %esi - popl %ebx - popl %ebp - ret - -_execaddr: - .long 0 - -#ifdef IMAGE_MULTIBOOT -/************************************************************************** -XEND - Restart Etherboot from the beginning (from protected mode) -**************************************************************************/ - - .globl xend -xend: - cs - lidt idtarg_realmode-_start+RELOC - cs - lgdt gdtarg-_start+RELOC -#ifdef GAS291 - ljmp $REAL_CODE_SEG,$1f-RELOC /* jump to a 16 bit segment */ -#else - ljmp $REAL_CODE_SEG,$1f-_start /* jump to a 16 bit segment */ -#endif /* GAS291 */ -1: - .code16 - movw $REAL_DATA_SEG,%ax - movw %ax,%ds - movw %ax,%ss - movw %ax,%es - - /* clear the PE bit of CR0 */ - movl %cr0,%eax - andl $0!CR0_PE,%eax - movl %eax,%cr0 - - /* make intersegment jmp to flush the processor pipeline - * and reload %cs:%eip (to clear upper 16 bits of %eip). - */ - DATA32 ljmp $(RELOC)>>4,$2f-_start -2: - /* we are in real mode now - * set up the real mode segment registers : %ds, %ss, %es - */ - movw %cs,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%ss - xorl %esp,%esp - ADDR32 movw initsp-RELOC,%sp - - movw $0,%ax - movw %ax,%fs - movw %ax,%gs - - sti - jmp _start - - .code32 -#endif /* IMAGE_MULTIBOOT */ - -.global get_cs -get_cs: - xorl %eax,%eax - movw %cs,%ax - ret - -.global get_ds -get_ds: - xorl %eax,%eax - movw %ds,%ax - ret - -.global getsp -getsp: - movl %esp,%eax /* GET STACK POINTER */ - subl $4, %eax /* ACCOUNT FOR RETURN ADDRESS ON */ - ret - -.global get_gdtbase -get_gdtbase: - sub $8,%esp /* ALLOCATE ROOM ON THE STACK */ - sgdt (%esp,1) /*STORE IGDT REGISTER ON STACK */ - mov 2(%esp),%eax /* READ GDT BASE ADDRESS */ - mov $KERN_DATA_SEG,%dx /* ASSUME UNIVERSAL DS. */ - add $8,%esp /* RESTORE STACK */ - ret /* DONE */ - -.global get_gdtsize -get_gdtsize: - sub $8,%esp /* ALLOCATE ROOM ON THE STACK */ - sgdt (%esp,1) /*STORE IGDT REGISTER ON STACK */ - xor %eax,%eax - mov 2(%esp),%eax /* READ GDT BASE ADDRESS */ - mov (%ESP),%ax - shr $3,%ax - add $8,%esp /* RESTORE STACK */ - ret /* DONE */ - -.global get_idtbase -get_idtbase: - sub $8,%esp - sidt (%esp,1) /* STORE IIDT REGISTER ON STACK */ - mov 2(%esp),%eax - mov $KERN_DATA_SEG,%dx - add $8,%esp - ret - -.global get_lw -get_lw: - xor %edx,%edx - mov 8(%esp),%eax - mov 4(%esp),%dx - ret - -/************************************************************************** -SETJMP - Save stack context for non-local goto -**************************************************************************/ - .globl setjmp -setjmp: - mov 4(%esp),%ecx - mov 0(%esp),%edx - mov %edx,0(%ecx) - mov %ebx,4(%ecx) - mov %esp,8(%ecx) - mov %ebp,12(%ecx) - mov %esi,16(%ecx) - mov %edi,20(%ecx) - mov %eax,24(%ecx) - mov $0,%eax - ret - -/************************************************************************** -LONGJMP - Non-local jump to a saved stack context -**************************************************************************/ - .globl longjmp -longjmp: - mov 4(%esp),%edx - mov 8(%esp),%eax - mov 0(%edx),%ecx - mov 4(%edx),%ebx - mov 8(%edx),%esp - mov 12(%edx),%ebp - mov 16(%edx),%esi - mov 20(%edx),%edi - cmp $0,%eax - jne 1f - mov $1,%eax -1: mov %ecx,0(%esp) - ret - -/************************************************************************** -_REAL_TO_PROT - Go from REAL mode to Protected Mode -**************************************************************************/ - .globl _real_to_prot -_real_to_prot: - .code16 - cli - cs - ADDR32 lgdt gdtarg-_start - movl %cr0,%eax - orl $CR0_PE,%eax - movl %eax,%cr0 /* turn on protected mode */ - - /* flush prefetch queue, and reload %cs:%eip */ - DATA32 ljmp $KERN_CODE_SEG,$1f -1: - .code32 - /* reload other segment registers */ - movl $KERN_DATA_SEG,%eax - movl %eax,%ds - movl %eax,%es - movl %eax,%ss - addl $RELOC,%esp /* Fix up stack pointer */ - xorl %eax,%eax - movl %eax,%fs - movl %eax,%gs - popl %eax /* Fix up return address */ - addl $RELOC,%eax - pushl %eax - ret - -/************************************************************************** -_PROT_TO_REAL - Go from Protected Mode to REAL Mode -**************************************************************************/ - .globl _prot_to_real -_prot_to_real: - .code32 - popl %eax - subl $RELOC,%eax /* Adjust return address */ - pushl %eax - subl $RELOC,%esp /* Adjust stack pointer */ -#ifdef GAS291 - ljmp $REAL_CODE_SEG,$1f-RELOC /* jump to a 16 bit segment */ -#else - ljmp $REAL_CODE_SEG,$1f-_start /* jump to a 16 bit segment */ -#endif /* GAS291 */ -1: - .code16 - movw $REAL_DATA_SEG,%ax - movw %ax,%ds - movw %ax,%ss - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - cli - - /* clear the PE bit of CR0 */ - movl %cr0,%eax - andl $0!CR0_PE,%eax - movl %eax,%cr0 - - /* make intersegment jmp to flush the processor pipeline - * and reload %cs:%eip (to clear upper 16 bits of %eip). - */ - DATA32 ljmp $(RELOC)>>4,$2f-_start -2: - /* we are in real mode now - * set up the real mode segment registers : %ds, $ss, %es - */ - movw %cs,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%ss -#if 0 - sti -#endif - DATA32 ret /* There is a 32 bit return address on the stack */ - .code32 - -/************************************************************************** -GLOBAL DESCRIPTOR TABLE -**************************************************************************/ - .align 4 -Idt_Reg: - .word 0x3ff - .long 0 - - .align 4 -_gdt: -gdtarg: -Gdt_Table: - .word 0x27 /* limit */ - .long _gdt /* addr */ - .word 0 -_pmcs: - /* 32 bit protected mode code segment */ - .word 0xffff,0 - .byte 0,0x9f,0xcf,0 - -_pmds: - /* 32 bit protected mode data segment */ - .word 0xffff,0 - .byte 0,0x93,0xcf,0 - -_rmcs: - /* 16 bit real mode code segment */ - .word 0xffff,(RELOC&0xffff) - .byte (RELOC>>16),0x9b,0x00,(RELOC>>24) - -_rmds: - /* 16 bit real mode data segment */ - .word 0xffff,(RELOC&0xffff) - .byte (RELOC>>16),0x93,0x00,(RELOC>>24) - - .align 4 -RUN_GDT: /* POINTER TO GDT IN RAM */ - .byte 0x7f,0 /* [BSP_GDT_NUM*8]-1 */ - .long Gdt_Table - - .align 4 - - .section ".rodata" -err_not386: - .ascii "Etherboot/32 requires 386+" - .byte 0x0d, 0x0a -err_not386_end: - -days: .long 0 -irq_num: .long - - .data - .align 4 - .org 2048 -.global stktop -stktop: - .long - -.section ".armando" -/* 1:::::::::2:::::::::3:::::::3 */ -/* 12345678901234567890123456789012345678 */ -/* v----+----v----+----v----+----v----+--- */ - -.global EtherbootString -EtherbootString: -.ascii "EtherBoot MPCC " /* fw identifier */ - -.byte 0, 0 /* mandatory hole */ - -.long _start /* entry point */ -.word 0 -.byte 'E' /* type */ -.byte 0 /* selector */ -.word 0 /* CRC */ |