예제 #1
0
파일: isa.c 프로젝트: apprisi/illumos-gate
static void
isa_create_ranges_prop(dev_info_t *dip)
{
	dev_info_t *used;
	int *ioarray, *memarray, status;
	uint_t nio = 0, nmem = 0, nrng = 0, n;
	pib_ranges_t *ranges;

	used = ddi_find_devinfo(USED_RESOURCES, -1, 0);
	if (used == NULL) {
		cmn_err(CE_WARN, "Failed to find used-resources <%s>\n",
		    ddi_get_name(dip));
		return;
	}
	status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, used,
	    DDI_PROP_DONTPASS, "io-space", &ioarray, &nio);
	if (status != DDI_PROP_SUCCESS && status != DDI_PROP_NOT_FOUND) {
		cmn_err(CE_WARN, "io-space property failure for %s (%x)\n",
		    ddi_get_name(used), status);
		return;
	}
	status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, used,
	    DDI_PROP_DONTPASS, "device-memory", &memarray, &nmem);
	if (status != DDI_PROP_SUCCESS && status != DDI_PROP_NOT_FOUND) {
		cmn_err(CE_WARN, "device-memory property failure for %s (%x)\n",
		    ddi_get_name(used), status);
		return;
	}
	n = (nio + nmem) / USED_CELL_SIZE;
	ranges =  (pib_ranges_t *)kmem_zalloc(sizeof (pib_ranges_t) * n,
	    KM_SLEEP);

	if (nio != 0) {
		nrng = isa_used_to_ranges(ISA_ADDR_IO, ioarray, nio, ranges);
		isa_remove_res_from_pci(ISA_ADDR_IO, ioarray, nio);
		ddi_prop_free(ioarray);
	}
	if (nmem != 0) {
		nrng += isa_used_to_ranges(ISA_ADDR_MEM, memarray, nmem,
		    ranges + nrng);
		isa_remove_res_from_pci(ISA_ADDR_MEM, memarray, nmem);
		ddi_prop_free(memarray);
	}

	if (!pseudo_isa)
		(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges",
		    (int *)ranges, nrng * sizeof (pib_ranges_t) / sizeof (int));
	kmem_free(ranges, sizeof (pib_ranges_t) * n);
}
예제 #2
0
/*
 * Build the reserved ISA irq list, and store it in the table pointed to by
 * reserved_irqs_table. The caller is responsible for allocating this table
 * with a minimum of MAX_ISA_IRQ + 1 entries.
 *
 * The routine looks in the device tree at the subtree rooted at /isa
 * for each of the devices under that node, if an interrupts property
 * is present, its values are used to "reserve" irqs so that later ACPI
 * configuration won't choose those irqs.
 *
 * In addition, if acpi_irq_check_elcr is set, will use ELCR register
 * to identify reserved IRQs.
 */
void
build_reserved_irqlist(uchar_t *reserved_irqs_table)
{
	dev_info_t *isanode = ddi_find_devinfo("isa", -1, 0);
	dev_info_t *isa_child = 0;
	int i;
	uint_t	elcrval;

	/* Initialize the reserved ISA IRQs: */
	for (i = 0; i <= MAX_ISA_IRQ; i++)
		reserved_irqs_table[i] = 0;

	if (acpi_irq_check_elcr) {

		elcrval = (inb(ELCR_PORT2) << 8) | (inb(ELCR_PORT1));
		if (ELCR_EDGE(elcrval, 0) && ELCR_EDGE(elcrval, 1) &&
		    ELCR_EDGE(elcrval, 2) && ELCR_EDGE(elcrval, 8) &&
		    ELCR_EDGE(elcrval, 13)) {
			/* valid ELCR */
			for (i = 0; i <= MAX_ISA_IRQ; i++)
				if (!ELCR_LEVEL(elcrval, i))
					reserved_irqs_table[i] = 1;
		}
	}

	/* always check the isa devinfo nodes */

	if (isanode != 0) { /* Found ISA */
		uint_t intcnt;		/* Interrupt count */
		int *intrs;		/* Interrupt values */

		/* Load first child: */
		isa_child = ddi_get_child(isanode);
		while (isa_child != 0) { /* Iterate over /isa children */
			/* if child has any interrupts, save them */
			if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, isa_child,
			    DDI_PROP_DONTPASS, "interrupts", &intrs, &intcnt)
			    == DDI_PROP_SUCCESS) {
				/*
				 * iterate over child interrupt list, adding
				 * them to the reserved irq list
				 */
				while (intcnt-- > 0) {
					/*
					 * Each value MUST be <= MAX_ISA_IRQ
					 */

					if ((intrs[intcnt] > MAX_ISA_IRQ) ||
					    (intrs[intcnt] < 0))
						continue;

					reserved_irqs_table[intrs[intcnt]] = 1;
				}
				ddi_prop_free(intrs);
			}
			isa_child = ddi_get_next_sibling(isa_child);
		}
		/* The isa node was held by ddi_find_devinfo, so release it */
		ndi_rele_devi(isanode);
	}

	/*
	 * Reserve IRQ14 & IRQ15 for IDE.  It shouldn't be hard-coded
	 * here but there's no other way to find the irqs for
	 * legacy-mode ata (since it's hard-coded in pci-ide also).
	 */
	reserved_irqs_table[14] = 1;
	reserved_irqs_table[15] = 1;
}
예제 #3
0
파일: busra.c 프로젝트: andreiw/polaris
/*
 * isa_resource_setup
 *	check for /used-resources and initialize
 *	based on info there.  If no /used-resources,
 *	fail.
 */
