efi_stub.c revision 135699
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 135699 2004-09-24 04:35:07Z 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 39extern void acpi_stub_init(void); 40extern void sal_stub_init(void); 41 42struct efi_cfgtbl efi_cfgtab[] = { 43 { EFI_TABLE_ACPI20, (intptr_t)&acpi_root }, 44 { EFI_TABLE_SAL, (intptr_t)&sal_systab } 45}; 46 47static efi_status GetTime(struct efi_tm *, struct efi_tmcap *); 48static efi_status SetTime(struct efi_tm *); 49static efi_status GetWakeupTime(uint8_t *, uint8_t *, struct efi_tm *); 50static efi_status SetWakeupTime(uint8_t, struct efi_tm *); 51 52static efi_status SetVirtualAddressMap(u_long, u_long, uint32_t, 53 struct efi_md*); 54static efi_status ConvertPointer(u_long, void **); 55 56static efi_status GetVariable(efi_char *, struct uuid *, uint32_t *, u_long *, 57 void *); 58static efi_status GetNextVariableName(u_long *, efi_char *, struct uuid *); 59static efi_status SetVariable(efi_char *, struct uuid *, uint32_t, u_long, 60 void *); 61 62static efi_status GetNextHighMonotonicCount(uint32_t *); 63static efi_status ResetSystem(enum efi_reset, efi_status, u_long, efi_char *); 64 65struct efi_rt efi_rttab = { 66 /* Header. */ 67 { 0, /* XXX Signature */ 68 0, /* XXX Revision */ 69 0, /* XXX HeaderSize */ 70 0, /* XXX CRC32 */ 71 }, 72 73 /* Time services */ 74 GetTime, 75 SetTime, 76 GetWakeupTime, 77 SetWakeupTime, 78 79 /* Virtual memory services */ 80 SetVirtualAddressMap, 81 ConvertPointer, 82 83 /* Variable services */ 84 GetVariable, 85 GetNextVariableName, 86 SetVariable, 87 88 /* Misc */ 89 GetNextHighMonotonicCount, 90 ResetSystem 91}; 92 93struct efi_systbl efi_systab = { 94 /* Header. */ 95 { EFI_SYSTBL_SIG, 96 0, /* XXX Revision */ 97 0, /* XXX HeaderSize */ 98 0, /* XXX CRC32 */ 99 }, 100 101 /* Firmware info. */ 102 L"FreeBSD", 0, 0, 103 104 /* Console stuff. */ 105 NULL, NULL, 106 NULL, NULL, 107 NULL, NULL, 108 109 /* Services (runtime first). */ 110 (intptr_t)&efi_rttab, 111 NULL, 112 113 /* Configuration tables. */ 114 sizeof(efi_cfgtab)/sizeof(struct efi_cfgtbl), 115 (intptr_t)efi_cfgtab 116}; 117 118static efi_status 119unsupported(const char *func) 120{ 121 printf("EFI: %s not supported\n", func); 122 return ((1UL << 63) + 3); 123} 124 125static efi_status 126GetTime(struct efi_tm *time, struct efi_tmcap *caps) 127{ 128 uint32_t comps[8]; 129 130 ssc((uint64_t)comps, 0, 0, 0, SSC_GET_RTC); 131 time->tm_year = comps[0] + 1900; 132 time->tm_mon = comps[1] + 1; 133 time->tm_mday = comps[2]; 134 time->tm_hour = comps[3]; 135 time->tm_min = comps[4]; 136 time->tm_sec = comps[5]; 137 time->__pad1 = time->__pad2 = 0; 138 time->tm_nsec = 0; 139 time->tm_tz = 0; 140 time->tm_dst = 0; 141 return (0); 142} 143 144static efi_status 145SetTime(struct efi_tm *time) 146{ 147 return (0); 148} 149 150static efi_status 151GetWakeupTime(uint8_t *enabled, uint8_t *pending, struct efi_tm *time) 152{ 153 return (unsupported(__func__)); 154} 155 156static efi_status 157SetWakeupTime(uint8_t enable, struct efi_tm *time) 158{ 159 return (unsupported(__func__)); 160} 161 162static void 163Reloc(void *addr, uint64_t delta) 164{ 165 uint64_t **fpp = addr; 166 167 *fpp[0] += delta; 168 *fpp[1] += delta; 169 *fpp += delta >> 3; 170} 171 172static efi_status 173SetVirtualAddressMap(u_long mapsz, u_long descsz, uint32_t version, 174 struct efi_md *memmap) 175{ 176 uint64_t delta; 177 178 delta = (uintptr_t)memmap->md_virt - memmap->md_phys; 179 Reloc(&efi_rttab.rt_gettime, delta); 180 Reloc(&efi_rttab.rt_settime, delta); 181 return (0); /* Hah... */ 182} 183 184static efi_status 185ConvertPointer(u_long debug, void **addr) 186{ 187 return (unsupported(__func__)); 188} 189 190static efi_status 191GetVariable(efi_char *name, struct uuid *vendor, uint32_t *attrs, 192 u_long *datasz, void *data) 193{ 194 return (unsupported(__func__)); 195} 196 197static efi_status 198GetNextVariableName(u_long *namesz, efi_char *name, struct uuid *vendor) 199{ 200 return (unsupported(__func__)); 201} 202 203static efi_status 204SetVariable(efi_char *name, struct uuid *vendor, uint32_t attrs, u_long datasz, 205 void *data) 206{ 207 return (unsupported(__func__)); 208} 209 210static efi_status 211GetNextHighMonotonicCount(uint32_t *high) 212{ 213 static uint32_t counter = 0; 214 215 *high = counter++; 216 return (0); 217} 218 219static efi_status 220ResetSystem(enum efi_reset type, efi_status status, u_long datasz, 221 efi_char *data) 222{ 223 return (unsupported(__func__)); 224} 225 226int 227ski_init_stubs(struct bootinfo *bi) 228{ 229 struct efi_md *memp; 230 231 /* Describe the SKI memory map. */ 232 bi->bi_memmap = (u_int64_t)(bi + 1); 233 bi->bi_memmap_size = 4 * sizeof(struct efi_md); 234 bi->bi_memdesc_size = sizeof(struct efi_md); 235 bi->bi_memdesc_version = 1; 236 237 memp = (struct efi_md *)bi->bi_memmap; 238 239 memp[0].md_type = EFI_MD_TYPE_PALCODE; 240 memp[0].md_phys = 0x100000; 241 memp[0].md_virt = NULL; 242 memp[0].md_pages = (4L*1024*1024)>>12; 243 memp[0].md_attr = EFI_MD_ATTR_WB | EFI_MD_ATTR_RT; 244 245 memp[1].md_type = EFI_MD_TYPE_FREE; 246 memp[1].md_phys = 5L*1024*1024; 247 memp[1].md_virt = NULL; 248 memp[1].md_pages = (128L*1024*1024)>>12; 249 memp[1].md_attr = EFI_MD_ATTR_WB; 250 251 memp[2].md_type = EFI_MD_TYPE_FREE; 252 memp[2].md_phys = 4L*1024*1024*1024; 253 memp[2].md_virt = NULL; 254 memp[2].md_pages = (64L*1024*1024)>>12; 255 memp[2].md_attr = EFI_MD_ATTR_WB; 256 257 memp[3].md_type = EFI_MD_TYPE_IOPORT; 258 memp[3].md_phys = 0xffffc000000; 259 memp[3].md_virt = NULL; 260 memp[3].md_pages = (64L*1024*1024)>>12; 261 memp[3].md_attr = EFI_MD_ATTR_UC; 262 263 bi->bi_systab = (u_int64_t)&efi_systab; 264 265 sal_stub_init(); 266 acpi_stub_init(); 267 268 return (0); 269} 270