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