139833Speter/*- 239833Speter * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 339833Speter * All rights reserved. 439833Speter * 539833Speter * Redistribution and use in source and binary forms, with or without 639833Speter * modification, are permitted provided that the following conditions 739833Speter * are met: 839833Speter * 1. Redistributions of source code must retain the above copyright 939833Speter * notice, this list of conditions and the following disclaimer. 1039833Speter * 2. Redistributions in binary form must reproduce the above copyright 1139833Speter * notice, this list of conditions and the following disclaimer in the 1239833Speter * documentation and/or other materials provided with the distribution. 1339833Speter * 1439833Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1539833Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1639833Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1739833Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1839833Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1939833Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2039833Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2139833Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2239833Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2339833Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2439833Speter * SUCH DAMAGE. 2539833Speter */ 2639833Speter 27119482Sobrien#include <sys/cdefs.h> 28119482Sobrien__FBSDID("$FreeBSD$"); 29119482Sobrien 30114379Speter#define __ELF_WORD_SIZE 64 3139833Speter#include <sys/param.h> 3239833Speter#include <sys/exec.h> 3339833Speter#include <sys/linker.h> 3439833Speter#include <string.h> 3539833Speter#include <machine/bootinfo.h> 3639833Speter#include <machine/elf.h> 3739833Speter#include <stand.h> 3839833Speter 3939833Speter#include "bootstrap.h" 4039833Speter#include "libi386.h" 4139833Speter#include "btxv86.h" 4239833Speter 43114379Speterstatic int elf64_exec(struct preloaded_file *amp); 44134459Siedowsestatic int elf64_obj_exec(struct preloaded_file *amp); 4539833Speter 46114379Speterstruct file_format amd64_elf = { elf64_loadfile, elf64_exec }; 47134459Siedowsestruct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; 4839833Speter 49114379Speter#define PG_V 0x001 50114379Speter#define PG_RW 0x002 51114379Speter#define PG_U 0x004 52114379Speter#define PG_PS 0x080 53114379Speter 54114379Spetertypedef u_int64_t p4_entry_t; 55114379Spetertypedef u_int64_t p3_entry_t; 56114379Spetertypedef u_int64_t p2_entry_t; 57114379Speterextern p4_entry_t PT4[]; 58114379Speterextern p3_entry_t PT3[]; 59114379Speterextern p2_entry_t PT2[]; 60114379Speter 61114379Speteru_int32_t entry_hi; 62114379Speteru_int32_t entry_lo; 63114379Speter 64162814Sruextern void amd64_tramp(); 65114379Speter 6639833Speter/* 67163708Sru * There is an ELF kernel and one or more ELF modules loaded. 6839833Speter * We wish to start executing the kernel image, so make such 6939833Speter * preparations as are required, and do so. 7039833Speter */ 7139833Speterstatic int 72114379Speterelf64_exec(struct preloaded_file *fp) 7339833Speter{ 7459854Sbp struct file_metadata *md; 7539833Speter Elf_Ehdr *ehdr; 76114379Speter vm_offset_t modulep, kernend; 77114379Speter int err; 78114379Speter int i; 7939833Speter 8059854Sbp if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) 81199806Strasz return(EFTYPE); 8239833Speter ehdr = (Elf_Ehdr *)&(md->md_data); 8339833Speter 84114379Speter err = bi_load64(fp->f_args, &modulep, &kernend); 85114379Speter if (err != 0) 8639902Smsmith return(err); 8739902Smsmith 88114379Speter bzero(PT4, PAGE_SIZE); 89114379Speter bzero(PT3, PAGE_SIZE); 90114379Speter bzero(PT2, PAGE_SIZE); 9139833Speter 92114920Speter /* 93114920Speter * This is kinda brutal, but every single 1GB VM memory segment points to 94114920Speter * the same first 1GB of physical memory. But it is more than adequate. 95114920Speter */ 96114920Speter for (i = 0; i < 512; i++) { 97114920Speter /* Each slot of the level 4 pages points to the same level 3 page */ 98114920Speter PT4[i] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]); 99114920Speter PT4[i] |= PG_V | PG_RW | PG_U; 10039833Speter 101114920Speter /* Each slot of the level 3 pages points to the same level 2 page */ 102114920Speter PT3[i] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]); 103114920Speter PT3[i] |= PG_V | PG_RW | PG_U; 104114379Speter 105114920Speter /* The level 2 page slots are mapped with 2MB pages for 1GB. */ 106114379Speter PT2[i] = i * (2 * 1024 * 1024); 107114379Speter PT2[i] |= PG_V | PG_RW | PG_PS | PG_U; 108114379Speter } 109114379Speter 110114379Speter entry_lo = ehdr->e_entry & 0xffffffff; 111114379Speter entry_hi = (ehdr->e_entry >> 32) & 0xffffffff; 11239833Speter#ifdef DEBUG 113114379Speter printf("Start @ %#llx ...\n", ehdr->e_entry); 11439833Speter#endif 11539833Speter 11661659Sps dev_cleanup(); 117114379Speter __exec((void *)VTOP(amd64_tramp), modulep, kernend); 11839833Speter 11939833Speter panic("exec returned"); 12039833Speter} 121134459Siedowse 122134459Siedowsestatic int 123134459Siedowseelf64_obj_exec(struct preloaded_file *fp) 124134459Siedowse{ 125134459Siedowse return (EFTYPE); 126134459Siedowse} 127