mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-26 20:12:44 +00:00
Merge 78d6582411
into f2233ac33a
This commit is contained in:
commit
91d38d869a
@ -239,10 +239,10 @@ struct preloaded_file
|
||||
size_t f_size; /* file size */
|
||||
struct kernel_module *f_modules; /* list of modules if any */
|
||||
struct preloaded_file *f_next; /* next file */
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
#if defined(__amd64__) || (defined(__i386__) && defined(EFI))
|
||||
bool f_kernphys_relocatable;
|
||||
#endif
|
||||
#if defined(__i386__)
|
||||
#if defined(__i386__) && !defined(EFI)
|
||||
bool f_tg_kernel_support;
|
||||
#endif
|
||||
};
|
||||
|
@ -217,7 +217,7 @@ static int elf_section_header_convert(const Elf_Ehdr *ehdr, Elf_Shdr *shdr)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
#if defined(__amd64__) || (defined(__i386__) && defined(EFI))
|
||||
static bool
|
||||
is_kernphys_relocatable(elf_file_t ef)
|
||||
{
|
||||
@ -491,10 +491,10 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest,
|
||||
/* Load OK, return module pointer */
|
||||
*result = (struct preloaded_file *)fp;
|
||||
err = 0;
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
#if defined(__amd64__) || (defined(__i386__) && defined(EFI))
|
||||
fp->f_kernphys_relocatable = multiboot || is_kernphys_relocatable(&ef);
|
||||
#endif
|
||||
#ifdef __i386__
|
||||
#if defined(__i386__) && !defined(EFI)
|
||||
fp->f_tg_kernel_support = is_tg_kernel_support(fp, &ef);
|
||||
#endif
|
||||
goto out;
|
||||
|
@ -42,9 +42,6 @@
|
||||
|
||||
#include "loader_efi.h"
|
||||
|
||||
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
|
||||
static int elf64_exec(struct preloaded_file *amp);
|
||||
static int elf64_obj_exec(struct preloaded_file *amp);
|
||||
|
||||
@ -74,8 +71,6 @@ static pdp_entry_t *PT3_l, *PT3_u;
|
||||
static pd_entry_t *PT2;
|
||||
static pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
|
||||
|
||||
extern EFI_PHYSICAL_ADDRESS staging;
|
||||
|
||||
static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend,
|
||||
uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry);
|
||||
|
||||
@ -106,8 +101,7 @@ elf64_exec(struct preloaded_file *fp)
|
||||
ehdr = (Elf_Ehdr *)&(md->md_data);
|
||||
|
||||
trampcode = copy_staging == COPY_STAGING_ENABLE ?
|
||||
(vm_offset_t)0x0000000040000000 /* 1G */ :
|
||||
(vm_offset_t)0x0000000100000000; /* 4G */;
|
||||
(vm_offset_t)G(1) : (vm_offset_t)G(4);
|
||||
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1,
|
||||
(EFI_PHYSICAL_ADDRESS *)&trampcode);
|
||||
if (EFI_ERROR(err)) {
|
||||
@ -122,7 +116,7 @@ elf64_exec(struct preloaded_file *fp)
|
||||
trampoline = (void *)trampcode;
|
||||
|
||||
if (copy_staging == COPY_STAGING_ENABLE) {
|
||||
PT4 = (pml4_entry_t *)0x0000000040000000; /* 1G */
|
||||
PT4 = (pml4_entry_t *)G(1);
|
||||
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3,
|
||||
(EFI_PHYSICAL_ADDRESS *)&PT4);
|
||||
if (EFI_ERROR(err)) {
|
||||
@ -159,11 +153,11 @@ elf64_exec(struct preloaded_file *fp)
|
||||
/*
|
||||
* The L2 page slots are mapped with 2MB pages for 1GB.
|
||||
*/
|
||||
PT2[i] = (pd_entry_t)i * (2 * 1024 * 1024);
|
||||
PT2[i] = (pd_entry_t)i * M(2);
|
||||
PT2[i] |= PG_V | PG_RW | PG_PS;
|
||||
}
|
||||
} else {
|
||||
PT4 = (pml4_entry_t *)0x0000000100000000; /* 4G */
|
||||
PT4 = (pml4_entry_t *)G(4);
|
||||
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9,
|
||||
(EFI_PHYSICAL_ADDRESS *)&PT4);
|
||||
if (EFI_ERROR(err)) {
|
||||
|
@ -57,8 +57,6 @@ extern int elf32_loadfile_raw(char *filename, uint64_t dest,
|
||||
extern int elf64_load_modmetadata(struct preloaded_file *fp, uint64_t dest);
|
||||
extern int elf64_obj_loadfile(char *filename, uint64_t dest,
|
||||
struct preloaded_file **result);
|
||||
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
|
||||
extern void multiboot2_exec(void *entry, uint64_t multiboot_info,
|
||||
uint64_t stack);
|
||||
|
@ -40,8 +40,6 @@
|
||||
#include "bootstrap.h"
|
||||
#include "loader_efi.h"
|
||||
|
||||
extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool);
|
||||
|
||||
static int
|
||||
__elfN(arm_load)(char *filename, uint64_t dest,
|
||||
struct preloaded_file **result)
|
||||
|
@ -42,9 +42,6 @@
|
||||
static int elf64_exec(struct preloaded_file *amp);
|
||||
static int elf64_obj_exec(struct preloaded_file *amp);
|
||||
|
||||
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
|
||||
static struct file_format arm64_elf = {
|
||||
elf64_loadfile,
|
||||
elf64_exec
|
||||
|
@ -28,7 +28,11 @@
|
||||
#define __ELF_WORD_SIZE 64
|
||||
#include <sys/param.h>
|
||||
#include <sys/linker.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/pmap_pae.h>
|
||||
#include <machine/segments.h>
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
@ -37,9 +41,6 @@
|
||||
|
||||
#include "loader_efi.h"
|
||||
|
||||
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
|
||||
static int elf64_exec(struct preloaded_file *amp);
|
||||
static int elf64_obj_exec(struct preloaded_file *amp);
|
||||
|
||||
@ -59,40 +60,14 @@ struct file_format *file_formats[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
struct gdtr {
|
||||
uint16_t size;
|
||||
uint64_t ptr;
|
||||
} __packed;
|
||||
|
||||
#define PG_V 0x001
|
||||
#define PG_RW 0x002
|
||||
#define PG_PS 0x080
|
||||
|
||||
#define GDT_P 0x00800000000000
|
||||
#define GDT_E 0x00080000000000
|
||||
#define GDT_S 0x00100000000000
|
||||
#define GDT_RW 0x00020000000000
|
||||
#define GDT_L 0x20000000000000
|
||||
|
||||
#define M(x) ((x) * 1024 * 1024)
|
||||
#define G(x) (1ULL * (x) * 1024 * 1024 * 1024)
|
||||
|
||||
typedef uint64_t p4_entry_t;
|
||||
typedef uint64_t p3_entry_t;
|
||||
typedef uint64_t p2_entry_t;
|
||||
typedef uint64_t gdt_t;
|
||||
|
||||
static p4_entry_t *PT4;
|
||||
static p3_entry_t *PT3;
|
||||
static p3_entry_t *PT3_l, *PT3_u;
|
||||
static p2_entry_t *PT2;
|
||||
static p2_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
|
||||
static gdt_t *GDT;
|
||||
|
||||
extern EFI_PHYSICAL_ADDRESS staging;
|
||||
/*
|
||||
* i386's pmap_pae.h doesn't provide this, so
|
||||
* just typedef our own.
|
||||
*/
|
||||
typedef pdpt_entry_t pml4_entry_t;
|
||||
|
||||
static void (*trampoline)(uint32_t stack, void *copy_finish, uint32_t kernend,
|
||||
uint32_t modulep, uint64_t *pagetable, struct gdtr *gdtr, uint64_t entry);
|
||||
uint32_t modulep, uint64_t *pagetable, void *gdtr, uint64_t entry);
|
||||
|
||||
extern void *amd64_tramp;
|
||||
extern uint32_t amd64_tramp_size;
|
||||
@ -105,12 +80,23 @@ extern uint32_t amd64_tramp_size;
|
||||
static int
|
||||
elf64_exec(struct preloaded_file *fp)
|
||||
{
|
||||
/*
|
||||
* segments.h gives us a 32-bit gdtr, but
|
||||
* we want a 64-bit one, so define our own.
|
||||
*/
|
||||
struct {
|
||||
uint16_t rd_limit;
|
||||
uint64_t rd_base;
|
||||
} __packed *gdtr;
|
||||
EFI_PHYSICAL_ADDRESS ptr;
|
||||
EFI_ALLOCATE_TYPE type;
|
||||
EFI_STATUS err;
|
||||
struct file_metadata *md;
|
||||
struct gdtr *gdtr;
|
||||
Elf_Ehdr *ehdr;
|
||||
pml4_entry_t *PT4;
|
||||
pdpt_entry_t *PT3;
|
||||
pd_entry_t *PT2;
|
||||
struct user_segment_descriptor *gdt;
|
||||
vm_offset_t modulep, kernend, trampstack;
|
||||
int i;
|
||||
|
||||
@ -131,36 +117,47 @@ elf64_exec(struct preloaded_file *fp)
|
||||
return (EFTYPE);
|
||||
ehdr = (Elf_Ehdr *)&(md->md_data);
|
||||
|
||||
/*
|
||||
* Make our temporary stack 32 bytes big, which is
|
||||
* a little more than we need.
|
||||
*/
|
||||
ptr = G(1);
|
||||
err = BS->AllocatePages(type, EfiLoaderCode,
|
||||
EFI_SIZE_TO_PAGES(amd64_tramp_size + 32), &ptr);
|
||||
EFI_SIZE_TO_PAGES(amd64_tramp_size), &ptr);
|
||||
if (EFI_ERROR(err)) {
|
||||
printf("Unable to allocate trampoline\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
trampoline = (void *)(uintptr_t)ptr;
|
||||
trampstack = ptr + amd64_tramp_size + 32;
|
||||
bcopy(&amd64_tramp, trampoline, amd64_tramp_size);
|
||||
|
||||
/*
|
||||
* Allocate enough space for the GDTR + two GDT segments +
|
||||
* our temporary stack (28 bytes).
|
||||
*/
|
||||
#define DATASZ (sizeof(*gdtr) + \
|
||||
sizeof(struct user_segment_descriptor) * 2 + 28)
|
||||
|
||||
ptr = G(1);
|
||||
err = BS->AllocatePages(type, EfiLoaderData,
|
||||
EFI_SIZE_TO_PAGES(sizeof(struct gdtr) + sizeof(uint64_t) * 2), &ptr);
|
||||
EFI_SIZE_TO_PAGES(DATASZ), &ptr);
|
||||
if (EFI_ERROR(err)) {
|
||||
printf("Unable to allocate GDT\n");
|
||||
printf("Unable to allocate GDT and stack\n");
|
||||
BS->FreePages((uintptr_t)trampoline, 1);
|
||||
return (ENOMEM);
|
||||
}
|
||||
GDT = (gdt_t *)(uintptr_t)ptr;
|
||||
GDT[1] = GDT_P | GDT_E | GDT_S | GDT_RW | GDT_L; /* CS */
|
||||
GDT[0] = 0;
|
||||
gdtr = (struct gdtr *)&GDT[2];
|
||||
gdtr->size = sizeof(uint64_t) * 2 - 1;
|
||||
gdtr->ptr = (uintptr_t)GDT;
|
||||
|
||||
trampstack = ptr + DATASZ;
|
||||
|
||||
#undef DATASZ
|
||||
|
||||
gdt = (void *)(uintptr_t)ptr;
|
||||
gdt[0] = (struct user_segment_descriptor) { 0 };
|
||||
gdt[1] = (struct user_segment_descriptor) {
|
||||
.sd_p = 1, .sd_long = 1, .sd_type = SDT_MEMERC
|
||||
};
|
||||
|
||||
gdtr = (void *)(uintptr_t)(ptr +
|
||||
sizeof(struct user_segment_descriptor) * 2);
|
||||
gdtr->rd_limit = sizeof(struct user_segment_descriptor) * 2 - 1;
|
||||
gdtr->rd_base = (uintptr_t)gdt;
|
||||
|
||||
if (type == AllocateMaxAddress) {
|
||||
/* Copy staging enabled */
|
||||
@ -171,10 +168,10 @@ elf64_exec(struct preloaded_file *fp)
|
||||
if (EFI_ERROR(err)) {
|
||||
printf("Unable to allocate trampoline page table\n");
|
||||
BS->FreePages((uintptr_t)trampoline, 1);
|
||||
BS->FreePages((uintptr_t)GDT, 1);
|
||||
BS->FreePages((uintptr_t)gdt, 1);
|
||||
return (ENOMEM);
|
||||
}
|
||||
PT4 = (p4_entry_t *)(uintptr_t)ptr;
|
||||
PT4 = (pml4_entry_t *)(uintptr_t)ptr;
|
||||
|
||||
PT3 = &PT4[512];
|
||||
PT2 = &PT3[512];
|
||||
@ -203,15 +200,18 @@ elf64_exec(struct preloaded_file *fp)
|
||||
PT2[i] = (i * M(2)) | PG_V | PG_RW | PG_PS;
|
||||
}
|
||||
} else {
|
||||
pdpt_entry_t *PT3_l, *PT3_u;
|
||||
pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
|
||||
|
||||
err = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
|
||||
EFI_SIZE_TO_PAGES(512 * 9 * sizeof(uint64_t)), &ptr);
|
||||
if (EFI_ERROR(err)) {
|
||||
printf("Unable to allocate trampoline page table\n");
|
||||
BS->FreePages((uintptr_t)trampoline, 1);
|
||||
BS->FreePages((uintptr_t)GDT, 1);
|
||||
BS->FreePages((uintptr_t)gdt, 1);
|
||||
return (ENOMEM);
|
||||
}
|
||||
PT4 = (p4_entry_t *)(uintptr_t)ptr;
|
||||
PT4 = (pml4_entry_t *)(uintptr_t)ptr;
|
||||
|
||||
PT3_l = &PT4[512];
|
||||
PT3_u = &PT3_l[512];
|
||||
@ -229,7 +229,7 @@ elf64_exec(struct preloaded_file *fp)
|
||||
PT3_l[2] = (uintptr_t)PT2_l2 | PG_V | PG_RW;
|
||||
PT3_l[3] = (uintptr_t)PT2_l3 | PG_V | PG_RW;
|
||||
for (i = 0; i < 2048; i++) {
|
||||
PT2_l0[i] = ((p2_entry_t)i * M(2)) | PG_V | PG_RW | PG_PS;
|
||||
PT2_l0[i] = ((pd_entry_t)i * M(2)) | PG_V | PG_RW | PG_PS;
|
||||
}
|
||||
|
||||
/* mapping of kernel 2G below top */
|
||||
@ -248,7 +248,7 @@ elf64_exec(struct preloaded_file *fp)
|
||||
printf(
|
||||
"staging %#llx (%scopying) tramp %p PT4 %p GDT %p\n"
|
||||
"Start @ %#llx ...\n", staging,
|
||||
type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, GDT,
|
||||
type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, gdt,
|
||||
ehdr->e_entry
|
||||
);
|
||||
|
||||
|
@ -40,8 +40,6 @@
|
||||
#include "bootstrap.h"
|
||||
#include "loader_efi.h"
|
||||
|
||||
extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool);
|
||||
|
||||
static int
|
||||
__elfN(exec)(struct preloaded_file *fp)
|
||||
{
|
||||
|
@ -64,9 +64,6 @@
|
||||
#include "geliboot.h"
|
||||
#endif
|
||||
|
||||
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
|
||||
static int
|
||||
bi_getboothowto(char *kargs)
|
||||
{
|
||||
|
@ -35,9 +35,6 @@
|
||||
|
||||
#include "loader_efi.h"
|
||||
|
||||
#define M(x) ((x) * 1024 * 1024)
|
||||
#define G(x) (1ULL * (x) * 1024 * 1024 * 1024)
|
||||
|
||||
#if defined(__amd64__)
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/specialreg.h>
|
||||
@ -181,12 +178,7 @@ out:
|
||||
#define EFI_STAGING_SIZE DEFAULT_EFI_STAGING_SIZE
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \
|
||||
defined(__riscv) || defined(__i386__)
|
||||
#define EFI_STAGING_2M_ALIGN 1
|
||||
#else
|
||||
#define EFI_STAGING_2M_ALIGN 0
|
||||
#endif
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
#define EFI_STAGING_SLOP M(8)
|
||||
|
@ -41,6 +41,10 @@ enum {
|
||||
extern int copy_staging;
|
||||
#endif
|
||||
|
||||
/* Useful for various calculations */
|
||||
#define M(x) ((x) * 1024 * 1024)
|
||||
#define G(x) (1ULL * (x) * 1024 * 1024 * 1024)
|
||||
|
||||
extern EFI_LOADED_IMAGE *boot_img;
|
||||
|
||||
int efi_autoload(void);
|
||||
@ -55,4 +59,12 @@ void * efi_translate(vm_offset_t ptr);
|
||||
void efi_copy_finish(void);
|
||||
void efi_copy_finish_nop(void);
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
/* Need this to setup page tables */
|
||||
extern EFI_PHYSICAL_ADDRESS staging;
|
||||
#endif
|
||||
|
||||
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
|
||||
#endif /* _LOADER_EFI_COPY_H_ */
|
||||
|
@ -28,8 +28,11 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/linker.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <string.h>
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/pmap_pae.h>
|
||||
#include <machine/elf.h>
|
||||
#include <stand.h>
|
||||
|
||||
@ -43,16 +46,15 @@ static int elf64_obj_exec(struct preloaded_file *amp);
|
||||
struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
|
||||
struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
|
||||
|
||||
#define PG_V 0x001
|
||||
#define PG_RW 0x002
|
||||
#define PG_PS 0x080
|
||||
/*
|
||||
* i386's pmap_pae.h doesn't provide this, so
|
||||
* just typedef our own.
|
||||
*/
|
||||
typedef pdpt_entry_t pml4_entry_t;
|
||||
|
||||
typedef uint64_t p4_entry_t;
|
||||
typedef uint64_t p3_entry_t;
|
||||
typedef uint64_t p2_entry_t;
|
||||
extern p4_entry_t PT4[];
|
||||
extern p3_entry_t PT3[];
|
||||
extern p2_entry_t PT2[];
|
||||
extern pml4_entry_t PT4[];
|
||||
extern pdpt_entry_t PT3[];
|
||||
extern pd_entry_t PT2[];
|
||||
|
||||
uint32_t entry_hi;
|
||||
uint32_t entry_lo;
|
||||
@ -91,11 +93,11 @@ elf64_exec(struct preloaded_file *fp)
|
||||
*/
|
||||
for (i = 0; i < 512; i++) {
|
||||
/* Each slot of the level 4 pages points to the same level 3 page */
|
||||
PT4[i] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]);
|
||||
PT4[i] = (pml4_entry_t)VTOP((uintptr_t)&PT3[0]);
|
||||
PT4[i] |= PG_V | PG_RW;
|
||||
|
||||
/* Each slot of the level 3 pages points to the same level 2 page */
|
||||
PT3[i] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]);
|
||||
PT3[i] = (pdpt_entry_t)VTOP((uintptr_t)&PT2[0]);
|
||||
PT3[i] |= PG_V | PG_RW;
|
||||
|
||||
/* The level 2 page slots are mapped with 2MB pages for 1GB. */
|
||||
|
@ -42,7 +42,6 @@
|
||||
|
||||
#include "bootstrap.h"
|
||||
#include "kboot.h"
|
||||
#include "bootstrap.h"
|
||||
|
||||
#include "platform/acfreebsd.h"
|
||||
#include "acconfig.h"
|
||||
@ -70,8 +69,11 @@ extern uint32_t efi_map_size;
|
||||
extern vm_paddr_t efi_map_phys_src; /* From DTB */
|
||||
extern vm_paddr_t efi_map_phys_dst; /* From our memory map metadata module */
|
||||
|
||||
/* Usually provided by loader_efi.h */
|
||||
#ifndef EFI
|
||||
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
#endif
|
||||
|
||||
static struct file_format arm64_elf = {
|
||||
elf64_loadfile,
|
||||
|
@ -56,6 +56,10 @@
|
||||
|
||||
static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
|
||||
static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
|
||||
#else
|
||||
/* Usually provided by loader_efi.h */
|
||||
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
#endif
|
||||
|
||||
#ifdef EFI
|
||||
@ -64,9 +68,6 @@ static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
|
||||
#define LOADER_PAGE_SIZE PAGE_SIZE
|
||||
#endif
|
||||
|
||||
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
|
||||
bool exit_bs);
|
||||
|
||||
static int elf64_exec(struct preloaded_file *amp);
|
||||
static int elf64_obj_exec(struct preloaded_file *amp);
|
||||
|
||||
@ -121,8 +122,6 @@ static pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
|
||||
static pdp_entry_t *PT3;
|
||||
static pd_entry_t *PT2;
|
||||
|
||||
extern EFI_PHYSICAL_ADDRESS staging;
|
||||
|
||||
static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend,
|
||||
uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry);
|
||||
#endif
|
||||
@ -210,8 +209,7 @@ elf64_exec(struct preloaded_file *fp)
|
||||
|
||||
#ifdef EFI
|
||||
trampcode = copy_staging == COPY_STAGING_ENABLE ?
|
||||
(vm_offset_t)0x0000000040000000 /* 1G */ :
|
||||
(vm_offset_t)0x0000000100000000; /* 4G */;
|
||||
(vm_offset_t)G(1) : (vm_offset_t)G(4);
|
||||
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1,
|
||||
(EFI_PHYSICAL_ADDRESS *)&trampcode);
|
||||
if (EFI_ERROR(err)) {
|
||||
@ -235,7 +233,7 @@ elf64_exec(struct preloaded_file *fp)
|
||||
|
||||
#ifdef EFI
|
||||
if (copy_staging == COPY_STAGING_ENABLE) {
|
||||
PT4 = (pml4_entry_t *)0x0000000040000000; /* 1G */
|
||||
PT4 = (pml4_entry_t *)G(1);
|
||||
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3,
|
||||
(EFI_PHYSICAL_ADDRESS *)&PT4);
|
||||
if (EFI_ERROR(err)) {
|
||||
@ -272,11 +270,11 @@ elf64_exec(struct preloaded_file *fp)
|
||||
/*
|
||||
* The L2 page slots are mapped with 2MB pages for 1GB.
|
||||
*/
|
||||
PT2[i] = (pd_entry_t)i * (2 * 1024 * 1024);
|
||||
PT2[i] = (pd_entry_t)i * M(2);
|
||||
PT2[i] |= PG_V | PG_RW | PG_PS;
|
||||
}
|
||||
} else {
|
||||
PT4 = (pml4_entry_t *)0x0000000100000000; /* 4G */
|
||||
PT4 = (pml4_entry_t *)G(4);
|
||||
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9,
|
||||
(EFI_PHYSICAL_ADDRESS *)&PT4);
|
||||
if (EFI_ERROR(err)) {
|
||||
|
@ -31,9 +31,10 @@
|
||||
#ifdef DEBUG
|
||||
#include <machine/_inttypes.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <i386/include/bootinfo.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/segments.h>
|
||||
#include <stand.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
@ -45,35 +46,21 @@ static int elf64_obj_exec(struct preloaded_file *amp);
|
||||
struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
|
||||
struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
|
||||
|
||||
#define MSR_EFER 0xc0000080
|
||||
#define EFER_LME 0x00000100
|
||||
#define EFER_LMA 0x00000400 /* Long mode active (R) */
|
||||
#define CR4_PAE 0x00000020
|
||||
#define CR4_VMXE (1UL << 13)
|
||||
#define CR4_PSE 0x00000010
|
||||
#define CR0_PG 0x80000000
|
||||
#define CR0_PE 0x00000001 /* Protected mode Enable */
|
||||
#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
|
||||
|
||||
#define PG_V 0x001
|
||||
#define PG_RW 0x002
|
||||
#define PG_PS 0x080
|
||||
|
||||
typedef uint64_t p4_entry_t;
|
||||
typedef uint64_t p3_entry_t;
|
||||
typedef uint64_t p2_entry_t;
|
||||
|
||||
#define GUEST_NULL_SEL 0
|
||||
#define GUEST_CODE_SEL 1
|
||||
#define GUEST_DATA_SEL 2
|
||||
#define GUEST_GDTR_LIMIT (3 * 8 - 1)
|
||||
|
||||
static void
|
||||
setup_freebsd_gdt(uint64_t *gdtr)
|
||||
setup_freebsd_gdt(struct user_segment_descriptor *gdt)
|
||||
{
|
||||
gdtr[GUEST_NULL_SEL] = 0;
|
||||
gdtr[GUEST_CODE_SEL] = 0x0020980000000000;
|
||||
gdtr[GUEST_DATA_SEL] = 0x0000900000000000;
|
||||
gdt[GUEST_NULL_SEL] = (struct user_segment_descriptor) { 0 };
|
||||
gdt[GUEST_CODE_SEL] = (struct user_segment_descriptor) {
|
||||
.sd_p = 1, .sd_long = 1, .sd_type = SDT_MEME
|
||||
};
|
||||
gdt[GUEST_DATA_SEL] = (struct user_segment_descriptor) {
|
||||
.sd_p = 1, .sd_type = SDT_MEMRO
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
@ -90,10 +77,10 @@ elf64_exec(struct preloaded_file *fp)
|
||||
int err;
|
||||
int i;
|
||||
uint32_t stack[1024];
|
||||
p4_entry_t PT4[512];
|
||||
p3_entry_t PT3[512];
|
||||
p2_entry_t PT2[512];
|
||||
uint64_t gdtr[3];
|
||||
pml4_entry_t PT4[512];
|
||||
pdp_entry_t PT3[512];
|
||||
pd_entry_t PT2[512];
|
||||
struct user_segment_descriptor gdt[3];
|
||||
|
||||
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
|
||||
return(EFTYPE);
|
||||
@ -122,11 +109,11 @@ elf64_exec(struct preloaded_file *fp)
|
||||
*/
|
||||
for (i = 0; i < 512; i++) {
|
||||
/* Each slot of the level 4 pages points to the same level 3 page */
|
||||
PT4[i] = (p4_entry_t) 0x3000;
|
||||
PT4[i] = (pml4_entry_t) 0x3000;
|
||||
PT4[i] |= PG_V | PG_RW;
|
||||
|
||||
/* Each slot of the level 3 pages points to the same level 2 page */
|
||||
PT3[i] = (p3_entry_t) 0x4000;
|
||||
PT3[i] = (pdp_entry_t) 0x4000;
|
||||
PT3[i] |= PG_V | PG_RW;
|
||||
|
||||
/* The level 2 page slots are mapped with 2MB pages for 1GB. */
|
||||
@ -154,9 +141,9 @@ elf64_exec(struct preloaded_file *fp)
|
||||
CALLBACK(setcr, 3, 0x2000);
|
||||
CALLBACK(setcr, 0, CR0_PG | CR0_PE | CR0_NE);
|
||||
|
||||
setup_freebsd_gdt(gdtr);
|
||||
CALLBACK(copyin, gdtr, 0x5000, sizeof(gdtr));
|
||||
CALLBACK(setgdt, 0x5000, sizeof(gdtr));
|
||||
setup_freebsd_gdt(gdt);
|
||||
CALLBACK(copyin, gdt, 0x5000, sizeof(gdt));
|
||||
CALLBACK(setgdt, 0x5000, sizeof(gdt));
|
||||
|
||||
CALLBACK(exec, ehdr->e_entry);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user