Module Name: src Committed By: nonaka Date: Tue Feb 21 10:53:37 UTC 2017
Modified Files: src/sys/arch/i386/stand/efiboot: TODO.efiboot src/sys/arch/i386/stand/efiboot/bootia32: Makefile efibootia32.c Added Files: src/sys/arch/i386/stand/efiboot/bootia32: startprog32.S Log Message: fix to be able to boot amd64 kernel from 32bit efiboot (booia32.efi). To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/i386/stand/efiboot/TODO.efiboot cvs rdiff -u -r1.1 -r1.2 src/sys/arch/i386/stand/efiboot/bootia32/Makefile \ src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/stand/efiboot/TODO.efiboot diff -u src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.1 src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.2 --- src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.1 Sat Feb 11 10:33:44 2017 +++ src/sys/arch/i386/stand/efiboot/TODO.efiboot Tue Feb 21 10:53:37 2017 @@ -3,7 +3,6 @@ * boot from CD/DVD (bootable from CD/DVD, but root fs not found.) * load boot.cfg from EFI system partition (FAT32) * fix module_init(). need to allocate memory for modules. - * bootia32.efi can load kernel, but can't start kernel - kernel * handle UEFI variables (/dev/efivar) Index: src/sys/arch/i386/stand/efiboot/bootia32/Makefile diff -u src/sys/arch/i386/stand/efiboot/bootia32/Makefile:1.1 src/sys/arch/i386/stand/efiboot/bootia32/Makefile:1.2 --- src/sys/arch/i386/stand/efiboot/bootia32/Makefile:1.1 Tue Jan 24 11:09:14 2017 +++ src/sys/arch/i386/stand/efiboot/bootia32/Makefile Tue Feb 21 10:53:37 2017 @@ -1,9 +1,9 @@ -# $NetBSD: Makefile,v 1.1 2017/01/24 11:09:14 nonaka Exp $ +# $NetBSD: Makefile,v 1.2 2017/02/21 10:53:37 nonaka Exp $ PROG= bootia32.efi OBJFMT= pei-i386 -EXTRA_SOURCES= efibootia32.c +EXTRA_SOURCES= efibootia32.c startprog32.S CPUFLAGS= -march=i686 -mtune=i686 GNUEFIARCH= ia32 Index: src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c diff -u src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c:1.1 src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c:1.2 --- src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c:1.1 Tue Jan 24 11:09:14 2017 +++ src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c Tue Feb 21 10:53:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: efibootia32.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */ +/* $NetBSD: efibootia32.c,v 1.2 2017/02/21 10:53:37 nonaka Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -32,18 +32,40 @@ struct x86_boot_params boot_params; +void startprog32_start(physaddr_t, uint32_t, uint32_t *, physaddr_t, + physaddr_t, physaddr_t, u_long, void *); +extern void (*startprog32)(physaddr_t, uint32_t, uint32_t *, physaddr_t, + physaddr_t, physaddr_t, u_long, void *); +extern u_int startprog32_size; + void efi_md_init(void) { - /* Nothing to do */ + EFI_STATUS status; + EFI_PHYSICAL_ADDRESS addr = EFI_ALLOCATE_MAX_ADDRESS; + u_int sz = EFI_SIZE_TO_PAGES(startprog32_size); + + status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress, + EfiLoaderData, sz, &addr); + if (EFI_ERROR(status)) + Panic(L"%a: AllocatePages() failed: %d page(s): %r", + __func__, sz, status); + startprog32 = (void *)(u_long)addr; + CopyMem(startprog32, startprog32_start, startprog32_size); } +/* ARGSUSED */ void startprog(physaddr_t entry, uint32_t argc, uint32_t *argv, physaddr_t sp) { - Panic(L"%a: not implemented", __func__); + + (*startprog32)(entry, argc, argv, + (physaddr_t)startprog32 + startprog32_size, + efi_kernel_start, efi_kernel_start + efi_loadaddr, + efi_kernel_size, startprog32); } +/* ARGSUSED */ void multiboot(physaddr_t entry, physaddr_t header, physaddr_t sp) { Added files: Index: src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S:1.1 --- /dev/null Tue Feb 21 10:53:37 2017 +++ src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S Tue Feb 21 10:53:37 2017 @@ -0,0 +1,243 @@ +/* $NetBSD: startprog32.S,v 1.1 2017/02/21 10:53:37 nonaka Exp $ */ +/* NetBSD: startprog.S,v 1.4 2016/12/04 08:21:08 maxv Exp */ + +/* + * Ported to boot 386BSD by Julian Elischer (jul...@tfs.com) Sept 1992 + * + * Mach Operating System + * Copyright (c) 1992, 1991 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or software.distribut...@cs.cmu.edu + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * Copyright 1988, 1989, 1990, 1991, 1992 + * by Intel Corporation, Santa Clara, California. + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appears in all + * copies and that both the copyright notice and this permission notice + * appear in supporting documentation, and that the name of Intel + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <machine/asm.h> +#include <machine/specialreg.h> + +#define CODE_SEGMENT 0x08 +#define DATA_SEGMENT 0x10 + + .align 16 + .globl _C_LABEL(startprog32) +_C_LABEL(startprog32): + .quad 0 + + .globl _C_LABEL(startprog32_size) +_C_LABEL(startprog32_size): + .long startprog32_end - _C_LABEL(startprog32_start) + + .text + .p2align 4,,15 + +/* + * startprog32(entry,argc,argv,stack,kern_start,kern_load,kern_size,loadaddr) + */ +ENTRY(startprog32_start) +start: + pushl %ebp + movl %esp, %ebp + + /* + * 8(%ebp): kernel entry address + * 12(%ebp): argc + * 16(%ebp): argv + * 20(%ebp): stack address + * 24(%ebp): kernel start address + * 28(%ebp): loaded kernel address + * 32(%ebp): loaded kernel size + * 36(%ebp): loaded start address + */ + + cli + + /* Prepare a new stack */ + movl 20(%ebp), %eax /* stack */ + subl $4, %eax + movl %eax, %edi + + /* Push some number of args onto the stack */ + movl 12(%ebp), %ecx /* argc */ + movl %ecx, %eax + decl %eax + shl $2, %eax + addl 16(%ebp), %eax /* ptr to last arg */ + movl %eax, %esi + + std /* backwards */ + rep + movsl /* copy %ds:(%esi) -> %es:(%edi) */ + cld + mov %edi, %edx /* %edx: new stack pointer */ + + /* Copy kernel */ + movl 24(%esp), %edi /* dest */ + movl 28(%esp), %esi /* src */ + movl 32(%esp), %ecx /* size */ +#if defined(NO_OVERLAP) + movl %ecx, %eax +#else + movl %edi, %eax + subl %esi, %eax + cmpl %ecx, %eax /* overlapping? */ + movl %ecx, %eax + jb .Lbackwards +#endif + /* nope, copy forwards. */ + shrl $2, %ecx /* copy by words */ + rep + movsl + and $3, %eax /* any bytes left? */ + jnz .Ltrailing + jmp .Lcopy_done + +.Ltrailing: + cmp $2, %eax + jb 1f + movw (%esi), %ax + movw %ax, (%edi) + je .Lcopy_done + movb 2(%esi), %al + movb %al, 2(%edi) + jmp .Lcopy_done +1: movb (%esi), %al + movb %al, (%edi) + jmp .Lcopy_done + +#if !defined(NO_OVERLAP) +.Lbackwards: + addl %ecx, %edi /* copy backwards. */ + addl %ecx, %esi + and $3, %eax /* any fractional bytes? */ + jnz .Lback_align +.Lback_aligned: + shrl $2, %ecx + subl $4, %esi + subl $4, %edi + std + rep + movsl + cld + jmp .Lcopy_done + +.Lback_align: + sub %eax, %esi + sub %eax, %edi + cmp $2, %eax + jb 1f + je 2f + movb 2(%esi), %al + movb %al, 2(%edi) +2: movw (%esi), %ax + movw %ax, (%edi) + jmp .Lback_aligned +1: movb (%esi), %al + movb %al, (%edi) + jmp .Lback_aligned +#endif + /* End of copy kernel */ +.Lcopy_done: + cld /* LynxOS depends on it */ + + movl 8(%ebp), %esi /* %esi: entry address */ + movl 36(%ebp), %edi /* %edi: loaded start address */ + + /* Prepare jump address */ + lea (start32a - start)(%edi), %eax + movl %eax, (start32r - start)(%edi) + + /* Setup GDT */ + lea (gdt - start)(%edi), %eax + movl %eax, (gdtrr - start)(%edi) + lgdt (gdtr - start)(%edi) + + /* Jump to set %cs */ + ljmp *(start32r - start)(%edi) + + .align 4 +start32a: + movl $DATA_SEGMENT, %eax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + movl %edx, %esp + + /* Disable Paging in CR0 */ + movl %cr0, %eax + andl $(~CR0_PG), %eax + movl %eax, %cr0 + + /* Disable PAE in CR4 */ + movl %cr4, %eax + andl $(~CR4_PAE), %eax + movl %eax, %cr4 + + jmp start32b + + .align 4 +start32b: + xor %eax, %eax + movl %esi, (start32r - start)(%edi) + ljmp *(start32r - start)(%edi) + + .align 16 +start32r: + .long 0 + .long CODE_SEGMENT + .align 16 +gdt: + .long 0, 0 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00 +gdtr: + .word gdtr - gdt +gdtrr: + .quad +start32end: + /* Space for the stack */ + .align 16 + .space 8192 +startprog32_end: