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