Пример #1
0
static void
find_pal_proc(void)
{
	int i;
	struct sal_system_table *saltab = NULL;
	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;
}
Пример #2
0
static u_long
acpi_get_root_from_efi(void)
{
	static struct uuid acpi_root_uuid = EFI_TABLE_ACPI20;
	void *acpi_root;

	acpi_root = efi_get_table(&acpi_root_uuid);
	if (acpi_root != NULL)
		return (IA64_RR_MASK((uintptr_t)acpi_root));

	return (0);
}
Пример #3
0
static int
efidev_ioctl(struct dev_ioctl_args *ap)
{
	u_long cmd = ap->a_cmd;
	caddr_t addr = ap->a_data;
	int error;

	switch (cmd) {
	case EFIIOC_GET_TABLE:
	{
		struct efi_get_table_ioc *egtioc =
		    (struct efi_get_table_ioc *)addr;

		error = efi_get_table(&egtioc->uuid, &egtioc->ptr);
		break;
	}
	case EFIIOC_GET_TIME:
	{
		struct efi_tm *tm = (struct efi_tm *)addr;

		error = efi_get_time(tm);
		break;
	}
	case EFIIOC_SET_TIME:
	{
		struct efi_tm *tm = (struct efi_tm *)addr;

		error = efi_set_time(tm);
		break;
	}
	case EFIIOC_VAR_GET:
	{
		struct efi_var_ioc *ev = (struct efi_var_ioc *)addr;
		void *data;
		efi_char *name;

		data = kmalloc(ev->datasize, M_TEMP, M_WAITOK);
		name = kmalloc(ev->namesize, M_TEMP, M_WAITOK);
		error = copyin(ev->name, name, ev->namesize);
		if (error)
			goto vg_out;
		if (name[ev->namesize / sizeof(efi_char) - 1] != 0) {
			error = EINVAL;
			goto vg_out;
		}

		error = efi_var_get(name, &ev->vendor, &ev->attrib,
		    &ev->datasize, data);

		if (error == 0) {
			error = copyout(data, ev->data, ev->datasize);
		} else if (error == EOVERFLOW) {
			/*
			 * Pass back the size we really need, but
			 * convert the error to 0 so the copyout
			 * happens. datasize was updated in the
			 * efi_var_get call.
			 */
			ev->data = NULL;
			error = 0;
		}
vg_out:
		kfree(data, M_TEMP);
		kfree(name, M_TEMP);
		break;
	}
	case EFIIOC_VAR_NEXT:
	{
		struct efi_var_ioc *ev = (struct efi_var_ioc *)addr;
		efi_char *name;

		name = kmalloc(ev->namesize, M_TEMP, M_WAITOK);
		error = copyin(ev->name, name, ev->namesize);
		if (error)
			goto vn_out;
		/* Note: namesize is the buffer size, not the string lenght */

		error = efi_var_nextname(&ev->namesize, name, &ev->vendor);
		if (error == 0) {
			error = copyout(name, ev->name, ev->namesize);
		} else if (error == EOVERFLOW) {
			ev->name = NULL;
			error = 0;
		}
	vn_out:
		kfree(name, M_TEMP);
		break;
	}
	case EFIIOC_VAR_SET:
	{
		struct efi_var_ioc *ev = (struct efi_var_ioc *)addr;
		void *data = NULL;
		efi_char *name;

		/* datasize == 0 -> delete (more or less) */
		if (ev->datasize > 0)
			data = kmalloc(ev->datasize, M_TEMP, M_WAITOK);
		name = kmalloc(ev->namesize, M_TEMP, M_WAITOK);
		if (ev->datasize) {
			error = copyin(ev->data, data, ev->datasize);
			if (error)
				goto vs_out;
		}
		error = copyin(ev->name, name, ev->namesize);
		if (error)
			goto vs_out;
		if (name[ev->namesize / sizeof(efi_char) - 1] != 0) {
			error = EINVAL;
			goto vs_out;
		}

		error = efi_var_set(name, &ev->vendor, ev->attrib, ev->datasize,
		    data);
vs_out:
		kfree(data, M_TEMP);
		kfree(name, M_TEMP);
		break;
	}
	default:
		error = ENOTTY;
		break;
	}

	return (error);
}
Пример #4
0
int
ldr_bootinfo(struct bootinfo *bi, uint64_t *bi_addr)
{
	VOID *fpswa;
	EFI_MEMORY_DESCRIPTOR *mm;
	EFI_PHYSICAL_ADDRESS addr;
	EFI_HANDLE handle;
	EFI_STATUS status;
	size_t bisz;
	UINTN mmsz, pages, sz;
	UINT32 mmver;

	bi->bi_systab = (uint64_t)ST;
	bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp_guid);

	sz = sizeof(EFI_HANDLE);
	status = BS->LocateHandle(ByProtocol, &fpswa_guid, 0, &sz, &handle);
	if (status == 0)
		status = BS->HandleProtocol(handle, &fpswa_guid, &fpswa);
	bi->bi_fpswa = (status == 0) ? (uint64_t)fpswa : 0;

	bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f;

	/*
	 * Allocate enough pages to hold the bootinfo block and the memory
	 * map EFI will return to us. The memory map has an unknown size,
	 * so we have to determine that first. Note that the AllocatePages
	 * call can itself modify the memory map, so we have to take that
	 * into account as well. The changes to the memory map are caused
	 * by splitting a range of free memory into two (AFAICT), so that
	 * one is marked as being loader data.
	 */
	sz = 0;
	BS->GetMemoryMap(&sz, NULL, &mapkey, &mmsz, &mmver);
	sz += mmsz;
	sz = (sz + 15) & ~15;
	pages = EFI_SIZE_TO_PAGES(sz + bisz);
	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
	    &addr);
	if (EFI_ERROR(status)) {
		printf("%s: AllocatePages() returned 0x%lx\n", __func__,
		    (long)status);
		return (ENOMEM);
	}

	/*
	 * Read the memory map and stash it after bootinfo. Align the
	 * memory map on a 16-byte boundary (the bootinfo block is page
	 * aligned).
	 */
	*bi_addr = addr;
	mm = (void *)(addr + bisz);
	sz = (EFI_PAGE_SIZE * pages) - bisz;
	status = BS->GetMemoryMap(&sz, mm, &mapkey, &mmsz, &mmver);
	if (EFI_ERROR(status)) {
		printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
		    (long)status);
		return (EINVAL);
	}
	bi->bi_memmap = (uint64_t)mm;
	bi->bi_memmap_size = sz;
	bi->bi_memdesc_size = mmsz;
	bi->bi_memdesc_version = mmver;

	bcopy(bi, (void *)(*bi_addr), sizeof(*bi));
	return (0);
}
Пример #5
0
void
ia64_sal_init(void)
{
	static int sizes[6] = {
		48, 32, 16, 32, 16, 16
	};
	u_int8_t *p;
	int i;

	sal_systbl = efi_get_table(&sal_table);
	if (sal_systbl == NULL)
		return;

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

	p = (u_int8_t *) (sal_systbl + 1);
	for (i = 0; i < sal_systbl->sal_entry_count; i++) {
		switch (*p) {
		case 0: {
			struct sal_entrypoint_descriptor *dp;

			dp = (struct sal_entrypoint_descriptor*)p;
			ia64_pal_entry = IA64_PHYS_TO_RR7(dp->sale_pal_proc);
			if (bootverbose)
				printf("PAL Proc at 0x%lx\n", ia64_pal_entry);
			sal_fdesc.func = IA64_PHYS_TO_RR7(dp->sale_sal_proc);
			sal_fdesc.gp = IA64_PHYS_TO_RR7(dp->sale_sal_gp);
			if (bootverbose)
				printf("SAL Proc at 0x%lx, GP at 0x%lx\n",
				    sal_fdesc.func, sal_fdesc.gp);
			ia64_sal_entry = (sal_entry_t *) &sal_fdesc;
			break;
		}
		case 5: {
			struct sal_ap_wakeup_descriptor *dp;
#ifdef SMP
			struct ia64_sal_result result;
			struct ia64_fdesc *fd;
#endif

			dp = (struct sal_ap_wakeup_descriptor*)p;
			if (dp->sale_mechanism != 0) {
				printf("SAL: unsupported AP wake-up mechanism "
				    "(%d)\n", dp->sale_mechanism);
				break;
			}

			if (dp->sale_vector < 0x10 || dp->sale_vector > 0xff) {
				printf("SAL: invalid AP wake-up vector "
				    "(0x%lx)\n", dp->sale_vector);
				break;
			}

			/*
			 * SAL documents that the wake-up vector should be
			 * high (close to 255). The MCA rendezvous vector
			 * should be less than the wake-up vector, but still
			 * "high". We use the following priority assignment:
			 *	Wake-up:	priority of the sale_vector
			 *	Rendezvous:	priority-1
			 *	Generic IPIs:	priority-2
			 *	Special IPIs:	priority-3
			 * Consequently, the wake-up priority should be at
			 * least 4 (ie vector >= 0x40).
			 */
			if (dp->sale_vector < 0x40) {
				printf("SAL: AP wake-up vector too low "
				    "(0x%lx)\n", dp->sale_vector);
				break;
			}

			if (bootverbose)
				printf("SAL: AP wake-up vector: 0x%lx\n",
				    dp->sale_vector);

			ipi_vector[IPI_AP_WAKEUP] = dp->sale_vector;
			setup_ipi_vectors(dp->sale_vector & 0xf0);

#ifdef SMP
			fd = (struct ia64_fdesc *) os_boot_rendez;
			result = ia64_sal_entry(SAL_SET_VECTORS,
			    SAL_OS_BOOT_RENDEZ, ia64_tpa(fd->func),
			    ia64_tpa(fd->gp), 0, 0, 0, 0);
#endif

			break;
		}
		}
		p += sizes[*p];
	}

	if (ipi_vector[IPI_AP_WAKEUP] == 0)
		setup_ipi_vectors(0xf0);
}
Пример #6
0
static int
elf64_exec(struct preloaded_file *fp)
{
	vm_offset_t modulep, kernendp;
	vm_offset_t clean_addr;
	size_t clean_size;
	struct file_metadata *md;
	ACPI_TABLE_RSDP *rsdp;
	Elf_Ehdr *ehdr;
	char buf[24];
	int err, revision;
	void (*entry)(vm_offset_t);

	rsdp = efi_get_table(&acpi20_guid);
	if (rsdp == NULL) {
		rsdp = efi_get_table(&acpi_guid);
	}
	if (rsdp != NULL) {
		sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
		setenv("hint.acpi.0.rsdp", buf, 1);
		revision = rsdp->Revision;
		if (revision == 0)
			revision = 1;
		sprintf(buf, "%d", revision);
		setenv("hint.acpi.0.revision", buf, 1);
		strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
		buf[sizeof(rsdp->OemId)] = '\0';
		setenv("hint.acpi.0.oem", buf, 1);
		sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
		setenv("hint.acpi.0.rsdt", buf, 1);
		if (revision >= 2) {
			/* XXX extended checksum? */
			sprintf(buf, "0x%016llx",
			    (unsigned long long)rsdp->XsdtPhysicalAddress);
			setenv("hint.acpi.0.xsdt", buf, 1);
			sprintf(buf, "%d", rsdp->Length);
			setenv("hint.acpi.0.xsdt_length", buf, 1);
		}
	}

	if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
        	return(EFTYPE);

	ehdr = (Elf_Ehdr *)&(md->md_data);
	entry = efi_translate(ehdr->e_entry);

	err = bi_load(fp->f_args, &modulep, &kernendp);
	if (err != 0)
		return (err);

	dev_cleanup();

	/* Clean D-cache under kernel area and invalidate whole I-cache */
	clean_addr = (vm_offset_t)efi_translate(fp->f_addr);
	clean_size = (vm_offset_t)efi_translate(kernendp) - clean_addr;

	cpu_flush_dcache((void *)clean_addr, clean_size);
	cpu_inval_icache(NULL, 0);

	(*entry)(modulep);
	panic("exec returned");
}
Пример #7
0
static int
command_sal(int argc, char *argv[])
{
	int i;
	struct sal_system_table *saltab = NULL;
	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;
}
Пример #8
0
/*
 * Load the information expected by the kernel.
 *
 * - The kernel environment is copied into kernel space.
 * - Module metadata are formatted and placed in kernel space.
 */
