elf64_freebsd.c revision 163708
121259Swollman/*- 221259Swollman * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 321259Swollman * All rights reserved. 421259Swollman * 521259Swollman * Redistribution and use in source and binary forms, with or without 621259Swollman * modification, are permitted provided that the following conditions 721259Swollman * are met: 821259Swollman * 1. Redistributions of source code must retain the above copyright 921259Swollman * notice, this list of conditions and the following disclaimer. 1021259Swollman * 2. Redistributions in binary form must reproduce the above copyright 1121259Swollman * notice, this list of conditions and the following disclaimer in the 1221259Swollman * documentation and/or other materials provided with the distribution. 1321259Swollman * 1421259Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1521259Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1621259Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1721259Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1821259Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1921259Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2021259Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2121259Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2221259Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2321259Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2421259Swollman * SUCH DAMAGE. 2521259Swollman */ 2621259Swollman 2721259Swollman#include <sys/cdefs.h> 2821259Swollman__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/elf64_freebsd.c 163708 2006-10-26 20:04:22Z ru $"); 2921259Swollman 3050477Speter#define __ELF_WORD_SIZE 64 3121259Swollman#include <sys/param.h> 3221259Swollman#include <sys/exec.h> 3321259Swollman#include <sys/linker.h> 3421259Swollman#include <string.h> 3521259Swollman#include <machine/bootinfo.h> 3621259Swollman#include <machine/elf.h> 3721259Swollman#include <stand.h> 3821259Swollman 3921259Swollman#include "bootstrap.h" 4021259Swollman#include "libi386.h" 4121259Swollman#include "btxv86.h" 4221259Swollman 4321259Swollmanstatic int elf64_exec(struct preloaded_file *amp); 4421259Swollmanstatic int elf64_obj_exec(struct preloaded_file *amp); 4521259Swollman 4621259Swollmanstruct file_format amd64_elf = { elf64_loadfile, elf64_exec }; 4721259Swollmanstruct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; 4821259Swollman 4921259Swollman#define PG_V 0x001 5021259Swollman#define PG_RW 0x002 51108533Sschweikh#define PG_U 0x004 5221259Swollman#define PG_PS 0x080 5321259Swollman 5421259Swollmantypedef u_int64_t p4_entry_t; 5521259Swollmantypedef u_int64_t p3_entry_t; 56108533Sschweikhtypedef u_int64_t p2_entry_t; 5721259Swollmanextern p4_entry_t PT4[]; 5821259Swollmanextern p3_entry_t PT3[]; 5921259Swollmanextern p2_entry_t PT2[]; 6021259Swollman 6121259Swollmanu_int32_t entry_hi; 6221259Swollmanu_int32_t entry_lo; 6321259Swollman 6421259Swollmanextern void amd64_tramp(); 6521259Swollman 6683366Sjulian/* 6721259Swollman * There is an ELF kernel and one or more ELF modules loaded. 6885074Sru * We wish to start executing the kernel image, so make such 6921259Swollman * preparations as are required, and do so. 7021259Swollman */ 7121259Swollmanstatic int 7221259Swollmanelf64_exec(struct preloaded_file *fp) 7321259Swollman{ 7421259Swollman struct file_metadata *md; 7569224Sjlemon Elf_Ehdr *ehdr; 7669152Sjlemon vm_offset_t modulep, kernend; 77126264Smlaier int err; 7869224Sjlemon int i; 7974914Sjhb 8074914Sjhb if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) 8183130Sjlemon return(EFTYPE); /* XXX actually EFUCKUP */ 8269152Sjlemon ehdr = (Elf_Ehdr *)&(md->md_data); 83121816Sbrooks 84121816Sbrooks err = bi_load64(fp->f_args, &modulep, &kernend); 8560938Sjake if (err != 0) 8660938Sjake return(err); 8760938Sjake 8872084Sphk bzero(PT4, PAGE_SIZE); 8921259Swollman bzero(PT3, PAGE_SIZE); 9021259Swollman bzero(PT2, PAGE_SIZE); 9121259Swollman 9221259Swollman /* 9321259Swollman * This is kinda brutal, but every single 1GB VM memory segment points to 9421259Swollman * the same first 1GB of physical memory. But it is more than adequate. 9521259Swollman */ 9621259Swollman for (i = 0; i < 512; i++) { 9721259Swollman /* Each slot of the level 4 pages points to the same level 3 page */ 9821259Swollman PT4[i] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]); 9969152Sjlemon PT4[i] |= PG_V | PG_RW | PG_U; 10021259Swollman 10121259Swollman /* Each slot of the level 3 pages points to the same level 2 page */ 10221259Swollman PT3[i] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]); 10321259Swollman PT3[i] |= PG_V | PG_RW | PG_U; 10421259Swollman 10521259Swollman /* The level 2 page slots are mapped with 2MB pages for 1GB. */ 10621259Swollman PT2[i] = i * (2 * 1024 * 1024); 10784380Smjacob PT2[i] |= PG_V | PG_RW | PG_PS | PG_U; 10884380Smjacob } 10984380Smjacob 11084380Smjacob entry_lo = ehdr->e_entry & 0xffffffff; 11186797Sluigi entry_hi = (ehdr->e_entry >> 32) & 0xffffffff; 11286797Sluigi#ifdef DEBUG 11386797Sluigi printf("Start @ %#llx ...\n", ehdr->e_entry); 11486797Sluigi#endif 11586797Sluigi 11686797Sluigi dev_cleanup(); 11786797Sluigi __exec((void *)VTOP(amd64_tramp), modulep, kernend); 11886797Sluigi 11986797Sluigi panic("exec returned"); 12086797Sluigi} 12186797Sluigi 12286797Sluigistatic int 12386797Sluigielf64_obj_exec(struct preloaded_file *fp) 12486797Sluigi{ 12586797Sluigi return (EFTYPE); 12684380Smjacob} 12721259Swollman