2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3 * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
34 #include <machine/sal.h>
35 #include <machine/pal.h>
36 #include <machine/pte.h>
37 #include <machine/dig64.h>
44 /* DIG64 Headless Console & Debug Port Table. */
45 #define HCDP_TABLE_GUID \
46 {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
48 extern char bootprog_name[];
49 extern char bootprog_rev[];
50 extern char bootprog_date[];
51 extern char bootprog_maker[];
53 struct arch_switch archsw; /* MI/MD interface boundary */
55 extern u_int64_t ia64_pal_entry;
57 EFI_GUID acpi = ACPI_TABLE_GUID;
58 EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
59 EFI_GUID devid = DEVICE_PATH_PROTOCOL;
60 EFI_GUID hcdp = HCDP_TABLE_GUID;
61 EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
62 EFI_GUID mps = MPS_TABLE_GUID;
63 EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
64 EFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
65 EFI_GUID smbios = SMBIOS_TABLE_GUID;
71 struct sal_system_table *saltab = 0;
72 static int sizes[6] = {
73 48, 32, 16, 32, 16, 16
77 saltab = efi_get_table(&sal);
79 printf("Can't find SAL System Table\n");
83 if (memcmp(saltab->sal_signature, "SST_", 4)) {
84 printf("Bad signature for SAL System Table\n");
88 p = (u_int8_t *) (saltab + 1);
89 for (i = 0; i < saltab->sal_entry_count; i++) {
91 struct sal_entrypoint_descriptor *dp;
92 dp = (struct sal_entrypoint_descriptor *) p;
93 ia64_pal_entry = dp->sale_pal_proc;
99 printf("Can't find PAL proc\n");
104 usc2cmp(CHAR16 *s1, CHAR16 *s2)
107 while (*s1 == *s2++) {
111 return (*s1 - *(s2 - 1));
115 get_dev_option(int argc, CHAR16 *argv[])
123 for (i = 0; i < argc; i++) {
124 if (usc2cmp(argv[i], L"-dev") == 0 && i < argc - 1) {
127 while (j < sizeof(dev) && *arg != 0)
129 if (j == sizeof(dev))
141 main(int argc, CHAR16 *argv[])
143 struct devdesc currdev;
144 EFI_LOADED_IMAGE *img;
149 * XXX Chicken-and-egg problem; we want to have console output
150 * early, but some console attributes may depend on reading from
151 * eg. the boot device, which we can't do yet. We can use
152 * printf() etc. once this is done.
157 printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
158 printf("(%s, %s)\n", bootprog_maker, bootprog_date);
163 * March through the device switch probing for things.
165 for (i = 0; devsw[i] != NULL; i++)
166 if (devsw[i]->dv_init != NULL)
167 (devsw[i]->dv_init)();
170 * Disable the watchdog timer. By default the boot manager sets
171 * the timer to 5 minutes before invoking a boot option. If we
172 * want to return to the boot manager, we have to disable the
173 * watchdog timer and since we're an interactive program, we don't
174 * want to wait until the user types "quit". The timer may have
175 * fired by then. We don't care if this fails. It does not prevent
176 * normal functioning in any way...
178 BS->SetWatchdogTimer(0, 0, 0, NULL);
180 /* Get our loaded image protocol interface structure. */
181 BS->HandleProtocol(IH, &imgid, (VOID**)&img);
183 bzero(&currdev, sizeof(currdev));
184 efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
185 currdev.d_type = currdev.d_dev->dv_type;
187 env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset,
190 dev = get_dev_option(argc, argv);
192 dev = ia64_fmtdev(&currdev);
194 env_setenv("currdev", EV_VOLATILE, dev, ia64_setcurrdev, env_nounset);
196 setenv("LINES", "24", 1); /* optional */
198 archsw.arch_autoload = ia64_autoload;
199 archsw.arch_getdev = ia64_getdev;
200 archsw.arch_copyin = ia64_copyin;
201 archsw.arch_copyout = ia64_copyout;
202 archsw.arch_readin = ia64_readin;
204 interact(); /* doesn't return */
206 return (EFI_SUCCESS); /* keep compiler happy */
209 COMMAND_SET(quit, "quit", "exit the loader", command_quit);
212 command_quit(int argc, char *argv[])
218 COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
221 command_memmap(int argc, char *argv[])
224 EFI_MEMORY_DESCRIPTOR *map, *p;
229 static char *types[] = {
235 "RuntimeServicesCode",
236 "RuntimeServicesData",
237 "ConventionalMemory",
242 "MemoryMappedIOPortSpace",
247 status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
248 if (status != EFI_BUFFER_TOO_SMALL) {
249 printf("Can't determine memory map size\n");
253 status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
254 if (EFI_ERROR(status)) {
255 printf("Can't read memory map\n");
260 printf("%23s %12s %12s %8s %4s\n",
261 "Type", "Physical", "Virtual", "#Pages", "Attr");
263 for (i = 0, p = map; i < ndesc;
264 i++, p = NextMemoryDescriptor(p, dsz)) {
265 printf("%23s %012lx %012lx %08lx ",
270 if (p->Attribute & EFI_MEMORY_UC)
272 if (p->Attribute & EFI_MEMORY_WC)
274 if (p->Attribute & EFI_MEMORY_WT)
276 if (p->Attribute & EFI_MEMORY_WB)
278 if (p->Attribute & EFI_MEMORY_UCE)
280 if (p->Attribute & EFI_MEMORY_WP)
282 if (p->Attribute & EFI_MEMORY_RP)
284 if (p->Attribute & EFI_MEMORY_XP)
286 if (p->Attribute & EFI_MEMORY_RUNTIME)
294 COMMAND_SET(configuration, "configuration",
295 "print configuration tables", command_configuration);
298 guid_to_string(EFI_GUID *guid)
302 sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
303 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
304 guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
305 guid->Data4[5], guid->Data4[6], guid->Data4[7]);
310 command_configuration(int argc, char *argv[])
314 printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
315 for (i = 0; i < ST->NumberOfTableEntries; i++) {
319 guid = &ST->ConfigurationTable[i].VendorGuid;
320 if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
322 else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
323 printf("ACPI Table");
324 else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
325 printf("ACPI 2.0 Table");
326 else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
327 printf("SMBIOS Table");
328 else if (!memcmp(guid, &sal, sizeof(EFI_GUID)))
329 printf("SAL System Table");
330 else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID)))
331 printf("DIG64 HCDP Table");
333 printf("Unknown Table (%s)", guid_to_string(guid));
334 printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
340 COMMAND_SET(sal, "sal", "print SAL System Table", command_sal);
343 command_sal(int argc, char *argv[])
346 struct sal_system_table *saltab = 0;
347 static int sizes[6] = {
348 48, 32, 16, 32, 16, 16
352 saltab = efi_get_table(&sal);
353 if (saltab == NULL) {
354 printf("Can't find SAL System Table\n");
358 if (memcmp(saltab->sal_signature, "SST_", 4)) {
359 printf("Bad signature for SAL System Table\n");
363 printf("SAL Revision %x.%02x\n",
366 printf("SAL A Version %x.%02x\n",
367 saltab->sal_a_version[1],
368 saltab->sal_a_version[0]);
369 printf("SAL B Version %x.%02x\n",
370 saltab->sal_b_version[1],
371 saltab->sal_b_version[0]);
373 p = (u_int8_t *) (saltab + 1);
374 for (i = 0; i < saltab->sal_entry_count; i++) {
375 printf(" Desc %d", *p);
377 struct sal_entrypoint_descriptor *dp;
378 dp = (struct sal_entrypoint_descriptor *) p;
380 printf(" PAL Proc at 0x%lx\n",
382 printf(" SAL Proc at 0x%lx\n",
384 printf(" SAL GP at 0x%lx\n",
386 } else if (*p == 1) {
387 struct sal_memory_descriptor *dp;
388 dp = (struct sal_memory_descriptor *) p;
389 printf(" Type %d.%d, ",
390 dp->sale_memory_type[0],
391 dp->sale_memory_type[1]);
392 printf("Address 0x%lx, ",
393 dp->sale_physical_address);
394 printf("Length 0x%x\n",
396 } else if (*p == 5) {
397 struct sal_ap_wakeup_descriptor *dp;
398 dp = (struct sal_ap_wakeup_descriptor *) p;
400 printf(" Mechanism %d\n", dp->sale_mechanism);
401 printf(" Vector 0x%lx\n", dp->sale_vector);
414 struct ia64_pal_result res;
422 static const char *psnames[] = {
423 "1B", "2B", "4B", "8B",
424 "16B", "32B", "64B", "128B",
425 "256B", "512B", "1K", "2K",
426 "4K", "8K", "16K", "32K",
427 "64K", "128K", "256K", "512K",
428 "1M", "2M", "4M", "8M",
429 "16M", "32M", "64M", "128M",
430 "256M", "512M", "1G", "2G"
432 static const char *manames[] = {
433 "WB", "bad", "bad", "bad",
434 "UC", "UCE", "WC", "NaT",
437 res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0);
438 if (res.pal_status != 0) {
439 printf("Can't get VM summary\n");
444 maxtr = (res.pal_result[0] >> 40) & 0xff;
446 maxtr = (res.pal_result[0] >> 32) & 0xff;
448 printf("%d translation registers\n", maxtr);
451 pager_output("TR# RID Virtual Page Physical Page PgSz ED AR PL D A MA P KEY\n");
452 for (i = 0; i <= maxtr; i++) {
455 bzero(&buf, sizeof(buf));
456 res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type,
458 if (res.pal_status != 0)
461 /* Only display valid translations */
462 if ((buf.ifa & 1) == 0)
465 if (!(res.pal_result[0] & 1))
466 buf.pte &= ~PTE_AR_MASK;
467 if (!(res.pal_result[0] & 2))
468 buf.pte &= ~PTE_PL_MASK;
469 if (!(res.pal_result[0] & 4))
470 buf.pte &= ~PTE_DIRTY;
471 if (!(res.pal_result[0] & 8))
472 buf.pte &= ~PTE_MA_MASK;
473 sprintf(lbuf, "%03d %06x %013lx %013lx %4s %d %d %d %d %d "
474 "%-3s %d %06x\n", i, buf.rr.rr_rid, buf.ifa >> 12,
475 (buf.pte & PTE_PPN_MASK) >> 12,
476 psnames[(buf.itir & ITIR_PS_MASK) >> 2],
477 (buf.pte & PTE_ED) ? 1 : 0,
478 (int)(buf.pte & PTE_AR_MASK) >> 9,
479 (int)(buf.pte & PTE_PL_MASK) >> 7,
480 (buf.pte & PTE_DIRTY) ? 1 : 0,
481 (buf.pte & PTE_ACCESSED) ? 1 : 0,
482 manames[(buf.pte & PTE_MA_MASK) >> 2],
483 (buf.pte & PTE_PRESENT) ? 1 : 0,
484 (int)((buf.itir & ITIR_KEY_MASK) >> 8));
489 if (res.pal_status != 0) {
490 printf("Error while getting TR contents\n");
496 COMMAND_SET(itr, "itr", "print instruction TRs", command_itr);
499 command_itr(int argc, char *argv[])
504 COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr);
507 command_dtr(int argc, char *argv[])
512 COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp);
515 hcdp_string(char *s, u_int len)
517 static char buffer[256];
519 memcpy(buffer, s, len);
525 command_hcdp(int argc, char *argv[])
527 struct dig64_hcdp_table *tbl;
528 struct dig64_hcdp_entry *ent;
529 struct dig64_gas *gas;
532 tbl = efi_get_table(&hcdp);
534 printf("No HCDP table present\n");
537 if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) {
538 printf("HCDP table has invalid signature\n");
541 if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) {
542 printf("HCDP table too short\n");
545 printf("HCDP table at 0x%016lx\n", (u_long)tbl);
546 printf("Signature = %s\n", hcdp_string(tbl->signature, 4));
547 printf("Length = %u\n", tbl->length);
548 printf("Revision = %u\n", tbl->revision);
549 printf("Checksum = %u\n", tbl->checksum);
550 printf("OEM Id = %s\n", hcdp_string(tbl->oem_id, 6));
551 printf("Table Id = %s\n", hcdp_string(tbl->oem_tbl_id, 8));
552 printf("OEM rev = %u\n", tbl->oem_rev);
553 printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4));
554 printf("Creator rev= %u\n", tbl->creator_rev);
555 printf("Entries = %u\n", tbl->entries);
556 for (i = 0; i < tbl->entries; i++) {
557 ent = tbl->entry + i;
558 printf("Entry #%d:\n", i + 1);
559 printf(" Type = %u\n", ent->type);
560 printf(" Databits = %u\n", ent->databits);
561 printf(" Parity = %u\n", ent->parity);
562 printf(" Stopbits = %u\n", ent->stopbits);
563 printf(" PCI seg = %u\n", ent->pci_segment);
564 printf(" PCI bus = %u\n", ent->pci_bus);
565 printf(" PCI dev = %u\n", ent->pci_device);
566 printf(" PCI func = %u\n", ent->pci_function);
567 printf(" Interrupt = %u\n", ent->interrupt);
568 printf(" PCI flag = %u\n", ent->pci_flag);
569 printf(" Baudrate = %lu\n",
570 ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low);
572 printf(" Addr space= %u\n", gas->addr_space);
573 printf(" Bit width = %u\n", gas->bit_width);
574 printf(" Bit offset= %u\n", gas->bit_offset);
575 printf(" Address = 0x%016lx\n",
576 ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low);
577 printf(" PCI type = %u\n", ent->pci_devid);
578 printf(" PCI vndr = %u\n", ent->pci_vendor);
579 printf(" IRQ = %u\n", ent->irq);
580 printf(" PClock = %u\n", ent->pclock);
581 printf(" PCI iface = %u\n", ent->pci_interface);