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 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 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 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 1765084Sjohnlev _init(void) 1775084Sjohnlev { 1785084Sjohnlev int error; 1795084Sjohnlev 1805084Sjohnlev error = mod_install(&modlinkage); 1815084Sjohnlev return (error); 1825084Sjohnlev } 1835084Sjohnlev 1845084Sjohnlev int 1855084Sjohnlev _fini(void) 1865084Sjohnlev { 1875084Sjohnlev int error; 1885084Sjohnlev 1895084Sjohnlev error = mod_remove(&modlinkage); 1905084Sjohnlev return (error); 1915084Sjohnlev } 1925084Sjohnlev 1935084Sjohnlev int 1945084Sjohnlev _info(struct modinfo *modinfop) 1955084Sjohnlev { 1965084Sjohnlev return (mod_info(&modlinkage, modinfop)); 1975084Sjohnlev } 198