Home | History | Annotate | Line # | Download | only in ski
      1 /*	$NetBSD: efi_stub.c,v 1.7 2022/08/21 10:30:54 riastradh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2003,2004 Marcel Moolenaar
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     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 ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 /* __FBSDID("$FreeBSD: src/sys/boot/ia64/libski/efi_stub.c,v 1.2 2003/09/08 09:11:32 obrien Exp $"); */
     31 
     32 
     33 #include <sys/types.h>
     34 #include <sys/stdint.h>
     35 
     36 #include <machine/bootinfo.h>
     37 #include <machine/efi.h>
     38 #include <lib/libsa/stand.h>
     39 #include <lib/libsa/loadfile.h>
     40 #include <bootstrap.h>
     41 
     42 #include "libski.h"
     43 
     44 extern char acpi_root[];
     45 extern char sal_systab[];
     46 
     47 extern void acpi_stub_init(void);
     48 extern void sal_stub_init(void);
     49 
     50 struct efi_cfgtbl efi_cfgtab[] = {
     51 	{ .ct_uuid = EFI_TABLE_ACPI20,	.ct_data = &acpi_root },
     52 	{ .ct_uuid = EFI_TABLE_SAL,	.ct_data = &sal_systab },
     53 };
     54 
     55 static efi_status GetTime(struct efi_tm *, struct efi_tmcap *);
     56 static efi_status SetTime(struct efi_tm *);
     57 static efi_status GetWakeupTime(uint8_t *, uint8_t *, struct efi_tm *);
     58 static efi_status SetWakeupTime(uint8_t, struct efi_tm *);
     59 
     60 static efi_status SetVirtualAddressMap(u_long, u_long, uint32_t,
     61     struct efi_md*);
     62 static efi_status ConvertPointer(u_long, void **);
     63 
     64 static efi_status GetVariable(efi_char *, struct uuid *, uint32_t *, u_long *,
     65     void *);
     66 static efi_status GetNextVariableName(u_long *, efi_char *, struct uuid *);
     67 static efi_status SetVariable(efi_char *, struct uuid *, uint32_t, u_long,
     68     void *);
     69 
     70 static efi_status GetNextHighMonotonicCount(uint32_t *);
     71 static efi_status ResetSystem(enum efi_reset, efi_status, u_long, efi_char *);
     72 
     73 struct efi_rt efi_rttab = {
     74 	/* Header. */
     75 	.rt_hdr = {
     76 		.th_sig = 0,		/* XXX Signature */
     77 		.th_rev = 0,		/* XXX Revision */
     78 		.th_hdrsz = 0,		/* XXX HeaderSize */
     79 		.th_crc32 = 0,		/* XXX CRC32 */
     80 	},
     81 
     82 	/* Time services */
     83 	.rt_gettime = GetTime,
     84 	.rt_settime = SetTime,
     85 	.rt_getwaketime = GetWakeupTime,
     86 	.rt_setwaketime = SetWakeupTime,
     87 
     88 	/* Virtual memory services */
     89 	.rt_setvirtual = SetVirtualAddressMap,
     90 	.rt_cvtptr = ConvertPointer,
     91 
     92 	/* Variable services */
     93 	.rt_getvar = GetVariable,
     94 	.rt_scanvar = GetNextVariableName,
     95 	.rt_setvar = SetVariable,
     96 
     97 	/* Misc */
     98 	.rt_gethicnt = GetNextHighMonotonicCount,
     99 	.rt_reset = ResetSystem
    100 };
    101 
    102 struct efi_systbl efi_systab = {
    103 	/* Header. */
    104 	.st_hdr = {
    105 		.th_sig = EFI_SYSTBL_SIG,
    106 		.th_rev = 0,		/* XXX Revision */
    107 		.th_hdrsz = 0,		/* XXX HeaderSize */
    108 		.th_crc32 = 0,		/* XXX CRC32 */
    109 	},
    110 
    111 	/* Firmware info. */
    112 	.st_fwvendor = L"FreeBSD", .st_fwrev = 0, .__pad = 0,
    113 
    114 	/* Console stuff. */
    115 	.st_cin = NULL, .st_cinif = NULL,
    116 	.st_cout = NULL, .st_coutif = NULL,
    117 	.st_cerr = NULL, .st_cerrif = NULL,
    118 
    119 	/* Services (runtime first). */
    120 	.st_rt = &efi_rttab,
    121 	.st_bs = NULL,
    122 
    123 	/* Configuration tables. */
    124 	.st_entries = sizeof(efi_cfgtab)/sizeof(struct efi_cfgtbl),
    125 	.st_cfgtbl = efi_cfgtab,
    126 };
    127 
    128 static efi_status
    129 unsupported(const char *func)
    130 {
    131 	printf("EFI: %s not supported\n", func);
    132 	return ((1UL << 63) + 3);
    133 }
    134 
    135 static efi_status
    136 GetTime(struct efi_tm *time, struct efi_tmcap *caps)
    137 {
    138 	uint32_t comps[8];
    139 
    140 	ssc((uint64_t)comps, 0, 0, 0, SSC_GET_RTC);
    141 	time->tm_year = comps[0] + 1900;
    142 	time->tm_mon = comps[1] + 1;
    143 	time->tm_mday = comps[2];
    144 	time->tm_hour = comps[3];
    145 	time->tm_min = comps[4];
    146 	time->tm_sec = comps[5];
    147 	time->__pad1 = time->__pad2 = 0;
    148 	time->tm_nsec = 0;
    149 	time->tm_tz = 0;
    150 	time->tm_dst = 0;
    151 	return (0);
    152 }
    153 
    154 static efi_status
    155 SetTime(struct efi_tm *time)
    156 {
    157 	return (0);
    158 }
    159 
    160 static efi_status
    161 GetWakeupTime(uint8_t *enabled, uint8_t *pending, struct efi_tm *time)
    162 {
    163 	return (unsupported(__func__));
    164 }
    165 
    166 static efi_status
    167 SetWakeupTime(uint8_t enable, struct efi_tm *time)
    168 {
    169 	return (unsupported(__func__));
    170 }
    171 
    172 static void
    173 Reloc(void *addr, uint64_t delta)
    174 {
    175 	uint64_t **fpp = addr;
    176 
    177 	*fpp[0] += delta;
    178 	*fpp[1] += delta;
    179 	*fpp += delta >> 3;
    180 }
    181 
    182 static efi_status
    183 SetVirtualAddressMap(u_long mapsz, u_long descsz, uint32_t version,
    184     struct efi_md *memmap)
    185 {
    186 	uint64_t delta;
    187 
    188 	delta = memmap->md_virt - memmap->md_phys;
    189 	Reloc(&efi_rttab.rt_gettime, delta);
    190 	Reloc(&efi_rttab.rt_settime, delta);
    191 	return (0);		/* Hah... */
    192 }
    193 
    194 static efi_status
    195 ConvertPointer(u_long debug, void **addr)
    196 {
    197 	return (unsupported(__func__));
    198 }
    199 
    200 static efi_status
    201 GetVariable(efi_char *name, struct uuid *vendor, uint32_t *attrs,
    202     u_long *datasz, void *data)
    203 {
    204 	return (unsupported(__func__));
    205 }
    206 
    207 static efi_status
    208 GetNextVariableName(u_long *namesz, efi_char *name, struct uuid *vendor)
    209 {
    210 	return (unsupported(__func__));
    211 }
    212 
    213 static efi_status
    214 SetVariable(efi_char *name, struct uuid *vendor, uint32_t attrs, u_long datasz,
    215     void *data)
    216 {
    217 	return (unsupported(__func__));
    218 }
    219 
    220 static efi_status
    221 GetNextHighMonotonicCount(uint32_t *high)
    222 {
    223 	static uint32_t counter = 0;
    224 
    225 	*high = counter++;
    226 	return (0);
    227 }
    228 
    229 static efi_status
    230 ResetSystem(enum efi_reset type, efi_status status, u_long datasz,
    231     efi_char *data)
    232 {
    233 	return (unsupported(__func__));
    234 }
    235 
    236 int
    237 ski_init_stubs(struct bootinfo *bi)
    238 {
    239 	struct efi_md *memp;
    240 
    241 	/* Describe the SKI memory map. */
    242 	bi->bi_memmap = (u_int64_t)(bi + 1);
    243 	bi->bi_memmap_size = 4 * sizeof(struct efi_md);
    244 	bi->bi_memdesc_size = sizeof(struct efi_md);
    245 	bi->bi_memdesc_version = 1;
    246 
    247 	memp = (struct efi_md *)bi->bi_memmap;
    248 
    249 	memp[0].md_type = EFI_MD_TYPE_PALCODE;
    250 	memp[0].md_phys = 0x100000;
    251 	memp[0].md_virt = 0;
    252 	memp[0].md_pages = (4L*1024*1024)>>12;
    253 	memp[0].md_attr = EFI_MD_ATTR_WB | EFI_MD_ATTR_RT;
    254 
    255 	memp[1].md_type = EFI_MD_TYPE_FREE;
    256 	memp[1].md_phys = 5L*1024*1024;
    257 	memp[1].md_virt = 0;
    258 	memp[1].md_pages = (128L*1024*1024)>>12;
    259 	memp[1].md_attr = EFI_MD_ATTR_WB;
    260 
    261 	memp[2].md_type = EFI_MD_TYPE_FREE;
    262 	memp[2].md_phys = 4L*1024*1024*1024;
    263 	memp[2].md_virt = 0;
    264 	memp[2].md_pages = (64L*1024*1024)>>12;
    265 	memp[2].md_attr = EFI_MD_ATTR_WB;
    266 
    267 	memp[3].md_type = EFI_MD_TYPE_IOPORT;
    268 	memp[3].md_phys = 0xffffc000000;
    269 	memp[3].md_virt = 0;
    270 	memp[3].md_pages = (64L*1024*1024)>>12;
    271 	memp[3].md_attr = EFI_MD_ATTR_UC;
    272 
    273 	bi->bi_systab = (u_int64_t)&efi_systab;
    274 
    275 	sal_stub_init();
    276 	acpi_stub_init();
    277 
    278 	return (0);
    279 }
    280