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 44extern char acpi_root[]; 45extern char sal_systab[]; 46 47extern void acpi_stub_init(void); 48extern void sal_stub_init(void); 49 50struct 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 55static efi_status GetTime(struct efi_tm *, struct efi_tmcap *); 56static efi_status SetTime(struct efi_tm *); 57static efi_status GetWakeupTime(uint8_t *, uint8_t *, struct efi_tm *); 58static efi_status SetWakeupTime(uint8_t, struct efi_tm *); 59 60static efi_status SetVirtualAddressMap(u_long, u_long, uint32_t, 61 struct efi_md*); 62static efi_status ConvertPointer(u_long, void **); 63 64static efi_status GetVariable(efi_char *, struct uuid *, uint32_t *, u_long *, 65 void *); 66static efi_status GetNextVariableName(u_long *, efi_char *, struct uuid *); 67static efi_status SetVariable(efi_char *, struct uuid *, uint32_t, u_long, 68 void *); 69 70static efi_status GetNextHighMonotonicCount(uint32_t *); 71static efi_status ResetSystem(enum efi_reset, efi_status, u_long, efi_char *); 72 73struct 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 102struct 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 128static efi_status 129unsupported(const char *func) 130{ 131 printf("EFI: %s not supported\n", func); 132 return ((1UL << 63) + 3); 133} 134 135static efi_status 136GetTime(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 154static efi_status 155SetTime(struct efi_tm *time) 156{ 157 return (0); 158} 159 160static efi_status 161GetWakeupTime(uint8_t *enabled, uint8_t *pending, struct efi_tm *time) 162{ 163 return (unsupported(__func__)); 164} 165 166static efi_status 167SetWakeupTime(uint8_t enable, struct efi_tm *time) 168{ 169 return (unsupported(__func__)); 170} 171 172static void 173Reloc(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 182static efi_status 183SetVirtualAddressMap(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 194static efi_status 195ConvertPointer(u_long debug, void **addr) 196{ 197 return (unsupported(__func__)); 198} 199 200static efi_status 201GetVariable(efi_char *name, struct uuid *vendor, uint32_t *attrs, 202 u_long *datasz, void *data) 203{ 204 return (unsupported(__func__)); 205} 206 207static efi_status 208GetNextVariableName(u_long *namesz, efi_char *name, struct uuid *vendor) 209{ 210 return (unsupported(__func__)); 211} 212 213static efi_status 214SetVariable(efi_char *name, struct uuid *vendor, uint32_t attrs, u_long datasz, 215 void *data) 216{ 217 return (unsupported(__func__)); 218} 219 220static efi_status 221GetNextHighMonotonicCount(uint32_t *high) 222{ 223 static uint32_t counter = 0; 224 225 *high = counter++; 226 return (0); 227} 228 229static efi_status 230ResetSystem(enum efi_reset type, efi_status status, u_long datasz, 231 efi_char *data) 232{ 233 return (unsupported(__func__)); 234} 235 236int 237ski_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