1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _SYS_NSCTL_MODEL_H
  27 #define _SYS_NSCTL_MODEL_H
  28 
  29 #ifdef  __cplusplus
  30 extern "C" {
  31 #endif
  32 
  33 /*
  34  * Stolen from Solaris 8
  35  * Only used for Solaris 2.6
  36  */
  37 #define _ILP32
  38 #undef _ASM
  39 
  40 
  41 #ifdef _KERNEL
  42 #include <sys/debug.h>
  43 #endif
  44 
  45 #ifndef DS_DDICT
  46 #include <sys/isa_defs.h>
  47 #endif
  48 
  49 typedef uint32_t        caddr32_t;
  50 
  51 #if defined(_KERNEL) || defined(_KMEMUSER)
  52 
  53 /*
  54  * These bits are used in various places to specify the data model
  55  * of the originator (and/or consumer) of data items.  See <sys/conf.h>
  56  * <sys/file.h>, <sys/stream.h> and <sys/sunddi.h>.
  57  *
  58  * This state should only be known to the kernel implementation.
  59  */
  60 #define DATAMODEL_MASK  0x0FF00000
  61 
  62 #define DATAMODEL_ILP32 0x00100000
  63 #define DATAMODEL_LP64  0x00200000
  64 
  65 #define DATAMODEL_NONE  0
  66 
  67 #if     defined(_LP64)
  68 #define DATAMODEL_NATIVE        DATAMODEL_LP64
  69 #elif   defined(_ILP32)
  70 #define DATAMODEL_NATIVE        DATAMODEL_ILP32
  71 #else
  72 #error  "No DATAMODEL_NATIVE specified"
  73 #endif  /* _LP64 || _ILP32 */
  74 
  75 #endif  /* _KERNEL || _KMEMUSER */
  76 
  77 #ifndef _ASM
  78 /*
  79  * XXX  Ick.  This type needs to be visible outside the above guard because
  80  * the proc structure is visible outside the _KERNEL | _KMEMUSER guard.
  81  * If we can make proc internals less visible, (which we obviously should)
  82  * then this can be invisible too.
  83  */
  84 typedef unsigned int model_t;
  85 
  86 #endif  /* _ASM */
  87 
  88 #if defined(_KERNEL) && !defined(_ASM)
  89 /*
  90  * These macros allow two views of the same piece of memory depending
  91  * on the originating user-mode program's data model.  See the manual
  92  * pages (or uts/README.XX64).
  93  */
  94 #if defined(_LP64)
  95 
  96 #define STRUCT_HANDLE(struct_type, handle)                              \
  97         struct __##handle##_type {                                      \
  98                 union {                                                 \
  99                         struct struct_type##32  *m32;                   \
 100                         struct struct_type      *m64;                   \
 101                 }       ptr;                                            \
 102                 model_t model;                                          \
 103         } handle = { NULL, DATAMODEL_ILP32 }
 104 
 105 #define STRUCT_DECL(struct_type, handle)                                \
 106         struct struct_type __##handle##_buf;                            \
 107         STRUCT_HANDLE(struct_type, handle)
 108 
 109 #define STRUCT_SET_HANDLE(handle, umodel, addr)                         \
 110         (handle).model = (model_t)(umodel) & DATAMODEL_MASK;                \
 111         ASSERT(((umodel) & DATAMODEL_MASK) != DATAMODEL_NONE);              \
 112         ((handle).ptr.m64) = (addr)
 113 
 114 #define STRUCT_INIT(handle, umodel)                                     \
 115         STRUCT_SET_HANDLE(handle, umodel, &__##handle##_buf)
 116 
 117 #define STRUCT_SIZE(handle)                                             \
 118         ((handle).model == DATAMODEL_ILP32 ?                            \
 119             sizeof (*(handle).ptr.m32) :                                \
 120             sizeof (*(handle).ptr.m64))
 121 
 122 /*
 123  * In STRUCT_FADDR and STRUCT_FGETP a sleight of hand is employed to make
 124  * the compiler cope with having two different pointer types within ?:.
 125  * The (void *) case on the ILP32 case makes it a pointer which can be
 126  * converted to the pointer on the LP64 case, thus quieting the compiler.
 127  */
 128 #define STRUCT_FADDR(handle, field)                                     \
 129         ((handle).model == DATAMODEL_ILP32 ?                            \
 130             (void *)&(handle).ptr.m32->field :                           \
 131             &(handle).ptr.m64->field)
 132 
 133 #define STRUCT_FGET(handle, field)                                      \
 134         (((handle).model == DATAMODEL_ILP32) ?                          \
 135             (handle).ptr.m32->field :                                        \
 136             (handle).ptr.m64->field)
 137 
 138 #define STRUCT_FGETP(handle, field)                                     \
 139         ((handle).model == DATAMODEL_ILP32 ?                            \
 140             (void *)(handle).ptr.m32->field :                                \
 141             (handle).ptr.m64->field)
 142 
 143 #define STRUCT_FSET(handle, field, val)                                 \
 144         ((handle).model == DATAMODEL_ILP32 ?                            \
 145             ((handle).ptr.m32->field = (val)) :                              \
 146             ((handle).ptr.m64->field = (val)))
 147 
 148 #define STRUCT_FSETP(handle, field, val)                                \
 149         ((handle).model == DATAMODEL_ILP32 ?                            \
 150             (void) ((handle).ptr.m32->field = (caddr32_t)(val)) :    \
 151             (void) ((handle).ptr.m64->field = (val)))
 152 
 153 #define STRUCT_BUF(handle)      ((handle).ptr.m64)
 154 
 155 #define SIZEOF_PTR(umodel)                                              \
 156         (((umodel) & DATAMODEL_MASK) == DATAMODEL_ILP32 ?           \
 157             sizeof (caddr32_t) :                                        \
 158             sizeof (caddr_t))
 159 
 160 #define SIZEOF_STRUCT(struct_type, umodel)                              \
 161         (((umodel) & DATAMODEL_MASK) == DATAMODEL_ILP32 ?           \
 162             sizeof (struct struct_type##32) :                           \
 163             sizeof (struct struct_type))
 164 
 165 #else   /*  _LP64 */
 166 
 167 #define STRUCT_HANDLE(struct_type, handle)                              \
 168         struct __##handle##_32 {                                        \
 169                 struct struct_type *ptr;                                \
 170         };                                                              \
 171         struct __##handle##_32 handle = { NULL }
 172 
 173 #define STRUCT_DECL(struct_type, handle)                                \
 174         struct struct_type __##handle##_buf;                            \
 175         STRUCT_HANDLE(struct_type, handle)
 176 
 177 #ifdef  lint
 178 #define STRUCT_SET_HANDLE(handle, umodel, addr)                         \
 179         (void) (umodel);                                                \
 180         (handle).ptr = (addr)
 181 #else
 182 #define STRUCT_SET_HANDLE(handle, umodel, addr)                         \
 183         (handle).ptr = (addr)
 184 #endif  /* lint */
 185 
 186 #define STRUCT_INIT(handle, umodel)                                     \
 187         STRUCT_SET_HANDLE(handle, umodel, &__##handle##_buf)
 188 
 189 #define STRUCT_SIZE(handle)             (sizeof (*(handle).ptr))
 190 
 191 #define STRUCT_FADDR(handle, field)     (&(handle).ptr->field)
 192 
 193 #define STRUCT_FGET(handle, field)      ((handle).ptr->field)
 194 
 195 #define STRUCT_FGETP                    STRUCT_FGET
 196 
 197 #define STRUCT_FSET(handle, field, val) ((handle).ptr->field = (val))
 198 
 199 #define STRUCT_FSETP                    STRUCT_FSET
 200 
 201 #define STRUCT_BUF(handle)              ((handle).ptr)
 202 
 203 #define SIZEOF_PTR(umodel)              sizeof (caddr_t)
 204 
 205 #define SIZEOF_STRUCT(struct_type, umodel)      sizeof (struct struct_type)
 206 
 207 #endif  /* _LP64 */
 208 
 209 #if defined(_LP64) || defined(lint) || defined(__lint)
 210 
 211 struct _klwp;
 212 
 213 extern  model_t lwp_getdatamodel(struct _klwp *);
 214 extern  model_t get_udatamodel(void);
 215 
 216 #else
 217 
 218 /*
 219  * If we're the 32-bit kernel, the result of these function
 220  * calls is completely predictable, so let's just cheat.  A
 221  * good compiler should be able to elide all the unreachable code
 222  * that results.  Optimism about optimization reigns supreme ;-)
 223  */
 224 #define lwp_getdatamodel(t)             DATAMODEL_ILP32
 225 #define get_udatamodel()                DATAMODEL_ILP32
 226 
 227 #endif  /* _LP64 || lint || __lint */
 228 
 229 #endif  /* _KERNEL && !_ASM */
 230 
 231 #ifdef  __cplusplus
 232 }
 233 #endif
 234 
 235 #endif  /* _SYS_NSCTL_MODEL_H */