1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/kobj.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/membar.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/dmv.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/prom_debug.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate /* 39*7c478bd9Sstevel@tonic-gate * Implementation of databearing mondo vector handler registration routines. 40*7c478bd9Sstevel@tonic-gate * See PSARC 1998/222 for more details. 41*7c478bd9Sstevel@tonic-gate */ 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate /* 44*7c478bd9Sstevel@tonic-gate * The dmv_interface_*_version variables are provided to protect a 45*7c478bd9Sstevel@tonic-gate * driver against changes in the databearing mondo interfaces. 46*7c478bd9Sstevel@tonic-gate * 47*7c478bd9Sstevel@tonic-gate * The major version is incremented when an incompatible change 48*7c478bd9Sstevel@tonic-gate * is made to an interface; for instance, a routine which used to take 49*7c478bd9Sstevel@tonic-gate * 3 parameters now takes 4, or a routine which used have the semantics 50*7c478bd9Sstevel@tonic-gate * "do X" now has the semantics "do Y". Before calling any of the 51*7c478bd9Sstevel@tonic-gate * databearing mondo routines, a driver must check the major version 52*7c478bd9Sstevel@tonic-gate * it was compiled with (i.e., the constant DMV_INTERFACE_MAJOR_VERSION) 53*7c478bd9Sstevel@tonic-gate * against the contents of dmv_interface_major_version. If the two 54*7c478bd9Sstevel@tonic-gate * are different, the driver must refuse to operate. 55*7c478bd9Sstevel@tonic-gate * 56*7c478bd9Sstevel@tonic-gate * The minor version is incremented when an upward-compatible change 57*7c478bd9Sstevel@tonic-gate * is made to an interface; for instance, a routine now supports a new 58*7c478bd9Sstevel@tonic-gate * flag bit (in an existing flags argument). A client can use the 59*7c478bd9Sstevel@tonic-gate * minor version to see whether a feature it depends on is available 60*7c478bd9Sstevel@tonic-gate * in its environment; in order to enable this, the documentation 61*7c478bd9Sstevel@tonic-gate * for new features should note which major and minor version the 62*7c478bd9Sstevel@tonic-gate * feature first appears in. 63*7c478bd9Sstevel@tonic-gate */ 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate int dmv_interface_major_version = DMV_INTERFACE_MAJOR_VERSION; 66*7c478bd9Sstevel@tonic-gate int dmv_interface_minor_version = DMV_INTERFACE_MINOR_VERSION; 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate /* 69*7c478bd9Sstevel@tonic-gate * These are where the number of hardware and software DMV inums are kept. 70*7c478bd9Sstevel@tonic-gate * If they're zero, we use the platform's default values. (These are not 71*7c478bd9Sstevel@tonic-gate * patchable in /etc/system, since the dispatch table is allocated before 72*7c478bd9Sstevel@tonic-gate * /etc/system is loaded; however, you could patch them by adb'ing unix.) 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate uint_t dmv_hwint = 0; 76*7c478bd9Sstevel@tonic-gate uint_t dmv_swint = 0; 77*7c478bd9Sstevel@tonic-gate uint_t dmv_totalints = 0; 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate struct dmv_disp *dmv_dispatch_table = (struct dmv_disp *)0; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate * dmv_disp_lock protects the dispatch table from being modified by two 83*7c478bd9Sstevel@tonic-gate * threads concurrently. It is not used to protect the table from being 84*7c478bd9Sstevel@tonic-gate * modified while being used by the actual interrupt dispatch code; see 85*7c478bd9Sstevel@tonic-gate * comments at the end of dmv.h for the rationale. 86*7c478bd9Sstevel@tonic-gate */ 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate kmutex_t dmv_disp_lock; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* 91*7c478bd9Sstevel@tonic-gate * dmv_add_intr is called to add a databearing mondo interrupt handler 92*7c478bd9Sstevel@tonic-gate * for a real device to the system. Only one handler may be registered 93*7c478bd9Sstevel@tonic-gate * for a dmv_inum at any one time. 94*7c478bd9Sstevel@tonic-gate * 95*7c478bd9Sstevel@tonic-gate * Note that if a processor receives a databearing mondo interrupt 96*7c478bd9Sstevel@tonic-gate * for which a handler has not been registered, the behavior is 97*7c478bd9Sstevel@tonic-gate * undefined. (Current practice for normal mondos which are unhandled 98*7c478bd9Sstevel@tonic-gate * depends on whether DEBUG is on; a DEBUG kernel prints an error 99*7c478bd9Sstevel@tonic-gate * and breaks to OBP, while a non-DEBUG kernel simply panics. This 100*7c478bd9Sstevel@tonic-gate * model will likely be followed for databearing mondos.) 101*7c478bd9Sstevel@tonic-gate * 102*7c478bd9Sstevel@tonic-gate * Parameters: 103*7c478bd9Sstevel@tonic-gate * dmv_inum interrupt number for the device. 104*7c478bd9Sstevel@tonic-gate * 105*7c478bd9Sstevel@tonic-gate * routine pointer to the device's vectored interrupt 106*7c478bd9Sstevel@tonic-gate * handler. This routine is subject to the 107*7c478bd9Sstevel@tonic-gate * constraints outlined below in "Handler 108*7c478bd9Sstevel@tonic-gate * Characteristics and Environment". 109*7c478bd9Sstevel@tonic-gate * 110*7c478bd9Sstevel@tonic-gate * arg argument which will be passed to the device's 111*7c478bd9Sstevel@tonic-gate * handler. 112*7c478bd9Sstevel@tonic-gate * 113*7c478bd9Sstevel@tonic-gate * Return value: 0 if the handler was added successfully, -1 if 114*7c478bd9Sstevel@tonic-gate * handler was already registered for the given 115*7c478bd9Sstevel@tonic-gate * dmv_inum. 116*7c478bd9Sstevel@tonic-gate * 117*7c478bd9Sstevel@tonic-gate * Handler Characteristics and Environment 118*7c478bd9Sstevel@tonic-gate * 119*7c478bd9Sstevel@tonic-gate * Handler Entry: 120*7c478bd9Sstevel@tonic-gate * 121*7c478bd9Sstevel@tonic-gate * On entry to the handler, the %g registers are set as follows: 122*7c478bd9Sstevel@tonic-gate * 123*7c478bd9Sstevel@tonic-gate * %g1 The argument (arg) passed to dmv_add_intr(). 124*7c478bd9Sstevel@tonic-gate * %g2 Word 0 of the incoming mondo vector. 125*7c478bd9Sstevel@tonic-gate * 126*7c478bd9Sstevel@tonic-gate * 127*7c478bd9Sstevel@tonic-gate * Handler Constraints: 128*7c478bd9Sstevel@tonic-gate * 129*7c478bd9Sstevel@tonic-gate * While executing, the handler must obey the following rules: 130*7c478bd9Sstevel@tonic-gate * 131*7c478bd9Sstevel@tonic-gate * 1. The handler is limited to the use of registers %g1 through 132*7c478bd9Sstevel@tonic-gate * %g7. 133*7c478bd9Sstevel@tonic-gate * 134*7c478bd9Sstevel@tonic-gate * 2. The handler may not modify %cwp (i.e., may not execute a 135*7c478bd9Sstevel@tonic-gate * SAVE or RESTORE instruction). 136*7c478bd9Sstevel@tonic-gate * 137*7c478bd9Sstevel@tonic-gate * 3. The handler may not read or write the stack. 138*7c478bd9Sstevel@tonic-gate * 139*7c478bd9Sstevel@tonic-gate * 4. The handler may not call any other DDI or kernel routines. 140*7c478bd9Sstevel@tonic-gate * 141*7c478bd9Sstevel@tonic-gate * 5. The handler may not call any other routines inside the 142*7c478bd9Sstevel@tonic-gate * handler's own driver, since this would modify %o7; however, 143*7c478bd9Sstevel@tonic-gate * it is permissible to jump to a routine within the handler's 144*7c478bd9Sstevel@tonic-gate * driver. 145*7c478bd9Sstevel@tonic-gate * 146*7c478bd9Sstevel@tonic-gate * 6. The handler may read the Incoming Interrupt Vector Data 147*7c478bd9Sstevel@tonic-gate * registers, and the Interrupt Vector Receive register, but 148*7c478bd9Sstevel@tonic-gate * must not modify these registers. (Note: symbols for the 149*7c478bd9Sstevel@tonic-gate * ASIs and addresses of these registers are in <sys/spitasi.h> 150*7c478bd9Sstevel@tonic-gate * and <sys/intreg.h>.) 151*7c478bd9Sstevel@tonic-gate * 152*7c478bd9Sstevel@tonic-gate * 7. The handler may read or write driver-private data 153*7c478bd9Sstevel@tonic-gate * structures; in order to protect against simultaneous 154*7c478bd9Sstevel@tonic-gate * modification by other driver routines, nonblocking data 155*7c478bd9Sstevel@tonic-gate * sharing algorithms must be used. (For instance, 156*7c478bd9Sstevel@tonic-gate * compare-and-swap could be used to update counters or add 157*7c478bd9Sstevel@tonic-gate * entries to linked lists; producer-consumer queues are 158*7c478bd9Sstevel@tonic-gate * another possibility.) 159*7c478bd9Sstevel@tonic-gate * 160*7c478bd9Sstevel@tonic-gate * 8. The handler should neither read nor write any other 161*7c478bd9Sstevel@tonic-gate * processor register nor kernel data item which is not 162*7c478bd9Sstevel@tonic-gate * explicitly mentioned in this list. [Yes, this is rather 163*7c478bd9Sstevel@tonic-gate * strict; the intent here is that as handler implementations 164*7c478bd9Sstevel@tonic-gate * are done, and more experience is gained, additional items 165*7c478bd9Sstevel@tonic-gate * may be permitted.] 166*7c478bd9Sstevel@tonic-gate * 167*7c478bd9Sstevel@tonic-gate * 168*7c478bd9Sstevel@tonic-gate * Handler Exit: 169*7c478bd9Sstevel@tonic-gate * 170*7c478bd9Sstevel@tonic-gate * When the handler's processing is complete, the handler must 171*7c478bd9Sstevel@tonic-gate * exit by jumping to the label dmv_finish_intr. At this time, 172*7c478bd9Sstevel@tonic-gate * the handler may optionally request the execution of a soft 173*7c478bd9Sstevel@tonic-gate * interrupt routine in order to do further processing at normal 174*7c478bd9Sstevel@tonic-gate * interrupt level. It is strongly advised that drivers do 175*7c478bd9Sstevel@tonic-gate * minimal processing in their databearing mondo handlers; 176*7c478bd9Sstevel@tonic-gate * whenever possible, tasks should be postponed to a later 177*7c478bd9Sstevel@tonic-gate * soft interrupt routine. (This is analogous to the DDI 178*7c478bd9Sstevel@tonic-gate * "high-level interrupt" concept, although a databearing mondo 179*7c478bd9Sstevel@tonic-gate * handler's environment is even more restrictive than that of 180*7c478bd9Sstevel@tonic-gate * a high-level interrupt routine.) 181*7c478bd9Sstevel@tonic-gate * 182*7c478bd9Sstevel@tonic-gate * Soft interrupt routines should be registered by calling 183*7c478bd9Sstevel@tonic-gate * add_softintr(), which will return an interrupt number. This 184*7c478bd9Sstevel@tonic-gate * interrupt number should be saved in a driver-private data 185*7c478bd9Sstevel@tonic-gate * structure for later use. 186*7c478bd9Sstevel@tonic-gate * 187*7c478bd9Sstevel@tonic-gate * The contents of %g1 on entry to dmv_finish_intr determine 188*7c478bd9Sstevel@tonic-gate * whether a soft interrupt routine will be called, as follows: 189*7c478bd9Sstevel@tonic-gate * 190*7c478bd9Sstevel@tonic-gate * If %g1 is less than zero, no interrupt will be queued. 191*7c478bd9Sstevel@tonic-gate * 192*7c478bd9Sstevel@tonic-gate * Otherwise, %g1 is assumed to be an interrupt number 193*7c478bd9Sstevel@tonic-gate * obtained from add_softintr. This interrupt routine 194*7c478bd9Sstevel@tonic-gate * will be executed in the normal way at the requested 195*7c478bd9Sstevel@tonic-gate * priority. (Note that this routine may or may not 196*7c478bd9Sstevel@tonic-gate * execute on the same CPU as the current handler.) 197*7c478bd9Sstevel@tonic-gate */ 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate int 200*7c478bd9Sstevel@tonic-gate dmv_add_intr(int dmv_inum, void (*routine)(), void *arg) 201*7c478bd9Sstevel@tonic-gate { 202*7c478bd9Sstevel@tonic-gate if (dmv_inum < 0 || dmv_inum >= dmv_hwint) 203*7c478bd9Sstevel@tonic-gate return (-1); 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate mutex_enter(&dmv_disp_lock); 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate if (dmv_dispatch_table[dmv_inum].dmv_func != 0) { 208*7c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 209*7c478bd9Sstevel@tonic-gate return (-1); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate dmv_dispatch_table[dmv_inum].dmv_arg = arg; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate membar_sync(); 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate dmv_dispatch_table[dmv_inum].dmv_func = routine; 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 219*7c478bd9Sstevel@tonic-gate return (0); 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate /* 223*7c478bd9Sstevel@tonic-gate * dmv_add_softintr is called to add a databearing mondo interrupt 224*7c478bd9Sstevel@tonic-gate * handler for a pseudo-device to the system. 225*7c478bd9Sstevel@tonic-gate * 226*7c478bd9Sstevel@tonic-gate * Parameters: 227*7c478bd9Sstevel@tonic-gate * routine pointer to the device's vectored interrupt 228*7c478bd9Sstevel@tonic-gate * handler. This routine is subject to the 229*7c478bd9Sstevel@tonic-gate * constraints outlined above in "Handler 230*7c478bd9Sstevel@tonic-gate * Characteristics and Environment". 231*7c478bd9Sstevel@tonic-gate * 232*7c478bd9Sstevel@tonic-gate * arg argument which will be passed to the device's 233*7c478bd9Sstevel@tonic-gate * handler. 234*7c478bd9Sstevel@tonic-gate * 235*7c478bd9Sstevel@tonic-gate * Return value: dmv_inum allocated if one was available, -1 if 236*7c478bd9Sstevel@tonic-gate * all soft dmv_inums are already allocated 237*7c478bd9Sstevel@tonic-gate */ 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate int 240*7c478bd9Sstevel@tonic-gate dmv_add_softintr(void (*routine)(void), void *arg) 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate int i; 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate mutex_enter(&dmv_disp_lock); 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate for (i = dmv_hwint; i < dmv_totalints; i++) { 247*7c478bd9Sstevel@tonic-gate if (dmv_dispatch_table[i].dmv_func == 0) { 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate dmv_dispatch_table[i].dmv_arg = arg; 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate membar_sync(); 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate dmv_dispatch_table[i].dmv_func = routine; 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 256*7c478bd9Sstevel@tonic-gate return (i); 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 261*7c478bd9Sstevel@tonic-gate return (-1); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* 265*7c478bd9Sstevel@tonic-gate * dmv_rem_intr is called to remove a databearing interrupt handler 266*7c478bd9Sstevel@tonic-gate * from the system. 267*7c478bd9Sstevel@tonic-gate * 268*7c478bd9Sstevel@tonic-gate * Parameters: 269*7c478bd9Sstevel@tonic-gate * dmv_inum interrupt number for the device. 270*7c478bd9Sstevel@tonic-gate * 271*7c478bd9Sstevel@tonic-gate * Return value: 0 if the handler was removed successfully, -1 272*7c478bd9Sstevel@tonic-gate * if no handler was registered for the given 273*7c478bd9Sstevel@tonic-gate * dmv_inum. 274*7c478bd9Sstevel@tonic-gate */ 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate int 277*7c478bd9Sstevel@tonic-gate dmv_rem_intr(int dmv_inum) 278*7c478bd9Sstevel@tonic-gate { 279*7c478bd9Sstevel@tonic-gate if (dmv_inum < 0 || dmv_inum >= (dmv_totalints)) 280*7c478bd9Sstevel@tonic-gate return (-1); 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate mutex_enter(&dmv_disp_lock); 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate if (dmv_dispatch_table[dmv_inum].dmv_func == 0) { 285*7c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 286*7c478bd9Sstevel@tonic-gate return (-1); 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate dmv_dispatch_table[dmv_inum].dmv_func = 0; 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate mutex_exit(&dmv_disp_lock); 292*7c478bd9Sstevel@tonic-gate return (0); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate /* 297*7c478bd9Sstevel@tonic-gate * Allocate the dmv dispatch table from nucleus data memory. 298*7c478bd9Sstevel@tonic-gate */ 299*7c478bd9Sstevel@tonic-gate int 300*7c478bd9Sstevel@tonic-gate ndata_alloc_dmv(struct memlist *ndata) 301*7c478bd9Sstevel@tonic-gate { 302*7c478bd9Sstevel@tonic-gate size_t alloc_sz; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate uint_t plat_hwint = 0; 305*7c478bd9Sstevel@tonic-gate uint_t plat_swint = 0; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate void (*plat_dmv_params)(uint_t *, uint_t *); 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate /* 311*7c478bd9Sstevel@tonic-gate * Get platform default values, if they exist 312*7c478bd9Sstevel@tonic-gate */ 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate plat_dmv_params = (void (*)(uint_t *, uint_t *)) 315*7c478bd9Sstevel@tonic-gate kobj_getsymvalue("plat_dmv_params", 0); 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate if (plat_dmv_params) 318*7c478bd9Sstevel@tonic-gate (*plat_dmv_params)(&plat_hwint, &plat_swint); 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate /* 321*7c478bd9Sstevel@tonic-gate * Set sizes to platform defaults if user hasn't set them 322*7c478bd9Sstevel@tonic-gate */ 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate if (dmv_hwint == 0) 325*7c478bd9Sstevel@tonic-gate dmv_hwint = plat_hwint; 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate if (dmv_swint == 0) 328*7c478bd9Sstevel@tonic-gate dmv_swint = plat_swint; 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate /* 331*7c478bd9Sstevel@tonic-gate * Allocate table if we need it 332*7c478bd9Sstevel@tonic-gate */ 333*7c478bd9Sstevel@tonic-gate dmv_totalints = dmv_hwint + dmv_swint; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate if (dmv_totalints != 0) { 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate alloc_sz = sizeof (struct dmv_disp) * (dmv_totalints + 1); 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate dmv_dispatch_table = ndata_alloc(ndata, alloc_sz, 340*7c478bd9Sstevel@tonic-gate sizeof (struct dmv_disp)); 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate if (dmv_dispatch_table == NULL) 343*7c478bd9Sstevel@tonic-gate return (-1); 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate bzero(dmv_dispatch_table, alloc_sz); 346*7c478bd9Sstevel@tonic-gate PRM_DEBUG(dmv_dispatch_table); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate return (0); 350*7c478bd9Sstevel@tonic-gate } 351