177943Sdfr/*-
277943Sdfr * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
377943Sdfr * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org>
477943Sdfr * All rights reserved.
577943Sdfr *
677943Sdfr * Redistribution and use in source and binary forms, with or without
777943Sdfr * modification, are permitted provided that the following conditions
877943Sdfr * are met:
977943Sdfr * 1. Redistributions of source code must retain the above copyright
1077943Sdfr *    notice, this list of conditions and the following disclaimer.
1177943Sdfr * 2. Redistributions in binary form must reproduce the above copyright
1277943Sdfr *    notice, this list of conditions and the following disclaimer in the
1377943Sdfr *    documentation and/or other materials provided with the distribution.
1477943Sdfr *
1577943Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1677943Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1777943Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1877943Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1977943Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2077943Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2177943Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2277943Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2377943Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2477943Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2577943Sdfr * SUCH DAMAGE.
2677943Sdfr */
2777943Sdfr
28113038Sobrien#include <sys/cdefs.h>
29113038Sobrien__FBSDID("$FreeBSD$");
3078332Sobrien
3177943Sdfr#include <stand.h>
3277943Sdfr#include <string.h>
3377943Sdfr#include <setjmp.h>
3483857Sdfr#include <machine/sal.h>
3583904Sdfr#include <machine/pal.h>
3683904Sdfr#include <machine/pte.h>
37108025Smarcel#include <machine/dig64.h>
3877943Sdfr
3977943Sdfr#include <efi.h>
4077943Sdfr#include <efilib.h>
4177943Sdfr
42164010Smarcel#include <libia64.h>
4377943Sdfr
44164010Smarcel/* DIG64 Headless Console & Debug Port Table. */
45164010Smarcel#define	HCDP_TABLE_GUID		\
46164010Smarcel    {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
47164010Smarcel
4877943Sdfrextern char bootprog_name[];
4977943Sdfrextern char bootprog_rev[];
5077943Sdfrextern char bootprog_date[];
5177943Sdfrextern char bootprog_maker[];
5277943Sdfr
53164010Smarcelstruct arch_switch archsw;	/* MI/MD interface boundary */
5477943Sdfr
5583904Sdfrextern u_int64_t	ia64_pal_entry;
5683904Sdfr
57107722SmarcelEFI_GUID acpi = ACPI_TABLE_GUID;
58107722SmarcelEFI_GUID acpi20 = ACPI_20_TABLE_GUID;
59118346SmarcelEFI_GUID devid = DEVICE_PATH_PROTOCOL;
60107722SmarcelEFI_GUID hcdp = HCDP_TABLE_GUID;
61107722SmarcelEFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
62107722SmarcelEFI_GUID mps = MPS_TABLE_GUID;
63107722SmarcelEFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
64107722SmarcelEFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
65107722SmarcelEFI_GUID smbios = SMBIOS_TABLE_GUID;
66107722Smarcel
6783904Sdfrstatic void
6883904Sdfrfind_pal_proc(void)
6983904Sdfr{
7083904Sdfr	int i;
7183904Sdfr	struct sal_system_table *saltab = 0;
7283904Sdfr	static int sizes[6] = {
7383904Sdfr		48, 32, 16, 32, 16, 16
7483904Sdfr	};
7583904Sdfr	u_int8_t *p;
7683904Sdfr
77107733Smarcel	saltab = efi_get_table(&sal);
78107733Smarcel	if (saltab == NULL) {
7983904Sdfr		printf("Can't find SAL System Table\n");
8083904Sdfr		return;
8183904Sdfr	}
8283904Sdfr
8383904Sdfr	if (memcmp(saltab->sal_signature, "SST_", 4)) {
8483904Sdfr		printf("Bad signature for SAL System Table\n");
8583904Sdfr		return;
8683904Sdfr	}
8783904Sdfr
8883904Sdfr	p = (u_int8_t *) (saltab + 1);
8983904Sdfr	for (i = 0; i < saltab->sal_entry_count; i++) {
9083904Sdfr		if (*p == 0) {
9183904Sdfr			struct sal_entrypoint_descriptor *dp;
9283904Sdfr			dp = (struct sal_entrypoint_descriptor *) p;
9383904Sdfr			ia64_pal_entry = dp->sale_pal_proc;
9483904Sdfr			return;
9583904Sdfr		}
9683904Sdfr		p += sizes[*p];
9783904Sdfr	}
9883904Sdfr
9983904Sdfr	printf("Can't find PAL proc\n");
10083904Sdfr	return;
10183904Sdfr}
10283904Sdfr
103202552Smarcelstatic int
104202552Smarcelusc2cmp(CHAR16 *s1, CHAR16 *s2)
105202552Smarcel{
106202552Smarcel
107202552Smarcel	while (*s1 == *s2++) {
108202552Smarcel		if (*s1++ == 0)
109202552Smarcel			return (0);
110202552Smarcel	}
111202552Smarcel	return (*s1 - *(s2 - 1));
112202552Smarcel}
113202552Smarcel
114202552Smarcelstatic char *
115202552Smarcelget_dev_option(int argc, CHAR16 *argv[])
116202552Smarcel{
117202552Smarcel	static char dev[32];
118202552Smarcel	CHAR16 *arg;
119202552Smarcel	char *devp;
120202552Smarcel	int i, j;
121202552Smarcel
122202552Smarcel	devp = NULL;
123202552Smarcel	for (i = 0; i < argc; i++) {
124202552Smarcel		if (usc2cmp(argv[i], L"-dev") == 0 && i < argc - 1) {
125202552Smarcel			arg = argv[i + 1];
126202552Smarcel			j = 0;
127202552Smarcel			while (j < sizeof(dev) && *arg != 0)
128202552Smarcel				dev[j++] = *arg++;
129202552Smarcel			if (j == sizeof(dev))
130202552Smarcel				j--;
131202552Smarcel			dev[j] = '\0';
132202552Smarcel			devp = dev;
133202552Smarcel			break;
134202552Smarcel		}
135202552Smarcel	}
136202552Smarcel
137202552Smarcel	return (devp);
138202552Smarcel}
139202552Smarcel
14077943SdfrEFI_STATUS
141107723Smarcelmain(int argc, CHAR16 *argv[])
14277943Sdfr{
143202552Smarcel	struct devdesc currdev;
14493411Smarcel	EFI_LOADED_IMAGE *img;
145202552Smarcel	char *dev;
14693411Smarcel	int i;
14778332Sobrien
14877943Sdfr	/*
14977943Sdfr	 * XXX Chicken-and-egg problem; we want to have console output
15077943Sdfr	 * early, but some console attributes may depend on reading from
15177943Sdfr	 * eg. the boot device, which we can't do yet.  We can use
15277943Sdfr	 * printf() etc. once this is done.
15377943Sdfr	 */
15477943Sdfr	cons_probe();
15577943Sdfr
156222799Smarcel	printf("\n%s, Revision %s\n", bootprog_name, bootprog_rev);
157202552Smarcel
15883904Sdfr	find_pal_proc();
15983904Sdfr
16077943Sdfr	/*
16177943Sdfr	 * March through the device switch probing for things.
16277943Sdfr	 */
16377943Sdfr	for (i = 0; devsw[i] != NULL; i++)
16477943Sdfr		if (devsw[i]->dv_init != NULL)
16577943Sdfr			(devsw[i]->dv_init)();
16677943Sdfr
167107683Smarcel	/*
168107683Smarcel	 * Disable the watchdog timer. By default the boot manager sets
169107683Smarcel	 * the timer to 5 minutes before invoking a boot option. If we
170107683Smarcel	 * want to return to the boot manager, we have to disable the
171107683Smarcel	 * watchdog timer and since we're an interactive program, we don't
172107683Smarcel	 * want to wait until the user types "quit". The timer may have
173107683Smarcel	 * fired by then. We don't care if this fails. It does not prevent
174107683Smarcel	 * normal functioning in any way...
175107683Smarcel	 */
176107683Smarcel	BS->SetWatchdogTimer(0, 0, 0, NULL);
17777943Sdfr
178202552Smarcel	/* Get our loaded image protocol interface structure. */
179202552Smarcel	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
180202552Smarcel
181202552Smarcel	bzero(&currdev, sizeof(currdev));
182295538Ssmh	efi_handle_lookup(img->DeviceHandle, &currdev.d_dev,
183295538Ssmh	    &currdev.d_unit, NULL);
184202552Smarcel	currdev.d_type = currdev.d_dev->dv_type;
185202552Smarcel
186164010Smarcel	env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset,
18778332Sobrien	    env_nounset);
18877943Sdfr
189202552Smarcel	dev = get_dev_option(argc, argv);
190202552Smarcel	if (dev == NULL)
191202552Smarcel		dev = ia64_fmtdev(&currdev);
192202552Smarcel
193202552Smarcel	env_setenv("currdev", EV_VOLATILE, dev, ia64_setcurrdev, env_nounset);
194202552Smarcel
19578332Sobrien	setenv("LINES", "24", 1);	/* optional */
196202552Smarcel
197164010Smarcel	archsw.arch_autoload = ia64_autoload;
198164010Smarcel	archsw.arch_copyin = ia64_copyin;
199164010Smarcel	archsw.arch_copyout = ia64_copyout;
200220313Smarcel	archsw.arch_getdev = ia64_getdev;
201220313Smarcel	archsw.arch_loadaddr = ia64_loadaddr;
202220313Smarcel	archsw.arch_loadseg = ia64_loadseg;
203164010Smarcel	archsw.arch_readin = ia64_readin;
20477943Sdfr
20577943Sdfr	interact();			/* doesn't return */
20677943Sdfr
20778332Sobrien	return (EFI_SUCCESS);		/* keep compiler happy */
20877943Sdfr}
20977943Sdfr
21077943SdfrCOMMAND_SET(quit, "quit", "exit the loader", command_quit);
21177943Sdfr
21277943Sdfrstatic int
21377943Sdfrcommand_quit(int argc, char *argv[])
21477943Sdfr{
21578332Sobrien	exit(0);
216222799Smarcel	/* NOTREACHED */
21778332Sobrien	return (CMD_OK);
21877943Sdfr}
21983215Sdfr
220222799SmarcelCOMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
221222799Smarcel
222222799Smarcelstatic int
223222799Smarcelcommand_reboot(int argc, char *argv[])
224222799Smarcel{
225222799Smarcel
226222799Smarcel	RS->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
227222799Smarcel	/* NOTREACHED */
228222799Smarcel	return (CMD_OK);
229222799Smarcel}
230222799Smarcel
23183215SdfrCOMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
23283215Sdfr
23383215Sdfrstatic int
23483215Sdfrcommand_memmap(int argc, char *argv[])
23583215Sdfr{
23683215Sdfr	UINTN sz;
23783215Sdfr	EFI_MEMORY_DESCRIPTOR *map, *p;
23883215Sdfr	UINTN key, dsz;
23983215Sdfr	UINT32 dver;
24083215Sdfr	EFI_STATUS status;
24183215Sdfr	int i, ndesc;
24283215Sdfr	static char *types[] = {
24383215Sdfr	    "Reserved",
24483215Sdfr	    "LoaderCode",
24583215Sdfr	    "LoaderData",
24683215Sdfr	    "BootServicesCode",
24783215Sdfr	    "BootServicesData",
24883215Sdfr	    "RuntimeServicesCode",
24983215Sdfr	    "RuntimeServicesData",
25083215Sdfr	    "ConventionalMemory",
25183216Sdfr	    "UnusableMemory",
25283215Sdfr	    "ACPIReclaimMemory",
25383215Sdfr	    "ACPIMemoryNVS",
25483215Sdfr	    "MemoryMappedIO",
25583215Sdfr	    "MemoryMappedIOPortSpace",
25683215Sdfr	    "PalCode"
25783215Sdfr	};
25883215Sdfr
25983215Sdfr	sz = 0;
26083215Sdfr	status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
26183215Sdfr	if (status != EFI_BUFFER_TOO_SMALL) {
26283215Sdfr		printf("Can't determine memory map size\n");
26383857Sdfr		return CMD_ERROR;
26483215Sdfr	}
26583215Sdfr	map = malloc(sz);
26683215Sdfr	status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
26783215Sdfr	if (EFI_ERROR(status)) {
26883215Sdfr		printf("Can't read memory map\n");
26983857Sdfr		return CMD_ERROR;
27083215Sdfr	}
27183215Sdfr
27283215Sdfr	ndesc = sz / dsz;
27383216Sdfr	printf("%23s %12s %12s %8s %4s\n",
27483215Sdfr	       "Type", "Physical", "Virtual", "#Pages", "Attr");
27583215Sdfr
27683215Sdfr	for (i = 0, p = map; i < ndesc;
27783215Sdfr	     i++, p = NextMemoryDescriptor(p, dsz)) {
27883216Sdfr	    printf("%23s %012lx %012lx %08lx ",
27983215Sdfr		   types[p->Type],
28083215Sdfr		   p->PhysicalStart,
28183215Sdfr		   p->VirtualStart,
28283215Sdfr		   p->NumberOfPages);
28383215Sdfr	    if (p->Attribute & EFI_MEMORY_UC)
28483215Sdfr		printf("UC ");
28583215Sdfr	    if (p->Attribute & EFI_MEMORY_WC)
28683215Sdfr		printf("WC ");
28783215Sdfr	    if (p->Attribute & EFI_MEMORY_WT)
28883215Sdfr		printf("WT ");
28983215Sdfr	    if (p->Attribute & EFI_MEMORY_WB)
29083215Sdfr		printf("WB ");
29183215Sdfr	    if (p->Attribute & EFI_MEMORY_UCE)
29283215Sdfr		printf("UCE ");
29383215Sdfr	    if (p->Attribute & EFI_MEMORY_WP)
29483215Sdfr		printf("WP ");
29583215Sdfr	    if (p->Attribute & EFI_MEMORY_RP)
29683215Sdfr		printf("RP ");
29783215Sdfr	    if (p->Attribute & EFI_MEMORY_XP)
29883215Sdfr		printf("XP ");
29983215Sdfr	    if (p->Attribute & EFI_MEMORY_RUNTIME)
30083215Sdfr		printf("RUNTIME");
30183215Sdfr	    printf("\n");
30283215Sdfr	}
30383215Sdfr
30483857Sdfr	return CMD_OK;
30583215Sdfr}
30683857Sdfr
30783857SdfrCOMMAND_SET(configuration, "configuration",
30883857Sdfr	    "print configuration tables", command_configuration);
30983857Sdfr
310107722Smarcelstatic const char *
311107722Smarcelguid_to_string(EFI_GUID *guid)
312107722Smarcel{
313107722Smarcel	static char buf[40];
314107722Smarcel
315107722Smarcel	sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
316107722Smarcel	    guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
317107722Smarcel	    guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
318107722Smarcel	    guid->Data4[5], guid->Data4[6], guid->Data4[7]);
319107722Smarcel	return (buf);
320107722Smarcel}
321107722Smarcel
32283857Sdfrstatic int
32383857Sdfrcommand_configuration(int argc, char *argv[])
32483857Sdfr{
32583857Sdfr	int i;
32683857Sdfr
327100387Speter	printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
32883857Sdfr	for (i = 0; i < ST->NumberOfTableEntries; i++) {
329107722Smarcel		EFI_GUID *guid;
330107722Smarcel
33183857Sdfr		printf("  ");
332107722Smarcel		guid = &ST->ConfigurationTable[i].VendorGuid;
333107722Smarcel		if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
33483857Sdfr			printf("MPS Table");
335107722Smarcel		else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
33683857Sdfr			printf("ACPI Table");
337107722Smarcel		else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
33883857Sdfr			printf("ACPI 2.0 Table");
339107722Smarcel		else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
34083857Sdfr			printf("SMBIOS Table");
341107722Smarcel		else if (!memcmp(guid, &sal, sizeof(EFI_GUID)))
34283857Sdfr			printf("SAL System Table");
343107722Smarcel		else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID)))
344107722Smarcel			printf("DIG64 HCDP Table");
34583857Sdfr		else
346107722Smarcel			printf("Unknown Table (%s)", guid_to_string(guid));
34783857Sdfr		printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
34883857Sdfr	}
34983857Sdfr
35083857Sdfr	return CMD_OK;
35183857Sdfr}
35283857Sdfr
35383857SdfrCOMMAND_SET(sal, "sal", "print SAL System Table", command_sal);
35483857Sdfr
35583857Sdfrstatic int
35683857Sdfrcommand_sal(int argc, char *argv[])
35783857Sdfr{
35883857Sdfr	int i;
35983857Sdfr	struct sal_system_table *saltab = 0;
36083857Sdfr	static int sizes[6] = {
36183857Sdfr		48, 32, 16, 32, 16, 16
36283857Sdfr	};
36383857Sdfr	u_int8_t *p;
36483857Sdfr
365107733Smarcel	saltab = efi_get_table(&sal);
366107733Smarcel	if (saltab == NULL) {
36783857Sdfr		printf("Can't find SAL System Table\n");
36883857Sdfr		return CMD_ERROR;
36983857Sdfr	}
37083857Sdfr
37183857Sdfr	if (memcmp(saltab->sal_signature, "SST_", 4)) {
37283857Sdfr		printf("Bad signature for SAL System Table\n");
37383857Sdfr		return CMD_ERROR;
37483857Sdfr	}
37583857Sdfr
37683857Sdfr	printf("SAL Revision %x.%02x\n",
37783857Sdfr	       saltab->sal_rev[1],
37883857Sdfr	       saltab->sal_rev[0]);
37983857Sdfr	printf("SAL A Version %x.%02x\n",
38083857Sdfr	       saltab->sal_a_version[1],
38183857Sdfr	       saltab->sal_a_version[0]);
38283857Sdfr	printf("SAL B Version %x.%02x\n",
38383857Sdfr	       saltab->sal_b_version[1],
38483857Sdfr	       saltab->sal_b_version[0]);
38583857Sdfr
38683857Sdfr	p = (u_int8_t *) (saltab + 1);
38783857Sdfr	for (i = 0; i < saltab->sal_entry_count; i++) {
38883857Sdfr		printf("  Desc %d", *p);
38983857Sdfr		if (*p == 0) {
39083857Sdfr			struct sal_entrypoint_descriptor *dp;
39183857Sdfr			dp = (struct sal_entrypoint_descriptor *) p;
39283857Sdfr			printf("\n");
39383857Sdfr			printf("    PAL Proc at 0x%lx\n",
39483857Sdfr			       dp->sale_pal_proc);
39583857Sdfr			printf("    SAL Proc at 0x%lx\n",
39683857Sdfr			       dp->sale_sal_proc);
39783857Sdfr			printf("    SAL GP at 0x%lx\n",
39883857Sdfr			       dp->sale_sal_gp);
39983857Sdfr		} else if (*p == 1) {
40083857Sdfr			struct sal_memory_descriptor *dp;
40183857Sdfr			dp = (struct sal_memory_descriptor *) p;
40283857Sdfr			printf(" Type %d.%d, ",
40383857Sdfr			       dp->sale_memory_type[0],
40483857Sdfr			       dp->sale_memory_type[1]);
40583857Sdfr			printf("Address 0x%lx, ",
40683857Sdfr			       dp->sale_physical_address);
40783857Sdfr			printf("Length 0x%x\n",
40883857Sdfr			       dp->sale_length);
409107203Smarcel		} else if (*p == 5) {
410107203Smarcel			struct sal_ap_wakeup_descriptor *dp;
411107203Smarcel			dp = (struct sal_ap_wakeup_descriptor *) p;
41283857Sdfr			printf("\n");
413107203Smarcel			printf("    Mechanism %d\n", dp->sale_mechanism);
414107203Smarcel			printf("    Vector 0x%lx\n", dp->sale_vector);
415107203Smarcel		} else
416107203Smarcel			printf("\n");
417107203Smarcel
41883857Sdfr		p += sizes[*p];
41983857Sdfr	}
42083857Sdfr
42183857Sdfr	return CMD_OK;
42283857Sdfr}
42383904Sdfr
42483904Sdfrint
42583904Sdfrprint_trs(int type)
42683904Sdfr{
427133420Smarcel	struct ia64_pal_result res;
428133420Smarcel	int i, maxtr;
42983904Sdfr	struct {
430135630Smarcel		pt_entry_t	pte;
431137978Smarcel		uint64_t	itir;
432133420Smarcel		uint64_t	ifa;
43383904Sdfr		struct ia64_rr	rr;
434133420Smarcel	} buf;
435133420Smarcel	static const char *psnames[] = {
43683904Sdfr		"1B",	"2B",	"4B",	"8B",
43783904Sdfr		"16B",	"32B",	"64B",	"128B",
43883904Sdfr		"256B",	"512B",	"1K",	"2K",
43983904Sdfr		"4K",	"8K",	"16K",	"32K",
44083904Sdfr		"64K",	"128K",	"256K",	"512K",
44183904Sdfr		"1M",	"2M",	"4M",	"8M",
44283904Sdfr		"16M",	"32M",	"64M",	"128M",
44383904Sdfr		"256M",	"512M",	"1G",	"2G"
44483904Sdfr	};
445133420Smarcel	static const char *manames[] = {
44683904Sdfr		"WB",	"bad",	"bad",	"bad",
44783904Sdfr		"UC",	"UCE",	"WC",	"NaT",
44883904Sdfr	};
44983904Sdfr
45083904Sdfr	res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0);
45183904Sdfr	if (res.pal_status != 0) {
45283904Sdfr		printf("Can't get VM summary\n");
45383904Sdfr		return CMD_ERROR;
45483904Sdfr	}
45583904Sdfr
45683904Sdfr	if (type == 0)
45783904Sdfr		maxtr = (res.pal_result[0] >> 40) & 0xff;
45883904Sdfr	else
45983904Sdfr		maxtr = (res.pal_result[0] >> 32) & 0xff;
46083904Sdfr
461107203Smarcel	printf("%d translation registers\n", maxtr);
462107203Smarcel
46383904Sdfr	pager_open();
464107203Smarcel	pager_output("TR# RID    Virtual Page  Physical Page PgSz ED AR PL D A MA  P KEY\n");
46583904Sdfr	for (i = 0; i <= maxtr; i++) {
46683904Sdfr		char lbuf[128];
46783904Sdfr
46883904Sdfr		bzero(&buf, sizeof(buf));
46983904Sdfr		res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type,
47083904Sdfr					    (u_int64_t) &buf);
471107203Smarcel		if (res.pal_status != 0)
472107203Smarcel			break;
473107203Smarcel
474107203Smarcel		/* Only display valid translations */
475133420Smarcel		if ((buf.ifa & 1) == 0)
476107203Smarcel			continue;
477107203Smarcel
47883904Sdfr		if (!(res.pal_result[0] & 1))
479135630Smarcel			buf.pte &= ~PTE_AR_MASK;
48083904Sdfr		if (!(res.pal_result[0] & 2))
481135630Smarcel			buf.pte &= ~PTE_PL_MASK;
48283904Sdfr		if (!(res.pal_result[0] & 4))
483135630Smarcel			buf.pte &= ~PTE_DIRTY;
48483904Sdfr		if (!(res.pal_result[0] & 8))
485135630Smarcel			buf.pte &= ~PTE_MA_MASK;
486135630Smarcel		sprintf(lbuf, "%03d %06x %013lx %013lx %4s %d  %d  %d  %d %d "
487135630Smarcel		    "%-3s %d %06x\n", i, buf.rr.rr_rid, buf.ifa >> 12,
488137978Smarcel		    (buf.pte & PTE_PPN_MASK) >> 12,
489137978Smarcel		    psnames[(buf.itir & ITIR_PS_MASK) >> 2],
490135630Smarcel		    (buf.pte & PTE_ED) ? 1 : 0,
491135630Smarcel		    (int)(buf.pte & PTE_AR_MASK) >> 9,
492135630Smarcel		    (int)(buf.pte & PTE_PL_MASK) >> 7,
493135630Smarcel		    (buf.pte & PTE_DIRTY) ? 1 : 0,
494135630Smarcel		    (buf.pte & PTE_ACCESSED) ? 1 : 0,
495135630Smarcel		    manames[(buf.pte & PTE_MA_MASK) >> 2],
496135630Smarcel		    (buf.pte & PTE_PRESENT) ? 1 : 0,
497137978Smarcel		    (int)((buf.itir & ITIR_KEY_MASK) >> 8));
49883904Sdfr		pager_output(lbuf);
49983904Sdfr	}
50083904Sdfr	pager_close();
50183939Sdfr
502107203Smarcel	if (res.pal_status != 0) {
503107203Smarcel		printf("Error while getting TR contents\n");
504107203Smarcel		return CMD_ERROR;
505107203Smarcel	}
50683939Sdfr	return CMD_OK;
50783904Sdfr}
50883904Sdfr
50983904SdfrCOMMAND_SET(itr, "itr", "print instruction TRs", command_itr);
51083904Sdfr
51183904Sdfrstatic int
51283904Sdfrcommand_itr(int argc, char *argv[])
51383904Sdfr{
51483904Sdfr	return print_trs(0);
51583904Sdfr}
51683904Sdfr
51783904SdfrCOMMAND_SET(dtr, "dtr", "print data TRs", command_dtr);
51883904Sdfr
51983904Sdfrstatic int
52083904Sdfrcommand_dtr(int argc, char *argv[])
52183904Sdfr{
52283904Sdfr	return print_trs(1);
52383904Sdfr}
52483904Sdfr
525108025SmarcelCOMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp);
526108025Smarcel
527108025Smarcelstatic char *
528108025Smarcelhcdp_string(char *s, u_int len)
529108025Smarcel{
530108025Smarcel	static char buffer[256];
531108025Smarcel
532108025Smarcel	memcpy(buffer, s, len);
533108025Smarcel	buffer[len] = 0;
534108025Smarcel	return (buffer);
535108025Smarcel}
536108025Smarcel
537108025Smarcelstatic int
538108025Smarcelcommand_hcdp(int argc, char *argv[])
539108025Smarcel{
540108025Smarcel	struct dig64_hcdp_table *tbl;
541108025Smarcel	struct dig64_hcdp_entry *ent;
542108025Smarcel	struct dig64_gas *gas;
543108025Smarcel	int i;
544108025Smarcel
545108025Smarcel	tbl = efi_get_table(&hcdp);
546108025Smarcel	if (tbl == NULL) {
547108025Smarcel		printf("No HCDP table present\n");
548108025Smarcel		return (CMD_OK);
549108025Smarcel	}
550108025Smarcel	if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) {
551108025Smarcel		printf("HCDP table has invalid signature\n");
552108025Smarcel		return (CMD_OK);
553108025Smarcel	}
554108025Smarcel	if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) {
555108025Smarcel		printf("HCDP table too short\n");
556108025Smarcel		return (CMD_OK);
557108025Smarcel	}
558108025Smarcel	printf("HCDP table at 0x%016lx\n", (u_long)tbl);
559108025Smarcel	printf("Signature  = %s\n", hcdp_string(tbl->signature, 4));
560108025Smarcel	printf("Length     = %u\n", tbl->length);
561108025Smarcel	printf("Revision   = %u\n", tbl->revision);
562108025Smarcel	printf("Checksum   = %u\n", tbl->checksum);
563108025Smarcel	printf("OEM Id     = %s\n", hcdp_string(tbl->oem_id, 6));
564108025Smarcel	printf("Table Id   = %s\n", hcdp_string(tbl->oem_tbl_id, 8));
565108025Smarcel	printf("OEM rev    = %u\n", tbl->oem_rev);
566108025Smarcel	printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4));
567108025Smarcel	printf("Creator rev= %u\n", tbl->creator_rev);
568108025Smarcel	printf("Entries    = %u\n", tbl->entries);
569108025Smarcel	for (i = 0; i < tbl->entries; i++) {
570108025Smarcel		ent = tbl->entry + i;
571108025Smarcel		printf("Entry #%d:\n", i + 1);
572108025Smarcel		printf("    Type      = %u\n", ent->type);
573108025Smarcel		printf("    Databits  = %u\n", ent->databits);
574108025Smarcel		printf("    Parity    = %u\n", ent->parity);
575108025Smarcel		printf("    Stopbits  = %u\n", ent->stopbits);
576108025Smarcel		printf("    PCI seg   = %u\n", ent->pci_segment);
577108025Smarcel		printf("    PCI bus   = %u\n", ent->pci_bus);
578108025Smarcel		printf("    PCI dev   = %u\n", ent->pci_device);
579108025Smarcel		printf("    PCI func  = %u\n", ent->pci_function);
580108025Smarcel		printf("    Interrupt = %u\n", ent->interrupt);
581108025Smarcel		printf("    PCI flag  = %u\n", ent->pci_flag);
582108025Smarcel		printf("    Baudrate  = %lu\n",
583108025Smarcel		    ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low);
584108025Smarcel		gas = &ent->address;
585108025Smarcel		printf("    Addr space= %u\n", gas->addr_space);
586108025Smarcel		printf("    Bit width = %u\n", gas->bit_width);
587108025Smarcel		printf("    Bit offset= %u\n", gas->bit_offset);
588108025Smarcel		printf("    Address   = 0x%016lx\n",
589108025Smarcel		    ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low);
590108025Smarcel		printf("    PCI type  = %u\n", ent->pci_devid);
591108025Smarcel		printf("    PCI vndr  = %u\n", ent->pci_vendor);
592108025Smarcel		printf("    IRQ       = %u\n", ent->irq);
593108025Smarcel		printf("    PClock    = %u\n", ent->pclock);
594108025Smarcel		printf("    PCI iface = %u\n", ent->pci_interface);
595108025Smarcel	}
596108025Smarcel	printf("<EOT>\n");
597108025Smarcel	return (CMD_OK);
598108025Smarcel}
599222799Smarcel
600222799SmarcelCOMMAND_SET(about, "about", "about the loader", command_about);
601222799Smarcel
602222799Smarcelextern uint64_t _start_plabel[];
603222799Smarcel
604222799Smarcelstatic int
605222799Smarcelcommand_about(int argc, char *argv[])
606222799Smarcel{
607222799Smarcel	EFI_LOADED_IMAGE *img;
608222799Smarcel
609222799Smarcel	printf("%s\n", bootprog_name);
610222799Smarcel	printf("revision %s\n", bootprog_rev);
611222799Smarcel	printf("built by %s\n", bootprog_maker);
612222799Smarcel	printf("built on %s\n", bootprog_date);
613222799Smarcel
614222799Smarcel	printf("\n");
615222799Smarcel
616222799Smarcel	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
617222799Smarcel	printf("image loaded at %p\n", img->ImageBase);
618222799Smarcel	printf("entry at %#lx (%#lx)\n", _start_plabel[0], _start_plabel[1]);
619222799Smarcel}
620