/[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.2 - (hide annotations)
Fri Dec 19 01:31:34 2008 UTC (5 years, 4 months ago) by rtoy
Branch: unicode-utf16-extfmt-branch
CVS Tags: unicode-utf16-extfmt-2009-03-27, unicode-snapshot-2009-05, unicode-utf16-extfmts-sync-2008-12
Changes since 1.23.4.1: +60 -22 lines
File MIME type: text/plain
Merge changes from utf16 branch to update to snapshot 2008-12.
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.2 2008/12/19 01:31:34 rtoy 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 rtoy 1.11
41 gerd 1.10
42     void
43 rtoy 1.11 os_init(void)
44 ram 1.1 {
45 rtoy 1.11 os_vm_page_size = getpagesize();
46 ram 1.1 }
47    
48 cshapiro 1.22 unsigned long *
49     os_sigcontext_reg(ucontext_t *scp, int index)
50 ram 1.1 {
51 rtoy 1.23.4.2 __register_t *rv;
52 cshapiro 1.22 switch (index) {
53     case 0:
54 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_eax;
55     break;
56 cshapiro 1.22 case 2:
57 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_ecx;
58     break;
59 cshapiro 1.22 case 4:
60 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_edx;
61     break;
62 cshapiro 1.22 case 6:
63 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_ebx;
64     break;
65 cshapiro 1.22 case 8:
66 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_esp;
67     break;
68 cshapiro 1.22 case 10:
69 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_ebp;
70     break;
71 cshapiro 1.22 case 12:
72 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_esi;
73     break;
74 cshapiro 1.22 case 14:
75 rtoy 1.23.4.2 rv = &scp->uc_mcontext.mc_edi;
76     break;
77     default:
78     rv = NULL;
79 ram 1.1 }
80 rtoy 1.23.4.2
81     /* Pre-cast to (void *), to avoid the compiler warning:
82     * FreeBSD-os.c:72: warning: dereferencing type-punned pointer will break strict-aliasing rules
83     */
84     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     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     }
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    
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 cshapiro 1.22 } else { /* _MC_FPFMT_NODEV */
133     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     if (arch_support_sse2()) {
141     u_int32_t mxcsr = env_xmm->en_mxcsr;
142     DPRINTF(0, (stderr, "SSE2 modes = %08x\n", (int) mxcsr));
143     modes |= mxcsr;
144     }
145     #endif
146     modes ^= (0x3f << 7);
147 cshapiro 1.22 return modes;
148 ram 1.1 }
149 dtc 1.5
150 rtoy 1.11 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
151 ram 1.1 {
152 cshapiro 1.15 int flags = MAP_PRIVATE | MAP_ANON;
153 dtc 1.5
154 rtoy 1.11 if (addr)
155     flags |= MAP_FIXED;
156 ram 1.1
157 rtoy 1.11 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
158 dtc 1.5
159 rtoy 1.11 if (addr == (os_vm_address_t) - 1) {
160     perror("mmap");
161     return NULL;
162 ram 1.1 }
163 dtc 1.5
164 rtoy 1.11 return addr;
165 ram 1.1 }
166    
167 gerd 1.10 void
168 rtoy 1.11 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
169 ram 1.1 {
170 rtoy 1.11 if (munmap(addr, len) == -1)
171     perror("munmap");
172 ram 1.1 }
173    
174 gerd 1.10 os_vm_address_t
175 rtoy 1.11 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
176 ram 1.1 {
177 rtoy 1.11 addr = mmap(addr, len, OS_VM_PROT_ALL,
178     MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
179 dtc 1.5
180 rtoy 1.11 if (addr == (os_vm_address_t) - 1)
181     perror("mmap");
182 dtc 1.5
183 rtoy 1.11 return addr;
184 ram 1.1 }
185    
186 gerd 1.10 void
187 rtoy 1.11 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
188 ram 1.1 {
189     }
190    
191 gerd 1.10 void
192 rtoy 1.11 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
193 ram 1.1 {
194 rtoy 1.11 if (mprotect(address, length, prot) == -1)
195     perror("mprotect");
196 ram 1.1 }
197 rtoy 1.11
198 dtc 1.5
199    
200 gerd 1.10 static boolean
201 rtoy 1.11 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
202 ram 1.1 {
203 rtoy 1.11 char *beg = (char *) sbeg;
204     char *end = (char *) sbeg + slen;
205     char *adr = (char *) a;
206    
207     return adr >= beg && adr < end;
208 ram 1.1 }
209 dtc 1.5
210 rtoy 1.11 boolean valid_addr(os_vm_address_t addr)
211 ram 1.1 {
212 rtoy 1.11 os_vm_address_t newaddr;
213 ram 1.1
214 rtoy 1.11 newaddr = os_trunc_to_page(addr);
215    
216     if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
217     || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
218     || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
219 gerd 1.10 #ifndef GENCGC
220 rtoy 1.11 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
221 gerd 1.10 #endif
222 rtoy 1.11 || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
223     || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
224     return TRUE;
225     return FALSE;
226 ram 1.1 }
227 rtoy 1.11
228 ram 1.1
229 gerd 1.10 static void
230 cshapiro 1.16 sigbus_handler(int signal, siginfo_t *info, ucontext_t *context)
231 gerd 1.10 {
232     #ifdef RED_ZONE_HIT
233 cshapiro 1.16 if (os_control_stack_overflow(info->si_addr, context))
234 rtoy 1.11 return;
235 gerd 1.10 #endif
236 rtoy 1.11
237 dtc 1.2 #if defined GENCGC
238 cshapiro 1.21 if (info->si_code == PROTECTION_VIOLATION_CODE) {
239 rtoy 1.23.4.1 if (gc_write_barrier(info->si_addr)) {
240 cshapiro 1.16 return;
241     }
242 dtc 1.2 }
243 gerd 1.10 #endif /* GENCGC */
244 dtc 1.2
245 cshapiro 1.16 interrupt_handle_now(signal, info, context);
246 ram 1.1 }
247 dtc 1.5
248 cshapiro 1.22 /*
249     * Restore the exception flags cleared by the kernel. These bits must
250     * be set for Lisp to determine which exception caused the signal. At
251     * present, there is no way to distinguish underflow exceptions from
252     * denormalized operand exceptions. An underflow exception is assumed
253     * if the subcode is FPE_FLTUND.
254     */
255     static void
256     sigfpe_handler(int signal, siginfo_t *info, ucontext_t *context)
257     {
258     union savefpu *sv = (union savefpu *) context->uc_mcontext.mc_fpstate;
259     int fpformat = context->uc_mcontext.mc_fpformat;
260     int code = info->si_code;
261     unsigned char trap = 0;
262    
263     switch (code) {
264     case FPE_FLTDIV: /* ZE */
265     trap = 0x04;
266     break;
267     case FPE_FLTOVF: /* OE */
268     trap = 0x08;
269     break;
270     case FPE_FLTUND: /* DE or UE */
271     trap = 0x10;
272     break;
273     case FPE_FLTRES: /* PE */
274     trap = 0x20;
275     break;
276     case FPE_FLTINV: /* IE */
277     trap = 0x01;
278     break;
279     }
280     switch (fpformat) {
281     case _MC_FPFMT_XMM:
282     sv->sv_xmm.sv_env.en_sw |= trap;
283     break;
284     case _MC_FPFMT_387:
285     sv->sv_87.sv_env.en_sw |= trap;
286     break;
287     }
288     interrupt_handle_now(signal, info, context);
289     }
290    
291 gerd 1.10 void
292 rtoy 1.11 os_install_interrupt_handlers(void)
293 ram 1.1 {
294 rtoy 1.11 interrupt_install_low_level_handler
295 cshapiro 1.21 (PROTECTION_VIOLATION_SIGNAL, sigbus_handler);
296 cshapiro 1.22 interrupt_install_low_level_handler(SIGFPE, sigfpe_handler);
297 moore 1.8 }
298    
299 gerd 1.10 void *
300 rtoy 1.11 os_dlsym(const char *sym_name, lispobj lib_list)
301 moore 1.8 {
302 rtoy 1.11 if (lib_list != NIL) {
303     lispobj lib_list_head;
304    
305     for (lib_list_head = lib_list;
306     lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) {
307     struct cons *lib_cons = CONS(CONS(lib_list_head)->car);
308     struct sap *dlhandle = (struct sap *) PTR(lib_cons->car);
309     void *sym_addr = dlsym((void *) dlhandle->pointer, sym_name);
310 moore 1.8
311 rtoy 1.11 if (sym_addr)
312     return sym_addr;
313 moore 1.8 }
314     }
315 rtoy 1.11
316     return dlsym(RTLD_DEFAULT, sym_name);
317 ram 1.1 }
318 cshapiro 1.22
319     void
320     restore_fpu(ucontext_t *scp)
321     {
322     union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
323     int fpformat = scp->uc_mcontext.mc_fpformat;
324 rtoy 1.23.4.2 struct env87 *env_87 = &sv->sv_87.sv_env;
325     struct envxmm *env_xmm = &sv->sv_xmm.sv_env;
326     u_int16_t cw;
327 cshapiro 1.22
328     if (fpformat == _MC_FPFMT_XMM) {
329 rtoy 1.23.4.2 cw = env_xmm->en_cw;
330 cshapiro 1.22 } else if (fpformat == _MC_FPFMT_387) {
331 rtoy 1.23.4.2 cw = env_87->en_cw & 0xffff;
332 cshapiro 1.22 } else { /* _MC_FPFMT_NODEV */
333     return;
334     }
335 rtoy 1.23.4.2 DPRINTF(0, (stderr, "restore_fpu: cw = %08x\n", (int) cw));
336 cshapiro 1.22 __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw));
337 rtoy 1.23.4.2 #ifdef FEATURE_SSE2
338     if (arch_support_sse2()) {
339     u_int32_t mxcsr = env_xmm->en_mxcsr;
340     DPRINTF(0, (stderr, "restore_fpu: mxcsr (raw) = %04x\n", mxcsr));
341     __asm__ __volatile__ ("ldmxcsr %0" :: "m" (*&mxcsr));
342     }
343     #endif
344 cshapiro 1.22 }

  ViewVC Help
Powered by ViewVC 1.1.5