/[cmucl]/src/lisp/FreeBSD-os.c
ViewVC logotype

Contents of /src/lisp/FreeBSD-os.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.23.4.3 - (hide annotations)
Wed May 13 02:53:40 2009 UTC (4 years, 11 months ago) by agoncharov
Branch: unicode-utf16-extfmt-branch
CVS Tags: unicode-snapshot-2009-06, unicode-utf16-extfmt-2009-06-11
Changes since 1.23.4.2: +67 -61 lines
File MIME type: text/plain
Merge from unicode-utf16-branch
1 ram 1.1 /*
2     * FreeBSD-os.c. Maybe could be just BSD-os.c
3     * From osf1-os.c,v 1.1 94/03/27 15:30:51 hallgren Exp $
4     *
5     * OS-dependent routines. This file (along with os.h) exports an
6     * OS-independent interface to the operating system VM facilities.
7     * Suprisingly, this interface looks a lot like the Mach interface
8     * (but simpler in some places). For some operating systems, a subset
9     * of these functions will have to be emulated.
10     *
11     * This is the OSF1 version. By Sean Hallgren.
12     * Much hacked by Paul Werkowski
13 dtc 1.2 * GENCGC support by Douglas Crosher, 1996, 1997.
14     *
15 rtoy 1.23.4.1 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/FreeBSD-os.c,v 1.23.4.3 2009/05/13 02:53:40 agoncharov Exp $
16 ram 1.1 *
17     */
18    
19 fgilham 1.12 #include "os.h"
20 ram 1.1 #include <sys/file.h>
21 cshapiro 1.22 #include <machine/npx.h>
22 ram 1.1 #include <errno.h>
23     #include "arch.h"
24     #include "globals.h"
25     #include "interrupt.h"
26     #include "lispregs.h"
27     #include "internals.h"
28    
29 dtc 1.2 #include <signal.h>
30 moore 1.8 #include <dlfcn.h>
31 pw 1.3 #include "validate.h"
32 cshapiro 1.23 #include <stdio.h>
33     #include <unistd.h>
34 dtc 1.2
35     #if defined GENCGC
36     #include "gencgc.h"
37     #endif
38    
39 gerd 1.10 vm_size_t os_vm_page_size;
40    
41     void
42 rtoy 1.11 os_init(void)
43 ram 1.1 {
44 rtoy 1.11 os_vm_page_size = getpagesize();
45 ram 1.1 }
46    
47 cshapiro 1.22 unsigned long *
48     os_sigcontext_reg(ucontext_t *scp, int index)
49 ram 1.1 {
50 rtoy 1.23.4.2 __register_t *rv;
51 agoncharov 1.23.4.3
52 cshapiro 1.22 switch (index) {
53 agoncharov 1.23.4.3 case 0:
54 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_eax;
55     break;
56 agoncharov 1.23.4.3 case 2:
57 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_ecx;
58     break;
59 agoncharov 1.23.4.3 case 4:
60 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_edx;
61     break;
62 agoncharov 1.23.4.3 case 6:
63 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_ebx;
64     break;
65 agoncharov 1.23.4.3 case 8:
66 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_esp;
67     break;
68 agoncharov 1.23.4.3 case 10:
69 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_ebp;
70     break;
71 agoncharov 1.23.4.3 case 12:
72 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_esi;
73     break;
74 agoncharov 1.23.4.3 case 14:
75 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_edi;
76     break;
77 agoncharov 1.23.4.3 default:
78 rtoy 1.23.4.2 rv = NULL;
79 ram 1.1 }
80 rtoy 1.23.4.2
81     /* Pre-cast to (void *), to avoid the compiler warning:
82 agoncharov 1.23.4.3 * dereferencing type-punned pointer will break strict-aliasing rules
83 rtoy 1.23.4.2 */
84 agoncharov 1.23.4.3 return (unsigned long *) (void *) rv;
85 cshapiro 1.22 }
86    
87     unsigned long *
88     os_sigcontext_pc(ucontext_t *scp)
89     {
90 rtoy 1.23.4.2 return (unsigned long *) (void *) &scp->uc_mcontext.mc_eip;
91 cshapiro 1.22 }
92    
93     unsigned char *
94     os_sigcontext_fpu_reg(ucontext_t *scp, int index)
95     {
96     union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
97     int fpformat = scp->uc_mcontext.mc_fpformat;
98     unsigned char *reg = NULL;
99 rtoy 1.11
100 cshapiro 1.22 switch (fpformat) {
101 agoncharov 1.23.4.3 case _MC_FPFMT_XMM:
102     reg = sv->sv_xmm.sv_fp[index].fp_acc.fp_bytes;
103     break;
104     case _MC_FPFMT_387:
105     reg = sv->sv_87.sv_ac[index].fp_bytes;
106     break;
107     case _MC_FPFMT_NODEV:
108     reg = NULL;
109     break;
110 cshapiro 1.22 }
111     return reg;
112     }
113    
114 rtoy 1.23.4.2 unsigned int
115 cshapiro 1.22 os_sigcontext_fpu_modes(ucontext_t *scp)
116     {
117 rtoy 1.23.4.2 unsigned int modes;
118 agoncharov 1.23.4.3
119 cshapiro 1.22 union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
120     int fpformat = scp->uc_mcontext.mc_fpformat;
121 rtoy 1.23.4.2 struct env87 *env_87 = &sv->sv_87.sv_env;
122     struct envxmm *env_xmm = &sv->sv_xmm.sv_env;
123     u_int16_t cw;
124     u_int16_t sw;
125 cshapiro 1.22
126     if (fpformat == _MC_FPFMT_XMM) {
127 rtoy 1.23.4.2 cw = env_xmm->en_cw;
128     sw = env_xmm->en_sw;
129 cshapiro 1.22 } else if (fpformat == _MC_FPFMT_387) {
130 rtoy 1.23.4.2 cw = env_87->en_cw & 0xffff;
131     sw = env_87->en_sw & 0xffff;
132 agoncharov 1.23.4.3 } else { /* _MC_FPFMT_NODEV */
133 cshapiro 1.22 cw = 0;
134     sw = 0x3f;
135     }
136 rtoy 1.23.4.2
137     modes = ((cw & 0x3f) << 7) | (sw & 0x3f);
138    
139     #ifdef FEATURE_SSE2
140 agoncharov 1.23.4.3 if (fpu_mode == SSE2) {
141     u_int32_t mxcsr = env_xmm->en_mxcsr;
142    
143     DPRINTF(0, (stderr, "SSE2 modes = %08x\n", (int)mxcsr));
144 rtoy 1.23.4.2 modes |= mxcsr;
145     }
146     #endif
147     modes ^= (0x3f << 7);
148 cshapiro 1.22 return modes;
149 ram 1.1 }
150 dtc 1.5
151 agoncharov 1.23.4.3 os_vm_address_t
152     os_validate(os_vm_address_t addr, os_vm_size_t len)
153 ram 1.1 {
154 cshapiro 1.15 int flags = MAP_PRIVATE | MAP_ANON;
155 dtc 1.5
156 rtoy 1.11 if (addr)
157     flags |= MAP_FIXED;
158 ram 1.1
159 rtoy 1.11 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
160 dtc 1.5
161 rtoy 1.11 if (addr == (os_vm_address_t) - 1) {
162     perror("mmap");
163     return NULL;
164 ram 1.1 }
165 dtc 1.5
166 rtoy 1.11 return addr;
167 ram 1.1 }
168    
169 gerd 1.10 void
170 rtoy 1.11 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
171 ram 1.1 {
172 rtoy 1.11 if (munmap(addr, len) == -1)
173     perror("munmap");
174 ram 1.1 }
175    
176 gerd 1.10 os_vm_address_t
177 rtoy 1.11 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
178 ram 1.1 {
179 rtoy 1.11 addr = mmap(addr, len, OS_VM_PROT_ALL,
180     MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
181 dtc 1.5
182 rtoy 1.11 if (addr == (os_vm_address_t) - 1)
183     perror("mmap");
184 dtc 1.5
185 rtoy 1.11 return addr;
186 ram 1.1 }
187    
188 gerd 1.10 void
189 rtoy 1.11 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
190 ram 1.1 {
191     }
192    
193 gerd 1.10 void
194 rtoy 1.11 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
195 ram 1.1 {
196 rtoy 1.11 if (mprotect(address, length, prot) == -1)
197     perror("mprotect");
198 ram 1.1 }
199 rtoy 1.11
200 dtc 1.5
201    
202 gerd 1.10 static boolean
203 rtoy 1.11 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
204 ram 1.1 {
205 rtoy 1.11 char *beg = (char *) sbeg;
206     char *end = (char *) sbeg + slen;
207     char *adr = (char *) a;
208    
209     return adr >= beg && adr < end;
210 ram 1.1 }
211 dtc 1.5
212 agoncharov 1.23.4.3 boolean
213     valid_addr(os_vm_address_t addr)
214 ram 1.1 {
215 rtoy 1.11 os_vm_address_t newaddr;
216 ram 1.1
217 rtoy 1.11 newaddr = os_trunc_to_page(addr);
218    
219     if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
220     || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
221     || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
222 gerd 1.10 #ifndef GENCGC
223 rtoy 1.11 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
224 gerd 1.10 #endif
225 rtoy 1.11 || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
226     || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
227     return TRUE;
228     return FALSE;
229 ram 1.1 }
230 rtoy 1.11
231 ram 1.1
232 gerd 1.10 static void
233 agoncharov 1.23.4.3 protection_violation_handler(HANDLER_ARGS)
234 gerd 1.10 {
235     #ifdef RED_ZONE_HIT
236 agoncharov 1.23.4.3 if (os_control_stack_overflow(code->si_addr, context))
237 rtoy 1.11 return;
238 gerd 1.10 #endif
239 rtoy 1.11
240 dtc 1.2 #if defined GENCGC
241 agoncharov 1.23.4.3 if (code->si_code == PROTECTION_VIOLATION_CODE) {
242     if (gc_write_barrier(code->si_addr)) {
243 cshapiro 1.16 return;
244     }
245 dtc 1.2 }
246 agoncharov 1.23.4.3 #endif
247 dtc 1.2
248 agoncharov 1.23.4.3 interrupt_handle_now(signal, code, context);
249 ram 1.1 }
250 dtc 1.5
251 cshapiro 1.22 /*
252     * Restore the exception flags cleared by the kernel. These bits must
253     * be set for Lisp to determine which exception caused the signal. At
254     * present, there is no way to distinguish underflow exceptions from
255     * denormalized operand exceptions. An underflow exception is assumed
256     * if the subcode is FPE_FLTUND.
257     */
258     static void
259 agoncharov 1.23.4.3 sigfpe_handler(HANDLER_ARGS)
260 cshapiro 1.22 {
261 agoncharov 1.23.4.3 ucontext_t *ucontext = (ucontext_t *) context;
262     union savefpu *sv = (union savefpu *) ucontext->uc_mcontext.mc_fpstate;
263     int fpformat = ucontext->uc_mcontext.mc_fpformat;
264     unsigned char trap = 0;
265 cshapiro 1.22
266 agoncharov 1.23.4.3 switch (code->si_code) {
267     case FPE_FLTDIV: /* ZE */
268 cshapiro 1.22 trap = 0x04;
269     break;
270 agoncharov 1.23.4.3 case FPE_FLTOVF: /* OE */
271 cshapiro 1.22 trap = 0x08;
272     break;
273 agoncharov 1.23.4.3 case FPE_FLTUND: /* DE or UE */
274 cshapiro 1.22 trap = 0x10;
275     break;
276 agoncharov 1.23.4.3 case FPE_FLTRES: /* PE */
277 cshapiro 1.22 trap = 0x20;
278     break;
279 agoncharov 1.23.4.3 case FPE_FLTINV: /* IE */
280 cshapiro 1.22 trap = 0x01;
281     break;
282 agoncharov 1.23.4.3 }
283    
284     switch (fpformat) {
285     case _MC_FPFMT_XMM:
286 cshapiro 1.22 sv->sv_xmm.sv_env.en_sw |= trap;
287     break;
288 agoncharov 1.23.4.3 case _MC_FPFMT_387:
289 cshapiro 1.22 sv->sv_87.sv_env.en_sw |= trap;
290     break;
291 agoncharov 1.23.4.3 }
292     interrupt_handle_now(signal, code, context);
293 cshapiro 1.22 }
294    
295 gerd 1.10 void
296 rtoy 1.11 os_install_interrupt_handlers(void)
297 ram 1.1 {
298 agoncharov 1.23.4.3 interrupt_install_low_level_handler(PROTECTION_VIOLATION_SIGNAL,
299     protection_violation_handler);
300 cshapiro 1.22 interrupt_install_low_level_handler(SIGFPE, sigfpe_handler);
301 moore 1.8 }
302    
303 gerd 1.10 void *
304 rtoy 1.11 os_dlsym(const char *sym_name, lispobj lib_list)
305 moore 1.8 {
306 rtoy 1.11 if (lib_list != NIL) {
307     lispobj lib_list_head;
308    
309     for (lib_list_head = lib_list;
310     lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) {
311     struct cons *lib_cons = CONS(CONS(lib_list_head)->car);
312 agoncharov 1.23.4.3 struct sap *dlhandle = (struct sap *)PTR(lib_cons->car);
313     void *sym_addr = dlsym((void *)dlhandle->pointer, sym_name);
314 moore 1.8
315 rtoy 1.11 if (sym_addr)
316     return sym_addr;
317 moore 1.8 }
318     }
319 rtoy 1.11
320     return dlsym(RTLD_DEFAULT, sym_name);
321 ram 1.1 }
322 cshapiro 1.22
323     void
324     restore_fpu(ucontext_t *scp)
325     {
326     union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
327     int fpformat = scp->uc_mcontext.mc_fpformat;
328 rtoy 1.23.4.2 struct env87 *env_87 = &sv->sv_87.sv_env;
329     struct envxmm *env_xmm = &sv->sv_xmm.sv_env;
330     u_int16_t cw;
331 cshapiro 1.22
332     if (fpformat == _MC_FPFMT_XMM) {
333 rtoy 1.23.4.2 cw = env_xmm->en_cw;
334 cshapiro 1.22 } else if (fpformat == _MC_FPFMT_387) {
335 rtoy 1.23.4.2 cw = env_87->en_cw & 0xffff;
336 agoncharov 1.23.4.3 } else { /* _MC_FPFMT_NODEV */
337 cshapiro 1.22 return;
338     }
339 agoncharov 1.23.4.3 DPRINTF(0, (stderr, "restore_fpu: cw = %08x\n", (int)cw));
340     __asm__ __volatile__ ("fldcw %0"::"m"(*&cw));
341    
342 rtoy 1.23.4.2 #ifdef FEATURE_SSE2
343     if (arch_support_sse2()) {
344 agoncharov 1.23.4.3 u_int32_t mxcsr = env_xmm->en_mxcsr;
345    
346     DPRINTF(0, (stderr, "restore_fpu: mxcsr (raw) = %04x\n", mxcsr));
347     __asm__ __volatile__ ("ldmxcsr %0"::"m"(*&mxcsr));
348 rtoy 1.23.4.2 }
349     #endif
350 cshapiro 1.22 }

  ViewVC Help
Powered by ViewVC 1.1.5