/[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.2 - (show annotations)
Tue Nov 25 17:59:16 1997 UTC (16 years, 5 months ago) by dtc
Branch: MAIN
Changes since 1.1: +66 -87 lines
File MIME type: text/plain
Conservative generational garbage collection for the x86 port.
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 * GENCGC support by Douglas Crosher, 1996, 1997.
14 *
15 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/FreeBSD-os.c,v 1.2 1997/11/25 17:59:16 dtc Exp $
16 *
17 */
18
19 #include <stdio.h>
20 #include <sys/param.h>
21 #include <sys/file.h>
22 #include <errno.h>
23 #include "./signal.h"
24 #include "os.h"
25 #include "arch.h"
26 #include "globals.h"
27 #include "interrupt.h"
28 #include "lispregs.h"
29 #include "internals.h"
30
31 #include <sys/types.h>
32 #include <signal.h>
33 /* #include <sys/sysinfo.h> */
34 #include <sys/proc.h>
35 #include "x86-validate.h"
36 vm_size_t os_vm_page_size;
37 #define DPRINTF(t,a) {if(t)fprintf a;}
38
39 #define HAVE_SIGVEC /* defined - now obsolete */
40 #define HAVE_SIGACTION /* replacement for SIGVEC */
41 /* SIGSTKSZ == 40Kb */
42 #define SIG_STACK_SIZE (SIGSTKSZ/sizeof(double))
43 /* make sure the stack is 8 byte aligned */
44 #if defined USE_SIG_STACK
45 static double estack_buf[SIG_STACK_SIZE];
46 #endif
47
48 #if defined GENCGC
49 #include "gencgc.h"
50 #endif
51
52
53 void
54 os_init()
55 {
56
57 #if defined USE_SIG_STACK
58 static struct sigaltstack estack;
59 estack.ss_base = (char*)estack_buf; /* this should be ss_sp */
60 estack.ss_size = SIGSTKSZ;
61 estack.ss_flags = 0;
62 if (sigaltstack(&estack, 0) < 0)
63 perror("sigaltstack");
64 #endif
65 os_vm_page_size=OS_VM_DEFAULT_PAGESIZE;
66 }
67
68 int
69 sc_reg(struct sigcontext *c, int offset)
70 {
71 switch(offset)
72 {
73 case 0: return c->sc_eax;
74 case 2: return c->sc_ecx;
75 case 4: return c->sc_edx;
76 case 6: return c->sc_ebx;
77 case 8: return c->sc_esp;
78 case 10: return c->sc_ebp;
79 case 12: return c->sc_esi;
80 case 14: return c->sc_edi;
81 }
82 return 0;
83 }
84 void
85 os_save_context()
86 {
87 /* Called from interrupt handlers so C stuff knows things set in Lisp
88 */
89 }
90 void
91 os_set_context()
92 {
93 }
94
95 os_vm_address_t
96 os_validate(os_vm_address_t addr, os_vm_size_t len)
97 {
98 int flags = MAP_PRIVATE|MAP_ANONYMOUS;
99
100 if(addr) flags|=MAP_FIXED;
101 else flags|=MAP_VARIABLE;
102
103 DPRINTF(0,(stderr,"os_validate %x %d => ",addr,len));
104 if((addr=mmap(addr,len,OS_VM_PROT_ALL,flags,-1,0)) == (os_vm_address_t) -1)
105 {
106 perror("mmap");
107 return NULL;
108 }
109 DPRINTF(0,(stderr,"%x\n",addr));
110
111 return addr;
112 }
113
114 void
115 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
116 {
117 DPRINTF(0,(stderr,"os_invalidate %x %d\n",addr,len));
118 if(munmap(addr,len) == -1) {
119 fprintf(stderr,"munmap(0x%x,%d)==-1\n",addr,len);
120 perror("munmap");
121 }
122 }
123
124 os_vm_address_t
125 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
126 {
127 if((addr=mmap(addr,len,OS_VM_PROT_ALL,MAP_PRIVATE|MAP_FILE|MAP_FIXED,fd,
128 (off_t) offset)) == (os_vm_address_t) -1)
129 perror("mmap");
130
131 return addr;
132 }
133
134 void
135 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
136 {
137 }
138
139 void
140 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
141 {
142 if(mprotect(address, length, prot) == -1)
143 perror("mprotect");
144 }
145
146 static boolean
147 in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
148 {
149 char* beg = (char*)sbeg;
150 char* end = (char*)sbeg + slen;
151 char* adr = (char*)a;
152 return (adr >= beg && adr < end);
153 }
154 boolean
155 valid_addr(os_vm_address_t addr)
156 {
157 int ret;
158 os_vm_address_t newaddr;
159 newaddr=os_trunc_to_page(addr);
160
161 if( in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
162 || in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE )
163 || in_range_p(addr, DYNAMIC_0_SPACE_START, DYNAMIC_SPACE_SIZE )
164 || in_range_p(addr, DYNAMIC_1_SPACE_START, DYNAMIC_SPACE_SIZE )
165 || in_range_p(addr, CONTROL_STACK_START , CONTROL_STACK_SIZE )
166 || in_range_p(addr, BINDING_STACK_START , BINDING_STACK_SIZE ))
167 return TRUE;
168 return FALSE;
169 }
170
171
172 static void
173 sigbus_handler(int signal, int code, struct sigcontext *context,
174 void *fault_addr)
175 {
176 #if defined GENCGC
177 int page_index = find_page_index(fault_addr);
178
179 #if SIGBUS_VERBOSE
180 fprintf(stderr,"Signal %d, fault_addr=%x, page_index=%d:\n",
181 signal,fault_addr,page_index);
182 #endif
183
184 /* Check if the fault is within the dynamic space. */
185 if (page_index != -1) {
186 /* Un-protect the page */
187
188 /* The page should have been marked write_protected */
189 if (page_table[page_index].write_protected != 1)
190 fprintf(stderr,"*** Sigbus in page not marked as write protected");
191
192 os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
193 page_table[page_index].write_protected = 0;
194 page_table[page_index].write_protected_cleared = 1;
195
196 #if SIGBUS_VERBOSE
197 fprintf(stderr,"* page: gen=%d bytes_used=%d first_object_offset=%d dont_move=%d\n",
198 page_table[page_index].gen,
199 page_table[page_index].bytes_used,
200 page_table[page_index].first_object_offset,
201 page_table[page_index].dont_move);
202 fprintf(stderr,"* data: %x %x %x %x\n",
203 *(((long *)fault_addr)-1),
204 *(((long *)fault_addr)-0),
205 *(((long *)fault_addr)+1),
206 *(((long *)fault_addr)+2));
207 {
208 int pi2 = find_page_index(*(((long *)fault_addr)-0));
209
210 if ( pi2!=-1 )
211 fprintf(stderr,"* pi2: gen=%d bytes_used=%d first_object_offset=%d dont_move=%d\n",
212 page_table[pi2].gen,
213 page_table[pi2].bytes_used,
214 page_table[pi2].first_object_offset,
215 page_table[pi2].dont_move);
216 }
217 #endif
218
219 return;
220 }
221 #endif
222
223 DPRINTF(0,(stderr,"sigbus:\n"));
224 interrupt_handle_now(signal, code, context);
225 }
226 static void
227 sigsegv_handler(int signal, int code, struct sigcontext *context)
228 {
229 DPRINTF(0,(stderr,"os_sigsegv\n"));
230 interrupt_handle_now(signal, code, context);
231 }
232
233 void
234 os_install_interrupt_handlers(void)
235 {
236 interrupt_install_low_level_handler(SIGSEGV,sigsegv_handler);
237 interrupt_install_low_level_handler(SIGBUS,sigbus_handler);
238 }

  ViewVC Help
Powered by ViewVC 1.1.5