示例#1
0
/* Main entry points */
static int
dummy_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
              int flags, char *name, caddr_t valuep, int *lengthp)
{
    cmn_err(CE_NOTE, "Inside dummy_prop_op");
    return(ddi_prop_op(dev,dip,prop_op,flags,name,valuep,lengthp));
}
示例#2
0
static int pci_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
    int flags, char *name, caddr_t valuep, int *lengthp)
{
	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "hotplug-capable"))
		return ((pcihp_get_cb_ops())->cb_prop_op(dev, dip,
		    prop_op, flags, name, valuep, lengthp));

	return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp));
}
示例#3
0
文件: busra.c 项目: andreiw/polaris
/*
 * If the device is a PCI bus device (i.e bus-range property exists) then
 * claim the bus numbers used by the device from the specified bus
 * resource map.
 */
static int
claim_pci_busnum(dev_info_t *dip, void *arg)
{
	struct bus_range pci_bus_range;
	struct busnum_ctrl *ctrl;
	ndi_ra_request_t req;
	char bus_type[16] = "(unknown)";
	int len;
	uint64_t base;
	uint64_t retlen;

	ctrl = (struct busnum_ctrl *)arg;

	/* check if this is a PCI bus node */
	len = sizeof (bus_type);
	if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
	    DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "device_type",
	    (caddr_t)&bus_type, &len) != DDI_SUCCESS)
		return (DDI_WALK_PRUNECHILD);

	/* it is not a pci/pci-ex bus type */
	if ((strcmp(bus_type, "pci") != 0) && (strcmp(bus_type, "pciex") != 0))
		return (DDI_WALK_PRUNECHILD);

	/* look for the bus-range property */
	len = sizeof (struct bus_range);
	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "bus-range", (caddr_t)&pci_bus_range, &len) == DDI_SUCCESS) {
		if ((pci_bus_range.lo >= ctrl->range->lo) &&
		    (pci_bus_range.hi <= ctrl->range->hi)) {

			/* claim the bus range from the bus resource map */
			bzero((caddr_t)&req, sizeof (req));
			req.ra_addr = (uint64_t)pci_bus_range.lo;
			req.ra_flags |= NDI_RA_ALLOC_SPECIFIED;
			req.ra_len = (uint64_t)pci_bus_range.hi -
			    (uint64_t)pci_bus_range.lo + 1;
			if (ndi_ra_alloc(ctrl->dip, &req, &base, &retlen,
			    NDI_RA_TYPE_PCI_BUSNUM, 0) == NDI_SUCCESS)
				return (DDI_WALK_PRUNECHILD);
		}
	}

	/*
	 * Error return.
	 */
	ctrl->rv = DDI_FAILURE;
	return (DDI_WALK_TERMINATE);
}
示例#4
0
int
get_portid_ddi(dev_info_t *dip, dev_info_t **cmpp)
{
    int portid;
    int i;
    char dev_type[OBP_MAXPROPNAME];
    int len = OBP_MAXPROPNAME;
    dev_info_t *cpu_parent;

    if (cmpp != NULL)
        *cmpp = NULL;

    if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                   DDI_PROP_DONTPASS, "portid", -1)) != -1)
        return (portid);
    if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                   DDI_PROP_DONTPASS, "upa-portid", -1)) != -1)
        return (portid);
    if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
                    DDI_PROP_DONTPASS, "device_type", (caddr_t)dev_type,
                    &len) != 0)
        return (-1);

    /*
     * For a virtual cpu node that is a CMP core, the "portid"
     * is in the parent node.
     * For a virtual cpu node that is a CMT strand, the "portid" is
     * in its grandparent node.
     * So we iterate up as far as 2 levels to get the "portid".
     */
    if (strcmp(dev_type, "cpu") == 0) {
        cpu_parent = dip = ddi_get_parent(dip);
        for (i = 0; dip != NULL && i < 2; i++) {
            if ((portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                           DDI_PROP_DONTPASS, "portid", -1)) != -1) {
                if (cmpp != NULL)
                    *cmpp = cpu_parent;
                return (portid);
            }
            dip = ddi_get_parent(dip);
        }
    }

    return (-1);
}
示例#5
0
/*
 * A hotplug version of fill_cpu().  (Doesn't assume that there's a node
 * in the PROM device tree for this CPU.)  We still need the PROM version
 * since it is called very early in the boot cycle before (before
 * setup_ddi()).  Sigh...someday this will all be cleaned up.
 */
