config root man

Current Path : /sys/amd64/compile/hs32/modules/usr/src/sys/modules/reiserfs/@/boot/ia64/efi/

FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64
Upload File :
Current File : //sys/amd64/compile/hs32/modules/usr/src/sys/modules/reiserfs/@/boot/ia64/efi/main.c

/*-
 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
 * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__FBSDID("$FreeBSD: release/9.1.0/sys/boot/ia64/efi/main.c 222799 2011-06-07 00:59:31Z marcel $");

#include <stand.h>
#include <string.h>
#include <setjmp.h>
#include <machine/sal.h>
#include <machine/pal.h>
#include <machine/pte.h>
#include <machine/dig64.h>

#include <efi.h>
#include <efilib.h>

#include <libia64.h>

/* DIG64 Headless Console & Debug Port Table. */
#define	HCDP_TABLE_GUID		\
    {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
 
extern char bootprog_name[];
extern char bootprog_rev[];
extern char bootprog_date[];
extern char bootprog_maker[];

struct arch_switch archsw;	/* MI/MD interface boundary */

extern u_int64_t	ia64_pal_entry;

EFI_GUID acpi = ACPI_TABLE_GUID;
EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
EFI_GUID devid = DEVICE_PATH_PROTOCOL;
EFI_GUID hcdp = HCDP_TABLE_GUID;
EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
EFI_GUID mps = MPS_TABLE_GUID;
EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
EFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
EFI_GUID smbios = SMBIOS_TABLE_GUID;

static void
find_pal_proc(void)
{
	int i;
	struct sal_system_table *saltab = 0;
	static int sizes[6] = {
		48, 32, 16, 32, 16, 16
	};
	u_int8_t *p;

	saltab = efi_get_table(&sal);
	if (saltab == NULL) {
		printf("Can't find SAL System Table\n");
		return;
	}

	if (memcmp(saltab->sal_signature, "SST_", 4)) {
		printf("Bad signature for SAL System Table\n");
		return;
	}

	p = (u_int8_t *) (saltab + 1);
	for (i = 0; i < saltab->sal_entry_count; i++) {
		if (*p == 0) {
			struct sal_entrypoint_descriptor *dp;
			dp = (struct sal_entrypoint_descriptor *) p;
			ia64_pal_entry = dp->sale_pal_proc;
			return;
		}
		p += sizes[*p];
	}

	printf("Can't find PAL proc\n");
	return;
}

static int
usc2cmp(CHAR16 *s1, CHAR16 *s2)
{

	while (*s1 == *s2++) {
		if (*s1++ == 0)
			return (0);
	}
	return (*s1 - *(s2 - 1));
}

static char *
get_dev_option(int argc, CHAR16 *argv[])
{
	static char dev[32];
	CHAR16 *arg;
	char *devp;
	int i, j;

	devp = NULL;
	for (i = 0; i < argc; i++) {
		if (usc2cmp(argv[i], L"-dev") == 0 && i < argc - 1) {
			arg = argv[i + 1];
			j = 0;
			while (j < sizeof(dev) && *arg != 0)
				dev[j++] = *arg++;
			if (j == sizeof(dev))
				j--;
			dev[j] = '\0';
			devp = dev;
			break;
		}
	}

	return (devp);
}

EFI_STATUS
main(int argc, CHAR16 *argv[])
{
	struct devdesc currdev;
	EFI_LOADED_IMAGE *img;
	char *dev;
	int i;

	/* 
	 * XXX Chicken-and-egg problem; we want to have console output
	 * early, but some console attributes may depend on reading from
	 * eg. the boot device, which we can't do yet.  We can use
	 * printf() etc. once this is done.
	 */
	cons_probe();

	printf("\n%s, Revision %s\n", bootprog_name, bootprog_rev);

	find_pal_proc();

	/*
	 * March through the device switch probing for things.
	 */
	for (i = 0; devsw[i] != NULL; i++)
		if (devsw[i]->dv_init != NULL)
			(devsw[i]->dv_init)();

	/*
	 * Disable the watchdog timer. By default the boot manager sets
	 * the timer to 5 minutes before invoking a boot option. If we
	 * want to return to the boot manager, we have to disable the
	 * watchdog timer and since we're an interactive program, we don't
	 * want to wait until the user types "quit". The timer may have
	 * fired by then. We don't care if this fails. It does not prevent
	 * normal functioning in any way...
	 */
	BS->SetWatchdogTimer(0, 0, 0, NULL);

	/* Get our loaded image protocol interface structure. */
	BS->HandleProtocol(IH, &imgid, (VOID**)&img);

	bzero(&currdev, sizeof(currdev));
	efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
	currdev.d_type = currdev.d_dev->dv_type;

	env_setenv("loaddev", EV_VOLATILE, ia64_fmtdev(&currdev), env_noset,
	    env_nounset);

	dev = get_dev_option(argc, argv);
	if (dev == NULL)
		dev = ia64_fmtdev(&currdev);

	env_setenv("currdev", EV_VOLATILE, dev, ia64_setcurrdev, env_nounset);

	setenv("LINES", "24", 1);	/* optional */

	archsw.arch_autoload = ia64_autoload;
	archsw.arch_copyin = ia64_copyin;
	archsw.arch_copyout = ia64_copyout;
	archsw.arch_getdev = ia64_getdev;
	archsw.arch_loadaddr = ia64_loadaddr;
	archsw.arch_loadseg = ia64_loadseg;
	archsw.arch_readin = ia64_readin;

	interact();			/* doesn't return */

	return (EFI_SUCCESS);		/* keep compiler happy */
}

COMMAND_SET(quit, "quit", "exit the loader", command_quit);

static int
command_quit(int argc, char *argv[])
{
	exit(0);
	/* NOTREACHED */
	return (CMD_OK);
}

COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
 
static int
command_reboot(int argc, char *argv[])
{

	RS->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
	/* NOTREACHED */
	return (CMD_OK);
}

COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);

