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 */ 226