int
bi_load(struct bootinfo *bi, struct preloaded_file *fp, UINTN *mapkey,
    UINTN pages)
{
    char			*rootdevname;
    struct efi_devdesc		*rootdev;
    struct preloaded_file	*xp;
    vaddr_t			addr, bootinfo_addr;
    vaddr_t			ssym, esym;
    struct file_metadata	*md;
    EFI_STATUS			status;
    UINTN			bisz, key;

    /*
     * Version 1 bootinfo.
     */
    bi->bi_magic = BOOTINFO_MAGIC;
    bi->bi_version = 1;

    /*
     * Calculate boothowto.
     */
    bi->bi_boothowto = bi_getboothowto(fp->f_args);

    /*
     * Stash EFI System Table.
     */
    bi->bi_systab = (u_int64_t) ST;

    /* 
     * Allow the environment variable 'rootdev' to override the supplied
     * device. This should perhaps go to MI code and/or have $rootdev
     * tested/set by MI code before launching the kernel.
     */
    rootdevname = getenv("rootdev");
    efi_getdev((void **)(&rootdev), rootdevname, NULL);
    if (rootdev == NULL) {		/* bad $rootdev/$currdev */
	printf("can't determine root device\n");
	return(EINVAL);
    }

    /* Try reading the /etc/fstab file to select the root device */
    getrootmount(efi_fmtdev((void *)rootdev));
    free(rootdev);

    ssym = esym = 0;

    ssym = fp->marks[MARK_SYM];
    esym = fp->marks[MARK_END];

    if (ssym == 0 || esym == 0)
	ssym = esym = 0;		/* sanity */

    bi->bi_symtab = ssym;
    bi->bi_esymtab = esym;

    bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp); /* DIG64 HCDP table addr. */
    fpswa_init(&bi->bi_fpswa);		/* find FPSWA interface */

    /* find the last module in the chain */
    addr = 0;
    for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
	if (addr < (xp->f_addr + xp->f_size))
	    addr = xp->f_addr + xp->f_size;
    }

    /* pad to a page boundary */
    addr = (addr + PAGE_MASK) & ~PAGE_MASK;

    /* copy our environment */
    bi->bi_envp = addr;
    addr = bi_copyenv(addr);

    /* pad to a page boundary */
    addr = (addr + PAGE_MASK) & ~PAGE_MASK;

    /* all done copying stuff in, save end of loaded object space */
    bi->bi_kernend = addr;

    /*
     * Read the memory map and stash it after bootinfo. Align the memory map
     * on a 16-byte boundary (the bootinfo block is page aligned).
     */
    bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f;
    bi->bi_memmap = ((u_int64_t)bi) + bisz;
    bi->bi_memmap_size = EFI_PAGE_SIZE * pages - bisz;
    status = BS->GetMemoryMap(&bi->bi_memmap_size,
		(EFI_MEMORY_DESCRIPTOR *)bi->bi_memmap, &key,
		&bi->bi_memdesc_size, &bi->bi_memdesc_version);
    if (EFI_ERROR(status)) {
	printf("bi_load: Can't read memory map\n");
	return EINVAL;
    }
    *mapkey = key;

    return(0);
}
Пример #9
0
/*
 * There is an ELF kernel and one or more ELF modules loaded.
 * We wish to start executing the kernel image, so make such
 * preparations as are required, and do so.
 */