static int
command_memmap(int argc, char *argv[])
{
	UINTN sz;
	EFI_MEMORY_DESCRIPTOR *map, *p;
	UINTN key, dsz;
	UINT32 dver;
	EFI_STATUS status;
	int i, ndesc;
	static char *types[] = {
	    "Reserved",
	    "LoaderCode",
	    "LoaderData",
	    "BootServicesCode",
	    "BootServicesData",
	    "RuntimeServicesCode",
	    "RuntimeServicesData",
	    "ConventionalMemory",
	    "UnusableMemory",
	    "ACPIReclaimMemory",
	    "ACPIMemoryNVS",
	    "MemoryMappedIO",
	    "MemoryMappedIOPortSpace",
	    "PalCode"
	};

	sz = 0;
	status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
	if (status != EFI_BUFFER_TOO_SMALL) {
		printf("Can't determine memory map size\n");
		return CMD_ERROR;
	}
	map = malloc(sz);
	status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
	if (EFI_ERROR(status)) {
		printf("Can't read memory map\n");
		return CMD_ERROR;
	}

	ndesc = sz / dsz;
	printf("%23s %12s %12s %8s %4s\n",
	       "Type", "Physical", "Virtual", "#Pages", "Attr");
	       
	for (i = 0, p = map; i < ndesc;
	     i++, p = NextMemoryDescriptor(p, dsz)) {
	    printf("%23s %012lx %012lx %08lx ",
		   types[p->Type],
		   p->PhysicalStart,
		   p->VirtualStart,
		   p->NumberOfPages);
	    if (p->Attribute & EFI_MEMORY_UC)
		printf("UC ");
	    if (p->Attribute & EFI_MEMORY_WC)
		printf("WC ");
	    if (p->Attribute & EFI_MEMORY_WT)
		printf("WT ");
	    if (p->Attribute & EFI_MEMORY_WB)
		printf("WB ");
	    if (p->Attribute & EFI_MEMORY_UCE)
		printf("UCE ");
	    if (p->Attribute & EFI_MEMORY_WP)
		printf("WP ");
	    if (p->Attribute & EFI_MEMORY_RP)
		printf("RP ");
	    if (p->Attribute & EFI_MEMORY_XP)
		printf("XP ");
	    if (p->Attribute & EFI_MEMORY_RUNTIME)
		printf("RUNTIME");
	    printf("\n");
	}

	return CMD_OK;
}

COMMAND_SET(configuration, "configuration",
	    "print configuration tables", command_configuration);

static const char *
guid_to_string(EFI_GUID *guid)
{
	static char buf[40];

	sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
	    guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
	    guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
	    guid->Data4[5], guid->Data4[6], guid->Data4[7]);
	return (buf);
}

static int
command_configuration(int argc, char *argv[])
{
	int i;

	printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
	for (i = 0; i < ST->NumberOfTableEntries; i++) {
		EFI_GUID *guid;

		printf("  ");
		guid = &ST->ConfigurationTable[i].VendorGuid;
		if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
			printf("MPS Table");
		else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
			printf("ACPI Table");
		else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
			printf("ACPI 2.0 Table");
		else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
			printf("SMBIOS Table");
		else if (!memcmp(guid, &sal, sizeof(EFI_GUID)))
			printf("SAL System Table");
		else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID)))
			printf("DIG64 HCDP Table");
		else
			printf("Unknown Table (%s)", guid_to_string(guid));
		printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
	}

	return CMD_OK;
}    

