2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #endif /* !defined(RLD) */
28 #include <mach/mach.h>
29 #include "stuff/openstep_mach.h"
30 #include "stuff/arch.h"
31 #include "stuff/allocate.h"
34 * The array of all currently know architecture flags (terminated with an entry
35 * with all zeros). Pointer to this returned with get_arch_flags().
38 static struct arch_flag arch_flags
[] = {
40 static const struct arch_flag arch_flags
[] = {
42 { "any", CPU_TYPE_ANY
, CPU_SUBTYPE_MULTIPLE
},
43 { "little", CPU_TYPE_ANY
, CPU_SUBTYPE_LITTLE_ENDIAN
},
44 { "big", CPU_TYPE_ANY
, CPU_SUBTYPE_BIG_ENDIAN
},
46 /* 64-bit Mach-O architectures */
48 /* architecture families */
49 { "ppc64", CPU_TYPE_POWERPC64
, CPU_SUBTYPE_POWERPC_ALL
},
50 { "x86_64", CPU_TYPE_X86_64
, CPU_SUBTYPE_X86_64_ALL
},
51 /* specific architecture implementations */
52 { "ppc970-64", CPU_TYPE_POWERPC64
, CPU_SUBTYPE_POWERPC_970
},
54 /* 32-bit Mach-O architectures */
56 /* architecture families */
57 { "ppc", CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_ALL
},
58 { "i386", CPU_TYPE_I386
, CPU_SUBTYPE_I386_ALL
},
59 { "m68k", CPU_TYPE_MC680x0
, CPU_SUBTYPE_MC680x0_ALL
},
60 { "hppa", CPU_TYPE_HPPA
, CPU_SUBTYPE_HPPA_ALL
},
61 { "sparc", CPU_TYPE_SPARC
, CPU_SUBTYPE_SPARC_ALL
},
62 { "m88k", CPU_TYPE_MC88000
, CPU_SUBTYPE_MC88000_ALL
},
63 { "i860", CPU_TYPE_I860
, CPU_SUBTYPE_I860_ALL
},
64 { "veo", CPU_TYPE_VEO
, CPU_SUBTYPE_VEO_ALL
},
65 { "arm", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_ALL
},
66 /* specific architecture implementations */
67 { "ppc601", CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_601
},
68 { "ppc603", CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_603
},
69 { "ppc603e",CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_603e
},
70 { "ppc603ev",CPU_TYPE_POWERPC
,CPU_SUBTYPE_POWERPC_603ev
},
71 { "ppc604", CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_604
},
72 { "ppc604e",CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_604e
},
73 { "ppc750", CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_750
},
74 { "ppc7400",CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_7400
},
75 { "ppc7450",CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_7450
},
76 { "ppc970", CPU_TYPE_POWERPC
, CPU_SUBTYPE_POWERPC_970
},
77 { "i486", CPU_TYPE_I386
, CPU_SUBTYPE_486
},
78 { "i486SX", CPU_TYPE_I386
, CPU_SUBTYPE_486SX
},
79 { "pentium",CPU_TYPE_I386
, CPU_SUBTYPE_PENT
}, /* same as i586 */
80 { "i586", CPU_TYPE_I386
, CPU_SUBTYPE_586
},
81 { "pentpro", CPU_TYPE_I386
, CPU_SUBTYPE_PENTPRO
}, /* same as i686 */
82 { "i686", CPU_TYPE_I386
, CPU_SUBTYPE_PENTPRO
},
83 { "pentIIm3",CPU_TYPE_I386
, CPU_SUBTYPE_PENTII_M3
},
84 { "pentIIm5",CPU_TYPE_I386
, CPU_SUBTYPE_PENTII_M5
},
85 { "pentium4",CPU_TYPE_I386
, CPU_SUBTYPE_PENTIUM_4
},
86 { "m68030", CPU_TYPE_MC680x0
, CPU_SUBTYPE_MC68030_ONLY
},
87 { "m68040", CPU_TYPE_MC680x0
, CPU_SUBTYPE_MC68040
},
88 { "hppa7100LC", CPU_TYPE_HPPA
, CPU_SUBTYPE_HPPA_7100LC
},
89 { "veo1", CPU_TYPE_VEO
, CPU_SUBTYPE_VEO_1
},
90 { "veo2", CPU_TYPE_VEO
, CPU_SUBTYPE_VEO_2
},
91 { "veo3", CPU_TYPE_VEO
, CPU_SUBTYPE_VEO_3
},
92 { "veo4", CPU_TYPE_VEO
, CPU_SUBTYPE_VEO_4
},
93 { "armv4t", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_V4T
},
94 { "armv5", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_V5TEJ
},
95 { "xscale", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_XSCALE
},
96 { "armv6", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_V6
},
97 { "armv7", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_V7
},
98 { "armv7f", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_V7F
},
99 { "armv7s", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_V7S
},
100 { "armv7k", CPU_TYPE_ARM
, CPU_SUBTYPE_ARM_V7K
},
106 * get_arch_from_flag() is passed a name of an architecture flag and returns
107 * zero if that flag is not known and non-zero if the flag is known.
108 * If the pointer to the arch_flag is not NULL it is filled in with the
109 * arch_flag struct that matches the name.
115 struct arch_flag
*arch_flag
)
119 for(i
= 0; arch_flags
[i
].name
!= NULL
; i
++){
120 if(strcmp(arch_flags
[i
].name
, name
) == 0){
121 if(arch_flag
!= NULL
)
122 *arch_flag
= arch_flags
[i
];
126 if(arch_flag
!= NULL
)
127 memset(arch_flag
, '\0', sizeof(struct arch_flag
));
132 * get_arch_flags() returns a pointer to an array of all currently know
133 * architecture flags (terminated with an entry with all zeros).
136 const struct arch_flag
*
142 #endif /* !defined(RLD) */
145 * get_arch_name_from_types() returns the name of the architecture for the
146 * specified cputype and cpusubtype if known. If unknown it returns a pointer
147 * to the an allocated string "cputype X cpusubtype Y" where X and Y are decimal
152 get_arch_name_from_types(
154 cpu_subtype_t cpusubtype
)
159 for(i
= 0; arch_flags
[i
].name
!= NULL
; i
++){
160 if(arch_flags
[i
].cputype
== cputype
&&
161 (arch_flags
[i
].cpusubtype
& ~CPU_SUBTYPE_MASK
) ==
162 (cpusubtype
& ~CPU_SUBTYPE_MASK
))
163 return(arch_flags
[i
].name
);
166 p
= savestr("cputype 1234567890 cpusubtype 1234567890");
168 sprintf(p
, "cputype %u cpusubtype %u", cputype
,
169 cpusubtype
& ~CPU_SUBTYPE_MASK
);
171 /* there is no sprintf() in the rld kernel API's */
172 p
= savestr("cputype ?? cpusubtype ??");
178 * get_arch_family_from_cputype() returns the family architecture for the
179 * specified cputype if known. If unknown it returns NULL.
182 const struct arch_flag
*
183 get_arch_family_from_cputype(
188 for(i
= 0; arch_flags
[i
].name
!= NULL
; i
++){
189 if(arch_flags
[i
].cputype
== cputype
)
190 return(arch_flags
+ i
);
196 * get_byte_sex_from_flag() returns the byte sex of the architecture for the
197 * specified cputype and cpusubtype if known. If unknown it returns
198 * UNKNOWN_BYTE_SEX. If the bytesex can be determined directly as in the case
199 * of reading a magic number from a file that should be done and this routine
200 * should not be used as it could be out of date.
204 get_byte_sex_from_flag(
205 const struct arch_flag
*flag
)
207 if(flag
->cputype
== CPU_TYPE_MC680x0
||
208 flag
->cputype
== CPU_TYPE_MC88000
||
209 flag
->cputype
== CPU_TYPE_POWERPC
||
210 flag
->cputype
== CPU_TYPE_POWERPC64
||
211 flag
->cputype
== CPU_TYPE_HPPA
||
212 flag
->cputype
== CPU_TYPE_SPARC
||
213 flag
->cputype
== CPU_TYPE_I860
||
214 flag
->cputype
== CPU_TYPE_VEO
)
215 return BIG_ENDIAN_BYTE_SEX
;
216 else if(flag
->cputype
== CPU_TYPE_I386
||
217 flag
->cputype
== CPU_TYPE_X86_64
||
218 flag
->cputype
== CPU_TYPE_ARM
)
219 return LITTLE_ENDIAN_BYTE_SEX
;
221 return UNKNOWN_BYTE_SEX
;
226 * get_stack_direction_from_flag() returns the direction the stack grows as
227 * either positive (+1) or negative (-1) of the architecture for the
228 * specified cputype and cpusubtype if known. If unknown it returns 0.
232 get_stack_direction_from_flag(
233 const struct arch_flag
*flag
)
235 if(flag
->cputype
== CPU_TYPE_MC680x0
||
236 flag
->cputype
== CPU_TYPE_MC88000
||
237 flag
->cputype
== CPU_TYPE_POWERPC
||
238 flag
->cputype
== CPU_TYPE_I386
||
239 flag
->cputype
== CPU_TYPE_SPARC
||
240 flag
->cputype
== CPU_TYPE_I860
||
241 flag
->cputype
== CPU_TYPE_VEO
||
242 flag
->cputype
== CPU_TYPE_ARM
)
244 else if(flag
->cputype
== CPU_TYPE_HPPA
)
251 * get_stack_addr_from_flag() returns the default starting address of the user
252 * stack. This should be in the header file <bsd/XXX/vmparam.h> as USRSTACK.
253 * Since some architectures have come and gone and come back and because you
254 * can't include all of these headers in one source the constants have been
259 get_stack_addr_from_flag(
260 const struct arch_flag
*flag
)
262 switch(flag
->cputype
){
263 case CPU_TYPE_MC680x0
:
265 case CPU_TYPE_MC88000
:
267 case CPU_TYPE_POWERPC
:
278 return(0xc0000000-0x04000000);
279 case CPU_TYPE_POWERPC64
:
280 return(0x7ffff00000000LL
);
281 case CPU_TYPE_X86_64
:
282 return(0x7fff5fc00000LL
);
289 * get_stack_size_from_flag() returns the default size of the userstack. This
290 * should be in the header file <bsd/XXX/vmparam.h> as MAXSSIZ. Since some
291 * architectures have come and gone and come back, you can't include all of
292 * these headers in one source and some of the constants covered the whole
293 * address space the common value of 64meg was chosen.
297 get_stack_size_from_flag(
298 const struct arch_flag
*flag
)
301 const struct arch_flag
*dummy
;
305 return(64*1024*1024);
307 #endif /* !defined(RLD) */
310 * get_segalign_from_flag() returns the default segment alignment (page size).
314 get_segalign_from_flag(
315 const struct arch_flag
*flag
)
317 if(flag
->cputype
== CPU_TYPE_POWERPC
||
318 flag
->cputype
== CPU_TYPE_POWERPC64
||
319 flag
->cputype
== CPU_TYPE_VEO
||
320 flag
->cputype
== CPU_TYPE_I386
||
321 flag
->cputype
== CPU_TYPE_X86_64
||
322 flag
->cputype
== CPU_TYPE_ARM
)
323 return(0x1000); /* 4K */
325 return(0x2000); /* 8K */
329 * get_segprot_from_flag() returns the default segment protection.
333 get_segprot_from_flag(
334 const struct arch_flag
*flag
)
336 if(flag
->cputype
== CPU_TYPE_I386
)
337 return(VM_PROT_READ
| VM_PROT_WRITE
);
339 return(VM_PROT_READ
| VM_PROT_WRITE
| VM_PROT_EXECUTE
);
343 * get_shared_region_size_from_flag() returns the default shared
348 get_shared_region_size_from_flag(
349 const struct arch_flag
*flag
)
351 if(flag
->cputype
== CPU_TYPE_ARM
)
358 * force_cpusubtype_ALL_for_cputype() takes a cputype and returns TRUE if for
359 * that cputype the cpusubtype should always be forced to the ALL cpusubtype,
360 * otherwise it returns FALSE.
364 force_cpusubtype_ALL_for_cputype(
367 if(cputype
== CPU_TYPE_I386
)