Changeset View
Changeset View
Standalone View
Standalone View
head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c
Show All 29 Lines | |||||
#define __ELF_WORD_SIZE 64 | #define __ELF_WORD_SIZE 64 | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/exec.h> | #include <sys/exec.h> | ||||
#include <sys/linker.h> | #include <sys/linker.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <machine/elf.h> | #include <machine/elf.h> | ||||
#include <stand.h> | #include <stand.h> | ||||
#include <vm/vm.h> | |||||
#include <vm/pmap.h> | |||||
#include <efi.h> | #include <efi.h> | ||||
#include <efilib.h> | #include <efilib.h> | ||||
#include "bootstrap.h" | #include "bootstrap.h" | ||||
#include "platform/acfreebsd.h" | #include "platform/acfreebsd.h" | ||||
#include "acconfig.h" | #include "acconfig.h" | ||||
#define ACPI_SYSTEM_XFACE | #define ACPI_SYSTEM_XFACE | ||||
#include "actypes.h" | #include "actypes.h" | ||||
#include "actbl.h" | #include "actbl.h" | ||||
#include "loader_efi.h" | #include "loader_efi.h" | ||||
static EFI_GUID acpi_guid = ACPI_TABLE_GUID; | static EFI_GUID acpi_guid = ACPI_TABLE_GUID; | ||||
static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; | static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; | ||||
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp); | extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp); | ||||
static int elf64_exec(struct preloaded_file *amp); | static int elf64_exec(struct preloaded_file *amp); | ||||
static int elf64_obj_exec(struct preloaded_file *amp); | static int elf64_obj_exec(struct preloaded_file *amp); | ||||
static struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; | static struct file_format amd64_elf = { | ||||
static struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; | .l_load = elf64_loadfile, | ||||
.l_exec = elf64_exec, | |||||
}; | |||||
static struct file_format amd64_elf_obj = { | |||||
.l_load = elf64_obj_loadfile, | |||||
.l_exec = elf64_obj_exec, | |||||
}; | |||||
struct file_format *file_formats[] = { | struct file_format *file_formats[] = { | ||||
&amd64_elf, | &amd64_elf, | ||||
&amd64_elf_obj, | &amd64_elf_obj, | ||||
NULL | NULL | ||||
}; | }; | ||||
#define PG_V 0x001 | static pml4_entry_t *PT4; | ||||
#define PG_RW 0x002 | static pdp_entry_t *PT3; | ||||
#define PG_U 0x004 | static pd_entry_t *PT2; | ||||
#define PG_PS 0x080 | |||||
typedef u_int64_t p4_entry_t; | |||||
typedef u_int64_t p3_entry_t; | |||||
typedef u_int64_t p2_entry_t; | |||||
static p4_entry_t *PT4; | |||||
static p3_entry_t *PT3; | |||||
static p2_entry_t *PT2; | |||||
static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend, | static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend, | ||||
uint64_t modulep, p4_entry_t *pagetable, | uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry); | ||||
uint64_t entry); | |||||
extern uintptr_t amd64_tramp; | extern uintptr_t amd64_tramp; | ||||
extern uint32_t amd64_tramp_size; | extern uint32_t amd64_tramp_size; | ||||
/* | /* | ||||
* There is an ELF kernel and one or more ELF modules loaded. | * There is an ELF kernel and one or more ELF modules loaded. | ||||
* We wish to start executing the kernel image, so make such | * We wish to start executing the kernel image, so make such | ||||
* preparations as are required, and do so. | * preparations as are required, and do so. | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | elf64_exec(struct preloaded_file *fp) | ||||
trampcode = (vm_offset_t)0x0000000040000000; | trampcode = (vm_offset_t)0x0000000040000000; | ||||
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, | err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, | ||||
(EFI_PHYSICAL_ADDRESS *)&trampcode); | (EFI_PHYSICAL_ADDRESS *)&trampcode); | ||||
bzero((void *)trampcode, EFI_PAGE_SIZE); | bzero((void *)trampcode, EFI_PAGE_SIZE); | ||||
trampstack = trampcode + EFI_PAGE_SIZE - 8; | trampstack = trampcode + EFI_PAGE_SIZE - 8; | ||||
bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size); | bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size); | ||||
trampoline = (void *)trampcode; | trampoline = (void *)trampcode; | ||||
PT4 = (p4_entry_t *)0x0000000040000000; | PT4 = (pml4_entry_t *)0x0000000040000000; | ||||
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3, | err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3, | ||||
(EFI_PHYSICAL_ADDRESS *)&PT4); | (EFI_PHYSICAL_ADDRESS *)&PT4); | ||||
bzero(PT4, 3 * EFI_PAGE_SIZE); | bzero(PT4, 3 * EFI_PAGE_SIZE); | ||||
PT3 = &PT4[512]; | PT3 = &PT4[512]; | ||||
PT2 = &PT3[512]; | PT2 = &PT3[512]; | ||||
/* | /* | ||||
* This is kinda brutal, but every single 1GB VM memory segment points | * This is kinda brutal, but every single 1GB VM memory segment points | ||||
* to the same first 1GB of physical memory. But it is more than | * to the same first 1GB of physical memory. But it is more than | ||||
* adequate. | * adequate. | ||||
*/ | */ | ||||
for (i = 0; i < 512; i++) { | for (i = 0; i < 512; i++) { | ||||
/* Each slot of the L4 pages points to the same L3 page. */ | /* Each slot of the L4 pages points to the same L3 page. */ | ||||
PT4[i] = (p4_entry_t)PT3; | PT4[i] = (pml4_entry_t)PT3; | ||||
PT4[i] |= PG_V | PG_RW | PG_U; | PT4[i] |= PG_V | PG_RW | PG_U; | ||||
/* Each slot of the L3 pages points to the same L2 page. */ | /* Each slot of the L3 pages points to the same L2 page. */ | ||||
PT3[i] = (p3_entry_t)PT2; | PT3[i] = (pdp_entry_t)PT2; | ||||
PT3[i] |= PG_V | PG_RW | PG_U; | PT3[i] |= PG_V | PG_RW | PG_U; | ||||
/* The L2 page slots are mapped with 2MB pages for 1GB. */ | /* The L2 page slots are mapped with 2MB pages for 1GB. */ | ||||
PT2[i] = i * (2 * 1024 * 1024); | PT2[i] = i * (2 * 1024 * 1024); | ||||
PT2[i] |= PG_V | PG_RW | PG_PS | PG_U; | PT2[i] |= PG_V | PG_RW | PG_PS | PG_U; | ||||
} | } | ||||
printf("Start @ 0x%lx ...\n", ehdr->e_entry); | printf("Start @ 0x%lx ...\n", ehdr->e_entry); | ||||
Show All 11 Lines | trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4, | ||||
ehdr->e_entry); | ehdr->e_entry); | ||||
panic("exec returned"); | panic("exec returned"); | ||||
} | } | ||||
static int | static int | ||||
elf64_obj_exec(struct preloaded_file *fp) | elf64_obj_exec(struct preloaded_file *fp) | ||||
{ | { | ||||
return (EFTYPE); | return (EFTYPE); | ||||
} | } |