int
isa_resource_setup()
{
	dev_info_t *used, *usedpdip;
	/*
	 * note that at this time bootconf creates 32 bit properties for
	 * io-space and device-memory
	 */
	struct iorange {
		uint32_t	base;
		uint32_t	len;
	} *iorange;
	struct memrange {
		uint32_t	base;
		uint32_t	len;
	} *memrange;
	uint32_t *irq;
	int proplen;
	int i, len;
	int maxrange;
	ndi_ra_request_t req;
	uint64_t retbase;
	uint64_t retlen;

	used = ddi_find_devinfo("used-resources", -1, 0);
	if (used == NULL) {
		DEBUGPRT(CE_CONT,
			"isa_resource_setup: used-resources not found");
		return (NDI_FAILURE);
	}

	/*
	 * initialize to all resources being present
	 * and then remove the ones in use.
	 */

	usedpdip = ddi_root_node();

	DEBUGPRT(CE_CONT, "isa_resource_setup: used = %p usedpdip = %p\n",
	    (void *)used, (void *)usedpdip);

	if (ndi_ra_map_setup(usedpdip, NDI_RA_TYPE_IO) == NDI_FAILURE) {
		return (NDI_FAILURE);
	}

	/* initialize io space, highest end base is 0xffff */
	/* note that length is highest addr + 1 since starts from 0 */

	(void) ndi_ra_free(usedpdip, 0, 0xffff + 1,  NDI_RA_TYPE_IO, 0);

	if (ddi_getlongprop(DDI_DEV_T_ANY, used, DDI_PROP_DONTPASS,
	    "io-space", (caddr_t)&iorange, &proplen) == DDI_SUCCESS) {
		maxrange = proplen / sizeof (struct iorange);
		/* remove the "used" I/O resources */
		for (i = 0; i < maxrange; i++) {
			bzero((caddr_t)&req, sizeof (req));
			req.ra_addr =  (uint64_t)iorange[i].base;
			req.ra_len = (uint64_t)iorange[i].len;
			req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
			(void) ndi_ra_alloc(usedpdip, &req, &retbase, &retlen,
			    NDI_RA_TYPE_IO, 0);
		}

		kmem_free((caddr_t)iorange, proplen);
	}

	if (ndi_ra_map_setup(usedpdip, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
		return (NDI_FAILURE);
	}
	/* initialize memory space where highest end base is 0xffffffff */
	/* note that length is highest addr + 1 since starts from 0 */
	(void) ndi_ra_free(usedpdip, 0, ((uint64_t)((uint32_t)~0)) + 1,
	    NDI_RA_TYPE_MEM, 0);

	if (ddi_getlongprop(DDI_DEV_T_ANY, used, DDI_PROP_DONTPASS,
	    "device-memory", (caddr_t)&memrange, &proplen) == DDI_SUCCESS) {
		maxrange = proplen / sizeof (struct memrange);
		/* remove the "used" memory resources */
		for (i = 0; i < maxrange; i++) {
			bzero((caddr_t)&req, sizeof (req));
			req.ra_addr = (uint64_t)memrange[i].base;
			req.ra_len = (uint64_t)memrange[i].len;
			req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
			(void) ndi_ra_alloc(usedpdip, &req, &retbase, &retlen,
			    NDI_RA_TYPE_MEM, 0);
		}

		kmem_free((caddr_t)memrange, proplen);
	}

	if (ndi_ra_map_setup(usedpdip, NDI_RA_TYPE_INTR) == NDI_FAILURE) {
		return (NDI_FAILURE);
	}

	/* initialize the interrupt space */
	(void) ndi_ra_free(usedpdip, 0, 16, NDI_RA_TYPE_INTR, 0);

#if defined(__i386) || defined(__amd64)
	bzero(&req, sizeof (req));
	req.ra_addr = 2;	/* 2 == 9 so never allow */
	req.ra_len = 1;
	req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
	(void) ndi_ra_alloc(usedpdip, &req, &retbase, &retlen,
	    NDI_RA_TYPE_INTR, 0);
#endif

	if (ddi_getlongprop(DDI_DEV_T_ANY, used, DDI_PROP_DONTPASS,
	    "interrupts", (caddr_t)&irq, &proplen) == DDI_SUCCESS) {
		/* Initialize available interrupts by negating the used */
		len = (proplen / sizeof (uint32_t));
		for (i = 0; i < len; i++) {
			bzero((caddr_t)&req, sizeof (req));
			req.ra_addr = (uint64_t)irq[i];
			req.ra_len = 1;
			req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
			(void) ndi_ra_alloc(usedpdip, &req, &retbase, &retlen,
			    NDI_RA_TYPE_INTR, 0);
		}
		kmem_free((caddr_t)irq, proplen);
	}

#ifdef BUSRA_DEBUG
	if (busra_debug) {
		(void) ra_dump_all(NULL, usedpdip);
	}
#endif
	return (NDI_SUCCESS);

}