main.c revision 83857
1/*- 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3 * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 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 AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#ifndef lint 29static const char rcsid[] = 30 "$FreeBSD: head/sys/boot/ia64/efi/main.c 83857 2001-09-23 10:28:01Z dfr $"; 31#endif /* not lint */ 32 33#include <stand.h> 34#include <string.h> 35#include <setjmp.h> 36#include <machine/sal.h> 37 38#include <efi.h> 39#include <efilib.h> 40 41#include "bootstrap.h" 42#include "efiboot.h" 43 44extern char bootprog_name[]; 45extern char bootprog_rev[]; 46extern char bootprog_date[]; 47extern char bootprog_maker[]; 48 49struct efi_devdesc currdev; /* our current device */ 50struct arch_switch archsw; /* MI/MD interface boundary */ 51 52EFI_STATUS 53efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) 54{ 55 int i; 56 EFI_PHYSICAL_ADDRESS mem; 57 58 efi_init(image_handle, system_table); 59 60 /* 61 * Initialise the heap as early as possible. Once this is done, 62 * alloc() is usable. The stack is buried inside us, so this is 63 * safe. 64 */ 65 BS->AllocatePages(AllocateAnyPages, EfiLoaderData, 66 512*1024/4096, &mem); 67 setheap((void *)mem, (void *)(mem + 512*1024)); 68 69 /* 70 * XXX Chicken-and-egg problem; we want to have console output 71 * early, but some console attributes may depend on reading from 72 * eg. the boot device, which we can't do yet. We can use 73 * printf() etc. once this is done. 74 */ 75 cons_probe(); 76 77 /* 78 * Initialise the block cache 79 */ 80 bcache_init(32, 512); /* 16k XXX tune this */ 81 82 /* 83 * March through the device switch probing for things. 84 */ 85 for (i = 0; devsw[i] != NULL; i++) 86 if (devsw[i]->dv_init != NULL) 87 (devsw[i]->dv_init)(); 88 89 efinet_init_driver(); 90 91 printf("\n"); 92 printf("%s, Revision %s\n", bootprog_name, bootprog_rev); 93 printf("(%s, %s)\n", bootprog_maker, bootprog_date); 94#if 0 95 printf("Memory: %ld k\n", memsize() / 1024); 96#endif 97 98 /* XXX presumes that biosdisk is first in devsw */ 99 currdev.d_dev = devsw[0]; 100 currdev.d_type = currdev.d_dev->dv_type; 101 currdev.d_kind.efidisk.unit = 0; 102 /* XXX should be able to detect this, default to autoprobe */ 103 currdev.d_kind.efidisk.slice = -1; 104 /* default to 'a' */ 105 currdev.d_kind.efidisk.partition = 0; 106 107#if 0 108 /* Create arc-specific variables */ 109 bootfile = GetEnvironmentVariable(ARCENV_BOOTFILE); 110 if (bootfile) 111 setenv("bootfile", bootfile, 1); 112#endif 113 114 env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), 115 efi_setcurrdev, env_nounset); 116 env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, 117 env_nounset); 118 119 setenv("LINES", "24", 1); /* optional */ 120 121 archsw.arch_autoload = efi_autoload; 122 archsw.arch_getdev = efi_getdev; 123 archsw.arch_copyin = efi_copyin; 124 archsw.arch_copyout = efi_copyout; 125 archsw.arch_readin = efi_readin; 126 127 interact(); /* doesn't return */ 128 129 return (EFI_SUCCESS); /* keep compiler happy */ 130} 131 132COMMAND_SET(quit, "quit", "exit the loader", command_quit); 133 134static int 135command_quit(int argc, char *argv[]) 136{ 137 exit(0); 138 return (CMD_OK); 139} 140 141COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); 142 143static int 144command_memmap(int argc, char *argv[]) 145{ 146 UINTN sz; 147 EFI_MEMORY_DESCRIPTOR *map, *p; 148 UINTN key, dsz; 149 UINT32 dver; 150 EFI_STATUS status; 151 int i, ndesc; 152 static char *types[] = { 153 "Reserved", 154 "LoaderCode", 155 "LoaderData", 156 "BootServicesCode", 157 "BootServicesData", 158 "RuntimeServicesCode", 159 "RuntimeServicesData", 160 "ConventionalMemory", 161 "UnusableMemory", 162 "ACPIReclaimMemory", 163 "ACPIMemoryNVS", 164 "MemoryMappedIO", 165 "MemoryMappedIOPortSpace", 166 "PalCode" 167 }; 168 169 sz = 0; 170 status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); 171 if (status != EFI_BUFFER_TOO_SMALL) { 172 printf("Can't determine memory map size\n"); 173 return CMD_ERROR; 174 } 175 map = malloc(sz); 176 status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); 177 if (EFI_ERROR(status)) { 178 printf("Can't read memory map\n"); 179 return CMD_ERROR; 180 } 181 182 ndesc = sz / dsz; 183 printf("%23s %12s %12s %8s %4s\n", 184 "Type", "Physical", "Virtual", "#Pages", "Attr"); 185 186 for (i = 0, p = map; i < ndesc; 187 i++, p = NextMemoryDescriptor(p, dsz)) { 188 printf("%23s %012lx %012lx %08lx ", 189 types[p->Type], 190 p->PhysicalStart, 191 p->VirtualStart, 192 p->NumberOfPages); 193 if (p->Attribute & EFI_MEMORY_UC) 194 printf("UC "); 195 if (p->Attribute & EFI_MEMORY_WC) 196 printf("WC "); 197 if (p->Attribute & EFI_MEMORY_WT) 198 printf("WT "); 199 if (p->Attribute & EFI_MEMORY_WB) 200 printf("WB "); 201 if (p->Attribute & EFI_MEMORY_UCE) 202 printf("UCE "); 203 if (p->Attribute & EFI_MEMORY_WP) 204 printf("WP "); 205 if (p->Attribute & EFI_MEMORY_RP) 206 printf("RP "); 207 if (p->Attribute & EFI_MEMORY_XP) 208 printf("XP "); 209 if (p->Attribute & EFI_MEMORY_RUNTIME) 210 printf("RUNTIME"); 211 printf("\n"); 212 } 213 214 return CMD_OK; 215} 216 217COMMAND_SET(configuration, "configuration", 218 "print configuration tables", command_configuration); 219 220static int 221command_configuration(int argc, char *argv[]) 222{ 223 int i; 224 225 printf("NumberOfTableEntries=%d\n", ST->NumberOfTableEntries); 226 for (i = 0; i < ST->NumberOfTableEntries; i++) { 227 static EFI_GUID mps = MPS_TABLE_GUID; 228 static EFI_GUID acpi = ACPI_TABLE_GUID; 229 static EFI_GUID acpi20 = ACPI_20_TABLE_GUID; 230 static EFI_GUID smbios = SMBIOS_TABLE_GUID; 231 static EFI_GUID sal = SAL_SYSTEM_TABLE_GUID; 232 233 printf(" "); 234 if (!memcmp(&ST->ConfigurationTable[i].VendorGuid, 235 &mps, sizeof(EFI_GUID))) 236 printf("MPS Table"); 237 else if (!memcmp(&ST->ConfigurationTable[i].VendorGuid, 238 &acpi, sizeof(EFI_GUID))) 239 printf("ACPI Table"); 240 else if (!memcmp(&ST->ConfigurationTable[i].VendorGuid, 241 &acpi20, sizeof(EFI_GUID))) 242 printf("ACPI 2.0 Table"); 243 else if (!memcmp(&ST->ConfigurationTable[i].VendorGuid, 244 &smbios, sizeof(EFI_GUID))) 245 printf("SMBIOS Table"); 246 else if (!memcmp(&ST->ConfigurationTable[i].VendorGuid, 247 &sal, sizeof(EFI_GUID))) 248 printf("SAL System Table"); 249 else 250 printf("Unknown Table"); 251 printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); 252 } 253 254 return CMD_OK; 255} 256 257COMMAND_SET(sal, "sal", "print SAL System Table", command_sal); 258 259static int 260command_sal(int argc, char *argv[]) 261{ 262 int i; 263 struct sal_system_table *saltab = 0; 264 static int sizes[6] = { 265 48, 32, 16, 32, 16, 16 266 }; 267 u_int8_t *p; 268 269 for (i = 0; i < ST->NumberOfTableEntries; i++) { 270 static EFI_GUID sal = SAL_SYSTEM_TABLE_GUID; 271 if (!memcmp(&ST->ConfigurationTable[i].VendorGuid, 272 &sal, sizeof(EFI_GUID))) 273 saltab = ST->ConfigurationTable[i].VendorTable; 274 } 275 276 if (!saltab) { 277 printf("Can't find SAL System Table\n"); 278 return CMD_ERROR; 279 } 280 281 if (memcmp(saltab->sal_signature, "SST_", 4)) { 282 printf("Bad signature for SAL System Table\n"); 283 return CMD_ERROR; 284 } 285 286 printf("SAL Revision %x.%02x\n", 287 saltab->sal_rev[1], 288 saltab->sal_rev[0]); 289 printf("SAL A Version %x.%02x\n", 290 saltab->sal_a_version[1], 291 saltab->sal_a_version[0]); 292 printf("SAL B Version %x.%02x\n", 293 saltab->sal_b_version[1], 294 saltab->sal_b_version[0]); 295 296 p = (u_int8_t *) (saltab + 1); 297 for (i = 0; i < saltab->sal_entry_count; i++) { 298 printf(" Desc %d", *p); 299 if (*p == 0) { 300 struct sal_entrypoint_descriptor *dp; 301 dp = (struct sal_entrypoint_descriptor *) p; 302 printf("\n"); 303 printf(" PAL Proc at 0x%lx\n", 304 dp->sale_pal_proc); 305 printf(" SAL Proc at 0x%lx\n", 306 dp->sale_sal_proc); 307 printf(" SAL GP at 0x%lx\n", 308 dp->sale_sal_gp); 309 } else if (*p == 1) { 310 struct sal_memory_descriptor *dp; 311 dp = (struct sal_memory_descriptor *) p; 312 printf(" Type %d.%d, ", 313 dp->sale_memory_type[0], 314 dp->sale_memory_type[1]); 315 printf("Address 0x%lx, ", 316 dp->sale_physical_address); 317 printf("Length 0x%x\n", 318 dp->sale_length); 319 } else { 320 printf("\n"); 321 } 322 p += sizes[*p]; 323 } 324 325 return CMD_OK; 326} 327