15084Sjohnlev /*
25084Sjohnlev * CDDL HEADER START
35084Sjohnlev *
45084Sjohnlev * The contents of this file are subject to the terms of the
55084Sjohnlev * Common Development and Distribution License (the "License").
65084Sjohnlev * You may not use this file except in compliance with the License.
75084Sjohnlev *
85084Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95084Sjohnlev * or http://www.opensolaris.org/os/licensing.
105084Sjohnlev * See the License for the specific language governing permissions
115084Sjohnlev * and limitations under the License.
125084Sjohnlev *
135084Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each
145084Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155084Sjohnlev * If applicable, add the following below this CDDL HEADER, with the
165084Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying
175084Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner]
185084Sjohnlev *
195084Sjohnlev * CDDL HEADER END
205084Sjohnlev */
215084Sjohnlev /*
22*7656SSherry.Moore@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
235084Sjohnlev * Use is subject to license terms.
245084Sjohnlev */
255084Sjohnlev
265084Sjohnlev
275084Sjohnlev /*
285084Sjohnlev * CPU nexus driver
295084Sjohnlev */
305084Sjohnlev
315084Sjohnlev #include <sys/types.h>
325084Sjohnlev #include <sys/param.h>
335084Sjohnlev #include <sys/conf.h>
345084Sjohnlev #include <sys/devops.h>
355084Sjohnlev #include <sys/modctl.h>
365084Sjohnlev #include <sys/cmn_err.h>
375084Sjohnlev #include <sys/ddi.h>
385084Sjohnlev #include <sys/sunddi.h>
395084Sjohnlev #include <sys/sunndi.h>
405084Sjohnlev
415084Sjohnlev static int cpunex_attach(dev_info_t *, ddi_attach_cmd_t);
425084Sjohnlev static int cpunex_detach(dev_info_t *, ddi_detach_cmd_t);
435084Sjohnlev static int cpunex_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
445084Sjohnlev void *, void *);
455084Sjohnlev
465084Sjohnlev static struct bus_ops cpunex_bus_ops = {
475084Sjohnlev BUSO_REV,
485084Sjohnlev nullbusmap,
495084Sjohnlev NULL,
505084Sjohnlev NULL,
515084Sjohnlev NULL,
525084Sjohnlev i_ddi_map_fault,
535084Sjohnlev ddi_no_dma_map,
545084Sjohnlev ddi_no_dma_allochdl,
555084Sjohnlev ddi_no_dma_freehdl,
565084Sjohnlev ddi_no_dma_bindhdl,
575084Sjohnlev ddi_no_dma_unbindhdl,
585084Sjohnlev ddi_no_dma_flush,
595084Sjohnlev ddi_no_dma_win,
605084Sjohnlev ddi_no_dma_mctl,
615084Sjohnlev cpunex_bus_ctl,
625084Sjohnlev ddi_bus_prop_op,
635084Sjohnlev };
645084Sjohnlev
655084Sjohnlev static struct dev_ops cpunex_ops = {
665084Sjohnlev DEVO_REV,
675084Sjohnlev 0,
685084Sjohnlev ddi_no_info,
695084Sjohnlev nulldev,
705084Sjohnlev nulldev,
715084Sjohnlev cpunex_attach,
725084Sjohnlev cpunex_detach,
735084Sjohnlev nodev,
745084Sjohnlev NULL,
755084Sjohnlev &cpunex_bus_ops,
76*7656SSherry.Moore@Sun.COM NULL,
77*7656SSherry.Moore@Sun.COM ddi_quiesce_not_needed, /* quiesce */
785084Sjohnlev };
795084Sjohnlev
805084Sjohnlev static struct modldrv modldrv = {
815084Sjohnlev &mod_driverops,
82*7656SSherry.Moore@Sun.COM "cpu nexus driver",
835084Sjohnlev &cpunex_ops
845084Sjohnlev };
855084Sjohnlev
865084Sjohnlev static struct modlinkage modlinkage = {
875084Sjohnlev MODREV_1,
885084Sjohnlev &modldrv,
895084Sjohnlev NULL
905084Sjohnlev };
915084Sjohnlev
925084Sjohnlev /*
935084Sjohnlev * cpunex_bus_ctl()
945084Sjohnlev * This routine implements nexus bus ctl operations. Of importance are
955084Sjohnlev * DDI_CTLOPS_REPORTDEV, DDI_CTLOPS_INITCHILD, DDI_CTLOPS_UNINITCHILD
965084Sjohnlev * and DDI_CTLOPS_POWER. For DDI_CTLOPS_INITCHILD, it tries to lookup
975084Sjohnlev * reg property on the child node and builds and sets the name.
985084Sjohnlev */
995084Sjohnlev static int
cpunex_bus_ctl(dev_info_t * dip,dev_info_t * rdip,ddi_ctl_enum_t op,void * arg,void * result)1005084Sjohnlev cpunex_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op, void *arg,
1015084Sjohnlev void *result)
1025084Sjohnlev {
1035084Sjohnlev switch (op) {
1045084Sjohnlev case DDI_CTLOPS_REPORTDEV: {
1055084Sjohnlev dev_info_t *pdip = ddi_get_parent(rdip);
1065084Sjohnlev cmn_err(CE_CONT, "?%s%d at %s%d",
1075084Sjohnlev ddi_node_name(rdip), ddi_get_instance(rdip),
1085084Sjohnlev ddi_node_name(pdip), ddi_get_instance(pdip));
1095084Sjohnlev return (DDI_SUCCESS);
1105084Sjohnlev }
1115084Sjohnlev
1125084Sjohnlev case DDI_CTLOPS_INITCHILD: {
1135084Sjohnlev dev_info_t *cdip = (dev_info_t *)arg;
1145084Sjohnlev int i;
1155084Sjohnlev char caddr[MAXNAMELEN];
1165084Sjohnlev
1175084Sjohnlev i = ddi_prop_get_int(DDI_DEV_T_ANY, cdip,
1185084Sjohnlev DDI_PROP_DONTPASS, "reg", -1);
1195084Sjohnlev
1205084Sjohnlev if (i == -1) {
1215084Sjohnlev cmn_err(CE_NOTE, "!%s(%d): \"reg\" property "
1225084Sjohnlev "not found", ddi_node_name(cdip),
1235084Sjohnlev ddi_get_instance(cdip));
1245084Sjohnlev return (DDI_NOT_WELL_FORMED);
1255084Sjohnlev }
1265084Sjohnlev
1275084Sjohnlev (void) sprintf(caddr, "%d", i);
1285084Sjohnlev ddi_set_name_addr(cdip, caddr);
1295084Sjohnlev
1305084Sjohnlev return (DDI_SUCCESS);
1315084Sjohnlev }
1325084Sjohnlev
1335084Sjohnlev case DDI_CTLOPS_UNINITCHILD: {
1345084Sjohnlev ddi_prop_remove_all((dev_info_t *)arg);
1355084Sjohnlev ddi_set_name_addr((dev_info_t *)arg, NULL);
1365084Sjohnlev return (DDI_SUCCESS);
1375084Sjohnlev }
1385084Sjohnlev
1395084Sjohnlev default: {
1405084Sjohnlev return (ddi_ctlops(dip, rdip, op, arg, result));
1415084Sjohnlev }
1425084Sjohnlev }
1435084Sjohnlev }
1445084Sjohnlev
1455084Sjohnlev /*ARGSUSED*/
1465084Sjohnlev static int
cpunex_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)1475084Sjohnlev cpunex_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1485084Sjohnlev {
1495084Sjohnlev switch (cmd) {
1505084Sjohnlev case DDI_ATTACH:
1515084Sjohnlev case DDI_RESUME:
1525084Sjohnlev break;
1535084Sjohnlev default:
1545084Sjohnlev return (DDI_FAILURE);
1555084Sjohnlev }
1565084Sjohnlev
1575084Sjohnlev return (DDI_SUCCESS);
1585084Sjohnlev }
1595084Sjohnlev
1605084Sjohnlev /*ARGSUSED*/
1615084Sjohnlev static int
cpunex_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1625084Sjohnlev cpunex_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1635084Sjohnlev {
1645084Sjohnlev switch (cmd) {
1655084Sjohnlev case DDI_DETACH:
1665084Sjohnlev case DDI_SUSPEND:
1675084Sjohnlev break;
1685084Sjohnlev default:
1695084Sjohnlev return (DDI_FAILURE);
1705084Sjohnlev }
1715084Sjohnlev
1725084Sjohnlev return (DDI_SUCCESS);
1735084Sjohnlev }
1745084Sjohnlev
1755084Sjohnlev int
_init(void)1765084Sjohnlev _init(void)
1775084Sjohnlev {
1785084Sjohnlev int error;
1795084Sjohnlev
1805084Sjohnlev error = mod_install(&modlinkage);
1815084Sjohnlev return (error);
1825084Sjohnlev }
1835084Sjohnlev
1845084Sjohnlev int
_fini(void)1855084Sjohnlev _fini(void)
1865084Sjohnlev {
1875084Sjohnlev int error;
1885084Sjohnlev
1895084Sjohnlev error = mod_remove(&modlinkage);
1905084Sjohnlev return (error);
1915084Sjohnlev }
1925084Sjohnlev
1935084Sjohnlev int
_info(struct modinfo * modinfop)1945084Sjohnlev _info(struct modinfo *modinfop)
1955084Sjohnlev {
1965084Sjohnlev return (mod_info(&modlinkage, modinfop));
1975084Sjohnlev }
198