static int
elf64_exec(struct preloaded_file *fp)
{
	struct file_metadata	*md;
	Elf_Ehdr 		*ehdr;
	vm_offset_t		modulep, kernend, trampcode, trampstack;
	int			err, i;
	ACPI_TABLE_RSDP		*rsdp;
	char			buf[24];
	int			revision;

	rsdp = efi_get_table(&acpi20_guid);
	if (rsdp == NULL) {
		rsdp = efi_get_table(&acpi_guid);
	}
	if (rsdp != NULL) {
		sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
		setenv("hint.acpi.0.rsdp", buf, 1);
		revision = rsdp->Revision;
		if (revision == 0)
			revision = 1;
		sprintf(buf, "%d", revision);
		setenv("hint.acpi.0.revision", buf, 1);
		strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
		buf[sizeof(rsdp->OemId)] = '\0';
		setenv("hint.acpi.0.oem", buf, 1);
		sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
		setenv("hint.acpi.0.rsdt", buf, 1);
		if (revision >= 2) {
			/* XXX extended checksum? */
			sprintf(buf, "0x%016llx",
			    (unsigned long long)rsdp->XsdtPhysicalAddress);
			setenv("hint.acpi.0.xsdt", buf, 1);
			sprintf(buf, "%d", rsdp->Length);
			setenv("hint.acpi.0.xsdt_length", buf, 1);
		}
	}

	if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
		return(EFTYPE);
	ehdr = (Elf_Ehdr *)&(md->md_data);

	trampcode = (vm_offset_t)0x0000000040000000;
	err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1,
	    (EFI_PHYSICAL_ADDRESS *)&trampcode);
	bzero((void *)trampcode, EFI_PAGE_SIZE);
	trampstack = trampcode + EFI_PAGE_SIZE - 8;
	bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size);
	trampoline = (void *)trampcode;

	PT4 = (p4_entry_t *)0x0000000040000000;
	err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3,
	    (EFI_PHYSICAL_ADDRESS *)&PT4);
	bzero(PT4, 3 * EFI_PAGE_SIZE);

	PT3 = &PT4[512];
	PT2 = &PT3[512];

	/*
	 * This is kinda brutal, but every single 1GB VM memory segment points
	 * to the same first 1GB of physical memory.  But it is more than
	 * adequate.
	 */
	for (i = 0; i < 512; i++) {
		/* Each slot of the L4 pages points to the same L3 page. */
		PT4[i] = (p4_entry_t)PT3;
		PT4[i] |= PG_V | PG_RW | PG_U;

		/* Each slot of the L3 pages points to the same L2 page. */
		PT3[i] = (p3_entry_t)PT2;
		PT3[i] |= PG_V | PG_RW | PG_U;

		/* The L2 page slots are mapped with 2MB pages for 1GB. */
		PT2[i] = i * (2 * 1024 * 1024);
		PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
	}

	printf("Start @ 0x%lx ...\n", ehdr->e_entry);

	err = bi_load(fp->f_args, &modulep, &kernend);
	if (err != 0)
		return(err);

	dev_cleanup();

	trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4,
	    ehdr->e_entry);

	panic("exec returned");
}
Пример #10
0
void
ia64_sal_init(void)
{
	static int sizes[6] = {
		48, 32, 16, 32, 16, 16
	};
	u_int8_t *p;
	int error, i;

	sal_systbl = efi_get_table(&sal_table);
	if (sal_systbl == NULL)
		return;

	if (bcmp(sal_systbl->sal_signature, SAL_SIGNATURE, 4)) {
		printf("Bad signature for SAL System Table\n");
		return;
	}

	p = (u_int8_t *) (sal_systbl + 1);
	for (i = 0; i < sal_systbl->sal_entry_count; i++) {
		switch (*p) {
		case 0: {
			struct sal_entrypoint_descriptor *dp;

			dp = (struct sal_entrypoint_descriptor*)p;
			ia64_pal_entry = IA64_PHYS_TO_RR7(dp->sale_pal_proc);
			if (bootverbose)
				printf("PAL Proc at 0x%lx\n", ia64_pal_entry);
			sal_fdesc.func = IA64_PHYS_TO_RR7(dp->sale_sal_proc);
			sal_fdesc.gp = IA64_PHYS_TO_RR7(dp->sale_sal_gp);
			if (bootverbose)
				printf("SAL Proc at 0x%lx, GP at 0x%lx\n",
				    sal_fdesc.func, sal_fdesc.gp);
			ia64_sal_entry = (sal_entry_t *) &sal_fdesc;
			break;
		}
		case 5: {
			struct sal_ap_wakeup_descriptor *dp;

			dp = (struct sal_ap_wakeup_descriptor*)p;
			if (dp->sale_mechanism != 0) {
				printf("SAL: unsupported AP wake-up mechanism "
				    "(%d)\n", dp->sale_mechanism);
				break;
			}

			/* Reserve the XIV so that we won't use it. */
			error = ia64_xiv_reserve(dp->sale_vector,
			    IA64_XIV_PLAT, NULL);
			if (error) {
				printf("SAL: invalid AP wake-up XIV (%#lx)\n",
				    dp->sale_vector);
				break;
			}

			ia64_ipi_wakeup = dp->sale_vector;
			if (bootverbose)
				printf("SAL: AP wake-up XIV: %#x\n",
				    ia64_ipi_wakeup);
			break;
		}
		}
		p += sizes[*p];
	}
}