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));
182202552Smarcel	efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
183202552Smarcel	currdev.d_type = currdev.d_dev->dv_type;
184202552Smarcel
185164010Smarcel	env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset,
18678332Sobrien	    env_nounset);
18777943Sdfr
188202552Smarcel	dev = get_dev_option(argc, argv);
189202552Smarcel	if (dev == NULL)
190202552Smarcel		dev = ia64_fmtdev(&currdev);
191202552Smarcel
192202552Smarcel	env_setenv("currdev", EV_VOLATILE, dev, ia64_setcurrdev, env_nounset);
193202552Smarcel
19478332Sobrien	setenv("LINES", "24", 1);	/* optional */
195202552Smarcel
196164010Smarcel	archsw.arch_autoload = ia64_autoload;
197164010Smarcel	archsw.arch_copyin = ia64_copyin;
198164010Smarcel	archsw.arch_copyout = ia64_copyout;
199220313Smarcel	archsw.arch_getdev = ia64_getdev;
200220313Smarcel	archsw.arch_loadaddr = ia64_loadaddr;
201220313Smarcel	archsw.arch_loadseg = ia64_loadseg;
202164010Smarcel	archsw.arch_readin = ia64_readin;
20377943Sdfr
20477943Sdfr	interact();			/* doesn't return */
20577943Sdfr
20678332Sobrien	return (EFI_SUCCESS);		/* keep compiler happy */
20777943Sdfr}
20877943Sdfr
20977943SdfrCOMMAND_SET(quit, "quit", "exit the loader", command_quit);
21077943Sdfr
21177943Sdfrstatic int
21277943Sdfrcommand_quit(int argc, char *argv[])
21377943Sdfr{
21478332Sobrien	exit(0);
215222799Smarcel	/* NOTREACHED */
21678332Sobrien	return (CMD_OK);
21777943Sdfr}
21883215Sdfr
219222799SmarcelCOMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
220222799Smarcel
221222799Smarcelstatic int
222222799Smarcelcommand_reboot(int argc, char *argv[])
223222799Smarcel{
224222799Smarcel
225222799Smarcel	RS->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
226222799Smarcel	/* NOTREACHED */
227222799Smarcel	return (CMD_OK);
228222799Smarcel}
229222799Smarcel
23083215SdfrCOMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
23183215Sdfr
23283215Sdfrstatic int
23383215Sdfrcommand_memmap(int argc, char *argv[])
23483215Sdfr{
23583215Sdfr	UINTN sz;
23683215Sdfr	EFI_MEMORY_DESCRIPTOR *map, *p;
23783215Sdfr	UINTN key, dsz;
23883215Sdfr	UINT32 dver;
23983215Sdfr	EFI_STATUS status;
24083215Sdfr	int i, ndesc;
24183215Sdfr	static char *types[] = {
24283215Sdfr	    "Reserved",
24383215Sdfr	    "LoaderCode",
24483215Sdfr	    "LoaderData",
24583215Sdfr	    "BootServicesCode",
24683215Sdfr	    "BootServicesData",
24783215Sdfr	    "RuntimeServicesCode",
24883215Sdfr	    "RuntimeServicesData",
24983215Sdfr	    "ConventionalMemory",
25083216Sdfr	    "UnusableMemory",
25183215Sdfr	    "ACPIReclaimMemory",
25283215Sdfr	    "ACPIMemoryNVS",
25383215Sdfr	    "MemoryMappedIO",
25483215Sdfr	    "MemoryMappedIOPortSpace",
25583215Sdfr	    "PalCode"
25683215Sdfr	};
25783215Sdfr
25883215Sdfr	sz = 0;
25983215Sdfr	status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
26083215Sdfr	if (status != EFI_BUFFER_TOO_SMALL) {
26183215Sdfr		printf("Can't determine memory map size\n");
26283857Sdfr		return CMD_ERROR;
26383215Sdfr	}
26483215Sdfr	map = malloc(sz);
26583215Sdfr	status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
26683215Sdfr	if (EFI_ERROR(status)) {
26783215Sdfr		printf("Can't read memory map\n");
26883857Sdfr		return CMD_ERROR;
26983215Sdfr	}
27083215Sdfr
27183215Sdfr	ndesc = sz / dsz;
27283216Sdfr	printf("%23s %12s %12s %8s %4s\n",
27383215Sdfr	       "Type", "Physical", "Virtual", "#Pages", "Attr");
27483215Sdfr
27583215Sdfr	for (i = 0, p = map; i < ndesc;
27683215Sdfr	     i++, p = NextMemoryDescriptor(p, dsz)) {
27783216Sdfr	    printf("%23s %012lx %012lx %08lx ",
27883215Sdfr		   types[p->Type],
27983215Sdfr		   p->PhysicalStart,
28083215Sdfr		   p->VirtualStart,
28183215Sdfr		   p->NumberOfPages);
28283215Sdfr	    if (p->Attribute & EFI_MEMORY_UC)
28383215Sdfr		printf("UC ");
28483215Sdfr	    if (p->Attribute & EFI_MEMORY_WC)
28583215Sdfr		printf("WC ");
28683215Sdfr	    if (p->Attribute & EFI_MEMORY_WT)
28783215Sdfr		printf("WT ");
28883215Sdfr	    if (p->Attribute & EFI_MEMORY_WB)
28983215Sdfr		printf("WB ");
29083215Sdfr	    if (p->Attribute & EFI_MEMORY_UCE)
29183215Sdfr		printf("UCE ");
29283215Sdfr	    if (p->Attribute & EFI_MEMORY_WP)
29383215Sdfr		printf("WP ");
29483215Sdfr	    if (p->Attribute & EFI_MEMORY_RP)
29583215Sdfr		printf("RP ");
29683215Sdfr	    if (p->Attribute & EFI_MEMORY_XP)
29783215Sdfr		printf("XP ");
29883215Sdfr	    if (p->Attribute & EFI_MEMORY_RUNTIME)
29983215Sdfr		printf("RUNTIME");
30083215Sdfr	    printf("\n");
30183215Sdfr	}
30283215Sdfr
30383857Sdfr	return CMD_OK;
30483215Sdfr}
30583857Sdfr
30683857SdfrCOMMAND_SET(configuration, "configuration",
30783857Sdfr	    "print configuration tables", command_configuration);
30883857Sdfr
309107722Smarcelstatic const char *
310107722Smarcelguid_to_string(EFI_GUID *guid)
311107722Smarcel{
312107722Smarcel	static char buf[40];
313107722Smarcel
314107722Smarcel	sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
315107722Smarcel	    guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
316107722Smarcel	    guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
317107722Smarcel	    guid->Data4[5], guid->Data4[6], guid->Data4[7]);
318107722Smarcel	return (buf);
319107722Smarcel}
320107722Smarcel
32183857Sdfrstatic int
32283857Sdfrcommand_configuration(int argc, char *argv[])
32383857Sdfr{
32483857Sdfr	int i;
32583857Sdfr
326100387Speter	printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
32783857Sdfr	for (i = 0; i < ST->NumberOfTableEntries; i++) {
328107722Smarcel		EFI_GUID *guid;
329107722Smarcel
33083857Sdfr		printf("  ");
331107722Smarcel		guid = &ST->ConfigurationTable[i].VendorGuid;
332107722Smarcel		if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
33383857Sdfr			printf("MPS Table");
334107722Smarcel		else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
33583857Sdfr			printf("ACPI Table");
336107722Smarcel		else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
33783857Sdfr			printf("ACPI 2.0 Table");
338107722Smarcel		else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
33983857Sdfr			printf("SMBIOS Table");
340107722Smarcel		else if (!memcmp(guid, &sal, sizeof(EFI_GUID)))
34183857Sdfr			printf("SAL System Table");
342107722Smarcel		else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID)))
343107722Smarcel			printf("DIG64 HCDP Table");
34483857Sdfr		else
345107722Smarcel			printf("Unknown Table (%s)", guid_to_string(guid));
34683857Sdfr		printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
34783857Sdfr	}
34883857Sdfr
34983857Sdfr	return CMD_OK;
35083857Sdfr}
35183857Sdfr
35283857SdfrCOMMAND_SET(sal, "sal", "print SAL System Table", command_sal);
35383857Sdfr
35483857Sdfrstatic int
35583857Sdfrcommand_sal(int argc, char *argv[])
35683857Sdfr{
35783857Sdfr	int i;
35883857Sdfr	struct sal_system_table *saltab = 0;
35983857Sdfr	static int sizes[6] = {
36083857Sdfr		48, 32, 16, 32, 16, 16
36183857Sdfr	};
36283857Sdfr	u_int8_t *p;
36383857Sdfr
364107733Smarcel	saltab = efi_get_table(&sal);
365107733Smarcel	if (saltab == NULL) {
36683857Sdfr		printf("Can't find SAL System Table\n");
36783857Sdfr		return CMD_ERROR;
36883857Sdfr	}
36983857Sdfr
37083857Sdfr	if (memcmp(saltab->sal_signature, "SST_", 4)) {
37183857Sdfr		printf("Bad signature for SAL System Table\n");
37283857Sdfr		return CMD_ERROR;
37383857Sdfr	}
37483857Sdfr
37583857Sdfr	printf("SAL Revision %x.%02x\n",
37683857Sdfr	       saltab->sal_rev[1],
37783857Sdfr	       saltab->sal_rev[0]);
37883857Sdfr	printf("SAL A Version %x.%02x\n",
37983857Sdfr	       saltab->sal_a_version[1],
38083857Sdfr	       saltab->sal_a_version[0]);
38183857Sdfr	printf("SAL B Version %x.%02x\n",
38283857Sdfr	       saltab->sal_b_version[1],
38383857Sdfr	       saltab->sal_b_version[0]);
38483857Sdfr
38583857Sdfr	p = (u_int8_t *) (saltab + 1);
38683857Sdfr	for (i = 0; i < saltab->sal_entry_count; i++) {
38783857Sdfr		printf("  Desc %d", *p);
38883857Sdfr		if (*p == 0) {
38983857Sdfr			struct sal_entrypoint_descriptor *dp;
39083857Sdfr			dp = (struct sal_entrypoint_descriptor *) p;
39183857Sdfr			printf("\n");
39283857Sdfr			printf("    PAL Proc at 0x%lx\n",
39383857Sdfr			       dp->sale_pal_proc);
39483857Sdfr			printf("    SAL Proc at 0x%lx\n",
39583857Sdfr			       dp->sale_sal_proc);
39683857Sdfr			printf("    SAL GP at 0x%lx\n",
39783857Sdfr			       dp->sale_sal_gp);
39883857Sdfr		} else if (*p == 1) {
39983857Sdfr			struct sal_memory_descriptor *dp;
40083857Sdfr			dp = (struct sal_memory_descriptor *) p;
40183857Sdfr			printf(" Type %d.%d, ",
40283857Sdfr			       dp->sale_memory_type[0],
40383857Sdfr			       dp->sale_memory_type[1]);
40483857Sdfr			printf("Address 0x%lx, ",
40583857Sdfr			       dp->sale_physical_address);
40683857Sdfr			printf("Length 0x%x\n",
40783857Sdfr			       dp->sale_length);
408107203Smarcel		} else if (*p == 5) {
409107203Smarcel			struct sal_ap_wakeup_descriptor *dp;
410107203Smarcel			dp = (struct sal_ap_wakeup_descriptor *) p;
41183857Sdfr			printf("\n");
412107203Smarcel			printf("    Mechanism %d\n", dp->sale_mechanism);
413107203Smarcel			printf("    Vector 0x%lx\n", dp->sale_vector);
414107203Smarcel		} else
415107203Smarcel			printf("\n");
416107203Smarcel
41783857Sdfr		p += sizes[*p];
41883857Sdfr	}
41983857Sdfr
42083857Sdfr	return CMD_OK;
42183857Sdfr}
42283904Sdfr
42383904Sdfrint
42483904Sdfrprint_trs(int type)
42583904Sdfr{
426133420Smarcel	struct ia64_pal_result res;
427133420Smarcel	int i, maxtr;
42883904Sdfr	struct {
429135630Smarcel		pt_entry_t	pte;
430137978Smarcel		uint64_t	itir;
431133420Smarcel		uint64_t	ifa;
43283904Sdfr		struct ia64_rr	rr;
433133420Smarcel	} buf;
434133420Smarcel	static const char *psnames[] = {
43583904Sdfr		"1B",	"2B",	"4B",	"8B",
43683904Sdfr		"16B",	"32B",	"64B",	"128B",
43783904Sdfr		"256B",	"512B",	"1K",	"2K",
43883904Sdfr		"4K",	"8K",	"16K",	"32K",
43983904Sdfr		"64K",	"128K",	"256K",	"512K",
44083904Sdfr		"1M",	"2M",	"4M",	"8M",
44183904Sdfr		"16M",	"32M",	"64M",	"128M",
44283904Sdfr		"256M",	"512M",	"1G",	"2G"
44383904Sdfr	};
444133420Smarcel	static const char *manames[] = {
44583904Sdfr		"WB",	"bad",	"bad",	"bad",
44683904Sdfr		"UC",	"UCE",	"WC",	"NaT",
44783904Sdfr	};
44883904Sdfr
44983904Sdfr	res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0);
45083904Sdfr	if (res.pal_status != 0) {
45183904Sdfr		printf("Can't get VM summary\n");
45283904Sdfr		return CMD_ERROR;
45383904Sdfr	}
45483904Sdfr
45583904Sdfr	if (type == 0)
45683904Sdfr		maxtr = (res.pal_result[0] >> 40) & 0xff;
45783904Sdfr	else
45883904Sdfr		maxtr = (res.pal_result[0] >> 32) & 0xff;
45983904Sdfr
460107203Smarcel	printf("%d translation registers\n", maxtr);
461107203Smarcel
46283904Sdfr	pager_open();
463107203Smarcel	pager_output("TR# RID    Virtual Page  Physical Page PgSz ED AR PL D A MA  P KEY\n");
46483904Sdfr	for (i = 0; i <= maxtr; i++) {
46583904Sdfr		char lbuf[128];
46683904Sdfr
46783904Sdfr		bzero(&buf, sizeof(buf));
46883904Sdfr		res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type,
46983904Sdfr					    (u_int64_t) &buf);
470107203Smarcel		if (res.pal_status != 0)
471107203Smarcel			break;
472107203Smarcel
473107203Smarcel		/* Only display valid translations */
474133420Smarcel		if ((buf.ifa & 1) == 0)
475107203Smarcel			continue;
476107203Smarcel
47783904Sdfr		if (!(res.pal_result[0] & 1))
478135630Smarcel			buf.pte &= ~PTE_AR_MASK;
47983904Sdfr		if (!(res.pal_result[0] & 2))
480135630Smarcel			buf.pte &= ~PTE_PL_MASK;
48183904Sdfr		if (!(res.pal_result[0] & 4))
482135630Smarcel			buf.pte &= ~PTE_DIRTY;
48383904Sdfr		if (!(res.pal_result[0] & 8))
484135630Smarcel			buf.pte &= ~PTE_MA_MASK;
485135630Smarcel		sprintf(lbuf, "%03d %06x %013lx %013lx %4s %d  %d  %d  %d %d "
486135630Smarcel		    "%-3s %d %06x\n", i, buf.rr.rr_rid, buf.ifa >> 12,
487137978Smarcel		    (buf.pte & PTE_PPN_MASK) >> 12,
488137978Smarcel		    psnames[(buf.itir & ITIR_PS_MASK) >> 2],
489135630Smarcel		    (buf.pte & PTE_ED) ? 1 : 0,
490135630Smarcel		    (int)(buf.pte & PTE_AR_MASK) >> 9,
491135630Smarcel		    (int)(buf.pte & PTE_PL_MASK) >> 7,
492135630Smarcel		    (buf.pte & PTE_DIRTY) ? 1 : 0,
493135630Smarcel		    (buf.pte & PTE_ACCESSED) ? 1 : 0,
494135630Smarcel		    manames[(buf.pte & PTE_MA_MASK) >> 2],
495135630Smarcel		    (buf.pte & PTE_PRESENT) ? 1 : 0,
496137978Smarcel		    (int)((buf.itir & ITIR_KEY_MASK) >> 8));
49783904Sdfr		pager_output(lbuf);
49883904Sdfr	}
49983904Sdfr	pager_close();
50083939Sdfr
501107203Smarcel	if (res.pal_status != 0) {
502107203Smarcel		printf("Error while getting TR contents\n");
503107203Smarcel		return CMD_ERROR;
504107203Smarcel	}
50583939Sdfr	return CMD_OK;
50683904Sdfr}
50783904Sdfr
50883904SdfrCOMMAND_SET(itr, "itr", "print instruction TRs", command_itr);
50983904Sdfr
51083904Sdfrstatic int
51183904Sdfrcommand_itr(int argc, char *argv[])
51283904Sdfr{
51383904Sdfr	return print_trs(0);
51483904Sdfr}
51583904Sdfr
51683904SdfrCOMMAND_SET(dtr, "dtr", "print data TRs", command_dtr);
51783904Sdfr
51883904Sdfrstatic int
51983904Sdfrcommand_dtr(int argc, char *argv[])
52083904Sdfr{
52183904Sdfr	return print_trs(1);
52283904Sdfr}
52383904Sdfr
524108025SmarcelCOMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp);
525108025Smarcel
526108025Smarcelstatic char *
527108025Smarcelhcdp_string(char *s, u_int len)
528108025Smarcel{
529108025Smarcel	static char buffer[256];
530108025Smarcel
531108025Smarcel	memcpy(buffer, s, len);
532108025Smarcel	buffer[len] = 0;
533108025Smarcel	return (buffer);
534108025Smarcel}
535108025Smarcel
536108025Smarcelstatic int
537108025Smarcelcommand_hcdp(int argc, char *argv[])
538108025Smarcel{
539108025Smarcel	struct dig64_hcdp_table *tbl;
540108025Smarcel	struct dig64_hcdp_entry *ent;
541108025Smarcel	struct dig64_gas *gas;
542108025Smarcel	int i;
543108025Smarcel
544108025Smarcel	tbl = efi_get_table(&hcdp);
545108025Smarcel	if (tbl == NULL) {
546108025Smarcel		printf("No HCDP table present\n");
547108025Smarcel		return (CMD_OK);
548108025Smarcel	}
549108025Smarcel	if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) {
550108025Smarcel		printf("HCDP table has invalid signature\n");
551108025Smarcel		return (CMD_OK);
552108025Smarcel	}
553108025Smarcel	if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) {
554108025Smarcel		printf("HCDP table too short\n");
555108025Smarcel		return (CMD_OK);
556108025Smarcel	}
557108025Smarcel	printf("HCDP table at 0x%016lx\n", (u_long)tbl);
558108025Smarcel	printf("Signature  = %s\n", hcdp_string(tbl->signature, 4));
559108025Smarcel	printf("Length     = %u\n", tbl->length);
560108025Smarcel	printf("Revision   = %u\n", tbl->revision);
561108025Smarcel	printf("Checksum   = %u\n", tbl->checksum);
562108025Smarcel	printf("OEM Id     = %s\n", hcdp_string(tbl->oem_id, 6));
563108025Smarcel	printf("Table Id   = %s\n", hcdp_string(tbl->oem_tbl_id, 8));
564108025Smarcel	printf("OEM rev    = %u\n", tbl->oem_rev);
565108025Smarcel	printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4));
566108025Smarcel	printf("Creator rev= %u\n", tbl->creator_rev);
567108025Smarcel	printf("Entries    = %u\n", tbl->entries);
568108025Smarcel	for (i = 0; i < tbl->entries; i++) {
569108025Smarcel		ent = tbl->entry + i;
570108025Smarcel		printf("Entry #%d:\n", i + 1);
571108025Smarcel		printf("    Type      = %u\n", ent->type);
572108025Smarcel		printf("    Databits  = %u\n", ent->databits);
573108025Smarcel		printf("    Parity    = %u\n", ent->parity);
574108025Smarcel		printf("    Stopbits  = %u\n", ent->stopbits);
575108025Smarcel		printf("    PCI seg   = %u\n", ent->pci_segment);
576108025Smarcel		printf("    PCI bus   = %u\n", ent->pci_bus);
577108025Smarcel		printf("    PCI dev   = %u\n", ent->pci_device);
578108025Smarcel		printf("    PCI func  = %u\n", ent->pci_function);
579108025Smarcel		printf("    Interrupt = %u\n", ent->interrupt);
580108025Smarcel		printf("    PCI flag  = %u\n", ent->pci_flag);
581108025Smarcel		printf("    Baudrate  = %lu\n",
582108025Smarcel		    ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low);
583108025Smarcel		gas = &ent->address;
584108025Smarcel		printf("    Addr space= %u\n", gas->addr_space);
585108025Smarcel		printf("    Bit width = %u\n", gas->bit_width);
586108025Smarcel		printf("    Bit offset= %u\n", gas->bit_offset);
587108025Smarcel		printf("    Address   = 0x%016lx\n",
588108025Smarcel		    ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low);
589108025Smarcel		printf("    PCI type  = %u\n", ent->pci_devid);
590108025Smarcel		printf("    PCI vndr  = %u\n", ent->pci_vendor);
591108025Smarcel		printf("    IRQ       = %u\n", ent->irq);
592108025Smarcel		printf("    PClock    = %u\n", ent->pclock);
593108025Smarcel		printf("    PCI iface = %u\n", ent->pci_interface);
594108025Smarcel	}
595108025Smarcel	printf("<EOT>\n");
596108025Smarcel	return (CMD_OK);
597108025Smarcel}
598222799Smarcel
599222799SmarcelCOMMAND_SET(about, "about", "about the loader", command_about);
600222799Smarcel
601222799Smarcelextern uint64_t _start_plabel[];
602222799Smarcel
603222799Smarcelstatic int
604222799Smarcelcommand_about(int argc, char *argv[])
605222799Smarcel{
606222799Smarcel	EFI_LOADED_IMAGE *img;
607222799Smarcel
608222799Smarcel	printf("%s\n", bootprog_name);
609222799Smarcel	printf("revision %s\n", bootprog_rev);
610222799Smarcel	printf("built by %s\n", bootprog_maker);
611222799Smarcel	printf("built on %s\n", bootprog_date);
612222799Smarcel
613222799Smarcel	printf("\n");
614222799Smarcel
615222799Smarcel	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
616222799Smarcel	printf("image loaded at %p\n", img->ImageBase);
617222799Smarcel	printf("entry at %#lx (%#lx)\n", _start_plabel[0], _start_plabel[1]);
618222799Smarcel}
619