Home | History | Annotate | Line # | Download | only in ia64
      1 /*	$NetBSD: efi.c,v 1.5 2022/08/20 10:55:03 riastradh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2004 Marcel Moolenaar
      5  * Copyright (c) 2001 Doug Rabson
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #include <sys/cdefs.h>
     31 #include <sys/param.h>
     32 #include <sys/systm.h>
     33 #include <sys/lock.h>
     34 
     35 #include <machine/bootinfo.h>
     36 #include <machine/efi.h>
     37 #include <machine/sal.h>
     38 #include <machine/vmparam.h>
     39 
     40 extern uint64_t ia64_call_efi_physical(uint64_t, uint64_t, uint64_t, uint64_t,
     41     uint64_t, uint64_t);
     42 
     43 static struct efi_systbl *efi_systbl;
     44 static struct efi_cfgtbl *efi_cfgtbl;
     45 static struct efi_rt *efi_runtime;
     46 
     47 void
     48 efi_boot_finish(void)
     49 {
     50 }
     51 
     52 /*
     53  * Collect the entry points for PAL and SAL. Be extra careful about NULL
     54  * pointer values. We're running pre-console, so it's better to return
     55  * error values than to cause panics, machine checks and other traps and
     56  * faults. Keep this minimal...
     57  */
     58 int
     59 efi_boot_minimal(uint64_t systbl)
     60 {
     61 	struct efi_md *md;
     62 	efi_status status;
     63 
     64 	if (systbl == 0)
     65 		return (EINVAL);
     66 	efi_systbl = (struct efi_systbl *)IA64_PHYS_TO_RR7(systbl);
     67 	if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) {
     68 		efi_systbl = NULL;
     69 		return (EFAULT);
     70 	}
     71 	efi_cfgtbl = (efi_systbl->st_cfgtbl == NULL) ? NULL :
     72 	    (struct efi_cfgtbl *)IA64_PHYS_TO_RR7(
     73 		(uint64_t)efi_systbl->st_cfgtbl);
     74 	if (efi_cfgtbl == NULL)
     75 		return (ENOENT);
     76 	efi_runtime = (efi_systbl->st_rt == NULL) ? NULL :
     77 	    (struct efi_rt *)IA64_PHYS_TO_RR7((uint64_t)efi_systbl->st_rt);
     78 	if (efi_runtime == NULL)
     79 		return (ENOENT);
     80 
     81 	/*
     82 	 * Relocate runtime memory segments for firmware.
     83 	 */
     84 	md = efi_md_first();
     85 	while (md != NULL) {
     86 		if (md->md_attr & EFI_MD_ATTR_RT) {
     87 			if (md->md_attr & EFI_MD_ATTR_WB)
     88 				md->md_virt =
     89 				    (uint64_t)IA64_PHYS_TO_RR7(md->md_phys);
     90 			else if (md->md_attr & EFI_MD_ATTR_UC)
     91 				md->md_virt =
     92 				    (uint64_t)IA64_PHYS_TO_RR6(md->md_phys);
     93 		}
     94 		md = efi_md_next(md);
     95 	}
     96 	status = ia64_call_efi_physical((uint64_t)efi_runtime->rt_setvirtual,
     97 	    bootinfo.bi_memmap_size, bootinfo.bi_memdesc_size,
     98 	    bootinfo.bi_memdesc_version, bootinfo.bi_memmap, 0);
     99 	return ((status < 0) ? EFAULT : 0);
    100 }
    101 
    102 void *
    103 efi_get_table(struct uuid *uuid)
    104 {
    105 	struct efi_cfgtbl *ct;
    106 	u_long count;
    107 
    108 	if (efi_cfgtbl == NULL)
    109 		return (NULL);
    110 	count = efi_systbl->st_entries;
    111 	ct = efi_cfgtbl;
    112 	while (count--) {
    113 		if (!memcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) {
    114 			uint64_t data_pa = (uint64_t)(uintptr_t)ct->ct_data;
    115 			return ((void *)IA64_PHYS_TO_RR7(data_pa));
    116 		}
    117 		ct++;
    118 	}
    119 	return (NULL);
    120 }
    121 
    122 void
    123 efi_get_time(struct efi_tm *tm)
    124 {
    125 
    126 	efi_runtime->rt_gettime(tm, NULL);
    127 }
    128 
    129 struct efi_md *
    130 efi_md_first(void)
    131 {
    132 
    133 	if (bootinfo.bi_memmap == 0)
    134 		return (NULL);
    135 	return ((struct efi_md *)IA64_PHYS_TO_RR7(bootinfo.bi_memmap));
    136 }
    137 
    138 struct efi_md *
    139 efi_md_next(struct efi_md *md)
    140 {
    141 	uint64_t plim;
    142 
    143 	plim = IA64_PHYS_TO_RR7(bootinfo.bi_memmap + bootinfo.bi_memmap_size);
    144 	md = (struct efi_md *)((uintptr_t)md + bootinfo.bi_memdesc_size);
    145 	return ((md >= (struct efi_md *)plim) ? NULL : md);
    146 }
    147 
    148 void
    149 efi_reset_system(void)
    150 {
    151 
    152 	if (efi_runtime != NULL)
    153 		efi_runtime->rt_reset(EFI_RESET_WARM, 0, 0, NULL);
    154 	panic("%s: unable to reset the machine", __func__);
    155 }
    156 
    157 efi_status
    158 efi_set_time(struct efi_tm *tm)
    159 {
    160 
    161 	return (efi_runtime->rt_settime(tm));
    162 }
    163