elf64_freebsd.c revision 162814
1204076Spjd/*- 2204076Spjd * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3204076Spjd * All rights reserved. 4204076Spjd * 5204076Spjd * Redistribution and use in source and binary forms, with or without 6204076Spjd * modification, are permitted provided that the following conditions 7204076Spjd * are met: 8204076Spjd * 1. Redistributions of source code must retain the above copyright 9204076Spjd * notice, this list of conditions and the following disclaimer. 10204076Spjd * 2. Redistributions in binary form must reproduce the above copyright 11204076Spjd * notice, this list of conditions and the following disclaimer in the 12204076Spjd * documentation and/or other materials provided with the distribution. 13204076Spjd * 14204076Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16204076Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17204076Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18204076Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19204076Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20204076Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21204076Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22204076Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23204076Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24204076Spjd * SUCH DAMAGE. 25204076Spjd */ 26204076Spjd 27204076Spjd#include <sys/cdefs.h> 28204076Spjd__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/elf64_freebsd.c 162814 2006-09-29 20:27:41Z ru $"); 29204076Spjd 30204076Spjd#define __ELF_WORD_SIZE 64 31204076Spjd#include <sys/param.h> 32204076Spjd#include <sys/exec.h> 33204076Spjd#include <sys/linker.h> 34204076Spjd#include <string.h> 35204076Spjd#include <machine/bootinfo.h> 36204076Spjd#include <machine/elf.h> 37204076Spjd#include <stand.h> 38204076Spjd 39204076Spjd#include "bootstrap.h" 40204076Spjd#include "libi386.h" 41204076Spjd#include "btxv86.h" 42204076Spjd 43219620Strocinystatic int elf64_exec(struct preloaded_file *amp); 44204076Spjdstatic int elf64_obj_exec(struct preloaded_file *amp); 45204076Spjd 46204076Spjdstruct file_format amd64_elf = { elf64_loadfile, elf64_exec }; 47204076Spjdstruct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; 48204076Spjd 49204076Spjd#define PG_V 0x001 50204076Spjd#define PG_RW 0x002 51204076Spjd#define PG_U 0x004 52204076Spjd#define PG_PS 0x080 53204076Spjd 54204076Spjdtypedef u_int64_t p4_entry_t; 55204076Spjdtypedef u_int64_t p3_entry_t; 56204076Spjdtypedef u_int64_t p2_entry_t; 57204076Spjdextern p4_entry_t PT4[]; 58204076Spjdextern p3_entry_t PT3[]; 59204076Spjdextern p2_entry_t PT2[]; 60204076Spjd 61204076Spjdu_int32_t entry_hi; 62204076Spjdu_int32_t entry_lo; 63204076Spjd 64204076Spjdextern void amd64_tramp(); 65204076Spjd 66204076Spjd/* 67204076Spjd * There is an a.out kernel and one or more a.out modules loaded. 68204076Spjd * We wish to start executing the kernel image, so make such 69204076Spjd * preparations as are required, and do so. 70204076Spjd */ 71204076Spjdstatic int 72204076Spjdelf64_exec(struct preloaded_file *fp) 73204076Spjd{ 74204076Spjd struct file_metadata *md; 75204076Spjd Elf_Ehdr *ehdr; 76204076Spjd vm_offset_t modulep, kernend; 77204076Spjd int err; 78204076Spjd int i; 79204076Spjd 80204076Spjd if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) 81204076Spjd return(EFTYPE); /* XXX actually EFUCKUP */ 82204076Spjd ehdr = (Elf_Ehdr *)&(md->md_data); 83204076Spjd 84204076Spjd err = bi_load64(fp->f_args, &modulep, &kernend); 85204076Spjd if (err != 0) 86204076Spjd return(err); 87204076Spjd 88204076Spjd bzero(PT4, PAGE_SIZE); 89204076Spjd bzero(PT3, PAGE_SIZE); 90204076Spjd bzero(PT2, PAGE_SIZE); 91204076Spjd 92204076Spjd /* 93204076Spjd * This is kinda brutal, but every single 1GB VM memory segment points to 94204076Spjd * the same first 1GB of physical memory. But it is more than adequate. 95204076Spjd */ 96204076Spjd for (i = 0; i < 512; i++) { 97204076Spjd /* Each slot of the level 4 pages points to the same level 3 page */ 98204076Spjd PT4[i] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]); 99204076Spjd PT4[i] |= PG_V | PG_RW | PG_U; 100204076Spjd 101204076Spjd /* Each slot of the level 3 pages points to the same level 2 page */ 102204076Spjd PT3[i] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]); 103204076Spjd PT3[i] |= PG_V | PG_RW | PG_U; 104204076Spjd 105204076Spjd /* The level 2 page slots are mapped with 2MB pages for 1GB. */ 106204076Spjd PT2[i] = i * (2 * 1024 * 1024); 107204076Spjd PT2[i] |= PG_V | PG_RW | PG_PS | PG_U; 108204076Spjd } 109204076Spjd 110204076Spjd entry_lo = ehdr->e_entry & 0xffffffff; 111204076Spjd entry_hi = (ehdr->e_entry >> 32) & 0xffffffff; 112204076Spjd#ifdef DEBUG 113204076Spjd printf("Start @ %#llx ...\n", ehdr->e_entry); 114204076Spjd#endif 115204076Spjd 116204076Spjd dev_cleanup(); 117204076Spjd __exec((void *)VTOP(amd64_tramp), modulep, kernend); 118204076Spjd 119204076Spjd panic("exec returned"); 120204076Spjd} 121204076Spjd 122204076Spjdstatic int 123204076Spjdelf64_obj_exec(struct preloaded_file *fp) 124204076Spjd{ 125204076Spjd return (EFTYPE); 126204076Spjd} 127204076Spjd