void
fill_cpu_ddi(dev_info_t *dip)
{
    extern int cpu_get_cpu_unum(int, char *, int, int *);
    struct cpu_node *cpunode;
    processorid_t cpuid;
    int portid;
    int len = OBP_MAXPROPNAME;
    int tlbsize;
    dev_info_t *cmpnode;
    char namebuf[OBP_MAXPROPNAME], unum[UNUM_NAMLEN];
    char *namebufp;
    char dev_type[OBP_MAXPROPNAME];

    if ((portid = get_portid_ddi(dip, &cmpnode)) == -1) {
        cmn_err(CE_PANIC, "portid not found");
    }

    if ((cpuid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                  DDI_PROP_DONTPASS, "cpuid", -1)) == -1) {
        cpuid = portid;
    }

    if (cpuid < 0 || cpuid >= NCPU) {
        cmn_err(CE_PANIC, "cpu dip %p: cpuid %d out of range",
                (void *)dip, cpuid);
        return;
    }

    cpunode = &cpunodes[cpuid];
    cpunode->portid = portid;
    cpunode->nodeid = ddi_get_nodeid(dip);

    if (cmpnode != NULL) {
        /*
         * For the CMT case, the parent "core" node contains
         * properties needed below, use it instead of the
         * cpu node.
         */
        if ((ddi_prop_op(DDI_DEV_T_ANY, cmpnode, PROP_LEN_AND_VAL_BUF,
                         DDI_PROP_DONTPASS, "device_type",
                         (caddr_t)dev_type, &len) == DDI_PROP_SUCCESS) &&
                (strcmp(dev_type, "core") == 0))
            dip = cmpnode;
    }

    if (cpu_get_cpu_unum(cpuid, unum, UNUM_NAMLEN, &len) != 0) {
        cpunode->fru_fmri[0] = '\0';
    } else {
        (void) snprintf(cpunode->fru_fmri, sizeof (cpunode->fru_fmri),
                        "%s%s", CPU_FRU_FMRI, unum);
    }

    len = sizeof (namebuf);
    (void) ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
                       DDI_PROP_DONTPASS, (cmpnode ? "compatible" : "name"),
                       (caddr_t)namebuf, &len);

    namebufp = namebuf;
    if (strncmp(namebufp, "SUNW,", 5) == 0)
        namebufp += 5;
    else if (strncmp(namebufp, "FJSV,", 5) == 0)
        namebufp += 5;
    (void) strcpy(cpunode->name, namebufp);

    cpunode->implementation = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                              DDI_PROP_DONTPASS, "implementation#", 0);

    cpunode->version = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                        DDI_PROP_DONTPASS, "mask#", 0);

    if (IS_CHEETAH(cpunode->implementation)) {
        /* remap mask reg */
        cpunode->version = REMAP_CHEETAH_MASK(cpunode->version);
    }

    cpunode->clock_freq = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                          DDI_PROP_DONTPASS, "clock-frequency", 0);

    ASSERT(cpunode->clock_freq != 0);
    /*
     * Compute scaling factor based on rate of %tick. This is used
     * to convert from ticks derived from %tick to nanoseconds. See
     * comment in sun4u/sys/clock.h for details.
     */
    cpunode->tick_nsec_scale = (uint_t)(((uint64_t)NANOSEC <<
                                         (32 - TICK_NSEC_SHIFT)) / cpunode->clock_freq);

    tlbsize = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                               DDI_PROP_DONTPASS, "#itlb-entries", 0);
    ASSERT(tlbsize < USHRT_MAX); /* since we cast it */
    cpunode->itlb_size = (ushort_t)tlbsize;

    tlbsize = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                               DDI_PROP_DONTPASS, "#dtlb-entries", 0);
    ASSERT(tlbsize < USHRT_MAX); /* since we cast it */
    cpunode->dtlb_size = (ushort_t)tlbsize;

    if (cmpnode != NULL) {
        /*
         * If the CPU has a level 3 cache, then that is it's
         * external cache. Otherwise the external cache must
         * be the level 2 cache.
         */
        cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY,
                                                dip, DDI_PROP_DONTPASS, "l3-cache-size", 0);
        if (cpunode->ecache_size == 0)
            cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY,
                                                    dip, DDI_PROP_DONTPASS, "l2-cache-size", 0);
        ASSERT(cpunode->ecache_size != 0);

        cpunode->ecache_linesize = ddi_prop_get_int(DDI_DEV_T_ANY,
                                   dip, DDI_PROP_DONTPASS, "l3-cache-line-size", 0);
        if (cpunode->ecache_linesize == 0)
            cpunode->ecache_linesize =
                ddi_prop_get_int(DDI_DEV_T_ANY, dip,
                                 DDI_PROP_DONTPASS, "l2-cache-line-size", 0);
        ASSERT(cpunode->ecache_linesize != 0);

        cpunode->ecache_associativity = ddi_prop_get_int(DDI_DEV_T_ANY,
                                        dip, DDI_PROP_DONTPASS, "l2-cache-associativity", 0);
        ASSERT(cpunode->ecache_associativity != 0);

        cmp_add_cpu(portid, cpuid);
    } else {
        cpunode->ecache_size = ddi_prop_get_int(DDI_DEV_T_ANY,
                                                dip, DDI_PROP_DONTPASS, "ecache-size", 0);
        ASSERT(cpunode->ecache_size != 0);

        cpunode->ecache_linesize = ddi_prop_get_int(DDI_DEV_T_ANY,
                                   dip, DDI_PROP_DONTPASS, "ecache-line-size", 0);
        ASSERT(cpunode->ecache_linesize != 0);

        cpunode->ecache_associativity = ddi_prop_get_int(DDI_DEV_T_ANY,
                                        dip, DDI_PROP_DONTPASS, "ecache-associativity", 0);
        ASSERT(cpunode->ecache_associativity != 0);
    }

    /* by default set msram to non-mirrored one */
    cpunode->msram = ECACHE_CPU_NON_MIRROR;

    if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "msram")) {
        cpunode->msram = ECACHE_CPU_MIRROR;
    } else if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
                               "msram-observed")) {
        cpunode->msram = ECACHE_CPU_MIRROR;
    }

    ASSERT(ncpunode > 0);	/* fiximp not req'd */

    cpunode->ecache_setsize =
        cpunode->ecache_size / cpunode->ecache_associativity;

    adj_ecache_setsize(cpunode->ecache_setsize);

    ncpunode++;
}
示例#6
0
文件: logi.c 项目: andreiw/polaris
static int
logiinit(dev_info_t *dip)
{
	int	i;
	int	ioaddr;
	int	len;
	int	old_probe;

#ifdef LOGI_DEBUG
	if (logi_debug)
		PRF("logiinit: call BASE_IOA = %x\n", BASE_IOA);
#endif
	old_probe = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
		"ignore-hardware-nodes", 0);

	if (old_probe) {
		len = sizeof (int);

		/*
		 * check if ioaddr is set in .conf file, it should be.  If it
		 * isn't then try the default i/o addr
		 */
		if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
		    DDI_PROP_DONTPASS, "ioaddr", (caddr_t)&ioaddr,
		    &len) == DDI_PROP_SUCCESS)
			BASE_IOA = ioaddr;
	} else {
		int reglen, nregs;
		int i;
		struct {
			int bustype;
			int base;
			int size;
		} *reglist;

		/* new probe */
		if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
		    "reg", (caddr_t)&reglist, &reglen) != DDI_PROP_SUCCESS)
			return (DDI_PROBE_FAILURE);
		nregs = reglen / sizeof (*reglist);
		for (i = 0; i < nregs; i++)
			if (reglist[i].bustype == 1) {
				ioaddr = reglist[i].base;
				BASE_IOA = ioaddr;
				break;
			}
		kmem_free(reglist, reglen);
	}
