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 devdesc currdev; /* our current device */
54 struct arch_switch archsw; /* MI/MD interface boundary */
56 extern u_int64_t ia64_pal_entry;
58 EFI_GUID acpi = ACPI_TABLE_GUID;
59 EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
60 EFI_GUID devid = DEVICE_PATH_PROTOCOL;
61 EFI_GUID hcdp = HCDP_TABLE_GUID;
62 EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
63 EFI_GUID mps = MPS_TABLE_GUID;
64 EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
65 EFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
66 EFI_GUID smbios = SMBIOS_TABLE_GUID;
72 struct sal_system_table *saltab = 0;
73 static int sizes[6] = {
74 48, 32, 16, 32, 16, 16
78 saltab = efi_get_table(&sal);
80 printf("Can't find SAL System Table\n");
84 if (memcmp(saltab->sal_signature, "SST_", 4)) {
85 printf("Bad signature for SAL System Table\n");
89 p = (u_int8_t *) (saltab + 1);
90 for (i = 0; i < saltab->sal_entry_count; i++) {
92 struct sal_entrypoint_descriptor *dp;
93 dp = (struct sal_entrypoint_descriptor *) p;
94 ia64_pal_entry = dp->sale_pal_proc;
100 printf("Can't find PAL proc\n");
105 main(int argc, CHAR16 *argv[])
107 EFI_LOADED_IMAGE *img;
111 * XXX Chicken-and-egg problem; we want to have console output
112 * early, but some console attributes may depend on reading from
113 * eg. the boot device, which we can't do yet. We can use
114 * printf() etc. once this is done.
121 * March through the device switch probing for things.
123 for (i = 0; devsw[i] != NULL; i++)
124 if (devsw[i]->dv_init != NULL)
125 (devsw[i]->dv_init)();
127 /* Get our loaded image protocol interface structure. */
128 BS->HandleProtocol(IH, &imgid, (VOID**)&img);
130 printf("Image base: 0x%016lx\n", (u_long)img->ImageBase);
133 printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
134 printf("(%s, %s)\n", bootprog_maker, bootprog_date);
136 efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
137 currdev.d_type = currdev.d_dev->dv_type;
140 * Disable the watchdog timer. By default the boot manager sets
141 * the timer to 5 minutes before invoking a boot option. If we
142 * want to return to the boot manager, we have to disable the
143 * watchdog timer and since we're an interactive program, we don't
144 * want to wait until the user types "quit". The timer may have
145 * fired by then. We don't care if this fails. It does not prevent
146 * normal functioning in any way...
148 BS->SetWatchdogTimer(0, 0, 0, NULL);
150 env_setenv("currdev", EV_VOLATILE, ia64_fmtdev(&currdev),
151 ia64_setcurrdev, env_nounset);
152 env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset,
155 setenv("LINES", "24", 1); /* optional */
157 archsw.arch_autoload = ia64_autoload;
158 archsw.arch_getdev = ia64_getdev;
159 archsw.arch_copyin = ia64_copyin;
160 archsw.arch_copyout = ia64_copyout;
161 archsw.arch_readin = ia64_readin;
163 interact(); /* doesn't return */
165 return (EFI_SUCCESS); /* keep compiler happy */
168 COMMAND_SET(quit, "quit", "exit the loader", command_quit);
171 command_quit(int argc, char *argv[])
177 COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
180 command_memmap(int argc, char *argv[])
183 EFI_MEMORY_DESCRIPTOR *map, *p;
188 static char *types[] = {
194 "RuntimeServicesCode",
195 "RuntimeServicesData",
196 "ConventionalMemory",
201 "MemoryMappedIOPortSpace",
206 status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
207 if (status != EFI_BUFFER_TOO_SMALL) {
208 printf("Can't determine memory map size\n");
212 status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
213 if (EFI_ERROR(status)) {
214 printf("Can't read memory map\n");
219 printf("%23s %12s %12s %8s %4s\n",
220 "Type", "Physical", "Virtual", "#Pages", "Attr");
222 for (i = 0, p = map; i < ndesc;
223 i++, p = NextMemoryDescriptor(p, dsz)) {
224 printf("%23s %012lx %012lx %08lx ",
229 if (p->Attribute & EFI_MEMORY_UC)
231 if (p->Attribute & EFI_MEMORY_WC)
233 if (p->Attribute & EFI_MEMORY_WT)
235 if (p->Attribute & EFI_MEMORY_WB)
237 if (p->Attribute & EFI_MEMORY_UCE)
239 if (p->Attribute & EFI_MEMORY_WP)
241 if (p->Attribute & EFI_MEMORY_RP)
243 if (p->Attribute & EFI_MEMORY_XP)
245 if (p->Attribute & EFI_MEMORY_RUNTIME)
253 COMMAND_SET(configuration, "configuration",
254 "print configuration tables", command_configuration);
257 guid_to_string(EFI_GUID *guid)
261 sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
262 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
263 guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
264 guid->Data4[5], guid->Data4[6], guid->Data4[7]);
269 command_configuration(int argc, char *argv[])
273 printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
274 for (i = 0; i < ST->NumberOfTableEntries; i++) {
278 guid = &ST->ConfigurationTable[i].VendorGuid;
279 if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
281 else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
282 printf("ACPI Table");
283 else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
284 printf("ACPI 2.0 Table");
285 else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
286 printf("SMBIOS Table");
287 else if (!memcmp(guid, &sal, sizeof(EFI_GUID)))
288 printf("SAL System Table");
289 else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID)))
290 printf("DIG64 HCDP Table");
292 printf("Unknown Table (%s)", guid_to_string(guid));
293 printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
299 COMMAND_SET(sal, "sal", "print SAL System Table", command_sal);
302 command_sal(int argc, char *argv[])
305 struct sal_system_table *saltab = 0;
306 static int sizes[6] = {
307 48, 32, 16, 32, 16, 16
311 saltab = efi_get_table(&sal);
312 if (saltab == NULL) {
313 printf("Can't find SAL System Table\n");
317 if (memcmp(saltab->sal_signature, "SST_", 4)) {
318 printf("Bad signature for SAL System Table\n");
322 printf("SAL Revision %x.%02x\n",
325 printf("SAL A Version %x.%02x\n",
326 saltab->sal_a_version[1],
327 saltab->sal_a_version[0]);
328 printf("SAL B Version %x.%02x\n",
329 saltab->sal_b_version[1],
330 saltab->sal_b_version[0]);
332 p = (u_int8_t *) (saltab + 1);
333 for (i = 0; i < saltab->sal_entry_count; i++) {
334 printf(" Desc %d", *p);
336 struct sal_entrypoint_descriptor *dp;
337 dp = (struct sal_entrypoint_descriptor *) p;
339 printf(" PAL Proc at 0x%lx\n",
341 printf(" SAL Proc at 0x%lx\n",
343 printf(" SAL GP at 0x%lx\n",
345 } else if (*p == 1) {
346 struct sal_memory_descriptor *dp;
347 dp = (struct sal_memory_descriptor *) p;
348 printf(" Type %d.%d, ",
349 dp->sale_memory_type[0],
350 dp->sale_memory_type[1]);
351 printf("Address 0x%lx, ",
352 dp->sale_physical_address);
353 printf("Length 0x%x\n",
355 } else if (*p == 5) {
356 struct sal_ap_wakeup_descriptor *dp;
357 dp = (struct sal_ap_wakeup_descriptor *) p;
359 printf(" Mechanism %d\n", dp->sale_mechanism);
360 printf(" Vector 0x%lx\n", dp->sale_vector);
373 struct ia64_pal_result res;
381 static const char *psnames[] = {
382 "1B", "2B", "4B", "8B",
383 "16B", "32B", "64B", "128B",
384 "256B", "512B", "1K", "2K",
385 "4K", "8K", "16K", "32K",
386 "64K", "128K", "256K", "512K",
387 "1M", "2M", "4M", "8M",
388 "16M", "32M", "64M", "128M",
389 "256M", "512M", "1G", "2G"
391 static const char *manames[] = {
392 "WB", "bad", "bad", "bad",
393 "UC", "UCE", "WC", "NaT",
396 res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0);
397 if (res.pal_status != 0) {
398 printf("Can't get VM summary\n");
403 maxtr = (res.pal_result[0] >> 40) & 0xff;
405 maxtr = (res.pal_result[0] >> 32) & 0xff;
407 printf("%d translation registers\n", maxtr);
410 pager_output("TR# RID Virtual Page Physical Page PgSz ED AR PL D A MA P KEY\n");
411 for (i = 0; i <= maxtr; i++) {
414 bzero(&buf, sizeof(buf));
415 res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type,
417 if (res.pal_status != 0)
420 /* Only display valid translations */
421 if ((buf.ifa & 1) == 0)
424 if (!(res.pal_result[0] & 1))
425 buf.pte &= ~PTE_AR_MASK;
426 if (!(res.pal_result[0] & 2))
427 buf.pte &= ~PTE_PL_MASK;
428 if (!(res.pal_result[0] & 4))
429 buf.pte &= ~PTE_DIRTY;
430 if (!(res.pal_result[0] & 8))
431 buf.pte &= ~PTE_MA_MASK;
432 sprintf(lbuf, "%03d %06x %013lx %013lx %4s %d %d %d %d %d "
433 "%-3s %d %06x\n", i, buf.rr.rr_rid, buf.ifa >> 12,
434 (buf.pte & PTE_PPN_MASK) >> 12,
435 psnames[(buf.itir & ITIR_PS_MASK) >> 2],
436 (buf.pte & PTE_ED) ? 1 : 0,
437 (int)(buf.pte & PTE_AR_MASK) >> 9,
438 (int)(buf.pte & PTE_PL_MASK) >> 7,
439 (buf.pte & PTE_DIRTY) ? 1 : 0,
440 (buf.pte & PTE_ACCESSED) ? 1 : 0,
441 manames[(buf.pte & PTE_MA_MASK) >> 2],
442 (buf.pte & PTE_PRESENT) ? 1 : 0,
443 (int)((buf.itir & ITIR_KEY_MASK) >> 8));
448 if (res.pal_status != 0) {
449 printf("Error while getting TR contents\n");
455 COMMAND_SET(itr, "itr", "print instruction TRs", command_itr);
458 command_itr(int argc, char *argv[])
463 COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr);
466 command_dtr(int argc, char *argv[])
471 COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp);
474 hcdp_string(char *s, u_int len)
476 static char buffer[256];
478 memcpy(buffer, s, len);
484 command_hcdp(int argc, char *argv[])
486 struct dig64_hcdp_table *tbl;
487 struct dig64_hcdp_entry *ent;
488 struct dig64_gas *gas;
491 tbl = efi_get_table(&hcdp);
493 printf("No HCDP table present\n");
496 if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) {
497 printf("HCDP table has invalid signature\n");
500 if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) {
501 printf("HCDP table too short\n");
504 printf("HCDP table at 0x%016lx\n", (u_long)tbl);
505 printf("Signature = %s\n", hcdp_string(tbl->signature, 4));
506 printf("Length = %u\n", tbl->length);
507 printf("Revision = %u\n", tbl->revision);
508 printf("Checksum = %u\n", tbl->checksum);
509 printf("OEM Id = %s\n", hcdp_string(tbl->oem_id, 6));
510 printf("Table Id = %s\n", hcdp_string(tbl->oem_tbl_id, 8));
511 printf("OEM rev = %u\n", tbl->oem_rev);
512 printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4));
513 printf("Creator rev= %u\n", tbl->creator_rev);
514 printf("Entries = %u\n", tbl->entries);
515 for (i = 0; i < tbl->entries; i++) {
516 ent = tbl->entry + i;
517 printf("Entry #%d:\n", i + 1);
518 printf(" Type = %u\n", ent->type);
519 printf(" Databits = %u\n", ent->databits);
520 printf(" Parity = %u\n", ent->parity);
521 printf(" Stopbits = %u\n", ent->stopbits);
522 printf(" PCI seg = %u\n", ent->pci_segment);
523 printf(" PCI bus = %u\n", ent->pci_bus);
524 printf(" PCI dev = %u\n", ent->pci_device);
525 printf(" PCI func = %u\n", ent->pci_function);
526 printf(" Interrupt = %u\n", ent->interrupt);
527 printf(" PCI flag = %u\n", ent->pci_flag);
528 printf(" Baudrate = %lu\n",
529 ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low);
531 printf(" Addr space= %u\n", gas->addr_space);
532 printf(" Bit width = %u\n", gas->bit_width);
533 printf(" Bit offset= %u\n", gas->bit_offset);
534 printf(" Address = 0x%016lx\n",
535 ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low);
536 printf(" PCI type = %u\n", ent->pci_devid);
537 printf(" PCI vndr = %u\n", ent->pci_vendor);
538 printf(" IRQ = %u\n", ent->irq);
539 printf(" PClock = %u\n", ent->pclock);
540 printf(" PCI iface = %u\n", ent->pci_interface);