COMMAND_SET(sal, "sal", "print SAL System Table", command_sal);

static int
command_sal(int argc, char *argv[])
{
	int i;
	struct sal_system_table *saltab = 0;
	static int sizes[6] = {
		48, 32, 16, 32, 16, 16
	};
	u_int8_t *p;

	saltab = efi_get_table(&sal);
	if (saltab == NULL) {
		printf("Can't find SAL System Table\n");
		return CMD_ERROR;
	}

	if (memcmp(saltab->sal_signature, "SST_", 4)) {
		printf("Bad signature for SAL System Table\n");
		return CMD_ERROR;
	}

	printf("SAL Revision %x.%02x\n",
	       saltab->sal_rev[1],
	       saltab->sal_rev[0]);
	printf("SAL A Version %x.%02x\n",
	       saltab->sal_a_version[1],
	       saltab->sal_a_version[0]);
	printf("SAL B Version %x.%02x\n",
	       saltab->sal_b_version[1],
	       saltab->sal_b_version[0]);

	p = (u_int8_t *) (saltab + 1);
	for (i = 0; i < saltab->sal_entry_count; i++) {
		printf("  Desc %d", *p);
		if (*p == 0) {
			struct sal_entrypoint_descriptor *dp;
			dp = (struct sal_entrypoint_descriptor *) p;
			printf("\n");
			printf("    PAL Proc at 0x%lx\n",
			       dp->sale_pal_proc);
			printf("    SAL Proc at 0x%lx\n",
			       dp->sale_sal_proc);
			printf("    SAL GP at 0x%lx\n",
			       dp->sale_sal_gp);
		} else if (*p == 1) {
			struct sal_memory_descriptor *dp;
			dp = (struct sal_memory_descriptor *) p;
			printf(" Type %d.%d, ",
			       dp->sale_memory_type[0],
			       dp->sale_memory_type[1]);
			printf("Address 0x%lx, ",
			       dp->sale_physical_address);
			printf("Length 0x%x\n",
			       dp->sale_length);
		} else if (*p == 5) {
			struct sal_ap_wakeup_descriptor *dp;
			dp = (struct sal_ap_wakeup_descriptor *) p;
			printf("\n");
			printf("    Mechanism %d\n", dp->sale_mechanism);
			printf("    Vector 0x%lx\n", dp->sale_vector);
		} else
			printf("\n");

		p += sizes[*p];
	}

	return CMD_OK;
}

int
print_trs(int type)
{
	struct ia64_pal_result res;
	int i, maxtr;
	struct {
		pt_entry_t	pte;
		uint64_t	itir;
		uint64_t	ifa;
		struct ia64_rr	rr;
	} buf;
	static const char *psnames[] = {
		"1B",	"2B",	"4B",	"8B",
		"16B",	"32B",	"64B",	"128B",
		"256B",	"512B",	"1K",	"2K",
		"4K",	"8K",	"16K",	"32K",
		"64K",	"128K",	"256K",	"512K",
		"1M",	"2M",	"4M",	"8M",
		"16M",	"32M",	"64M",	"128M",
		"256M",	"512M",	"1G",	"2G"
	};
	static const char *manames[] = {
		"WB",	"bad",	"bad",	"bad",
		"UC",	"UCE",	"WC",	"NaT",
	};

	res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0);
	if (res.pal_status != 0) {
		printf("Can't get VM summary\n");
		return CMD_ERROR;
	}

	if (type == 0)
		maxtr = (res.pal_result[0] >> 40) & 0xff;
	else
		maxtr = (res.pal_result[0] >> 32) & 0xff;

	printf("%d translation registers\n", maxtr);

	pager_open();
	pager_output("TR# RID    Virtual Page  Physical Page PgSz ED AR PL D A MA  P KEY\n");
	for (i = 0; i <= maxtr; i++) {
		char lbuf[128];

		bzero(&buf, sizeof(buf));
		res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type,
					    (u_int64_t) &buf);
		if (res.pal_status != 0)
			break;

		/* Only display valid translations */
		if ((buf.ifa & 1) == 0)
			continue;

		if (!(res.pal_result[0] & 1))
			buf.pte &= ~PTE_AR_MASK;
		if (!(res.pal_result[0] & 2))
			buf.pte &= ~PTE_PL_MASK;
		if (!(res.pal_result[0] & 4))
			buf.pte &= ~PTE_DIRTY;
		if (!(res.pal_result[0] & 8))
			buf.pte &= ~PTE_MA_MASK;
		sprintf(lbuf, "%03d %06x %013lx %013lx %4s %d  %d  %d  %d %d "
		    "%-3s %d %06x\n", i, buf.rr.rr_rid, buf.ifa >> 12,
		    (buf.pte & PTE_PPN_MASK) >> 12,
		    psnames[(buf.itir & ITIR_PS_MASK) >> 2],
		    (buf.pte & PTE_ED) ? 1 : 0,
		    (int)(buf.pte & PTE_AR_MASK) >> 9,
		    (int)(buf.pte & PTE_PL_MASK) >> 7,
		    (buf.pte & PTE_DIRTY) ? 1 : 0,
		    (buf.pte & PTE_ACCESSED) ? 1 : 0,
		    manames[(buf.pte & PTE_MA_MASK) >> 2],
		    (buf.pte & PTE_PRESENT) ? 1 : 0,
		    (int)((buf.itir & ITIR_KEY_MASK) >> 8));
		pager_output(lbuf);
	}
	pager_close();

	if (res.pal_status != 0) {
		printf("Error while getting TR contents\n");
		return CMD_ERROR;
	}
	return CMD_OK;
}

