コード例 #1
0
static void
efinet_init(struct iodesc *desc, void *machdep_hint)
{
	struct netif *nif = desc->io_netif;
	EFI_SIMPLE_NETWORK *net;
	EFI_HANDLE h;
	EFI_STATUS status;
	UINT32 mask;

	if (nif->nif_driver->netif_ifs[nif->nif_unit].dif_unit < 0) {
		printf("Invalid network interface %d\n", nif->nif_unit);
		return;
	}

	h = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private;
	status = BS->HandleProtocol(h, &sn_guid, (VOID **)&nif->nif_devdata);
	if (status != EFI_SUCCESS) {
		printf("net%d: cannot fetch interface data (status=%lu)\n",
		    nif->nif_unit, EFI_ERROR_CODE(status));
		return;
	}

	net = nif->nif_devdata;
	if (net->Mode->State == EfiSimpleNetworkStopped) {
		status = net->Start(net);
		if (status != EFI_SUCCESS) {
			printf("net%d: cannot start interface (status=%lu)\n",
			    nif->nif_unit, EFI_ERROR_CODE(status));
			return;
		}
	}

	if (net->Mode->State != EfiSimpleNetworkInitialized) {
		status = net->Initialize(net, 0, 0);
		if (status != EFI_SUCCESS) {
			printf("net%d: cannot init. interface (status=%lu)\n",
			    nif->nif_unit, EFI_ERROR_CODE(status));
			return;
		}
	}

	mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
	    EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;

	status = net->ReceiveFilters(net, mask, 0, FALSE, 0, NULL);
	if (status != EFI_SUCCESS) {
		printf("net%d: cannot set rx. filters (status=%lu)\n",
		    nif->nif_unit, EFI_ERROR_CODE(status));
		return;
	}

#ifdef EFINET_DEBUG
	dump_mode(net->Mode);
#endif

	bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6);
	desc->xid = 1;
}
コード例 #2
0
ファイル: copy.c プロジェクト: jaredmcneill/freebsd
int
efi_copy_init(void)
{
	EFI_STATUS	status;

	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
	    STAGE_PAGES, &staging);
	if (EFI_ERROR(status)) {
		printf("failed to allocate staging area: %lu\n",
		    EFI_ERROR_CODE(status));
		return (status);
	}
	staging_end = staging + STAGE_PAGES * EFI_PAGE_SIZE;

#if defined(__aarch64__) || defined(__arm__)
	/*
	 * Round the kernel load address to a 2MiB value. This is needed
	 * because the kernel builds a page table based on where it has
	 * been loaded in physical address space. As the kernel will use
	 * either a 1MiB or 2MiB page for this we need to make sure it
	 * is correctly aligned for both cases.
	 */
	staging = roundup2(staging, 2 * 1024 * 1024);
