1191783Srmacklem/*- 2191783Srmacklem * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3191783Srmacklem * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org> 4191783Srmacklem * All rights reserved. 5191783Srmacklem * 6191783Srmacklem * Redistribution and use in source and binary forms, with or without 7191783Srmacklem * modification, are permitted provided that the following conditions 8191783Srmacklem * are met: 9191783Srmacklem * 1. Redistributions of source code must retain the above copyright 10191783Srmacklem * notice, this list of conditions and the following disclaimer. 11191783Srmacklem * 2. Redistributions in binary form must reproduce the above copyright 12191783Srmacklem * notice, this list of conditions and the following disclaimer in the 13191783Srmacklem * documentation and/or other materials provided with the distribution. 14191783Srmacklem * 15191783Srmacklem * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16191783Srmacklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17191783Srmacklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18191783Srmacklem * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19191783Srmacklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20191783Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21191783Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22191783Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23191783Srmacklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24191783Srmacklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25191783Srmacklem * SUCH DAMAGE. 26191783Srmacklem */ 27191783Srmacklem 28191783Srmacklem#include <sys/cdefs.h> 29191783Srmacklem__FBSDID("$FreeBSD$"); 30191783Srmacklem 31191783Srmacklem#include <stand.h> 32191783Srmacklem#include <string.h> 33191783Srmacklem#include <setjmp.h> 34191783Srmacklem#include <machine/sal.h> 35191783Srmacklem#include <machine/pal.h> 36191783Srmacklem#include <machine/pte.h> 37191783Srmacklem#include <machine/dig64.h> 38191783Srmacklem 39191783Srmacklem#include <efi.h> 40191783Srmacklem#include <efilib.h> 41191783Srmacklem 42191783Srmacklem#include <libia64.h> 43191783Srmacklem 44191783Srmacklem/* DIG64 Headless Console & Debug Port Table. */ 45191783Srmacklem#define HCDP_TABLE_GUID \ 46191783Srmacklem {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}} 47191783Srmacklem 48244042Srmacklemextern char bootprog_name[]; 49191783Srmacklemextern char bootprog_rev[]; 50191783Srmacklemextern char bootprog_date[]; 51191783Srmacklemextern char bootprog_maker[]; 52191783Srmacklem 53191783Srmacklemstruct arch_switch archsw; /* MI/MD interface boundary */ 54244042Srmacklem 55191783Srmacklemextern u_int64_t ia64_pal_entry; 56191783Srmacklem 57191783SrmacklemEFI_GUID acpi = ACPI_TABLE_GUID; 58191783SrmacklemEFI_GUID acpi20 = ACPI_20_TABLE_GUID; 59191783SrmacklemEFI_GUID devid = DEVICE_PATH_PROTOCOL; 60191783SrmacklemEFI_GUID hcdp = HCDP_TABLE_GUID; 61191783SrmacklemEFI_GUID imgid = LOADED_IMAGE_PROTOCOL; 62191783SrmacklemEFI_GUID mps = MPS_TABLE_GUID; 63191783SrmacklemEFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; 64191783SrmacklemEFI_GUID sal = SAL_SYSTEM_TABLE_GUID; 65191783SrmacklemEFI_GUID smbios = SMBIOS_TABLE_GUID; 66191783Srmacklem 67192121Srmacklemstatic void 68191783Srmacklemfind_pal_proc(void) 69191783Srmacklem{ 70191783Srmacklem int i; 71191783Srmacklem struct sal_system_table *saltab = 0; 72191783Srmacklem static int sizes[6] = { 73191783Srmacklem 48, 32, 16, 32, 16, 16 74191783Srmacklem }; 75191783Srmacklem u_int8_t *p; 76191783Srmacklem 77191783Srmacklem saltab = efi_get_table(&sal); 78191783Srmacklem if (saltab == NULL) { 79191783Srmacklem printf("Can't find SAL System Table\n"); 80191783Srmacklem return; 81191783Srmacklem } 82191783Srmacklem 83191783Srmacklem if (memcmp(saltab->sal_signature, "SST_", 4)) { 84191783Srmacklem printf("Bad signature for SAL System Table\n"); 85191783Srmacklem return; 86249592Sken } 87191783Srmacklem 88191783Srmacklem p = (u_int8_t *) (saltab + 1); 89191783Srmacklem for (i = 0; i < saltab->sal_entry_count; i++) { 90191783Srmacklem if (*p == 0) { 91191783Srmacklem struct sal_entrypoint_descriptor *dp; 92191783Srmacklem dp = (struct sal_entrypoint_descriptor *) p; 93191783Srmacklem ia64_pal_entry = dp->sale_pal_proc; 94244042Srmacklem return; 95191783Srmacklem } 96192121Srmacklem p += sizes[*p]; 97191783Srmacklem } 98191783Srmacklem 99191783Srmacklem printf("Can't find PAL proc\n"); 100191783Srmacklem return; 101191783Srmacklem} 102192121Srmacklem 103192121Srmacklemstatic int 104191783Srmacklemusc2cmp(CHAR16 *s1, CHAR16 *s2) 105191783Srmacklem{ 106191783Srmacklem 107191783Srmacklem while (*s1 == *s2++) { 108191783Srmacklem if (*s1++ == 0) 109191783Srmacklem return (0); 110191783Srmacklem } 111191783Srmacklem return (*s1 - *(s2 - 1)); 112191783Srmacklem} 113191783Srmacklem 114191783Srmacklemstatic char * 115191783Srmacklemget_dev_option(int argc, CHAR16 *argv[]) 116191783Srmacklem{ 117191783Srmacklem static char dev[32]; 118191783Srmacklem CHAR16 *arg; 119191783Srmacklem char *devp; 120191783Srmacklem int i, j; 121191783Srmacklem 122191783Srmacklem devp = NULL; 123191783Srmacklem for (i = 0; i < argc; i++) { 124191783Srmacklem if (usc2cmp(argv[i], L"-dev") == 0 && i < argc - 1) { 125191783Srmacklem arg = argv[i + 1]; 126191783Srmacklem j = 0; 127191783Srmacklem while (j < sizeof(dev) && *arg != 0) 128191783Srmacklem dev[j++] = *arg++; 129191783Srmacklem if (j == sizeof(dev)) 130191783Srmacklem j--; 131191783Srmacklem dev[j] = '\0'; 132191783Srmacklem devp = dev; 133191783Srmacklem break; 134191783Srmacklem } 135191783Srmacklem } 136191783Srmacklem 137191783Srmacklem return (devp); 138244042Srmacklem} 139191783Srmacklem 140244042SrmacklemEFI_STATUS 141244042Srmacklemmain(int argc, CHAR16 *argv[]) 142191783Srmacklem{ 143191783Srmacklem struct devdesc currdev; 144191783Srmacklem EFI_LOADED_IMAGE *img; 145191783Srmacklem char *dev; 146191783Srmacklem int i; 147191783Srmacklem 148191783Srmacklem /* 149191783Srmacklem * XXX Chicken-and-egg problem; we want to have console output 150191783Srmacklem * early, but some console attributes may depend on reading from 151191783Srmacklem * eg. the boot device, which we can't do yet. We can use 152191783Srmacklem * printf() etc. once this is done. 153191783Srmacklem */ 154191783Srmacklem cons_probe(); 155191783Srmacklem 156191783Srmacklem printf("\n%s, Revision %s\n", bootprog_name, bootprog_rev); 157191783Srmacklem 158191783Srmacklem find_pal_proc(); 159191783Srmacklem 160191783Srmacklem /* 161191783Srmacklem * March through the device switch probing for things. 162191783Srmacklem */ 163191783Srmacklem for (i = 0; devsw[i] != NULL; i++) 164191783Srmacklem if (devsw[i]->dv_init != NULL) 165191783Srmacklem (devsw[i]->dv_init)(); 166191783Srmacklem 167191783Srmacklem /* 168191783Srmacklem * Disable the watchdog timer. By default the boot manager sets 169191783Srmacklem * the timer to 5 minutes before invoking a boot option. If we 170191783Srmacklem * want to return to the boot manager, we have to disable the 171191783Srmacklem * watchdog timer and since we're an interactive program, we don't 172191783Srmacklem * want to wait until the user types "quit". The timer may have 173191783Srmacklem * fired by then. We don't care if this fails. It does not prevent 174191783Srmacklem * normal functioning in any way... 175191783Srmacklem */ 176191783Srmacklem BS->SetWatchdogTimer(0, 0, 0, NULL); 177191783Srmacklem 178191783Srmacklem /* Get our loaded image protocol interface structure. */ 179191783Srmacklem BS->HandleProtocol(IH, &imgid, (VOID**)&img); 180191783Srmacklem 181191783Srmacklem bzero(&currdev, sizeof(currdev)); 182191783Srmacklem efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, 183191783Srmacklem &currdev.d_unit, NULL); 184191783Srmacklem currdev.d_type = currdev.d_dev->dv_type; 185191783Srmacklem 186191783Srmacklem env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset, 187191783Srmacklem env_nounset); 188191783Srmacklem 189191783Srmacklem dev = get_dev_option(argc, argv); 190191783Srmacklem if (dev == NULL) 191191783Srmacklem dev = ia64_fmtdev(&currdev); 192191783Srmacklem 193191783Srmacklem env_setenv("currdev", EV_VOLATILE, dev, ia64_setcurrdev, env_nounset); 194191783Srmacklem 195191783Srmacklem setenv("LINES", "24", 1); /* optional */ 196191783Srmacklem 197194408Srmacklem archsw.arch_autoload = ia64_autoload; 198191783Srmacklem archsw.arch_copyin = ia64_copyin; 199191783Srmacklem archsw.arch_copyout = ia64_copyout; 200191783Srmacklem archsw.arch_getdev = ia64_getdev; 201191783Srmacklem archsw.arch_loadaddr = ia64_loadaddr; 202191783Srmacklem archsw.arch_loadseg = ia64_loadseg; 203191783Srmacklem archsw.arch_readin = ia64_readin; 204191783Srmacklem 205191783Srmacklem interact(); /* doesn't return */ 206191783Srmacklem 207191783Srmacklem return (EFI_SUCCESS); /* keep compiler happy */ 208191783Srmacklem} 209191783Srmacklem 210191783SrmacklemCOMMAND_SET(quit, "quit", "exit the loader", command_quit); 211191783Srmacklem 212191783Srmacklemstatic int 213191783Srmacklemcommand_quit(int argc, char *argv[]) 214191783Srmacklem{ 215191783Srmacklem exit(0); 216191783Srmacklem /* NOTREACHED */ 217191783Srmacklem return (CMD_OK); 218191783Srmacklem} 219191783Srmacklem 220191783SrmacklemCOMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); 221191783Srmacklem 222191783Srmacklemstatic int 223191783Srmacklemcommand_reboot(int argc, char *argv[]) 224191783Srmacklem{ 225191783Srmacklem 226191783Srmacklem RS->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); 227191783Srmacklem /* NOTREACHED */ 228191783Srmacklem return (CMD_OK); 229191783Srmacklem} 230191783Srmacklem 231191783SrmacklemCOMMAND_SET(memmap, "memmap", "print memory map", command_memmap); 232191783Srmacklem 233191783Srmacklemstatic int 234191783Srmacklemcommand_memmap(int argc, char *argv[]) 235191783Srmacklem{ 236191783Srmacklem UINTN sz; 237191783Srmacklem EFI_MEMORY_DESCRIPTOR *map, *p; 238191783Srmacklem UINTN key, dsz; 239191783Srmacklem UINT32 dver; 240191783Srmacklem EFI_STATUS status; 241191783Srmacklem int i, ndesc; 242191783Srmacklem static char *types[] = { 243191783Srmacklem "Reserved", 244191783Srmacklem "LoaderCode", 245191783Srmacklem "LoaderData", 246223309Srmacklem "BootServicesCode", 247191783Srmacklem "BootServicesData", 248191783Srmacklem "RuntimeServicesCode", 249191783Srmacklem "RuntimeServicesData", 250191783Srmacklem "ConventionalMemory", 251191783Srmacklem "UnusableMemory", 252191783Srmacklem "ACPIReclaimMemory", 253191783Srmacklem "ACPIMemoryNVS", 254223309Srmacklem "MemoryMappedIO", 255191783Srmacklem "MemoryMappedIOPortSpace", 256191783Srmacklem "PalCode" 257191783Srmacklem }; 258191783Srmacklem 259191783Srmacklem sz = 0; 260191783Srmacklem status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); 261191783Srmacklem if (status != EFI_BUFFER_TOO_SMALL) { 262191783Srmacklem printf("Can't determine memory map size\n"); 263191783Srmacklem return CMD_ERROR; 264191783Srmacklem } 265191783Srmacklem map = malloc(sz); 266191783Srmacklem status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); 267191783Srmacklem if (EFI_ERROR(status)) { 268191783Srmacklem printf("Can't read memory map\n"); 269191783Srmacklem return CMD_ERROR; 270191783Srmacklem } 271191783Srmacklem 272191783Srmacklem ndesc = sz / dsz; 273191783Srmacklem printf("%23s %12s %12s %8s %4s\n", 274191783Srmacklem "Type", "Physical", "Virtual", "#Pages", "Attr"); 275191783Srmacklem 276191783Srmacklem for (i = 0, p = map; i < ndesc; 277244042Srmacklem i++, p = NextMemoryDescriptor(p, dsz)) { 278244042Srmacklem printf("%23s %012lx %012lx %08lx ", 279244042Srmacklem types[p->Type], 280244042Srmacklem p->PhysicalStart, 281317524Srmacklem p->VirtualStart, 282317524Srmacklem p->NumberOfPages); 283317524Srmacklem if (p->Attribute & EFI_MEMORY_UC) 284317524Srmacklem printf("UC "); 285317524Srmacklem if (p->Attribute & EFI_MEMORY_WC) 286255216Srmacklem printf("WC "); 287255216Srmacklem if (p->Attribute & EFI_MEMORY_WT) 288255216Srmacklem printf("WT "); 289191783Srmacklem if (p->Attribute & EFI_MEMORY_WB) 290255216Srmacklem printf("WB "); 291255216Srmacklem if (p->Attribute & EFI_MEMORY_UCE) 292255216Srmacklem printf("UCE "); 293255216Srmacklem if (p->Attribute & EFI_MEMORY_WP) 294255216Srmacklem printf("WP "); 295255216Srmacklem if (p->Attribute & EFI_MEMORY_RP) 296191783Srmacklem printf("RP "); 297191783Srmacklem if (p->Attribute & EFI_MEMORY_XP) 298 printf("XP "); 299 if (p->Attribute & EFI_MEMORY_RUNTIME) 300 printf("RUNTIME"); 301 printf("\n"); 302 } 303 304 return CMD_OK; 305} 306 307COMMAND_SET(configuration, "configuration", 308 "print configuration tables", command_configuration); 309 310static const char * 311guid_to_string(EFI_GUID *guid) 312{ 313 static char buf[40]; 314 315 sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 316 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], 317 guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], 318 guid->Data4[5], guid->Data4[6], guid->Data4[7]); 319 return (buf); 320} 321 322static int 323command_configuration(int argc, char *argv[]) 324{ 325 int i; 326 327 printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries); 328 for (i = 0; i < ST->NumberOfTableEntries; i++) { 329 EFI_GUID *guid; 330 331 printf(" "); 332 guid = &ST->ConfigurationTable[i].VendorGuid; 333 if (!memcmp(guid, &mps, sizeof(EFI_GUID))) 334 printf("MPS Table"); 335 else if (!memcmp(guid, &acpi, sizeof(EFI_GUID))) 336 printf("ACPI Table"); 337 else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID))) 338 printf("ACPI 2.0 Table"); 339 else if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) 340 printf("SMBIOS Table"); 341 else if (!memcmp(guid, &sal, sizeof(EFI_GUID))) 342 printf("SAL System Table"); 343 else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID))) 344 printf("DIG64 HCDP Table"); 345 else 346 printf("Unknown Table (%s)", guid_to_string(guid)); 347 printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); 348 } 349 350 return CMD_OK; 351} 352 353COMMAND_SET(sal, "sal", "print SAL System Table", command_sal); 354 355static int 356command_sal(int argc, char *argv[]) 357{ 358 int i; 359 struct sal_system_table *saltab = 0; 360 static int sizes[6] = { 361 48, 32, 16, 32, 16, 16 362 }; 363 u_int8_t *p; 364 365 saltab = efi_get_table(&sal); 366 if (saltab == NULL) { 367 printf("Can't find SAL System Table\n"); 368 return CMD_ERROR; 369 } 370 371 if (memcmp(saltab->sal_signature, "SST_", 4)) { 372 printf("Bad signature for SAL System Table\n"); 373 return CMD_ERROR; 374 } 375 376 printf("SAL Revision %x.%02x\n", 377 saltab->sal_rev[1], 378 saltab->sal_rev[0]); 379 printf("SAL A Version %x.%02x\n", 380 saltab->sal_a_version[1], 381 saltab->sal_a_version[0]); 382 printf("SAL B Version %x.%02x\n", 383 saltab->sal_b_version[1], 384 saltab->sal_b_version[0]); 385 386 p = (u_int8_t *) (saltab + 1); 387 for (i = 0; i < saltab->sal_entry_count; i++) { 388 printf(" Desc %d", *p); 389 if (*p == 0) { 390 struct sal_entrypoint_descriptor *dp; 391 dp = (struct sal_entrypoint_descriptor *) p; 392 printf("\n"); 393 printf(" PAL Proc at 0x%lx\n", 394 dp->sale_pal_proc); 395 printf(" SAL Proc at 0x%lx\n", 396 dp->sale_sal_proc); 397 printf(" SAL GP at 0x%lx\n", 398 dp->sale_sal_gp); 399 } else if (*p == 1) { 400 struct sal_memory_descriptor *dp; 401 dp = (struct sal_memory_descriptor *) p; 402 printf(" Type %d.%d, ", 403 dp->sale_memory_type[0], 404 dp->sale_memory_type[1]); 405 printf("Address 0x%lx, ", 406 dp->sale_physical_address); 407 printf("Length 0x%x\n", 408 dp->sale_length); 409 } else if (*p == 5) { 410 struct sal_ap_wakeup_descriptor *dp; 411 dp = (struct sal_ap_wakeup_descriptor *) p; 412 printf("\n"); 413 printf(" Mechanism %d\n", dp->sale_mechanism); 414 printf(" Vector 0x%lx\n", dp->sale_vector); 415 } else 416 printf("\n"); 417 418 p += sizes[*p]; 419 } 420 421 return CMD_OK; 422} 423 424int 425print_trs(int type) 426{ 427 struct ia64_pal_result res; 428 int i, maxtr; 429 struct { 430 pt_entry_t pte; 431 uint64_t itir; 432 uint64_t ifa; 433 struct ia64_rr rr; 434 } buf; 435 static const char *psnames[] = { 436 "1B", "2B", "4B", "8B", 437 "16B", "32B", "64B", "128B", 438 "256B", "512B", "1K", "2K", 439 "4K", "8K", "16K", "32K", 440 "64K", "128K", "256K", "512K", 441 "1M", "2M", "4M", "8M", 442 "16M", "32M", "64M", "128M", 443 "256M", "512M", "1G", "2G" 444 }; 445 static const char *manames[] = { 446 "WB", "bad", "bad", "bad", 447 "UC", "UCE", "WC", "NaT", 448 }; 449 450 res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0); 451 if (res.pal_status != 0) { 452 printf("Can't get VM summary\n"); 453 return CMD_ERROR; 454 } 455 456 if (type == 0) 457 maxtr = (res.pal_result[0] >> 40) & 0xff; 458 else 459 maxtr = (res.pal_result[0] >> 32) & 0xff; 460 461 printf("%d translation registers\n", maxtr); 462 463 pager_open(); 464 pager_output("TR# RID Virtual Page Physical Page PgSz ED AR PL D A MA P KEY\n"); 465 for (i = 0; i <= maxtr; i++) { 466 char lbuf[128]; 467 468 bzero(&buf, sizeof(buf)); 469 res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type, 470 (u_int64_t) &buf); 471 if (res.pal_status != 0) 472 break; 473 474 /* Only display valid translations */ 475 if ((buf.ifa & 1) == 0) 476 continue; 477 478 if (!(res.pal_result[0] & 1)) 479 buf.pte &= ~PTE_AR_MASK; 480 if (!(res.pal_result[0] & 2)) 481 buf.pte &= ~PTE_PL_MASK; 482 if (!(res.pal_result[0] & 4)) 483 buf.pte &= ~PTE_DIRTY; 484 if (!(res.pal_result[0] & 8)) 485 buf.pte &= ~PTE_MA_MASK; 486 sprintf(lbuf, "%03d %06x %013lx %013lx %4s %d %d %d %d %d " 487 "%-3s %d %06x\n", i, buf.rr.rr_rid, buf.ifa >> 12, 488 (buf.pte & PTE_PPN_MASK) >> 12, 489 psnames[(buf.itir & ITIR_PS_MASK) >> 2], 490 (buf.pte & PTE_ED) ? 1 : 0, 491 (int)(buf.pte & PTE_AR_MASK) >> 9, 492 (int)(buf.pte & PTE_PL_MASK) >> 7, 493 (buf.pte & PTE_DIRTY) ? 1 : 0, 494 (buf.pte & PTE_ACCESSED) ? 1 : 0, 495 manames[(buf.pte & PTE_MA_MASK) >> 2], 496 (buf.pte & PTE_PRESENT) ? 1 : 0, 497 (int)((buf.itir & ITIR_KEY_MASK) >> 8)); 498 pager_output(lbuf); 499 } 500 pager_close(); 501 502 if (res.pal_status != 0) { 503 printf("Error while getting TR contents\n"); 504 return CMD_ERROR; 505 } 506 return CMD_OK; 507} 508 509COMMAND_SET(itr, "itr", "print instruction TRs", command_itr); 510 511static int 512command_itr(int argc, char *argv[]) 513{ 514 return print_trs(0); 515} 516 517COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr); 518 519static int 520command_dtr(int argc, char *argv[]) 521{ 522 return print_trs(1); 523} 524 525COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp); 526 527static char * 528hcdp_string(char *s, u_int len) 529{ 530 static char buffer[256]; 531 532 memcpy(buffer, s, len); 533 buffer[len] = 0; 534 return (buffer); 535} 536 537static int 538command_hcdp(int argc, char *argv[]) 539{ 540 struct dig64_hcdp_table *tbl; 541 struct dig64_hcdp_entry *ent; 542 struct dig64_gas *gas; 543 int i; 544 545 tbl = efi_get_table(&hcdp); 546 if (tbl == NULL) { 547 printf("No HCDP table present\n"); 548 return (CMD_OK); 549 } 550 if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) { 551 printf("HCDP table has invalid signature\n"); 552 return (CMD_OK); 553 } 554 if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) { 555 printf("HCDP table too short\n"); 556 return (CMD_OK); 557 } 558 printf("HCDP table at 0x%016lx\n", (u_long)tbl); 559 printf("Signature = %s\n", hcdp_string(tbl->signature, 4)); 560 printf("Length = %u\n", tbl->length); 561 printf("Revision = %u\n", tbl->revision); 562 printf("Checksum = %u\n", tbl->checksum); 563 printf("OEM Id = %s\n", hcdp_string(tbl->oem_id, 6)); 564 printf("Table Id = %s\n", hcdp_string(tbl->oem_tbl_id, 8)); 565 printf("OEM rev = %u\n", tbl->oem_rev); 566 printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4)); 567 printf("Creator rev= %u\n", tbl->creator_rev); 568 printf("Entries = %u\n", tbl->entries); 569 for (i = 0; i < tbl->entries; i++) { 570 ent = tbl->entry + i; 571 printf("Entry #%d:\n", i + 1); 572 printf(" Type = %u\n", ent->type); 573 printf(" Databits = %u\n", ent->databits); 574 printf(" Parity = %u\n", ent->parity); 575 printf(" Stopbits = %u\n", ent->stopbits); 576 printf(" PCI seg = %u\n", ent->pci_segment); 577 printf(" PCI bus = %u\n", ent->pci_bus); 578 printf(" PCI dev = %u\n", ent->pci_device); 579 printf(" PCI func = %u\n", ent->pci_function); 580 printf(" Interrupt = %u\n", ent->interrupt); 581 printf(" PCI flag = %u\n", ent->pci_flag); 582 printf(" Baudrate = %lu\n", 583 ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low); 584 gas = &ent->address; 585 printf(" Addr space= %u\n", gas->addr_space); 586 printf(" Bit width = %u\n", gas->bit_width); 587 printf(" Bit offset= %u\n", gas->bit_offset); 588 printf(" Address = 0x%016lx\n", 589 ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low); 590 printf(" PCI type = %u\n", ent->pci_devid); 591 printf(" PCI vndr = %u\n", ent->pci_vendor); 592 printf(" IRQ = %u\n", ent->irq); 593 printf(" PClock = %u\n", ent->pclock); 594 printf(" PCI iface = %u\n", ent->pci_interface); 595 } 596 printf("<EOT>\n"); 597 return (CMD_OK); 598} 599 600COMMAND_SET(about, "about", "about the loader", command_about); 601 602extern uint64_t _start_plabel[]; 603 604static int 605command_about(int argc, char *argv[]) 606{ 607 EFI_LOADED_IMAGE *img; 608 609 printf("%s\n", bootprog_name); 610 printf("revision %s\n", bootprog_rev); 611 printf("built by %s\n", bootprog_maker); 612 printf("built on %s\n", bootprog_date); 613 614 printf("\n"); 615 616 BS->HandleProtocol(IH, &imgid, (VOID**)&img); 617 printf("image loaded at %p\n", img->ImageBase); 618 printf("entry at %#lx (%#lx)\n", _start_plabel[0], _start_plabel[1]); 619} 620