/[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.36 - (hide annotations)
Wed Sep 8 03:28:08 2010 UTC (3 years, 7 months ago) by agoncharov
Branch: MAIN
CVS Tags: cross-sol-x86-merged, cross-sol-x86-base, snapshot-2010-12, snapshot-2010-11, cross-sol-x86-2010-12-20, cross-sparc-branch-base
Branch point for: cross-sparc-branch, cross-sol-x86-branch
Changes since 1.35: +1 -2 lines
File MIME type: text/plain
EXECUTABLE seems to work on FreeBSD now. TODO: mv tools/linker-x86.sh tools/linker.sh
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 agoncharov 1.36 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/FreeBSD-os.c,v 1.36 2010/09/08 03:28:08 agoncharov Rel $
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.33 os_init(const char *argv[], const char *envp[])
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 agoncharov 1.25 __register_t *rv;
51 agoncharov 1.29
52 cshapiro 1.22 switch (index) {
53 agoncharov 1.29 case 0:
54 rtoy 1.30 rv = &scp->uc_mcontext.mc_eax;
55     break;
56 agoncharov 1.29 case 2:
57 rtoy 1.30 rv = &scp->uc_mcontext.mc_ecx;
58     break;
59 agoncharov 1.29 case 4:
60 rtoy 1.30 rv = &scp->uc_mcontext.mc_edx;
61     break;
62 agoncharov 1.29 case 6:
63 rtoy 1.30 rv = &scp->uc_mcontext.mc_ebx;
64     break;
65 agoncharov 1.29 case 8:
66 rtoy 1.30 rv = &scp->uc_mcontext.mc_esp;
67     break;
68 agoncharov 1.29 case 10:
69 rtoy 1.30 rv = &scp->uc_mcontext.mc_ebp;
70     break;
71 agoncharov 1.29 case 12:
72 rtoy 1.30 rv = &scp->uc_mcontext.mc_esi;
73     break;
74 agoncharov 1.29 case 14:
75 rtoy 1.30 rv = &scp->uc_mcontext.mc_edi;
76     break;
77 agoncharov 1.29 default:
78 rtoy 1.30 rv = NULL;
79 ram 1.1 }
80 rtoy 1.30
81 agoncharov 1.25 /* Pre-cast to (void *), to avoid the compiler warning:
82 agoncharov 1.29 * dereferencing type-punned pointer will break strict-aliasing rules
83 agoncharov 1.25 */
84 agoncharov 1.29 return (unsigned long *) (void *) rv;
85 cshapiro 1.22 }
86    
87     unsigned long *
88     os_sigcontext_pc(ucontext_t *scp)
89     {
90 agoncharov 1.25 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.29 case _MC_FPFMT_XMM:
102 rtoy 1.34 if (index < 8) {
103     reg = sv->sv_xmm.sv_fp[index].fp_acc.fp_bytes;
104     } else {
105     reg = sv->sv_xmm.sv_xmm[index - 8].xmm_bytes;
106     }
107 agoncharov 1.29 break;
108     case _MC_FPFMT_387:
109     reg = sv->sv_87.sv_ac[index].fp_bytes;
110     break;
111     case _MC_FPFMT_NODEV:
112     reg = NULL;
113     break;
114 cshapiro 1.22 }
115     return reg;
116     }
117    
118 rtoy 1.27 unsigned int
119 cshapiro 1.22 os_sigcontext_fpu_modes(ucontext_t *scp)
120     {
121 rtoy 1.27 unsigned int modes;
122 agoncharov 1.29
123 cshapiro 1.22 union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
124     int fpformat = scp->uc_mcontext.mc_fpformat;
125 agoncharov 1.26 struct env87 *env_87 = &sv->sv_87.sv_env;
126     struct envxmm *env_xmm = &sv->sv_xmm.sv_env;
127     u_int16_t cw;
128     u_int16_t sw;
129 cshapiro 1.22
130     if (fpformat == _MC_FPFMT_XMM) {
131 agoncharov 1.26 cw = env_xmm->en_cw;
132     sw = env_xmm->en_sw;
133 cshapiro 1.22 } else if (fpformat == _MC_FPFMT_387) {
134 agoncharov 1.26 cw = env_87->en_cw & 0xffff;
135     sw = env_87->en_sw & 0xffff;
136 agoncharov 1.29 } else { /* _MC_FPFMT_NODEV */
137 cshapiro 1.22 cw = 0;
138     sw = 0x3f;
139     }
140 agoncharov 1.26
141     modes = ((cw & 0x3f) << 7) | (sw & 0x3f);
142    
143     #ifdef FEATURE_SSE2
144 agoncharov 1.28 if (fpu_mode == SSE2) {
145 agoncharov 1.29 u_int32_t mxcsr = env_xmm->en_mxcsr;
146    
147     DPRINTF(0, (stderr, "SSE2 modes = %08x\n", (int)mxcsr));
148 agoncharov 1.26 modes |= mxcsr;
149     }
150     #endif
151     modes ^= (0x3f << 7);
152 cshapiro 1.22 return modes;
153 ram 1.1 }
154 dtc 1.5
155 agoncharov 1.29 os_vm_address_t
156     os_validate(os_vm_address_t addr, os_vm_size_t len)
157 ram 1.1 {
158 cshapiro 1.15 int flags = MAP_PRIVATE | MAP_ANON;
159 dtc 1.5
160 rtoy 1.11 if (addr)
161     flags |= MAP_FIXED;
162 ram 1.1
163 rtoy 1.11 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
164 dtc 1.5
165 rtoy 1.11 if (addr == (os_vm_address_t) - 1) {
166     perror("mmap");
167     return NULL;
168 ram 1.1 }
169 dtc 1.5
170 rtoy 1.11 return addr;
171 ram 1.1 }
172    
173 gerd 1.10 void
174 rtoy 1.11 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
175 ram 1.1 {
176 rtoy 1.11 if (munmap(addr, len) == -1)
177     perror("munmap");
178 ram 1.1 }
179    
180 gerd 1.10 os_vm_address_t
181 rtoy 1.11 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
182 ram 1.1 {
183 rtoy 1.11 addr = mmap(addr, len, OS_VM_PROT_ALL,
184     MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
185 dtc 1.5
186 rtoy 1.11 if (addr == (os_vm_address_t) - 1)
187     perror("mmap");
188 dtc 1.5
189 rtoy 1.11 return addr;
190 ram 1.1 }
191    
192 gerd 1.10 void
193 rtoy 1.11 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
194 ram 1.1 {
195     }
196    
197 gerd 1.10 void
198 rtoy 1.11 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
199 ram 1.1 {
200 rtoy 1.11 if (mprotect(address, length, prot) == -1)
201     perror("mprotect");
202 ram 1.1 }
203 rtoy 1.11
204 dtc 1.5
205    
206 gerd 1.10 static boolean
207 rtoy 1.11 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
208 ram 1.1 {
209 rtoy 1.11 char *beg = (char *) sbeg;
210     char *end = (char *) sbeg + slen;
211     char *adr = (char *) a;
212    
213     return adr >= beg && adr < end;
214 ram 1.1 }
215 dtc 1.5
216 agoncharov 1.29 boolean
217     valid_addr(os_vm_address_t addr)
218 ram 1.1 {
219 rtoy 1.11 os_vm_address_t newaddr;
220 ram 1.1
221 rtoy 1.11 newaddr = os_trunc_to_page(addr);
222    
223     if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
224     || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
225     || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
226 gerd 1.10 #ifndef GENCGC
227 rtoy 1.11 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
228 gerd 1.10 #endif
229 rtoy 1.11 || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
230     || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
231     return TRUE;
232     return FALSE;
233 ram 1.1 }
234 rtoy 1.11
235 ram 1.1
236 gerd 1.10 static void
237 agoncharov 1.29 protection_violation_handler(HANDLER_ARGS)
238 gerd 1.10 {
239     #ifdef RED_ZONE_HIT
240 agoncharov 1.29 if (os_control_stack_overflow(code->si_addr, context))
241 rtoy 1.11 return;
242 gerd 1.10 #endif
243 rtoy 1.11
244 dtc 1.2 #if defined GENCGC
245 agoncharov 1.29 if (code->si_code == PROTECTION_VIOLATION_CODE) {
246     if (gc_write_barrier(code->si_addr)) {
247 cshapiro 1.16 return;
248     }
249 dtc 1.2 }
250 agoncharov 1.29 #endif
251 dtc 1.2
252 agoncharov 1.29 interrupt_handle_now(signal, code, context);
253 ram 1.1 }
254 dtc 1.5
255 cshapiro 1.22 /*
256     * Restore the exception flags cleared by the kernel. These bits must
257     * be set for Lisp to determine which exception caused the signal. At
258     * present, there is no way to distinguish underflow exceptions from
259     * denormalized operand exceptions. An underflow exception is assumed
260     * if the subcode is FPE_FLTUND.
261     */
262     static void
263 agoncharov 1.29 sigfpe_handler(HANDLER_ARGS)
264 cshapiro 1.22 {
265 agoncharov 1.29 ucontext_t *ucontext = (ucontext_t *) context;
266     union savefpu *sv = (union savefpu *) ucontext->uc_mcontext.mc_fpstate;
267     int fpformat = ucontext->uc_mcontext.mc_fpformat;
268     unsigned char trap = 0;
269 cshapiro 1.22
270 agoncharov 1.29 switch (code->si_code) {
271     case FPE_FLTDIV: /* ZE */
272 cshapiro 1.22 trap = 0x04;
273     break;
274 agoncharov 1.29 case FPE_FLTOVF: /* OE */
275 cshapiro 1.22 trap = 0x08;
276     break;
277 agoncharov 1.29 case FPE_FLTUND: /* DE or UE */
278 cshapiro 1.22 trap = 0x10;
279     break;
280 agoncharov 1.29 case FPE_FLTRES: /* PE */
281 cshapiro 1.22 trap = 0x20;
282     break;
283 agoncharov 1.29 case FPE_FLTINV: /* IE */
284 cshapiro 1.22 trap = 0x01;
285     break;
286 agoncharov 1.29 }
287    
288     switch (fpformat) {
289     case _MC_FPFMT_XMM:
290 cshapiro 1.22 sv->sv_xmm.sv_env.en_sw |= trap;
291     break;
292 agoncharov 1.29 case _MC_FPFMT_387:
293 cshapiro 1.22 sv->sv_87.sv_env.en_sw |= trap;
294     break;
295 agoncharov 1.29 }
296     interrupt_handle_now(signal, code, context);
297 cshapiro 1.22 }
298    
299 gerd 1.10 void
300 rtoy 1.11 os_install_interrupt_handlers(void)
301 ram 1.1 {
302 agoncharov 1.29 interrupt_install_low_level_handler(PROTECTION_VIOLATION_SIGNAL,
303     protection_violation_handler);
304 cshapiro 1.22 interrupt_install_low_level_handler(SIGFPE, sigfpe_handler);
305 moore 1.8 }
306    
307 gerd 1.10 void *
308 rtoy 1.11 os_dlsym(const char *sym_name, lispobj lib_list)
309 moore 1.8 {
310 agoncharov 1.35 static void *program_handle;
311    
312     if (!program_handle)
313     program_handle = dlopen((void *) 0, RTLD_LAZY | RTLD_GLOBAL);
314    
315 rtoy 1.11 if (lib_list != NIL) {
316     lispobj lib_list_head;
317    
318     for (lib_list_head = lib_list;
319     lib_list_head != NIL; lib_list_head = CONS(lib_list_head)->cdr) {
320     struct cons *lib_cons = CONS(CONS(lib_list_head)->car);
321 agoncharov 1.29 struct sap *dlhandle = (struct sap *)PTR(lib_cons->car);
322     void *sym_addr = dlsym((void *)dlhandle->pointer, sym_name);
323 moore 1.8
324 rtoy 1.11 if (sym_addr)
325     return sym_addr;
326 moore 1.8 }
327     }
328 agoncharov 1.35 return dlsym(program_handle, sym_name);
329 ram 1.1 }
330 cshapiro 1.22
331     void
332     restore_fpu(ucontext_t *scp)
333     {
334     union savefpu *sv = (union savefpu *) scp->uc_mcontext.mc_fpstate;
335     int fpformat = scp->uc_mcontext.mc_fpformat;
336 agoncharov 1.26 struct env87 *env_87 = &sv->sv_87.sv_env;
337     struct envxmm *env_xmm = &sv->sv_xmm.sv_env;
338     u_int16_t cw;
339 cshapiro 1.22
340     if (fpformat == _MC_FPFMT_XMM) {
341 agoncharov 1.26 cw = env_xmm->en_cw;
342 cshapiro 1.22 } else if (fpformat == _MC_FPFMT_387) {
343 agoncharov 1.26 cw = env_87->en_cw & 0xffff;
344 agoncharov 1.29 } else { /* _MC_FPFMT_NODEV */
345 cshapiro 1.22 return;
346     }
347 agoncharov 1.29 DPRINTF(0, (stderr, "restore_fpu: cw = %08x\n", (int)cw));
348     __asm__ __volatile__ ("fldcw %0"::"m"(*&cw));
349    
350 agoncharov 1.26 #ifdef FEATURE_SSE2
351 rtoy 1.31 if (fpu_mode == SSE2) {
352 agoncharov 1.29 u_int32_t mxcsr = env_xmm->en_mxcsr;
353    
354     DPRINTF(0, (stderr, "restore_fpu: mxcsr (raw) = %04x\n", mxcsr));
355     __asm__ __volatile__ ("ldmxcsr %0"::"m"(*&mxcsr));
356 agoncharov 1.26 }
357     #endif
358 cshapiro 1.22 }

  ViewVC Help
Powered by ViewVC 1.1.5