#endif

	return (0);
}
コード例 #3
0
ファイル: main.c プロジェクト: RichardsonAlex/cheribsd
static int
command_efi_set(int argc, char *argv[])
{
	char *uuid, *var, *val;
	CHAR16 wvar[128];
	EFI_GUID guid;
	uint32_t status;
	EFI_STATUS err;

	if (argc != 4) {
		printf("efi-set uuid var new-value\n");
		return (CMD_ERROR);
	}
	uuid = argv[1];
	var = argv[2];
	val = argv[3];
	uuid_from_string(uuid, (uuid_t *)&guid, &status);
	if (status != uuid_s_ok) {
		printf("Invalid uuid %s %d\n", uuid, status);
		return (CMD_ERROR);
	}
	cpy8to16(var, wvar, sizeof(wvar));
	err = RS->SetVariable(wvar, &guid,
	    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
	    strlen(val) + 1, val);
	if (EFI_ERROR(err)) {
		printf("Failed to set variable: error %lu\n", EFI_ERROR_CODE(err));
		return (CMD_ERROR);
	}
	return (CMD_OK);
}
コード例 #4
0
ファイル: main.c プロジェクト: RichardsonAlex/cheribsd
static int
command_efi_unset(int argc, char *argv[])
{
	char *uuid, *var;
	CHAR16 wvar[128];
	EFI_GUID guid;
	uint32_t status;
	EFI_STATUS err;

	if (argc != 3) {
		printf("efi-unset uuid var\n");
		return (CMD_ERROR);
	}
	uuid = argv[1];
	var = argv[2];
	uuid_from_string(uuid, (uuid_t *)&guid, &status);
	if (status != uuid_s_ok) {
		printf("Invalid uuid %s\n", uuid);
		return (CMD_ERROR);
	}
	cpy8to16(var, wvar, sizeof(wvar));
	err = RS->SetVariable(wvar, &guid, 0, 0, NULL);
	if (EFI_ERROR(err)) {
		printf("Failed to unset variable: error %lu\n", EFI_ERROR_CODE(err));
		return (CMD_ERROR);
	}
	return (CMD_OK);
}
コード例 #5
0
ファイル: zfs_module.c プロジェクト: Enstone/freebsd
static EFI_STATUS
probe(dev_info_t *dev)
{
	spa_t *spa;
	dev_info_t *tdev;
	EFI_STATUS status;

	/* ZFS consumes the dev on success so we need a copy. */
	if ((status = bs->AllocatePool(EfiLoaderData, sizeof(*dev),
	    (void**)&tdev)) != EFI_SUCCESS) {
		DPRINTF("Failed to allocate tdev (%lu)\n",
		    EFI_ERROR_CODE(status));
		return (status);
	}
	memcpy(tdev, dev, sizeof(*dev));

	if (vdev_probe(vdev_read, tdev, &spa) != 0) {
		(void)bs->FreePool(tdev);
		return (EFI_UNSUPPORTED);
	}

	dev->devdata = spa;
	add_device(&devices, dev);

	return (EFI_SUCCESS);
}
コード例 #6
0
ファイル: ufs_module.c プロジェクト: derekmarcotte/freebsd
static EFI_STATUS
load(const char *filepath, dev_info_t *dev, void **bufp, size_t *bufsize)
{
	ufs_ino_t ino;
	EFI_STATUS status;
	size_t size;
	ssize_t read;
	void *buf;

#ifdef EFI_DEBUG
	{
		CHAR16 *text = efi_devpath_name(dev->devpath);
		DPRINTF("Loading '%s' from %S\n", filepath, text);
		efi_free_devpath_name(text);
	}
#endif
	if (init_dev(dev) < 0) {
		DPRINTF("Failed to init device\n");
		return (EFI_UNSUPPORTED);
	}

	if ((ino = lookup(filepath)) == 0) {
		DPRINTF("Failed to lookup '%s' (file not found?)\n", filepath);
		return (EFI_NOT_FOUND);
	}

	if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
		printf("Failed to read size of '%s' ino: %d\n", filepath, ino);
		return (EFI_INVALID_PARAMETER);
	}

	if ((status = BS->AllocatePool(EfiLoaderData, size, &buf)) !=
	    EFI_SUCCESS) {
		printf("Failed to allocate read buffer %zu for '%s' (%lu)\n",
		    size, filepath, EFI_ERROR_CODE(status));
		return (status);
	}

	read = fsread(ino, buf, size);
	if ((size_t)read != size) {
		printf("Failed to read '%s' (%zd != %zu)\n", filepath, read,
		    size);
		(void)BS->FreePool(buf);
		return (EFI_INVALID_PARAMETER);
	}

	DPRINTF("Load complete\n");

	*bufp = buf;
	*bufsize = size;

	return (EFI_SUCCESS);
}
コード例 #7
0
ファイル: boot1.c プロジェクト: Eastsideboy/freebsd
static void
load(const char *fname)
{
	ufs_ino_t ino;
	EFI_STATUS status;
	EFI_HANDLE loaderhandle;
	EFI_LOADED_IMAGE *loaded_image;
	void *buffer;
	size_t bufsize;

	if ((ino = lookup(fname)) == 0) {
		printf("File %s not found\n", fname);
		return;
	}

	bufsize = fsstat(ino);
	status = systab->BootServices->AllocatePool(EfiLoaderData,
	    bufsize, &buffer);
	fsread(ino, buffer, bufsize);

	/* XXX: For secure boot, we need our own loader here */
	status = systab->BootServices->LoadImage(TRUE, image, bootdevpath,
	    buffer, bufsize, &loaderhandle);
	if (EFI_ERROR(status))
		printf("LoadImage failed with error %lu\n",
		    EFI_ERROR_CODE(status));

	status = systab->BootServices->HandleProtocol(loaderhandle,
	    &LoadedImageGUID, (VOID**)&loaded_image);
	if (EFI_ERROR(status))
		printf("HandleProtocol failed with error %lu\n",
		    EFI_ERROR_CODE(status));

	loaded_image->DeviceHandle = bootdevhandle;

	status = systab->BootServices->StartImage(loaderhandle, NULL, NULL);
	if (EFI_ERROR(status))
		printf("StartImage failed with error %lu\n",
		    EFI_ERROR_CODE(status));
}
コード例 #8
0
ファイル: ufs_module.c プロジェクト: Cka3o4Huk/freebsd
static EFI_STATUS
try_load(dev_info_t *dev, const char *loader_path, void **bufp, size_t *bufsize)
{
	ufs_ino_t ino;
	EFI_STATUS status;
	size_t size;
	ssize_t read;
	void *buf;

	if (init_dev(dev) < 0)
		return (EFI_UNSUPPORTED);

	if ((ino = lookup(loader_path)) == 0)
		return (EFI_NOT_FOUND);

	if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
		printf("Failed to read size of '%s' ino: %d\n", loader_path,
		    ino);
		return (EFI_INVALID_PARAMETER);
	}

	if ((status = bs->AllocatePool(EfiLoaderData, size, &buf)) !=
	    EFI_SUCCESS) {
		printf("Failed to allocate read buffer (%lu)\n",
		    EFI_ERROR_CODE(status));
		return (status);
	}

	read = fsread(ino, buf, size);
	if ((size_t)read != size) {
		printf("Failed to read '%s' (%zd != %zu)\n", loader_path, read,
		    size);
		(void)bs->FreePool(buf);
		return (EFI_INVALID_PARAMETER);
	}

	*bufp = buf;
	*bufsize = size;

	return (EFI_SUCCESS);
}
コード例 #9
0
ファイル: ufs_module.c プロジェクト: 2asoft/freebsd
static int
dskread(void *buf, u_int64_t lba, int nblk)
{
	int size;
	EFI_STATUS status;

	lba = lba / (devinfo->dev->Media->BlockSize / DEV_BSIZE);
	size = nblk * DEV_BSIZE;

	status = devinfo->dev->ReadBlocks(devinfo->dev,
	    devinfo->dev->Media->MediaId, lba, size, buf);

	if (status != EFI_SUCCESS) {
		DPRINTF("dskread: failed dev: %p, id: %u, lba: %lu, size: %d, "
		    "status: %lu\n", devinfo->dev,
		    devinfo->dev->Media->MediaId, lba, size,
		    EFI_ERROR_CODE(status));
		return (-1);
	}

	return (0);
}
コード例 #10
0
ファイル: zfs_module.c プロジェクト: Enstone/freebsd
static int
vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
{
	dev_info_t *devinfo;
	off_t lba;
	EFI_STATUS status;

	devinfo = (dev_info_t *)priv;
	lba = off / devinfo->dev->Media->BlockSize;

	status = devinfo->dev->ReadBlocks(devinfo->dev,
	    devinfo->dev->Media->MediaId, lba, bytes, buf);
	if (status != EFI_SUCCESS) {
		DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %zu, size: %zu,"
                    " status: %lu\n", devinfo->dev,
                    devinfo->dev->Media->MediaId, lba, bytes,
                    EFI_ERROR_CODE(status));
		return (-1);
	}

	return (0);
}
コード例 #11
0
ファイル: memmap.c プロジェクト: allanjude/illumos-gate
void
efi_getsmap(void)
{
	UINTN size, desc_size, key;
	EFI_MEMORY_DESCRIPTOR *efi_mmap, *p;
	EFI_PHYSICAL_ADDRESS addr;
	EFI_STATUS status;
	STAILQ_HEAD(smap_head, smap_buf) head =
	    STAILQ_HEAD_INITIALIZER(head);
	struct smap_buf *cur, *next;
	int i, n, ndesc;
	int type = -1;

	size = 0;
	efi_mmap = NULL;
	status = BS->GetMemoryMap(&size, efi_mmap, &key, &desc_size, NULL);
	efi_mmap = malloc(size);
	status = BS->GetMemoryMap(&size, efi_mmap, &key, &desc_size, NULL);
	if (EFI_ERROR(status)) {
		printf("GetMemoryMap: error %lu\n", EFI_ERROR_CODE(status));
		free(efi_mmap);
		return;
	}

	STAILQ_INIT(&head);
	n = 0;
	i = 0;
	p = efi_mmap;
	next = NULL;
	ndesc = size / desc_size;
	while (i < ndesc) {
		if (next == NULL) {
			next = malloc(sizeof(*next));
			if (next == NULL)
				break;

			next->sb_smap.base = p->PhysicalStart;
			next->sb_smap.length =
			    p->NumberOfPages << EFI_PAGE_SHIFT;
			/*
			 * ACPI 6.1 tells the lower memory should be
			 * reported as normal memory, so we enforce
			 * page 0 type even as vmware maps it as
			 * acpi reclaimable.
			 */
			if (next->sb_smap.base == 0)
				type = SMAP_TYPE_MEMORY;
			else
				type = smap_type(p->Type);
			next->sb_smap.type = type;

			STAILQ_INSERT_TAIL(&head, next, sb_bufs);
			n++;
			p = NextMemoryDescriptor(p, desc_size);
			i++;
			continue;
		}
		addr = next->sb_smap.base + next->sb_smap.length;
		if ((smap_type(p->Type) == type) &&
		    (p->PhysicalStart == addr)) {
			next->sb_smap.length +=
			    (p->NumberOfPages << EFI_PAGE_SHIFT);
			p = NextMemoryDescriptor(p, desc_size);
			i++;
		} else
			next = NULL;
	}
	smaplen = n;
	if (smaplen > 0) {
		smapbase = malloc(smaplen * sizeof(*smapbase));
		if (smapbase != NULL) {
			n = 0;
			STAILQ_FOREACH(cur, &head, sb_bufs)
				smapbase[n++] = cur->sb_smap;
		}
		cur = STAILQ_FIRST(&head);
		while (cur != NULL) {
			next = STAILQ_NEXT(cur, sb_bufs);
			free(cur);
			cur = next;
		}
	}
	free(efi_mmap);
}
コード例 #12
0
ファイル: zfs_module.c プロジェクト: Enstone/freebsd
static EFI_STATUS
load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize)
{
	spa_t *spa;
	struct zfsmount zfsmount;
	dnode_phys_t dn;
	struct stat st;
	int err;
	void *buf;
	EFI_STATUS status;

	spa = devinfo->devdata;

	DPRINTF("load: '%s' spa: '%s', devpath: %s\n", filepath, spa->spa_name,
	    devpath_str(devinfo->devpath));

	if ((err = zfs_spa_init(spa)) != 0) {
		DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err);
		return (EFI_NOT_FOUND);
	}

	if ((err = zfs_mount(spa, 0, &zfsmount)) != 0) {
		DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err);
		return (EFI_NOT_FOUND);
	}

	if ((err = zfs_lookup(&zfsmount, filepath, &dn)) != 0) {
		if (err == ENOENT) {
			DPRINTF("Failed to find '%s' on pool '%s' (%d)\n",
			    filepath, spa->spa_name, err);
			return (EFI_NOT_FOUND);
		}
		printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath,
		    spa->spa_name, err);
		return (EFI_INVALID_PARAMETER);
	}

	if ((err = zfs_dnode_stat(spa, &dn, &st)) != 0) {
		printf("Failed to stat '%s' on pool '%s' (%d)\n", filepath,
		    spa->spa_name, err);
		return (EFI_INVALID_PARAMETER);
	}

	if ((status = bs->AllocatePool(EfiLoaderData, (UINTN)st.st_size, &buf))
	    != EFI_SUCCESS) {
		printf("Failed to allocate load buffer %zu for pool '%s' for '%s' "
		    "(%lu)\n", st.st_size, spa->spa_name, filepath, EFI_ERROR_CODE(status));
		return (EFI_INVALID_PARAMETER);
	}

	if ((err = dnode_read(spa, &dn, 0, buf, st.st_size)) != 0) {
		printf("Failed to read node from %s (%d)\n", spa->spa_name,
		    err);
		(void)bs->FreePool(buf);
		return (EFI_INVALID_PARAMETER);
	}

	*bufsize = st.st_size;
	*bufp = buf;

	return (EFI_SUCCESS);
}
コード例 #13
0
static int
efinet_dev_init()
{
	struct netif_dif *dif;
	struct netif_stats *stats;
	EFI_DEVICE_PATH *devpath, *node;
	EFI_SIMPLE_NETWORK *net;
	EFI_HANDLE *handles, *handles2;
	EFI_STATUS status;
	UINTN sz;
	int err, i, nifs;
	extern struct devsw netdev;

	sz = 0;
	handles = NULL;
	status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, NULL);
	if (status == EFI_BUFFER_TOO_SMALL) {
		handles = (EFI_HANDLE *)malloc(sz);
		status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz,
		    handles);
		if (EFI_ERROR(status))
			free(handles);
	}
	if (EFI_ERROR(status))
		return (efi_status_to_errno(status));
	handles2 = (EFI_HANDLE *)malloc(sz);
	if (handles2 == NULL) {
		free(handles);
		return (ENOMEM);
	}
	nifs = 0;
	for (i = 0; i < sz / sizeof(EFI_HANDLE); i++) {
		devpath = efi_lookup_devpath(handles[i]);
		if (devpath == NULL)
			continue;
		if ((node = efi_devpath_last_node(devpath)) == NULL)
			continue;

		if (DevicePathType(node) != MESSAGING_DEVICE_PATH ||
		    DevicePathSubType(node) != MSG_MAC_ADDR_DP)
			continue;

		/*
		 * Open the network device in exclusive mode. Without this
		 * we will be racing with the UEFI network stack. It will
		 * pull packets off the network leading to lost packets.
		 */
		status = BS->OpenProtocol(handles[i], &sn_guid, (void **)&net,
		    IH, NULL, EFI_OPEN_PROTOCOL_EXCLUSIVE);
		if (status != EFI_SUCCESS) {
			printf("Unable to open network interface %d for "
			    "exclusive access: %lu\n", i,
			    EFI_ERROR_CODE(status));
		}

		handles2[nifs] = handles[i];
		nifs++;
	}
	free(handles);
	if (nifs == 0) {
		err = ENOENT;
		goto done;
	}

	err = efi_register_handles(&efinet_dev, handles2, NULL, nifs);
	if (err != 0)
		goto done;

	efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif));
	stats = calloc(nifs, sizeof(struct netif_stats));
	if (efinetif.netif_ifs == NULL || stats == NULL) {
		free(efinetif.netif_ifs);
		free(stats);
		efinetif.netif_ifs = NULL;
		err = ENOMEM;
		goto done;
	}
	efinetif.netif_nifs = nifs;

	for (i = 0; i < nifs; i++) {

		dif = &efinetif.netif_ifs[i];
		dif->dif_unit = i;
		dif->dif_nsel = 1;
		dif->dif_stats = &stats[i];
		dif->dif_private = handles2[i];
	}

	efinet_dev.dv_open = netdev.dv_open;
	efinet_dev.dv_close = netdev.dv_close;
	efinet_dev.dv_strategy = netdev.dv_strategy;

done:
	free(handles2);
	return (err);
}