diff options
author | dfr <dfr@FreeBSD.org> | 2001-09-24 19:36:45 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2001-09-24 19:36:45 +0000 |
commit | e19e9a89725b0ba6f208a0a73cc571349c721078 (patch) | |
tree | a8732d678647498dd78ea299a2ba4cc087ef59b3 /sys/boot/efi/libefi | |
parent | 73f1755f493deb19546b69b9c51acf7c9f9d75ac (diff) | |
download | FreeBSD-src-e19e9a89725b0ba6f208a0a73cc571349c721078.zip FreeBSD-src-e19e9a89725b0ba6f208a0a73cc571349c721078.tar.gz |
Tidy up a little - don't try to print anything or enable interrupts after
we start changing translation registers. Also, call ExitBootServices
before we jump into the kernel.
Diffstat (limited to 'sys/boot/efi/libefi')
-rw-r--r-- | sys/boot/efi/libefi/elf_freebsd.c | 75 |
1 files changed, 24 insertions, 51 deletions
diff --git a/sys/boot/efi/libefi/elf_freebsd.c b/sys/boot/efi/libefi/elf_freebsd.c index b176e6c..8a64c1b 100644 --- a/sys/boot/efi/libefi/elf_freebsd.c +++ b/sys/boot/efi/libefi/elf_freebsd.c @@ -83,6 +83,10 @@ #include <sys/linker.h> #include <machine/elf.h> #include <machine/bootinfo.h> +#include <machine/pte.h> + +#include <efi.h> +#include <efilib.h> #include "bootstrap.h" @@ -92,30 +96,12 @@ static int elf_exec(struct preloaded_file *amp); struct file_format ia64_elf = { elf_loadfile, elf_exec }; -#define PTE_MA_WB 0 -#define PTE_MA_UC 4 -#define PTE_MA_UCE 5 -#define PTE_MA_WC 6 -#define PTE_MA_NATPAGE 7 - -#define PTE_PL_KERN 0 -#define PTE_PL_USER 3 - -#define PTE_AR_R 0 -#define PTE_AR_RX 1 -#define PTE_AR_RW 2 -#define PTE_AR_RWX 3 -#define PTE_AR_R_RW 4 -#define PTE_AR_RX_RWX 5 -#define PTE_AR_RWX_RW 6 -#define PTE_AR_X_RX 7 - static __inline u_int64_t disable_ic() { u_int64_t psr; __asm __volatile("mov %0=psr;;" : "=r" (psr)); - __asm __volatile("rsm psr.ic;; srlz.i;;"); + __asm __volatile("rsm psr.ic|psr.i;; srlz.i;;"); return psr; } @@ -126,30 +112,19 @@ restore_ic(u_int64_t psr) } /* - * A short-format VHPT entry. Also matches the TLB insertion format. + * Entered with psr.ic and psr.i both zero. */ -struct ia64_pte { - u_int64_t pte_p :1; /* bits 0..0 */ - u_int64_t pte_rv1 :1; /* bits 1..1 */ - u_int64_t pte_ma :3; /* bits 2..4 */ - u_int64_t pte_a :1; /* bits 5..5 */ - u_int64_t pte_d :1; /* bits 6..6 */ - u_int64_t pte_pl :2; /* bits 7..8 */ - u_int64_t pte_ar :3; /* bits 9..11 */ - u_int64_t pte_ppn :38; /* bits 12..49 */ - u_int64_t pte_rv2 :2; /* bits 50..51 */ - u_int64_t pte_ed :1; /* bits 52..52 */ - u_int64_t pte_ig :11; /* bits 53..63 */ -}; - void -enter_kernel(const char* filename, u_int64_t start) +enter_kernel(u_int64_t start, struct bootinfo *bi, UINTN mapkey) { - u_int64_t psr; + u_int64_t psr; + EFI_STATUS status; - printf("Entering %s at 0x%lx...\n", filename, start); - - psr = disable_ic(); + status = BS->ExitBootServices(IH, mapkey); + if (EFI_ERROR(status)) { + printf("ExitBootServices returned 0x%lx\n", status); + return; + } __asm __volatile("srlz.i;;"); __asm __volatile("mov cr.ipsr=%0" @@ -162,8 +137,7 @@ enter_kernel(const char* filename, u_int64_t start) __asm __volatile("mov cr.ifs=r0;;"); __asm __volatile("mov ar.rsc=0;; flushrs;;"); - __asm __volatile("1: mov r8=ip;; add r8=2f-1b,r8; mov r9=%0; rfi;; 2:" - :: "r"(psr)); + __asm __volatile("rfi;;"); } static int @@ -174,18 +148,21 @@ elf_exec(struct preloaded_file *fp) struct ia64_pte pte; struct bootinfo *bi; u_int64_t psr; + UINTN mapkey; if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); /* XXX actually EFUCKUP */ hdr = (Elf_Ehdr *)&(md->md_data); + printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry); + /* * Ugly hack, similar to linux. Dump the bootinfo into a * special page reserved in the link map. */ bi = (struct bootinfo *) 0x508000; bzero(bi, sizeof(struct bootinfo)); - bi_load(bi, fp); + bi_load(bi, fp, &mapkey); /* * Region 6 is direct mapped UC and region 7 is direct mapped @@ -196,6 +173,8 @@ elf_exec(struct preloaded_file *fp) ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2)); ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2)); + psr = disable_ic(); + bzero(&pte, sizeof(pte)); pte.pte_p = 1; pte.pte_ma = PTE_MA_WB; @@ -205,8 +184,6 @@ elf_exec(struct preloaded_file *fp) pte.pte_ar = PTE_AR_RWX; pte.pte_ppn = 0; - psr = disable_ic(); - __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_RR_BASE(7))); __asm __volatile("mov cr.itir=%0" :: "r"(28 << 2)); __asm __volatile("ptr.i %0,%1" :: "r"(IA64_RR_BASE(7)), "r"(28<<2)); @@ -218,8 +195,6 @@ elf_exec(struct preloaded_file *fp) :: "r"(0), "r"(*(u_int64_t*)&pte)); __asm __volatile("srlz.i;;"); - restore_ic(psr); - bzero(&pte, sizeof(pte)); pte.pte_p = 1; pte.pte_ma = PTE_MA_UC; @@ -229,17 +204,15 @@ elf_exec(struct preloaded_file *fp) pte.pte_ar = PTE_AR_RWX; pte.pte_ppn = 0xffffc000000 >> 12; - psr = disable_ic(); - __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_PHYS_TO_RR6(0xffffc000000))); __asm __volatile("mov cr.itir=%0" :: "r"(26 << 2)); - __asm __volatile("ptr.d %0,%1" :: "r"(IA64_PHYS_TO_RR6(0xffffc000000)), "r"(26<<2)); + //__asm __volatile("ptr.d %0,%1" :: "r"(IA64_PHYS_TO_RR6(0xffffc000000)), "r"(26<<2)); __asm __volatile("srlz.i;;"); __asm __volatile("itr.d dtr[%0]=%1;;" :: "r"(1), "r"(*(u_int64_t*)&pte)); __asm __volatile("srlz.i;;"); - restore_ic(psr); + enter_kernel(hdr->e_entry, bi, mapkey); - enter_kernel(fp->f_name, hdr->e_entry); + restore_ic(psr); } |