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