Index: head/sys/boot/ia64/common/copy.c =================================================================== --- head/sys/boot/ia64/common/copy.c (revision 220312) +++ head/sys/boot/ia64/common/copy.c (revision 220313) @@ -1,194 +1,212 @@ /*- * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include -#include +#include #include "libia64.h" +u_int ia64_legacy_kernel; + uint64_t *ia64_pgtbl; uint32_t ia64_pgtblsz; static int pgtbl_extend(u_int idx) { uint64_t *pgtbl; uint32_t pgtblsz; u_int pot; pgtblsz = (idx + 1) << 3; /* The minimum size is 4KB. */ if (pgtblsz < 4096) pgtblsz = 4096; /* Find the next higher power of 2. */ pgtblsz--; for (pot = 1; pot < 32; pot <<= 1) pgtblsz = pgtblsz | (pgtblsz >> pot); pgtblsz++; /* The maximum size is 1MB. */ if (pgtblsz > 1048576) return (ENOMEM); /* Make sure the size is a valid (mappable) page size. */ if (pgtblsz == 32*1024 || pgtblsz == 128*1024 || pgtblsz == 512*1024) pgtblsz <<= 1; /* Allocate naturally aligned memory. */ pgtbl = (void *)ia64_platform_alloc(0, pgtblsz); if (pgtbl == NULL) return (ENOMEM); /* Initialize new page table. */ if (ia64_pgtbl != NULL && ia64_pgtbl != pgtbl) bcopy(ia64_pgtbl, pgtbl, ia64_pgtblsz); bzero(pgtbl + (ia64_pgtblsz >> 3), pgtblsz - ia64_pgtblsz); if (ia64_pgtbl != NULL && ia64_pgtbl != pgtbl) ia64_platform_free(0, (uintptr_t)ia64_pgtbl, ia64_pgtblsz); ia64_pgtbl = pgtbl; ia64_pgtblsz = pgtblsz; return (0); } -static void * -va2pa(vm_offset_t va, size_t *len) +void * +ia64_va2pa(vm_offset_t va, size_t *len) { uint64_t pa; u_int idx, ofs; int error; /* Backward compatibility. */ if (va >= IA64_RR_BASE(7)) { + ia64_legacy_kernel = 1; pa = IA64_RR_MASK(va); return ((void *)pa); } if (va < IA64_PBVM_BASE) { error = EINVAL; goto fail; } + ia64_legacy_kernel = 0; + idx = (va - IA64_PBVM_BASE) >> IA64_PBVM_PAGE_SHIFT; if (idx >= (ia64_pgtblsz >> 3)) { error = pgtbl_extend(idx); if (error) goto fail; } ofs = va & IA64_PBVM_PAGE_MASK; pa = ia64_pgtbl[idx]; if (pa == 0) { pa = ia64_platform_alloc(va - ofs, IA64_PBVM_PAGE_SIZE); if (pa == 0) { error = ENOMEM; goto fail; } ia64_pgtbl[idx] = pa; } pa += ofs; /* We can not cross page boundaries (in general). */ if (*len + ofs > IA64_PBVM_PAGE_SIZE) *len = IA64_PBVM_PAGE_SIZE - ofs; return ((void *)pa); fail: *len = 0; return (NULL); } ssize_t ia64_copyin(const void *src, vm_offset_t va, size_t len) { void *pa; ssize_t res; size_t sz; res = 0; while (len > 0) { sz = len; - pa = va2pa(va, &sz); + pa = ia64_va2pa(va, &sz); if (sz == 0) break; bcopy(src, pa, sz); len -= sz; res += sz; va += sz; } return (res); } ssize_t ia64_copyout(vm_offset_t va, void *dst, size_t len) { void *pa; ssize_t res; size_t sz; res = 0; while (len > 0) { sz = len; - pa = va2pa(va, &sz); + pa = ia64_va2pa(va, &sz); if (sz == 0) break; bcopy(pa, dst, sz); len -= sz; res += sz; va += sz; } return (res); } +uint64_t +ia64_loadaddr(u_int type, void *data, uint64_t addr) +{ + uint64_t align; + + /* + * Align ELF objects at PBVM page boundaries. Align all other + * objects at cache line boundaries for good measure. + */ + align = (type == LOAD_ELF) ? IA64_PBVM_PAGE_SIZE : CACHE_LINE_SIZE; + return ((addr + align - 1) & ~(align - 1)); +} + ssize_t ia64_readin(int fd, vm_offset_t va, size_t len) { void *pa; ssize_t res, s; size_t sz; res = 0; while (len > 0) { sz = len; - pa = va2pa(va, &sz); + pa = ia64_va2pa(va, &sz); if (sz == 0) break; s = read(fd, pa, sz); if (s <= 0) break; len -= s; res += s; va += s; } return (res); } Index: head/sys/boot/ia64/common/exec.c =================================================================== --- head/sys/boot/ia64/common/exec.c (revision 220312) +++ head/sys/boot/ia64/common/exec.c (revision 220313) @@ -1,213 +1,266 @@ /*- * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include -#include - #include #include #include "libia64.h" +static u_int itr_idx = 0; +static u_int dtr_idx = 0; + +static vm_offset_t ia64_text_start; +static size_t ia64_text_size; + +static vm_offset_t ia64_data_start; +static size_t ia64_data_size; + static int elf64_exec(struct preloaded_file *amp); static int elf64_obj_exec(struct preloaded_file *amp); static struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; static struct file_format ia64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; struct file_format *file_formats[] = { &ia64_elf, &ia64_elf_obj, NULL }; +static u_int +sz2shft(vm_offset_t ofs, vm_size_t sz) +{ + vm_size_t s; + u_int shft; + + shft = 12; /* Start with 4K */ + s = 1 << shft; + while (s < sz) { + shft++; + s <<= 1; + } + do { + shft--; + s >>= 1; + } while (ofs & (s - 1)); + + return (shft); +} + /* * Entered with psr.ic and psr.i both zero. */ static void enter_kernel(uint64_t start, struct bootinfo *bi) { __asm __volatile("srlz.i;;"); __asm __volatile("mov cr.ipsr=%0" :: "r"(IA64_PSR_IC | IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_IT | IA64_PSR_BN)); __asm __volatile("mov cr.iip=%0" :: "r"(start)); __asm __volatile("mov cr.ifs=r0;;"); __asm __volatile("mov ar.rsc=0;; flushrs;;"); __asm __volatile("mov r8=%0" :: "r" (bi)); __asm __volatile("rfi;;"); /* NOTREACHED */ } -static void -mmu_wire(vm_offset_t va, vm_paddr_t pa, vm_size_t sz, u_int acc) +static u_int +mmu_wire(vm_offset_t va, vm_paddr_t pa, u_int pgshft, u_int acc) { - static u_int iidx = 0, didx = 0; pt_entry_t pte; - u_int shft; /* Round up to the smallest possible page size. */ - if (sz < 4096) - sz = 4096; - /* Determine the exponent (base 2). */ - shft = 0; - while (sz > 1) { - shft++; - sz >>= 1; - } + if (pgshft < 12) + pgshft = 12; /* Truncate to the largest possible page size (256MB). */ - if (shft > 28) - shft = 28; + if (pgshft > 28) + pgshft = 28; /* Round down to a valid (mappable) page size. */ - if (shft > 14 && (shft & 1) != 0) - shft--; + if (pgshft > 14 && (pgshft & 1) != 0) + pgshft--; pte = PTE_PRESENT | PTE_MA_WB | PTE_ACCESSED | PTE_DIRTY | PTE_PL_KERN | (acc & PTE_AR_MASK) | (pa & PTE_PPN_MASK); __asm __volatile("mov cr.ifa=%0" :: "r"(va)); - __asm __volatile("mov cr.itir=%0" :: "r"(shft << 2)); + __asm __volatile("mov cr.itir=%0" :: "r"(pgshft << 2)); __asm __volatile("srlz.d;;"); - __asm __volatile("ptr.d %0,%1" :: "r"(va), "r"(shft << 2)); + __asm __volatile("ptr.d %0,%1" :: "r"(va), "r"(pgshft << 2)); __asm __volatile("srlz.d;;"); - __asm __volatile("itr.d dtr[%0]=%1" :: "r"(didx), "r"(pte)); + __asm __volatile("itr.d dtr[%0]=%1" :: "r"(dtr_idx), "r"(pte)); __asm __volatile("srlz.d;;"); - didx++; + dtr_idx++; - if (acc == PTE_AR_RWX) { - __asm __volatile("ptr.i %0,%1;;" :: "r"(va), "r"(shft << 2)); + if (acc == PTE_AR_RWX || acc == PTE_AR_RX) { + __asm __volatile("ptr.i %0,%1;;" :: "r"(va), "r"(pgshft << 2)); __asm __volatile("srlz.i;;"); - __asm __volatile("itr.i itr[%0]=%1;;" :: "r"(iidx), "r"(pte)); + __asm __volatile("itr.i itr[%0]=%1;;" :: "r"(itr_idx), "r"(pte)); __asm __volatile("srlz.i;;"); - iidx++; + itr_idx++; } + + return (pgshft); } static void mmu_setup_legacy(uint64_t entry) { /* * Region 6 is direct mapped UC and region 7 is direct mapped * WC. The details of this is controlled by the Alt {I,D}TLB * handlers. Here we just make sure that they have the largest * possible page size to minimise TLB usage. */ ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2)); ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2)); __asm __volatile("srlz.i;;"); - mmu_wire(entry, IA64_RR_MASK(entry), 1UL << 28, PTE_AR_RWX); + mmu_wire(entry, IA64_RR_MASK(entry), 28, PTE_AR_RWX); } static void -mmu_setup_paged(vm_offset_t pbvm_top) +mmu_setup_paged(struct bootinfo *bi) { - vm_size_t sz; + void *pa; + size_t sz; + u_int shft; ia64_set_rr(IA64_RR_BASE(IA64_PBVM_RR), (IA64_PBVM_RR << 8) | (IA64_PBVM_PAGE_SHIFT << 2)); __asm __volatile("srlz.i;;"); /* Wire the PBVM page table. */ - mmu_wire(IA64_PBVM_PGTBL, (uintptr_t)ia64_pgtbl, ia64_pgtblsz, - PTE_AR_RW); + mmu_wire(IA64_PBVM_PGTBL, (uintptr_t)ia64_pgtbl, + sz2shft(IA64_PBVM_PGTBL, ia64_pgtblsz), PTE_AR_RW); - /* Wire as much of the PBVM we can. This must be a power of 2. */ - sz = pbvm_top - IA64_PBVM_BASE; - sz = (sz + IA64_PBVM_PAGE_MASK) & ~IA64_PBVM_PAGE_MASK; - while (sz & (sz - 1)) - sz -= IA64_PBVM_PAGE_SIZE; - mmu_wire(IA64_PBVM_BASE, ia64_pgtbl[0], sz, PTE_AR_RWX); + /* Wire as much of the text segment as we can. */ + sz = ia64_text_size; /* XXX */ + pa = ia64_va2pa(ia64_text_start, &ia64_text_size); + ia64_text_size = sz; /* XXX */ + shft = sz2shft(ia64_text_start, ia64_text_size); + shft = mmu_wire(ia64_text_start, (uintptr_t)pa, shft, PTE_AR_RX); + ia64_copyin(&shft, (uintptr_t)&bi->bi_text_mapped, 4); + + /* Wire as much of the data segment as well. */ + sz = ia64_data_size; /* XXX */ + pa = ia64_va2pa(ia64_data_start, &ia64_data_size); + ia64_data_size = sz; /* XXX */ + shft = sz2shft(ia64_data_start, ia64_data_size); + shft = mmu_wire(ia64_data_start, (uintptr_t)pa, shft, PTE_AR_RW); + ia64_copyin(&shft, (uintptr_t)&bi->bi_data_mapped, 4); + + /* Update the bootinfo with the number of TRs used. */ + ia64_copyin(&itr_idx, (uintptr_t)&bi->bi_itr_used, 4); + ia64_copyin(&dtr_idx, (uintptr_t)&bi->bi_dtr_used, 4); } static int elf64_exec(struct preloaded_file *fp) { struct bootinfo *bi; struct file_metadata *md; Elf_Ehdr *hdr; int error; md = file_findmetadata(fp, MODINFOMD_ELFHDR); if (md == NULL) return (EINVAL); error = ia64_bootinfo(fp, &bi); if (error) return (error); hdr = (Elf_Ehdr *)&(md->md_data); printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry); error = ia64_platform_enter(fp->f_name); if (error) return (error); __asm __volatile("rsm psr.ic|psr.i;;"); __asm __volatile("srlz.i;;"); if (IS_LEGACY_KERNEL()) mmu_setup_legacy(hdr->e_entry); else - mmu_setup_paged((uintptr_t)(bi + 1)); + mmu_setup_paged(bi); enter_kernel(hdr->e_entry, bi); /* NOTREACHED */ return (EDOOFUS); } static int elf64_obj_exec(struct preloaded_file *fp) { printf("%s called for preloaded file %p (=%s):\n", __func__, fp, fp->f_name); return (ENOSYS); } + +void +ia64_loadseg(Elf_Ehdr *eh, Elf_Phdr *ph, uint64_t delta) +{ + + if (eh->e_type != ET_EXEC) + return; + + if (ph->p_flags & PF_X) { + ia64_text_start = ph->p_vaddr + delta; + ia64_text_size = ph->p_memsz; + } else { + ia64_data_start = ph->p_vaddr + delta; + ia64_data_size = ph->p_memsz; + } +} + Index: head/sys/boot/ia64/common/libia64.h =================================================================== --- head/sys/boot/ia64/common/libia64.h (revision 220312) +++ head/sys/boot/ia64/common/libia64.h (revision 220313) @@ -1,65 +1,74 @@ /*- * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _LIBIA64_H_ #define _LIBIA64_H_ #include #include -#include +#include -#define IS_LEGACY_KERNEL() (ia64_pgtbl == NULL || ia64_pgtblsz == 0) +#define IS_LEGACY_KERNEL() (ia64_legacy_kernel) /* * Portability functions provided by the loader * implementation specific to the platform. */ vm_paddr_t ia64_platform_alloc(vm_offset_t, vm_size_t); void ia64_platform_free(vm_offset_t, vm_paddr_t, vm_size_t); int ia64_platform_bootinfo(struct bootinfo *, struct bootinfo **); int ia64_platform_enter(const char *); /* * Functions and variables provided by the ia64 common code * and shared by all loader implementations. */ +extern u_int ia64_legacy_kernel; + extern uint64_t *ia64_pgtbl; extern uint32_t ia64_pgtblsz; int ia64_autoload(void); int ia64_bootinfo(struct preloaded_file *, struct bootinfo **); +uint64_t ia64_loadaddr(u_int, void *, uint64_t); +#ifdef __elfN +void ia64_loadseg(Elf_Ehdr *, Elf_Phdr *, uint64_t); +#else +void ia64_loadseg(void *, void *, uint64_t); +#endif ssize_t ia64_copyin(const void *, vm_offset_t, size_t); ssize_t ia64_copyout(vm_offset_t, void *, size_t); ssize_t ia64_readin(int, vm_offset_t, size_t); +void *ia64_va2pa(vm_offset_t, size_t *); char *ia64_fmtdev(struct devdesc *); int ia64_getdev(void **, const char *, const char **); int ia64_setcurrdev(struct env_var *, int, const void *); #endif /* !_LIBIA64_H_ */ Index: head/sys/boot/ia64/efi/main.c =================================================================== --- head/sys/boot/ia64/efi/main.c (revision 220312) +++ head/sys/boot/ia64/efi/main.c (revision 220313) @@ -1,585 +1,587 @@ /*- * Copyright (c) 1998 Michael Smith * Copyright (c) 1998,2000 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include /* DIG64 Headless Console & Debug Port Table. */ #define HCDP_TABLE_GUID \ {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}} extern char bootprog_name[]; extern char bootprog_rev[]; extern char bootprog_date[]; extern char bootprog_maker[]; struct arch_switch archsw; /* MI/MD interface boundary */ extern u_int64_t ia64_pal_entry; EFI_GUID acpi = ACPI_TABLE_GUID; EFI_GUID acpi20 = ACPI_20_TABLE_GUID; EFI_GUID devid = DEVICE_PATH_PROTOCOL; EFI_GUID hcdp = HCDP_TABLE_GUID; EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; EFI_GUID mps = MPS_TABLE_GUID; EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; EFI_GUID sal = SAL_SYSTEM_TABLE_GUID; EFI_GUID smbios = SMBIOS_TABLE_GUID; static void find_pal_proc(void) { int i; struct sal_system_table *saltab = 0; static int sizes[6] = { 48, 32, 16, 32, 16, 16 }; u_int8_t *p; saltab = efi_get_table(&sal); if (saltab == NULL) { printf("Can't find SAL System Table\n"); return; } if (memcmp(saltab->sal_signature, "SST_", 4)) { printf("Bad signature for SAL System Table\n"); return; } p = (u_int8_t *) (saltab + 1); for (i = 0; i < saltab->sal_entry_count; i++) { if (*p == 0) { struct sal_entrypoint_descriptor *dp; dp = (struct sal_entrypoint_descriptor *) p; ia64_pal_entry = dp->sale_pal_proc; return; } p += sizes[*p]; } printf("Can't find PAL proc\n"); return; } static int usc2cmp(CHAR16 *s1, CHAR16 *s2) { while (*s1 == *s2++) { if (*s1++ == 0) return (0); } return (*s1 - *(s2 - 1)); } static char * get_dev_option(int argc, CHAR16 *argv[]) { static char dev[32]; CHAR16 *arg; char *devp; int i, j; devp = NULL; for (i = 0; i < argc; i++) { if (usc2cmp(argv[i], L"-dev") == 0 && i < argc - 1) { arg = argv[i + 1]; j = 0; while (j < sizeof(dev) && *arg != 0) dev[j++] = *arg++; if (j == sizeof(dev)) j--; dev[j] = '\0'; devp = dev; break; } } return (devp); } EFI_STATUS main(int argc, CHAR16 *argv[]) { struct devdesc currdev; EFI_LOADED_IMAGE *img; char *dev; int i; /* * XXX Chicken-and-egg problem; we want to have console output * early, but some console attributes may depend on reading from * eg. the boot device, which we can't do yet. We can use * printf() etc. once this is done. */ cons_probe(); printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); find_pal_proc(); /* * March through the device switch probing for things. */ for (i = 0; devsw[i] != NULL; i++) if (devsw[i]->dv_init != NULL) (devsw[i]->dv_init)(); /* * Disable the watchdog timer. By default the boot manager sets * the timer to 5 minutes before invoking a boot option. If we * want to return to the boot manager, we have to disable the * watchdog timer and since we're an interactive program, we don't * want to wait until the user types "quit". The timer may have * fired by then. We don't care if this fails. It does not prevent * normal functioning in any way... */ BS->SetWatchdogTimer(0, 0, 0, NULL); /* Get our loaded image protocol interface structure. */ BS->HandleProtocol(IH, &imgid, (VOID**)&img); bzero(&currdev, sizeof(currdev)); efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit); currdev.d_type = currdev.d_dev->dv_type; env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset, env_nounset); dev = get_dev_option(argc, argv); if (dev == NULL) dev = ia64_fmtdev(&currdev); env_setenv("currdev", EV_VOLATILE, dev, ia64_setcurrdev, env_nounset); setenv("LINES", "24", 1); /* optional */ archsw.arch_autoload = ia64_autoload; - archsw.arch_getdev = ia64_getdev; archsw.arch_copyin = ia64_copyin; archsw.arch_copyout = ia64_copyout; + archsw.arch_getdev = ia64_getdev; + archsw.arch_loadaddr = ia64_loadaddr; + archsw.arch_loadseg = ia64_loadseg; archsw.arch_readin = ia64_readin; interact(); /* doesn't return */ return (EFI_SUCCESS); /* keep compiler happy */ } COMMAND_SET(quit, "quit", "exit the loader", command_quit); static int command_quit(int argc, char *argv[]) { exit(0); return (CMD_OK); } COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); static int command_memmap(int argc, char *argv[]) { UINTN sz; EFI_MEMORY_DESCRIPTOR *map, *p; UINTN key, dsz; UINT32 dver; EFI_STATUS status; int i, ndesc; static char *types[] = { "Reserved", "LoaderCode", "LoaderData", "BootServicesCode", "BootServicesData", "RuntimeServicesCode", "RuntimeServicesData", "ConventionalMemory", "UnusableMemory", "ACPIReclaimMemory", "ACPIMemoryNVS", "MemoryMappedIO", "MemoryMappedIOPortSpace", "PalCode" }; sz = 0; status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); if (status != EFI_BUFFER_TOO_SMALL) { printf("Can't determine memory map size\n"); return CMD_ERROR; } map = malloc(sz); status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); if (EFI_ERROR(status)) { printf("Can't read memory map\n"); return CMD_ERROR; } ndesc = sz / dsz; printf("%23s %12s %12s %8s %4s\n", "Type", "Physical", "Virtual", "#Pages", "Attr"); for (i = 0, p = map; i < ndesc; i++, p = NextMemoryDescriptor(p, dsz)) { printf("%23s %012lx %012lx %08lx ", types[p->Type], p->PhysicalStart, p->VirtualStart, p->NumberOfPages); if (p->Attribute & EFI_MEMORY_UC) printf("UC "); if (p->Attribute & EFI_MEMORY_WC) printf("WC "); if (p->Attribute & EFI_MEMORY_WT) printf("WT "); if (p->Attribute & EFI_MEMORY_WB) printf("WB "); if (p->Attribute & EFI_MEMORY_UCE) printf("UCE "); if (p->Attribute & EFI_MEMORY_WP) printf("WP "); if (p->Attribute & EFI_MEMORY_RP) printf("RP "); if (p->Attribute & EFI_MEMORY_XP) printf("XP "); if (p->Attribute & EFI_MEMORY_RUNTIME) printf("RUNTIME"); printf("\n"); } return CMD_OK; } COMMAND_SET(configuration, "configuration", "print configuration tables", command_configuration); static const char * guid_to_string(EFI_GUID *guid) { static char buf[40]; sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); return (buf); } static int command_configuration(int argc, char *argv[]) { int i; printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries); for (i = 0; i < ST->NumberOfTableEntries; i++) { EFI_GUID *guid; printf(" "); guid = &ST->ConfigurationTable[i].VendorGuid; if (!memcmp(guid, &mps, sizeof(EFI_GUID))) printf("MPS Table"); else if (!memcmp(guid, &acpi, sizeof(EFI_GUID))) printf("ACPI Table"); else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID))) printf("ACPI 2.0 Table"); else if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) printf("SMBIOS Table"); else if (!memcmp(guid, &sal, sizeof(EFI_GUID))) printf("SAL System Table"); else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID))) printf("DIG64 HCDP Table"); else printf("Unknown Table (%s)", guid_to_string(guid)); printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); } return CMD_OK; } COMMAND_SET(sal, "sal", "print SAL System Table", command_sal); static int command_sal(int argc, char *argv[]) { int i; struct sal_system_table *saltab = 0; static int sizes[6] = { 48, 32, 16, 32, 16, 16 }; u_int8_t *p; saltab = efi_get_table(&sal); if (saltab == NULL) { printf("Can't find SAL System Table\n"); return CMD_ERROR; } if (memcmp(saltab->sal_signature, "SST_", 4)) { printf("Bad signature for SAL System Table\n"); return CMD_ERROR; } printf("SAL Revision %x.%02x\n", saltab->sal_rev[1], saltab->sal_rev[0]); printf("SAL A Version %x.%02x\n", saltab->sal_a_version[1], saltab->sal_a_version[0]); printf("SAL B Version %x.%02x\n", saltab->sal_b_version[1], saltab->sal_b_version[0]); p = (u_int8_t *) (saltab + 1); for (i = 0; i < saltab->sal_entry_count; i++) { printf(" Desc %d", *p); if (*p == 0) { struct sal_entrypoint_descriptor *dp; dp = (struct sal_entrypoint_descriptor *) p; printf("\n"); printf(" PAL Proc at 0x%lx\n", dp->sale_pal_proc); printf(" SAL Proc at 0x%lx\n", dp->sale_sal_proc); printf(" SAL GP at 0x%lx\n", dp->sale_sal_gp); } else if (*p == 1) { struct sal_memory_descriptor *dp; dp = (struct sal_memory_descriptor *) p; printf(" Type %d.%d, ", dp->sale_memory_type[0], dp->sale_memory_type[1]); printf("Address 0x%lx, ", dp->sale_physical_address); printf("Length 0x%x\n", dp->sale_length); } else if (*p == 5) { struct sal_ap_wakeup_descriptor *dp; dp = (struct sal_ap_wakeup_descriptor *) p; printf("\n"); printf(" Mechanism %d\n", dp->sale_mechanism); printf(" Vector 0x%lx\n", dp->sale_vector); } else printf("\n"); p += sizes[*p]; } return CMD_OK; } int print_trs(int type) { struct ia64_pal_result res; int i, maxtr; struct { pt_entry_t pte; uint64_t itir; uint64_t ifa; struct ia64_rr rr; } buf; static const char *psnames[] = { "1B", "2B", "4B", "8B", "16B", "32B", "64B", "128B", "256B", "512B", "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", "1G", "2G" }; static const char *manames[] = { "WB", "bad", "bad", "bad", "UC", "UCE", "WC", "NaT", }; res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0); if (res.pal_status != 0) { printf("Can't get VM summary\n"); return CMD_ERROR; } if (type == 0) maxtr = (res.pal_result[0] >> 40) & 0xff; else maxtr = (res.pal_result[0] >> 32) & 0xff; printf("%d translation registers\n", maxtr); pager_open(); pager_output("TR# RID Virtual Page Physical Page PgSz ED AR PL D A MA P KEY\n"); for (i = 0; i <= maxtr; i++) { char lbuf[128]; bzero(&buf, sizeof(buf)); res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type, (u_int64_t) &buf); if (res.pal_status != 0) break; /* Only display valid translations */ if ((buf.ifa & 1) == 0) continue; if (!(res.pal_result[0] & 1)) buf.pte &= ~PTE_AR_MASK; if (!(res.pal_result[0] & 2)) buf.pte &= ~PTE_PL_MASK; if (!(res.pal_result[0] & 4)) buf.pte &= ~PTE_DIRTY; if (!(res.pal_result[0] & 8)) buf.pte &= ~PTE_MA_MASK; sprintf(lbuf, "%03d %06x %013lx %013lx %4s %d %d %d %d %d " "%-3s %d %06x\n", i, buf.rr.rr_rid, buf.ifa >> 12, (buf.pte & PTE_PPN_MASK) >> 12, psnames[(buf.itir & ITIR_PS_MASK) >> 2], (buf.pte & PTE_ED) ? 1 : 0, (int)(buf.pte & PTE_AR_MASK) >> 9, (int)(buf.pte & PTE_PL_MASK) >> 7, (buf.pte & PTE_DIRTY) ? 1 : 0, (buf.pte & PTE_ACCESSED) ? 1 : 0, manames[(buf.pte & PTE_MA_MASK) >> 2], (buf.pte & PTE_PRESENT) ? 1 : 0, (int)((buf.itir & ITIR_KEY_MASK) >> 8)); pager_output(lbuf); } pager_close(); if (res.pal_status != 0) { printf("Error while getting TR contents\n"); return CMD_ERROR; } return CMD_OK; } COMMAND_SET(itr, "itr", "print instruction TRs", command_itr); static int command_itr(int argc, char *argv[]) { return print_trs(0); } COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr); static int command_dtr(int argc, char *argv[]) { return print_trs(1); } COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp); static char * hcdp_string(char *s, u_int len) { static char buffer[256]; memcpy(buffer, s, len); buffer[len] = 0; return (buffer); } static int command_hcdp(int argc, char *argv[]) { struct dig64_hcdp_table *tbl; struct dig64_hcdp_entry *ent; struct dig64_gas *gas; int i; tbl = efi_get_table(&hcdp); if (tbl == NULL) { printf("No HCDP table present\n"); return (CMD_OK); } if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) { printf("HCDP table has invalid signature\n"); return (CMD_OK); } if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) { printf("HCDP table too short\n"); return (CMD_OK); } printf("HCDP table at 0x%016lx\n", (u_long)tbl); printf("Signature = %s\n", hcdp_string(tbl->signature, 4)); printf("Length = %u\n", tbl->length); printf("Revision = %u\n", tbl->revision); printf("Checksum = %u\n", tbl->checksum); printf("OEM Id = %s\n", hcdp_string(tbl->oem_id, 6)); printf("Table Id = %s\n", hcdp_string(tbl->oem_tbl_id, 8)); printf("OEM rev = %u\n", tbl->oem_rev); printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4)); printf("Creator rev= %u\n", tbl->creator_rev); printf("Entries = %u\n", tbl->entries); for (i = 0; i < tbl->entries; i++) { ent = tbl->entry + i; printf("Entry #%d:\n", i + 1); printf(" Type = %u\n", ent->type); printf(" Databits = %u\n", ent->databits); printf(" Parity = %u\n", ent->parity); printf(" Stopbits = %u\n", ent->stopbits); printf(" PCI seg = %u\n", ent->pci_segment); printf(" PCI bus = %u\n", ent->pci_bus); printf(" PCI dev = %u\n", ent->pci_device); printf(" PCI func = %u\n", ent->pci_function); printf(" Interrupt = %u\n", ent->interrupt); printf(" PCI flag = %u\n", ent->pci_flag); printf(" Baudrate = %lu\n", ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low); gas = &ent->address; printf(" Addr space= %u\n", gas->addr_space); printf(" Bit width = %u\n", gas->bit_width); printf(" Bit offset= %u\n", gas->bit_offset); printf(" Address = 0x%016lx\n", ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low); printf(" PCI type = %u\n", ent->pci_devid); printf(" PCI vndr = %u\n", ent->pci_vendor); printf(" IRQ = %u\n", ent->irq); printf(" PClock = %u\n", ent->pclock); printf(" PCI iface = %u\n", ent->pci_interface); } printf("\n"); return (CMD_OK); } Index: head/sys/boot/ia64/ski/efi_stub.c =================================================================== --- head/sys/boot/ia64/ski/efi_stub.c (revision 220312) +++ head/sys/boot/ia64/ski/efi_stub.c (revision 220313) @@ -1,259 +1,259 @@ /*- * Copyright (c) 2003,2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include +#include #include -#include #include #include "libski.h" extern void acpi_root; extern void sal_systab; struct efi_cfgtbl efi_cfgtab[] = { { EFI_TABLE_ACPI20, (intptr_t)&acpi_root }, { EFI_TABLE_SAL, (intptr_t)&sal_systab } }; static efi_status GetTime(struct efi_tm *, struct efi_tmcap *); static efi_status SetTime(struct efi_tm *); static efi_status GetWakeupTime(uint8_t *, uint8_t *, struct efi_tm *); static efi_status SetWakeupTime(uint8_t, struct efi_tm *); static efi_status SetVirtualAddressMap(u_long, u_long, uint32_t, struct efi_md*); static efi_status ConvertPointer(u_long, void **); static efi_status GetVariable(efi_char *, struct uuid *, uint32_t *, u_long *, void *); static efi_status GetNextVariableName(u_long *, efi_char *, struct uuid *); static efi_status SetVariable(efi_char *, struct uuid *, uint32_t, u_long, void *); static efi_status GetNextHighMonotonicCount(uint32_t *); static efi_status ResetSystem(enum efi_reset, efi_status, u_long, efi_char *); struct efi_rt efi_rttab = { /* Header. */ { 0, /* XXX Signature */ 0, /* XXX Revision */ 0, /* XXX HeaderSize */ 0, /* XXX CRC32 */ }, /* Time services */ GetTime, SetTime, GetWakeupTime, SetWakeupTime, /* Virtual memory services */ SetVirtualAddressMap, ConvertPointer, /* Variable services */ GetVariable, GetNextVariableName, SetVariable, /* Misc */ GetNextHighMonotonicCount, ResetSystem }; struct efi_systbl efi_systab = { /* Header. */ { EFI_SYSTBL_SIG, 0, /* XXX Revision */ 0, /* XXX HeaderSize */ 0, /* XXX CRC32 */ }, /* Firmware info. */ L"FreeBSD", 0, 0, /* Console stuff. */ NULL, NULL, NULL, NULL, NULL, NULL, /* Services (runtime first). */ (intptr_t)&efi_rttab, NULL, /* Configuration tables. */ sizeof(efi_cfgtab)/sizeof(struct efi_cfgtbl), (intptr_t)efi_cfgtab }; static efi_status unsupported(const char *func) { printf("EFI: %s not supported\n", func); return ((1UL << 63) + 3); } static efi_status GetTime(struct efi_tm *time, struct efi_tmcap *caps) { uint32_t comps[8]; ssc((uint64_t)comps, 0, 0, 0, SSC_GET_RTC); time->tm_year = comps[0] + 1900; time->tm_mon = comps[1] + 1; time->tm_mday = comps[2]; time->tm_hour = comps[3]; time->tm_min = comps[4]; time->tm_sec = comps[5]; time->__pad1 = time->__pad2 = 0; time->tm_nsec = 0; time->tm_tz = 0; time->tm_dst = 0; return (0); } static efi_status SetTime(struct efi_tm *time) { return (0); } static efi_status GetWakeupTime(uint8_t *enabled, uint8_t *pending, struct efi_tm *time) { return (unsupported(__func__)); } static efi_status SetWakeupTime(uint8_t enable, struct efi_tm *time) { return (unsupported(__func__)); } static void Reloc(void *addr, uint64_t delta) { uint64_t **fpp = addr; *fpp[0] += delta; *fpp[1] += delta; *fpp += delta >> 3; } static efi_status SetVirtualAddressMap(u_long mapsz, u_long descsz, uint32_t version, struct efi_md *memmap) { uint64_t delta; delta = (uintptr_t)memmap->md_virt - memmap->md_phys; Reloc(&efi_rttab.rt_gettime, delta); Reloc(&efi_rttab.rt_settime, delta); return (0); /* Hah... */ } static efi_status ConvertPointer(u_long debug, void **addr) { return (unsupported(__func__)); } static efi_status GetVariable(efi_char *name, struct uuid *vendor, uint32_t *attrs, u_long *datasz, void *data) { return (unsupported(__func__)); } static efi_status GetNextVariableName(u_long *namesz, efi_char *name, struct uuid *vendor) { return (unsupported(__func__)); } static efi_status SetVariable(efi_char *name, struct uuid *vendor, uint32_t attrs, u_long datasz, void *data) { return (unsupported(__func__)); } static efi_status GetNextHighMonotonicCount(uint32_t *high) { static uint32_t counter = 0; *high = counter++; return (0); } static efi_status ResetSystem(enum efi_reset type, efi_status status, u_long datasz, efi_char *data) { return (unsupported(__func__)); } void efi_stub_init(struct bootinfo *bi) { static struct efi_md memmap[4]; /* Describe the SKI memory map. */ bi->bi_memmap = (uintptr_t)(void *)memmap; bi->bi_memmap_size = sizeof(memmap); bi->bi_memdesc_size = sizeof(struct efi_md); bi->bi_memdesc_version = 1; memmap[0].md_type = EFI_MD_TYPE_PALCODE; memmap[0].md_phys = 0x100000; memmap[0].md_virt = NULL; memmap[0].md_pages = (1L*1024*1024)>>12; memmap[0].md_attr = EFI_MD_ATTR_WB | EFI_MD_ATTR_RT; memmap[1].md_type = EFI_MD_TYPE_FREE; memmap[1].md_phys = 4L*1024*1024; memmap[1].md_virt = NULL; memmap[1].md_pages = (128L*1024*1024)>>12; memmap[1].md_attr = EFI_MD_ATTR_WB; memmap[2].md_type = EFI_MD_TYPE_FREE; memmap[2].md_phys = 4L*1024*1024*1024; memmap[2].md_virt = NULL; memmap[2].md_pages = (64L*1024*1024)>>12; memmap[2].md_attr = EFI_MD_ATTR_WB; memmap[3].md_type = EFI_MD_TYPE_IOPORT; memmap[3].md_phys = 0xffffc000000; memmap[3].md_virt = NULL; memmap[3].md_pages = (64L*1024*1024)>>12; memmap[3].md_attr = EFI_MD_ATTR_UC; bi->bi_systab = (u_int64_t)&efi_systab; } Index: head/sys/boot/ia64/ski/main.c =================================================================== --- head/sys/boot/ia64/ski/main.c (revision 220312) +++ head/sys/boot/ia64/ski/main.c (revision 220313) @@ -1,119 +1,121 @@ /*- * Copyright (c) 1998 Michael Smith * Copyright (c) 1998,2000 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "libski.h" extern char bootprog_name[]; extern char bootprog_rev[]; extern char bootprog_date[]; extern char bootprog_maker[]; struct devdesc currdev; /* our current device */ struct arch_switch archsw; /* MI/MD interface boundary */ void ski_main(void) { static char malloc[512*1024]; int i; /* * initialise the heap as early as possible. Once this is done, * alloc() is usable. The stack is buried inside us, so this is * safe. */ setheap((void *)malloc, (void *)(malloc + 512*1024)); /* * XXX Chicken-and-egg problem; we want to have console output * early, but some console attributes may depend on reading from * eg. the boot device, which we can't do yet. We can use * printf() etc. once this is done. */ cons_probe(); /* * March through the device switch probing for things. */ for (i = 0; devsw[i] != NULL; i++) if (devsw[i]->dv_init != NULL) (devsw[i]->dv_init)(); printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); #if 0 printf("Memory: %ld k\n", memsize() / 1024); #endif /* XXX presumes that biosdisk is first in devsw */ currdev.d_dev = devsw[0]; currdev.d_type = currdev.d_dev->dv_type; currdev.d_unit = 0; #if 0 /* Create arc-specific variables */ bootfile = GetEnvironmentVariable(ARCENV_BOOTFILE); if (bootfile) setenv("bootfile", bootfile, 1); #endif env_setenv("currdev", EV_VOLATILE, ia64_fmtdev(&currdev), ia64_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset, env_nounset); setenv("LINES", "24", 1); /* optional */ - + archsw.arch_autoload = ia64_autoload; - archsw.arch_getdev = ia64_getdev; archsw.arch_copyin = ia64_copyin; archsw.arch_copyout = ia64_copyout; + archsw.arch_getdev = ia64_getdev; + archsw.arch_loadaddr = ia64_loadaddr; + archsw.arch_loadseg = ia64_loadseg; archsw.arch_readin = ia64_readin; interact(); /* doesn't return */ exit(0); } COMMAND_SET(quit, "quit", "exit the loader", command_quit); static int command_quit(int argc, char *argv[]) { exit(0); return (CMD_OK); } Index: head/sys/ia64/include/bootinfo.h =================================================================== --- head/sys/ia64/include/bootinfo.h (revision 220312) +++ head/sys/ia64/include/bootinfo.h (revision 220313) @@ -1,51 +1,55 @@ /* $FreeBSD$ */ /*- * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ struct bootinfo { uint64_t bi_magic; /* BOOTINFO_MAGIC */ #define BOOTINFO_MAGIC 0xdeadbeeffeedface uint64_t bi_version; /* version 1 */ - uint64_t bi_spare[5]; /* was: name of booted kernel */ + uint64_t bi_spare[3]; /* was: name of booted kernel */ + uint32_t bi_itr_used; /* Number of ITR and DTR ... */ + uint32_t bi_dtr_used; /* ... entries used. */ + uint32_t bi_text_mapped; /* Size of text mapped. */ + uint32_t bi_data_mapped; /* Size of data mapped. */ uint64_t bi_pbvm_pgtbl; /* PA of PBVM page table. */ uint64_t bi_hcdp; /* DIG64 HCDP table */ uint64_t bi_fpswa; /* FPSWA interface */ uint64_t bi_boothowto; /* value for boothowto */ uint64_t bi_systab; /* pa of EFI system table */ uint64_t bi_memmap; /* pa of EFI memory map */ uint64_t bi_memmap_size; /* size of EFI memory map */ uint64_t bi_memdesc_size; /* sizeof EFI memory desc */ uint32_t bi_memdesc_version; /* EFI memory desc version */ uint32_t bi_pbvm_pgtblsz; /* PBVM page table size. */ uint64_t bi_symtab; /* start of kernel sym table */ uint64_t bi_esymtab; /* end of kernel sym table */ uint64_t bi_kernend; /* end of kernel space */ uint64_t bi_envp; /* environment */ uint64_t bi_modulep; /* preloaded modules */ }; extern struct bootinfo *bootinfo;