Пример #1
0
/*************************************************************************
 * map
 *************************************************************************/
int
i386_memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
               bus_space_handle_t *bshp)
{

    return i386_bus_space_handle_alloc(t, bpa, size, bshp);
}
Пример #2
0
static int
nexus_activate_resource(device_t bus, device_t child, int type, int rid,
			struct resource *r)
{
#ifdef PC98
	bus_space_handle_t bh;
	int error;
#endif
	void *vaddr;

	/*
	 * If this is a memory resource, map it into the kernel.
	 */
	switch (type) {
	case SYS_RES_IOPORT:
#ifdef PC98
		error = i386_bus_space_handle_alloc(X86_BUS_SPACE_IO,
		    rman_get_start(r), rman_get_size(r), &bh);
		if (error)
			return (error);
		rman_set_bushandle(r, bh);
#else
		rman_set_bushandle(r, rman_get_start(r));
#endif
		rman_set_bustag(r, X86_BUS_SPACE_IO);
		break;
	case SYS_RES_MEMORY:
#ifdef PC98
		error = i386_bus_space_handle_alloc(X86_BUS_SPACE_MEM,
		    rman_get_start(r), rman_get_size(r), &bh);
		if (error)
			return (error);
#endif
		vaddr = pmap_mapdev(rman_get_start(r), rman_get_size(r));
		rman_set_virtual(r, vaddr);
		rman_set_bustag(r, X86_BUS_SPACE_MEM);
#ifdef PC98
		/* PC-98: the type of bus_space_handle_t is the structure. */
		bh->bsh_base = (bus_addr_t) vaddr;
		rman_set_bushandle(r, bh);
#else
		/* IBM-PC: the type of bus_space_handle_t is u_int */
		rman_set_bushandle(r, (bus_space_handle_t) vaddr);
#endif
	}
	return (rman_activate_resource(r));
}
Пример #3
0
int
i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
                     bus_size_t offset, bus_size_t size,
                     bus_space_handle_t *tbshp)
{
    int i, error = 0;
    bus_space_handle_t bsh;
    bus_addr_t pbase;

    pbase = pbsh->bsh_base + offset;
    switch (t->bs_tag) {
    case BUS_SPACE_TAG_IO:
        if (pbsh->bsh_iatsz > 0) {
            if (offset >= pbsh->bsh_iatsz ||
                    offset + size > pbsh->bsh_iatsz)
                return EINVAL;
            pbase = pbsh->bsh_base;
        }
        break;

    case BUS_SPACE_TAG_MEM:
        if (pbsh->bsh_iatsz > 0)
            return EINVAL;
        if (offset > pbsh->bsh_sz || offset + size > pbsh->bsh_sz)
            return EINVAL;
        break;

    default:
        panic("i386_memio_subregion: bad bus space tag");
        break;
    }

    error = i386_bus_space_handle_alloc(t, pbase, size, &bsh);
    if (error != 0)
        return error;

    switch (t->bs_tag) {
    case BUS_SPACE_TAG_IO:
        if (pbsh->bsh_iatsz > 0) {
            for (i = 0; i < size; i ++)
                bsh->bsh_iat[i] = pbsh->bsh_iat[i + offset];
            bsh->bsh_iatsz = size;
        } else if (pbsh->bsh_base > bsh->bsh_base ||
                   pbsh->bsh_base + pbsh->bsh_sz <
                   bsh->bsh_base + bsh->bsh_sz) {
            i386_bus_space_handle_free(t, bsh, size);
            return EINVAL;
        }
        break;

    case BUS_SPACE_TAG_MEM:
        break;
    }

    if (pbsh->bsh_iatsz > 0)
        bsh->bsh_bam = t->bs_ra;	/* relocate access */
    *tbshp = bsh;
    return error;
}
Пример #4
0
/*
 * Allocate a resource on behalf of child.  NB: child is usually going to be a
 * child of one of our descendants, not a direct child of nexus0.
 * (Exceptions include npx.)
 */
static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
		     u_long start, u_long end, u_long count, u_int flags)
{
	struct nexus_device *ndev = DEVTONX(child);
	struct	resource *rv;
	struct resource_list_entry *rle;
	struct	rman *rm;
	int needactivate = flags & RF_ACTIVE;

	/*
	 * If this is an allocation of the "default" range for a given RID, and
	 * we know what the resources for this device are (ie. they aren't maintained
	 * by a child bus), then work out the start/end values.
	 */
	if ((start == 0UL) && (end == ~0UL) && (count == 1)) {
		if (ndev == NULL)
			return(NULL);
		rle = resource_list_find(&ndev->nx_resources, type, *rid);
		if (rle == NULL)
			return(NULL);
		start = rle->start;
		end = rle->end;
		count = rle->count;
	}

	flags &= ~RF_ACTIVE;

	switch (type) {
	case SYS_RES_IRQ:
		rm = &irq_rman;
		break;

	case SYS_RES_DRQ:
		rm = &drq_rman;
		break;

	case SYS_RES_IOPORT:
		rm = &port_rman;
		break;

	case SYS_RES_MEMORY:
		rm = &mem_rman;
		break;

	default:
		return 0;
	}

	rv = rman_reserve_resource(rm, start, end, count, flags, child);
	if (rv == 0)
		return 0;

	if (type == SYS_RES_MEMORY) {
		rman_set_bustag(rv, I386_BUS_SPACE_MEM);
	} else if (type == SYS_RES_IOPORT) {
		rman_set_bustag(rv, I386_BUS_SPACE_IO);
#ifndef PC98
		rman_set_bushandle(rv, rv->r_start);
#endif
	}

#ifdef PC98
	if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) &&
	    i386_bus_space_handle_alloc(rv->r_bustag, rv->r_start, count,
					&rv->r_bushandle) != 0) {
		rman_release_resource(rv);
		return 0;
	}
#endif

	if (needactivate) {
		if (bus_activate_resource(child, type, *rid, rv)) {
#ifdef PC98
			if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
				i386_bus_space_handle_free(rv->r_bustag,
				    rv->r_bushandle, rv->r_bushandle->bsh_sz);
			}
#endif
			rman_release_resource(rv);
			return 0;
		}
	}
	
	return rv;
}