Index: branches/zenith432/i386/libsaio/asm.s =================================================================== --- branches/zenith432/i386/libsaio/asm.s (revision 2596) +++ branches/zenith432/i386/libsaio/asm.s (revision 2597) @@ -124,9 +124,6 @@ #include #include "memory.h" -#define data32 .byte 0x66 -#define addr32 .byte 0x67 - .file "asm.s" CR0_PE_ON = 0x1 @@ -150,7 +147,7 @@ .globl _Gdtr //.data .section __INIT,__data // turbo - Data that must be in the first segment - .align 2, 0x90 + .align 2 _Gdtr: .word GDTLIMIT .long vtop(_Gdt) @@ -161,7 +158,6 @@ .section __INIT,__data // turbo - Data that must be in the first segment // Real mode IDT .align 2 -.globl _Idtr_real _Idtr_real: .word 0x03ff .long 0x00000000 @@ -181,11 +177,12 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Data area for __switch_stack. // + .align 2 save_sp: .long STACK_OFS -save_ss: .long STACK_SEG +save_ss: .word STACK_SEG //.text - .section __INIT,__text // turbo - This code must reside within the first segment + .section __INIT,__text,regular,pure_instructions // turbo - This code must reside within the first segment // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // real_to_prot() // @@ -194,34 +191,34 @@ // LABEL(__real_to_prot) + .code16 + // Interrupts are disabled in protected mode. cli // Load the Global Descriptor Table Register (GDTR). - addr32 - data32 - lgdt OFFSET16(_Gdtr) + lgdtl OFFSET16(_Gdtr) // Enter protected mode by setting the PE bit in CR0. mov %cr0, %eax - data32 - or $CR0_PE_ON, %eax + or $CR0_PE_ON, %ax mov %eax, %cr0 // Make intrasegment jump to flush the processor pipeline and // reload CS register. - data32 - ljmp $0x08, $xprot + ljmpl $0x08, $xprot + .code32 + xprot: // we are in USE32 mode now // set up the protected mode segment registers : DS, SS, ES, FS, GS - mov $0x10, %eax + movw $0x10, %ax movw %ax, %ds movw %ax, %ss movw %ax, %es @@ -248,10 +245,8 @@ popl %eax addl $CODE32_BASE, %eax - pushl %eax + jmp *%eax - ret - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // prot_to_real() // @@ -276,16 +271,17 @@ ljmp $0x18, $x16 // change to USE16 mode x16: + + .code16 + mov %cr0, %eax // clear the PE bit of CR0 - data32 and $CR0_PE_OFF, %eax mov %eax, %cr0 // make intersegment jmp to flush the processor pipeline // and reload CS register - data32 - ljmp $CODE16_SEG, $xreal - CODE32_BASE + ljmp $CODE16_SEG, $xreal xreal: // we are in real mode now @@ -299,34 +295,27 @@ // load stack segment register SS. - data32 - movl $STACK16_SEG, %eax + movw $STACK16_SEG, %ax movw %ax, %ss // clear top 16-bits of ESP and EBP. - data32 movzwl %sp, %esp - data32 movzwl %bp, %ebp // Modify caller's return address on the stack // from linear address to segment offset. - data32 popl %eax - data32 - movzwl %ax, %eax - data32 - pushl %eax // Reenable maskable interrupts. sti - data32 - ret + jmp *%ax + .code32 + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // halt() // @@ -345,18 +334,19 @@ // Passes arg to the program in %eax. // LABEL(_startprog) - push %ebp - mov %esp, %ebp + cli + xor %eax, %eax + mov %eax, _Idtr_prot + movw %ax, _Idtr_prot + 4 + lidt _Idtr_prot - mov 0xc(%ebp), %eax // argument to program - bootargs to mach_kernel - mov 0x8(%ebp), %ecx // entry offset - mov $0x28, %ebx // segment - push %ebx - push %ecx + add $4, %esp // discard return address + mov $0x28, %eax // segment + xchg 4(%esp), %eax // argument to program - bootargs to mach_kernel // set up %ds and %es - mov $0x20, %ebx + movw $0x20, %bx movw %bx, %ds movw %bx, %es @@ -386,37 +376,35 @@ // AX, DI, and SI are clobbered. // LABEL(__switch_stack) - popl %eax # save return address - popl %edi # discard upper 16-bit - data32 - addr32 - movl OFFSET16(save_ss), %esi # new SS to SI + .code16 - data32 - addr32 + pop %ax # save return address + pop %di # discard upper 16-bit + + movw OFFSET16(save_ss), %si # new SS to SI + movl OFFSET16(save_sp), %edi # new SP to DI - addr32 - mov %ss, OFFSET16(save_ss) # save current SS to memory + movw %ss, OFFSET16(save_ss) # save current SS to memory - data32 - addr32 movl %esp, OFFSET16(save_sp) # save current SP to memory cli mov %si, %ss # switch stack - mov %di, %sp + mov %edi, %esp sti - pushl %eax # push IP of caller onto the new stack + push %ax # push IP of caller onto the new stack - xorl %eax, %eax - xorl %esi, %esi - xorl %edi, %edi + xor %ax, %ax + xor %si, %si + xor %di, %di ret + .code32 + #ifndef BOOT1 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // loader() @@ -425,6 +413,8 @@ // LABEL(_loader) enter $0, $0 + pushfl + cli pushal # @@ -442,20 +432,22 @@ ###### Real Mode Begin ###### - data32 - call __switch_stack # Switch to NBP stack + .code16 + calll __switch_stack # Switch to NBP stack + int $0x2b # Call NBP - data32 - call __switch_stack # Restore stack + calll __switch_stack # Restore stack - data32 - call __real_to_prot # Back to protected mode + calll __real_to_prot # Back to protected mode + .code32 + ###### Real Mode End ###### popal + popfl leave ret #endif Index: branches/zenith432/i386/libsaio/bios.s =================================================================== --- branches/zenith432/i386/libsaio/bios.s (revision 2596) +++ branches/zenith432/i386/libsaio/bios.s (revision 2597) @@ -37,9 +37,6 @@ #include #include "memory.h" -#define data32 .byte 0x66 -#define addr32 .byte 0x67 - #define O_INT 0 #define O_EAX 4 #define O_EBX 8 @@ -80,24 +77,17 @@ bits of code and data within the first 63.5k and modify the loaders to be able to load more than 63.5k. */ - .align 4 + .align 2 save_eax: .space 4 - .align 4 save_edx: .space 4 - .align 2 save_es: .space 2 - .align 2 save_flag: .space 2 - .align 4 new_eax: .space 4 - .align 4 new_edx: .space 4 - .align 2 new_es: .space 2 - .align 2 new_ds: .space 2 - .section __INIT,__text // turbo - This code must reside within the first segment + .section __INIT,__text,regular,pure_instructions // turbo - This code must reside within the first segment /*============================================================================ @@ -131,39 +121,30 @@ call __prot_to_real - data32 - addr32 - mov OFFSET16(new_eax), %eax - data32 - addr32 + .code16 + + mov new_eax, %eax // OFFSET16 not needed due to special opcode for ax/eax mov OFFSET16(new_edx), %edx - data32 - addr32 - mov OFFSET16(new_es), %es + movw OFFSET16(new_es), %es push %ds // Save DS // Replace DS. WARNING: Don't access data until it's restored! - addr32 - data32 - mov OFFSET16(new_ds), %ds + movw OFFSET16(new_ds), %ds do_int: int $0x00 pop %ds // Restore DS before we do anything else pushf - data32 - addr32 - movl %eax, OFFSET16(save_eax) - popl %eax // actually pop %ax - addr32 - movl %eax, OFFSET16(save_flag) // actually movw + mov %eax, save_eax + pop %ax + mov %ax, save_flag mov %es, %ax - addr32 - movl %eax, OFFSET16(save_es) // actually movw - data32 - call __real_to_prot + mov %ax, save_es + calll __real_to_prot + .code32 + movl %edx, new_edx // save new edx before clobbering movl save_edx, %edx movl new_edx, %eax // now move it into buffer Index: branches/zenith432/i386/libsaio/table.c =================================================================== --- branches/zenith432/i386/libsaio/table.c (revision 2596) +++ branches/zenith432/i386/libsaio/table.c (revision 2597) @@ -70,7 +70,7 @@ }; // turbo - GDT must be in first 64k segment -struct seg_desc __attribute__ ((section("__INIT,__data"))) Gdt[ NGDTENT ] = { +struct seg_desc __attribute__ ((section("__INIT,__data"), aligned(8))) Gdt[ NGDTENT ] = { /* 0x0 : null */ {0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00}, Index: branches/zenith432/i386/libsaio/saio_internal.h =================================================================== --- branches/zenith432/i386/libsaio/saio_internal.h (revision 2596) +++ branches/zenith432/i386/libsaio/saio_internal.h (revision 2597) @@ -30,8 +30,8 @@ /* asm.s */ extern void real_to_prot(void); extern void prot_to_real(void); -extern void halt(void); -extern void startprog(unsigned int address, void *arg); +extern void halt(void) __attribute__((noreturn)); +extern void startprog(unsigned int address, void *arg) __attribute__((noreturn)); extern void loader(UInt32 code, UInt32 cmdptr); extern uint64_t computeRand(void); Index: branches/zenith432/i386/boot2/mboot.c =================================================================== --- branches/zenith432/i386/boot2/mboot.c (revision 2596) +++ branches/zenith432/i386/boot2/mboot.c (revision 2597) @@ -43,7 +43,7 @@ #define FIX_RETURN_ADDRESS_USING_FIRST_ARG(arg) \ RETURN_ADDRESS_USING_FIRST_ARG(arg) -= OFFSET_1MEG -extern void jump_to_chainbooter(); +extern void jump_to_chainbooter() __attribute__((noreturn)); extern unsigned char chainbootdev; extern unsigned char chainbootflag; Index: branches/zenith432/i386/boot2/boot.c =================================================================== --- branches/zenith432/i386/boot2/boot.c (revision 2596) +++ branches/zenith432/i386/boot2/boot.c (revision 2597) @@ -230,11 +230,6 @@ // Notify modules that the kernel is about to be started execute_hook("Kernel Start", (void *)kernelEntry, (void *)bootArgs, NULL, NULL); - if (interruptsAvailable) - { - DisableInterrupts(); - } - // Masking out so that Lion doesn't doublefault outb(0x21, 0xff); /* Maskout all interrupts Pic1 */ outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */ @@ -246,12 +241,6 @@ // Notify modules that the kernel is about to be started execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgsPreLion, NULL, NULL); - if (interruptsAvailable) - { - DisableInterrupts(); - } - - startprog( kernelEntry, bootArgsPreLion ); } Index: branches/zenith432/i386/boot2/boot2.s =================================================================== --- branches/zenith432/i386/boot2/boot2.s (revision 2596) +++ branches/zenith432/i386/boot2/boot2.s (revision 2597) @@ -40,11 +40,8 @@ #include "memory.h" #include "mboot.h" -#define data32 .byte 0x66 -#define retf .byte 0xcb - .file "boot2.s" - .section __INIT,__text // turbo - This initialization code must reside within the first segment + .section __INIT,__text,regular,pure_instructions // turbo - This initialization code must reside within the first segment //.data .section __INIT,__data // turbo - Data that must be in the first segment @@ -65,11 +62,14 @@ # Returns: # LABEL(boot2) # Entry point at 0:BOOTER_ADDR (will be called by boot1) - pushl %ecx # Save general purpose registers - pushl %ebx - pushl %ebp - pushl %esi - pushl %edi + + .code16 + + push %cx # Save general purpose registers + push %bx + push %bp + push %si + push %di push %ds # Save DS, ES push %es @@ -77,12 +77,12 @@ mov %ax, %ds # Set DS and ES to match CS mov %ax, %es - data32 - call __switch_stack # Switch to new stack + calll __switch_stack # Switch to new stack - data32 - call __real_to_prot # Enter protected mode. + calll __real_to_prot # Enter protected mode. + .code32 + fninit # FPU init # We are now in 32-bit protected mode. @@ -96,39 +96,43 @@ call __prot_to_real # Back to real mode. - data32 - call __switch_stack # Restore original stack - + .code16 + + calll __switch_stack # Restore original stack + pop %es # Restore original ES and DS pop %ds - popl %edi # Restore all general purpose registers - popl %esi # except EAX. - popl %ebp - popl %ebx - popl %ecx + pop %di # Restore all general purpose registers + pop %si # except AX. + pop %bp + pop %bx + pop %cx - retf # Hardcode a far return + lret # Far return + .code32 + start_chain_boot: xorl %edx, %edx movb _chainbootdev, %dl # Setup DL with the BIOS device number call __prot_to_real # Back to real mode. - data32 - call __switch_stack # Restore original stack - + .code16 + + calll __switch_stack # Restore original stack + pop %es # Restore original ES and DS pop %ds - popl %edi # Restore all general purpose registers - popl %esi # except EAX. - popl %ebp - popl %ebx - popl %ecx + pop %di # Restore all general purpose registers + pop %si # except AX. + pop %bp + pop %bx + pop %cx - data32 ljmp $0, $0x7c00 # Jump to boot code already in memory + .code32 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Multiboot support added by David F. Elliott on 2007/06/26 @@ -153,7 +157,11 @@ # cannot do that and have GRUB find it because GRUB only searches the first # 8k of the binary. Since __TEXT,__const follows __TEXT,__text (the code # section) and since the code is well over 8k long, it doesn't work. -.align 4, 0x90 # Make sure we're on a 4-byte boundary. Required by Multiboot. + + //.data - the entire __INIT segment is less than 1k + .section __INIT,__data // turbo + + .align 2 # Make sure we're on a 4-byte boundary. Required by Multiboot. _multiboot_header: # magic (NOTE: this shows up as 02b0 ad1b in a hex dump) .long MULTIBOOT_HEADER_MAGIC @@ -172,12 +180,11 @@ # entry_addr .long (_multiboot_entry + OFFSET_1MEG) -# Stick a couple of nop here so that we hopefully make disassemblers realize we have instructions again - nop - nop - nop -.align 8, 0x90 # Align to 8 byte boundary which should be enough nops + //.text + .section __INIT,__text // turbo + .align 3, 0x90 # Align to 8 byte boundary + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _multiboot_entry: # First thing's first, let's get ourselves a usable GDT. @@ -210,7 +217,7 @@ # The desired offset in this case is exactly 1 MB higher than the # assembler/linker thinks it is. As mentioned above, we use the kernel # init code selector instead of the boot code selector. - jmp $0x28,$(Lpost_gdt_switch+OFFSET_1MEG) + ljmp $0x28,$(Lpost_gdt_switch+OFFSET_1MEG) Lpost_gdt_switch: # Now that we have the right code selector we also want the rest of the @@ -276,7 +283,7 @@ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # _continue_at_low_address does some trickery to get the caller running from the low address with the right selector .globl _continue_at_low_address - .align 4, 0x90 + .align 2, 0x90 _continue_at_low_address: # Our stack frame has been set up with the return address on top # First, fix that to be 1 MB lower @@ -286,7 +293,7 @@ lgdt _Gdtr # Now jump to GDT selector 8 using the low address of this function # This finally puts us in low memory in the right selector (0x08) - jmpl $0x08,$L_continue_at_low_address_next + ljmp $0x08,$L_continue_at_low_address_next L_continue_at_low_address_next: # We don't need to set ss,ds,es,fs, or gs because they are already 0x10 # and the old GDT had the same information for selector 0x10 as the new @@ -309,6 +316,8 @@ call __prot_to_real # Back to real mode. + .code16 + # TODO: Set SS:SP to something reasonable? For instance, Microsoft MBR # code starts out by setting up the stack at 0:7c00 for itself and leaves # that intact. Thus the stack by default will grow down from the code @@ -316,19 +325,20 @@ # 0:fff0 and it seems that most boot code doesn't care and simply sets # SS:SP itself as one of the first things it does. - data32 ljmp $0, $0x7c00 # Jump to boot code already in memory + .code32 + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # _cause_crash jumps to offset 0 of a selector we know is not in our GDT # This causes Parallels to output all sorts of nice debugging information # We aren't using it right now so it's in an if 0 block. #if 0 .globl _cause_crash - .align 4, 0x90 + .align 2, 0x90 _cause_crash: # Cause a crash, there is no GDT selector f0 - jmp $0xf0,$0 + ljmp $0xf0,$0 hlt jmp _cause_crash #endif @@ -338,8 +348,7 @@ # See the comments above as to why we have OFFSET_1MEG. //.data .section __INIT,__data // turbo - .align 4, 0x90 + .align 2 _Gdtr_high: .word GDTLIMIT .long vtop(_Gdt + OFFSET_1MEG) - Index: branches/zenith432/i386/libsa/interrupts.c =================================================================== --- branches/zenith432/i386/libsa/interrupts.c (revision 2596) +++ branches/zenith432/i386/libsa/interrupts.c (revision 2597) @@ -107,6 +107,7 @@ "addl $4, %%esp\n\t" "iretl" :); + __builtin_unreachable(); } static @@ -131,6 +132,7 @@ "addl $8, %%esp\n\t" "iretl" :); + __builtin_unreachable(); } /*