#ifdef LOGI_DEBUG
	if (logi_debug)
		PRF("logiinit: call BASE_IOA = %x\n", BASE_IOA);
#endif
	mse_config.present = 0;
	/* Check if the mouse board exists */
	outb(CONFIGURATOR_PORT, 0x91);
	drv_usecwait(10);
	outb(SIGNATURE_PORT, 0xC);
	drv_usecwait(10);
	i = inb(SIGNATURE_PORT);
	drv_usecwait(10);
	outb(SIGNATURE_PORT, 0x50);
	drv_usecwait(10);
	if (i == 0xC && ((inb(SIGNATURE_PORT)) == 0x50)) {
		mse_config.present = 1;
#ifdef LOGI_DEBUG
	if (logi_debug)
		printf("logiinit:Disable interrupts ioaddr %x\n", BASE_IOA);
#endif
		control_port(INTR_DISABLE);	/* Disable interrupts */
#ifdef LOGI_DEBUG
	if (logi_debug)
		PRF("logiinit: succeeded\n");
#endif
		return (DDI_SUCCESS);
	} else {
#ifdef LOGI_DEBUG
	if (logi_debug)
		PRF("logiinit: failed\n");
#endif
		return (DDI_PROBE_FAILURE);
	}
}
示例#7
0
文件: busra.c 项目: andreiw/polaris
/*
 * Setup resource map for the pci bus node based on the "available"
 * property and "bus-range" property.
 */