COMMAND_SET(itr, "itr", "print instruction TRs", command_itr);

static int
command_itr(int argc, char *argv[])
{
	return print_trs(0);
}

COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr);

static int
command_dtr(int argc, char *argv[])
{
	return print_trs(1);
}

COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp);

static char *
hcdp_string(char *s, u_int len)
{
	static char buffer[256];

	memcpy(buffer, s, len);
	buffer[len] = 0;
	return (buffer);
}
	
static int
command_hcdp(int argc, char *argv[])
{
	struct dig64_hcdp_table *tbl;
	struct dig64_hcdp_entry *ent;
	struct dig64_gas *gas;
	int i;

	tbl = efi_get_table(&hcdp);
	if (tbl == NULL) {
		printf("No HCDP table present\n");
		return (CMD_OK);
	}
	if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) {
		printf("HCDP table has invalid signature\n");
		return (CMD_OK);
	}
	if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) {
		printf("HCDP table too short\n");
		return (CMD_OK);
	}
	printf("HCDP table at 0x%016lx\n", (u_long)tbl);
	printf("Signature  = %s\n", hcdp_string(tbl->signature, 4));
	printf("Length     = %u\n", tbl->length);
	printf("Revision   = %u\n", tbl->revision);
	printf("Checksum   = %u\n", tbl->checksum);
	printf("OEM Id     = %s\n", hcdp_string(tbl->oem_id, 6));
	printf("Table Id   = %s\n", hcdp_string(tbl->oem_tbl_id, 8));
	printf("OEM rev    = %u\n", tbl->oem_rev);
	printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4));
	printf("Creator rev= %u\n", tbl->creator_rev);
	printf("Entries    = %u\n", tbl->entries);
	for (i = 0; i < tbl->entries; i++) {
		ent = tbl->entry + i;
		printf("Entry #%d:\n", i + 1);
		printf("    Type      = %u\n", ent->type);
		printf("    Databits  = %u\n", ent->databits);
		printf("    Parity    = %u\n", ent->parity);
		printf("    Stopbits  = %u\n", ent->stopbits);
		printf("    PCI seg   = %u\n", ent->pci_segment);
		printf("    PCI bus   = %u\n", ent->pci_bus);
		printf("    PCI dev   = %u\n", ent->pci_device);
		printf("    PCI func  = %u\n", ent->pci_function);
		printf("    Interrupt = %u\n", ent->interrupt);
		printf("    PCI flag  = %u\n", ent->pci_flag);
		printf("    Baudrate  = %lu\n",
		    ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low);
		gas = &ent->address;
		printf("    Addr space= %u\n", gas->addr_space);
		printf("    Bit width = %u\n", gas->bit_width);
		printf("    Bit offset= %u\n", gas->bit_offset);
		printf("    Address   = 0x%016lx\n",
		    ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low);
		printf("    PCI type  = %u\n", ent->pci_devid);
		printf("    PCI vndr  = %u\n", ent->pci_vendor);
		printf("    IRQ       = %u\n", ent->irq);
		printf("    PClock    = %u\n", ent->pclock);
		printf("    PCI iface = %u\n", ent->pci_interface);
	}
	printf("<EOT>\n");
	return (CMD_OK);
}

COMMAND_SET(about, "about", "about the loader", command_about);

extern uint64_t _start_plabel[];

static int
command_about(int argc, char *argv[])
{
	EFI_LOADED_IMAGE *img;

	printf("%s\n", bootprog_name);
	printf("revision %s\n", bootprog_rev);
	printf("built by %s\n", bootprog_maker);
	printf("built on %s\n", bootprog_date);

	printf("\n");

	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
	printf("image loaded at %p\n", img->ImageBase);
	printf("entry at %#lx (%#lx)\n", _start_plabel[0], _start_plabel[1]);
}

Man Man