static void
init_abw(void)
{
    if (abw_count < 0) {
        abw_count = alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_MEM, &abw);
        if (abw_count <= 0)
            FatalError("init_abw: alpha_bus_getwindows failed\n");
    }
}
Exemplo n.º 2
0
int
alpha_pci_io_enable(int onoff)
{
	struct alpha_bus_window *abw;
	int i, count;

	if (onoff == 0 && alpha_pci_io_windows != NULL) {
		for (i = 0; i < alpha_pci_io_window_count; i++)
			alpha_bus_unmapwindow(&alpha_pci_io_windows[i]);
		free(alpha_pci_io_windows);
		alpha_pci_io_windows = NULL;
		alpha_pci_io_window_count = 0;
		alpha_pci_io_switch = NULL;
		return (0);
	} else if (onoff == 0)
		return (0);
	else if (alpha_pci_io_windows != NULL)
		return (0);

	count = alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_IO, &abw);
	if (count <= 0)
		return (-1);

	for (i = 0; i < count; i++) {
		if (alpha_bus_mapwindow(&abw[i]) == -1) {
			free(abw);
			return (-1);
		}
	}

	alpha_pci_io_windows = abw;
	alpha_pci_io_window_count = count;

	if (abw->abw_abst.abst_flags & ABST_BWX)
		alpha_pci_io_switch = &alpha_pci_io_bwx_ops;
	else
		alpha_pci_io_switch = &alpha_pci_io_swiz_ops;

	return (0);
}
Exemplo n.º 3
0
void *
alpha_pci_mem_map(bus_addr_t memaddr, bus_size_t memsize, int flags,
    struct alpha_bus_space_translation *rabst)
{
	struct alpha_bus_window *abw;
	void *addr;
	int prefetchable = flags & BUS_SPACE_MAP_PREFETCHABLE;
	int linear = flags & BUS_SPACE_MAP_LINEAR;
	bus_size_t offset;
	int i, fd;

	/*
	 * Can't have linear without prefetchable.
	 */
	if (linear && !prefetchable)
		return (MAP_FAILED);

	if (alpha_pci_mem_windows == NULL) {
		i = alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_MEM, &abw);
		if (i <= 0)
			return (MAP_FAILED);

		alpha_pci_mem_windows = abw;
		alpha_pci_mem_window_count = i;
	}

	for (i = 0; i < alpha_pci_mem_window_count; i++) {
		abw = &alpha_pci_mem_windows[i];
		if (memaddr < abw->abw_abst.abst_bus_start ||
		    (memaddr + (memsize - 1)) > abw->abw_abst.abst_bus_end)
			continue;

		/*
		 * Prefetchable memory must be mapped in dense space;
		 * otherwise use sparse space.
		 */
		if (prefetchable &&
		    (abw->abw_abst.abst_flags & ABST_DENSE) == 0)
			continue;
		if (!prefetchable &&
		    (abw->abw_abst.abst_flags & ABST_DENSE) != 0)
			continue;

		/* Looks like we have a winner! */
		goto found;
	}

	/* Not found in any of the windows. */
	return (MAP_FAILED);

 found:
	fd = open(_PATH_MEM, O_RDWR, 0600);
	if (fd == -1)
		return (MAP_FAILED);

	if (prefetchable)
		abw->abw_abst.abst_addr_shift = 0;
	memsize <<= abw->abw_abst.abst_addr_shift;
	offset = (memaddr - abw->abw_abst.abst_bus_start) <<
	    abw->abw_abst.abst_addr_shift;

	addr = mmap(NULL, memsize, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
	    fd, (off_t) (abw->abw_abst.abst_sys_start + offset));
	
	(void) close(fd);

	if (addr != MAP_FAILED) {
		/*
		 * Make a copy of the space translation so that the caller
		 * can do the correct access.
		 */
		*rabst = abw->abw_abst;
	}
	return (addr);
}