int
pci_resource_setup(dev_info_t *dip)
{
	pci_regspec_t *regs;
	int rlen, rcount, i;
	char bus_type[16] = "(unknown)";
	int len;
	struct busnum_ctrl ctrl;
	int circular_count;
	int rval = NDI_SUCCESS;

	/*
	 * If this is a pci bus node then look for "available" property
	 * to find the available resources on this bus.
	 */
	len = sizeof (bus_type);
	if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
	    DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "device_type",
	    (caddr_t)&bus_type, &len) != DDI_SUCCESS)
		return (NDI_FAILURE);

	/* it is not a pci/pci-ex bus type */
	if ((strcmp(bus_type, "pci") != 0) && (strcmp(bus_type, "pciex") != 0))
		return (NDI_FAILURE);

	/*
	 * The pci-hotplug project addresses adding the call
	 * to pci_resource_setup from pci nexus driver.
	 * However that project would initially be only for x86,
	 * so for sparc pcmcia-pci support we still need to call
	 * pci_resource_setup in pcic driver. Once all pci nexus drivers
	 * are updated to call pci_resource_setup this portion of the
	 * code would really become an assert to make sure this
	 * function is not called for the same dip twice.
	 */
	{
		if (ra_map_exist(dip, NDI_RA_TYPE_MEM) == NDI_SUCCESS) {
			return (NDI_FAILURE);
		}
	}


	/*
	 * Create empty resource maps first.
	 *
	 * NOTE: If all the allocated resources are already assigned to
	 * device(s) in the hot plug slot then "available" property may not
	 * be present. But, subsequent hot plug operation may unconfigure
	 * the device in the slot and try to free up it's resources. So,
	 * at the minimum we should create empty maps here.
	 */
	if (ndi_ra_map_setup(dip, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
		return (NDI_FAILURE);
	}

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

	if (ndi_ra_map_setup(dip, NDI_RA_TYPE_PCI_BUSNUM) == NDI_FAILURE) {
		return (NDI_FAILURE);
	}

	if (ndi_ra_map_setup(dip, NDI_RA_TYPE_PCI_PREFETCH_MEM) ==
	    NDI_FAILURE) {
		return (NDI_FAILURE);
	}

	/* read the "available" property if it is available */
	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "available", (caddr_t)&regs, &rlen) == DDI_SUCCESS) {
		/*
		 * create the available resource list for both memory and
		 * io space
		 */
		rcount = rlen / sizeof (pci_regspec_t);
		for (i = 0; i < rcount; i++) {
		    switch (PCI_REG_ADDR_G(regs[i].pci_phys_hi)) {
		    case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
			(void) ndi_ra_free(dip,
			    (uint64_t)regs[i].pci_phys_low,
			    (uint64_t)regs[i].pci_size_low,
			    (regs[i].pci_phys_hi & PCI_REG_PF_M) ?
			    NDI_RA_TYPE_PCI_PREFETCH_MEM : NDI_RA_TYPE_MEM,
			    0);
			break;
		    case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
			(void) ndi_ra_free(dip,
			    ((uint64_t)(regs[i].pci_phys_mid) << 32) |
			    ((uint64_t)(regs[i].pci_phys_low)),
			    ((uint64_t)(regs[i].pci_size_hi) << 32) |
			    ((uint64_t)(regs[i].pci_size_low)),
			    (regs[i].pci_phys_hi & PCI_REG_PF_M) ?
			    NDI_RA_TYPE_PCI_PREFETCH_MEM : NDI_RA_TYPE_MEM,
			    0);
			break;
		    case PCI_REG_ADDR_G(PCI_ADDR_IO):
			(void) ndi_ra_free(dip,
			    (uint64_t)regs[i].pci_phys_low,
			    (uint64_t)regs[i].pci_size_low,
			    NDI_RA_TYPE_IO,
			    0);
			break;
		    case PCI_REG_ADDR_G(PCI_ADDR_CONFIG):
			break;
		    default:
			cmn_err(CE_WARN,
			    "pci_resource_setup: bad addr type: %x\n",
			    PCI_REG_ADDR_G(regs[i].pci_phys_hi));
			break;
		    }
		}
		kmem_free((caddr_t)regs, rlen);
	}

	/*
	 * update resource map for available bus numbers if the node
	 * has available-bus-range or bus-range property.
	 */
	len = sizeof (struct bus_range);
	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "available-bus-range", (caddr_t)&pci_bus_range, &len) ==
	    DDI_SUCCESS) {
		/*
		 * Add bus numbers in the range to the free list.
		 */
		(void) ndi_ra_free(dip, (uint64_t)pci_bus_range.lo,
		    (uint64_t)pci_bus_range.hi - (uint64_t)pci_bus_range.lo +
		    1, NDI_RA_TYPE_PCI_BUSNUM, 0);
	} else {
		/*
		 * We don't have an available-bus-range property. If, instead,
		 * we have a bus-range property we add all the bus numbers
		 * in that range to the free list but we must then scan
		 * for pci-pci bridges on this bus to find out the if there
		 * are any of those bus numbers already in use. If so, we can
		 * reclaim them.
		 */
		len = sizeof (struct bus_range);
		if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip,
		    DDI_PROP_DONTPASS, "bus-range", (caddr_t)&pci_bus_range,
		    &len) == DDI_SUCCESS) {
			if (pci_bus_range.lo != pci_bus_range.hi) {
				/*
				 * Add bus numbers other than the secondary
				 * bus number to the free list.
				 */
				(void) ndi_ra_free(dip,
				    (uint64_t)pci_bus_range.lo + 1,
				    (uint64_t)pci_bus_range.hi -
				    (uint64_t)pci_bus_range.lo,
				    NDI_RA_TYPE_PCI_BUSNUM, 0);

				/* scan for pci-pci bridges */
				ctrl.rv = DDI_SUCCESS;
				ctrl.dip = dip;
				ctrl.range = &pci_bus_range;
				ndi_devi_enter(dip, &circular_count);
				ddi_walk_devs(ddi_get_child(dip),
				    claim_pci_busnum, (void *)&ctrl);
				ndi_devi_exit(dip, circular_count);
				if (ctrl.rv != DDI_SUCCESS) {
					/* failed to create the map */
					(void) ndi_ra_map_destroy(dip,
					    NDI_RA_TYPE_PCI_BUSNUM);
					rval = NDI_FAILURE;
				}
			}
		}
	}

#ifdef BUSRA_DEBUG
	if (busra_debug) {
		(void) ra_dump_all(NULL, dip);
	}
#endif

	return (rval);
}