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 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 #if defined(_KERNEL) && !defined(_ASM)
  35 #include <sys/debug.h>
  36 #endif /* _KERNEL && !_ASM */
  37 
  38 #include <sys/isa_defs.h>
  39 
  40 #if defined(_KERNEL) || defined(_FAKE_KERNEL) || defined(_KMEMUSER)
  41 
  42 /*
  43  * These bits are used in various places to specify the data model
  44  * of the originator (and/or consumer) of data items.  See <sys/conf.h>
  45  * <sys/file.h>, <sys/stream.h> and <sys/sunddi.h>.
  46  *
  47  * This state should only be known to the kernel implementation.
  48  */
  49 #define DATAMODEL_MASK  0x0FF00000
  50 
  51 #define DATAMODEL_ILP32 0x00100000
  52 #define DATAMODEL_LP64  0x00200000
  53 
  54 #define DATAMODEL_NONE  0
  55 
  56 #if     defined(_LP64)
  57 #define DATAMODEL_NATIVE        DATAMODEL_LP64
  58 #elif   defined(_ILP32)
  59 #define DATAMODEL_NATIVE        DATAMODEL_ILP32
  60 #else
  61 #error  "No DATAMODEL_NATIVE specified"
  62 #endif  /* _LP64 || _ILP32 */
  63 
  64 #endif  /* _KERNEL || _KMEMUSER */
  65 
  66 #ifndef _ASM
  67 /*
  68  * XXX  Ick.  This type needs to be visible outside the above guard because
  69  * the proc structure is visible outside the _KERNEL | _KMEMUSER guard.
  70  * If we can make proc internals less visible, (which we obviously should)
  71  * then this can be invisible too.
  72  */
  73 typedef unsigned int model_t;
  74 
  75 #endif  /* _ASM */
  76 
  77 #if defined(_KERNEL) && !defined(_ASM)
  78 /*
  79  * These macros allow two views of the same piece of memory depending
  80  * on the originating user-mode program's data model.  See the STRUCT_DECL(9F)
  81  * man page.
  82  */
  83 #if defined(_LP64)
  84 
  85 #define STRUCT_HANDLE(struct_type, handle)                              \
  86         struct {                                                        \
  87                 union {                                                 \
  88                         struct struct_type##32  *m32;                   \
  89                         struct struct_type      *m64;                   \
  90                 }       ptr;                                            \
  91                 model_t model;                                          \
  92         } handle = { NULL, DATAMODEL_ILP32 }
  93 
  94 #define STRUCT_DECL(struct_type, handle)                                \
  95         struct struct_type __##handle##_buf;                            \
  96         STRUCT_HANDLE(struct_type, handle)
  97 
  98 #define STRUCT_SET_HANDLE(handle, umodel, addr)                         \
  99         (handle).model = (model_t)(umodel) & DATAMODEL_MASK;                \
 100         ASSERT(((umodel) & DATAMODEL_MASK) != DATAMODEL_NONE);              \
 101         ((handle).ptr.m64) = (addr)
 102 
 103 #define STRUCT_INIT(handle, umodel)                                     \
 104         STRUCT_SET_HANDLE(handle, umodel, &__##handle##_buf)
 105 
 106 #define STRUCT_SIZE(handle)                                             \
 107         ((handle).model == DATAMODEL_ILP32 ?                            \
 108             sizeof (*(handle).ptr.m32) :                                \
 109             sizeof (*(handle).ptr.m64))
 110 
 111 /*
 112  * In STRUCT_FADDR and STRUCT_FGETP a sleight of hand is employed to make
 113  * the compiler cope with having two different pointer types within ?:.
 114  * The (void *) case on the ILP32 case makes it a pointer which can be
 115  * converted to the pointer on the LP64 case, thus quieting the compiler.
 116  */
 117 #define STRUCT_FADDR(handle, field)                                     \
 118         ((handle).model == DATAMODEL_ILP32 ?                            \
 119             (void *)&(handle).ptr.m32->field :                           \
 120             &(handle).ptr.m64->field)
 121 
 122 #define STRUCT_FGET(handle, field)                                      \
 123         (((handle).model == DATAMODEL_ILP32) ?                          \
 124             (handle).ptr.m32->field :                                        \
 125             (handle).ptr.m64->field)
 126 
 127 #define STRUCT_FGETP(handle, field)                                     \
 128         ((handle).model == DATAMODEL_ILP32 ?                            \
 129             (void *)(uintptr_t)(handle).ptr.m32->field :             \
 130             (handle).ptr.m64->field)
 131 
 132 #define STRUCT_FSET(handle, field, val)                                 \
 133         ((handle).model == DATAMODEL_ILP32 ?                            \
 134             ((handle).ptr.m32->field = (val)) :                              \
 135             ((handle).ptr.m64->field = (val)))
 136 
 137 #define STRUCT_FSETP(handle, field, val)                                \
 138         ((handle).model == DATAMODEL_ILP32 ?                            \
 139             (void) ((handle).ptr.m32->field = (caddr32_t)(uintptr_t)(val)) : \
 140             (void) ((handle).ptr.m64->field = (val)))
 141 
 142 #define STRUCT_BUF(handle)      ((handle).ptr.m64)
 143 
 144 #define SIZEOF_PTR(umodel)                                              \
 145         (((umodel) & DATAMODEL_MASK) == DATAMODEL_ILP32 ?           \
 146             sizeof (caddr32_t) :                                        \
 147             sizeof (caddr_t))
 148 
 149 #define SIZEOF_STRUCT(struct_type, umodel)                              \
 150         (((umodel) & DATAMODEL_MASK) == DATAMODEL_ILP32 ?           \
 151             sizeof (struct struct_type##32) :                           \
 152             sizeof (struct struct_type))
 153 
 154 #else   /*  _LP64 */
 155 
 156 #define STRUCT_HANDLE(struct_type, handle)                              \
 157         struct {                                                        \
 158                 struct struct_type *ptr;                                \
 159                 model_t model;                                          \
 160         } handle = { NULL, DATAMODEL_ILP32 }
 161 
 162 #define STRUCT_DECL(struct_type, handle)                                \
 163         struct struct_type __##handle##_buf;                            \
 164         STRUCT_HANDLE(struct_type, handle)
 165 
 166 #define STRUCT_SET_HANDLE(handle, umodel, addr)                         \
 167         (handle).model = (model_t)(umodel) & DATAMODEL_MASK;                \
 168         ASSERT(((umodel) & DATAMODEL_MASK) == DATAMODEL_ILP32);             \
 169         (handle).ptr = (addr)
 170 
 171 #define STRUCT_INIT(handle, umodel)                                     \
 172         STRUCT_SET_HANDLE(handle, umodel, &__##handle##_buf)
 173 
 174 #define STRUCT_SIZE(handle)             (sizeof (*(handle).ptr))
 175 
 176 #define STRUCT_FADDR(handle, field)     (&(handle).ptr->field)
 177 
 178 #define STRUCT_FGET(handle, field)      ((handle).ptr->field)
 179 
 180 #define STRUCT_FGETP                    STRUCT_FGET
 181 
 182 #define STRUCT_FSET(handle, field, val) ((handle).ptr->field = (val))
 183 
 184 #define STRUCT_FSETP                    STRUCT_FSET
 185 
 186 #define STRUCT_BUF(handle)              ((handle).ptr)
 187 
 188 #define SIZEOF_PTR(umodel)              sizeof (caddr_t)
 189 
 190 #define SIZEOF_STRUCT(struct_type, umodel)      sizeof (struct struct_type)
 191 
 192 #endif  /* _LP64 */
 193 
 194 #if defined(_LP64) || defined(__lint)
 195 
 196 struct _klwp;
 197 
 198 extern  model_t lwp_getdatamodel(struct _klwp *);
 199 extern  model_t get_udatamodel(void);
 200 
 201 #else
 202 
 203 /*
 204  * If we're the 32-bit kernel, the result of these function
 205  * calls is completely predictable, so let's just cheat.  A
 206  * good compiler should be able to elide all the unreachable code
 207  * that results.  Optimism about optimization reigns supreme ;-)
 208  */
 209 #define lwp_getdatamodel(t)             DATAMODEL_ILP32
 210 #define get_udatamodel()                DATAMODEL_ILP32
 211 
 212 #endif  /* _LP64 || __lint */
 213 
 214 #endif  /* _KERNEL && !_ASM */
 215 
 216 #ifdef  __cplusplus
 217 }
 218 #endif
 219 
 220 #endif  /* _SYS_MODEL_H */