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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show annotations)
Thu Sep 1 05:18:26 2011 UTC (2 years, 7 months ago) by rtoy
Branch: MAIN
CVS Tags: GIT-CONVERSION, snapshot-2011-09, HEAD
Changes since 1.8: +5 -1 lines
File MIME type: text/plain
Add os_init0 to allow for some really early OS inits.

On Linux, os_init can re-exec lisp to set up the correct personality.
Not normally a problem, but if any output happens before os_init is
called, the output appears to happen twice.  So add os_init0 to do
this early on, before any output.  This is a bit of a kludge.

lisp/lisp.c:
o Call os_init0 early in main.

lisp/Linux-os.c:
o Move the personality stuff from os_init to os_init0.

lisp/Darwin-os.c:
lisp/FreeBSD-os.c:
lisp/NetBSD-os.c:
lisp/OpenBSD-os.c:
lisp/hpux-os.c:
lisp/irix-os.c:
lisp/mach-os.c:
lisp/osf1-os.c:
lisp/solaris-os.c:
lisp/sunos-os.c:
o Add dummy implementation of os_init0.  These OSes don't (currently)
  need anything special.

lisp/os.h:
o Declare os_init0.
1 /*
2 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/mach-os.c,v 1.9 2011/09/01 05:18:26 rtoy Exp $
3 *
4 * OS-dependent routines. This file (along with os.h) exports an
5 * OS-independent interface to the operating system VM facilities.
6 * Suprisingly, this interface looks a lot like the Mach interface
7 * (but simpler in some places). For some operating systems, a subset
8 * of these functions will have to be emulated.
9 *
10 * This is the Mach version.
11 *
12 */
13
14 #include <stdio.h>
15 #include <mach.h>
16 #include <sys/file.h>
17 #include <signal.h>
18 #include "os.h"
19 #include "arch.h"
20 #include "interrupt.h"
21
22 #define MAX_SEGS 32
23
24 static struct segment {
25 vm_address_t start;
26 vm_size_t length;
27 } addr_map[MAX_SEGS];
28 static int segments = -1;
29
30 vm_size_t os_vm_page_size;
31
32 #if defined(i386) || defined(parisc)
33 mach_port_t
34 task_self(void)
35 {
36 return mach_task_self();
37 }
38 #endif
39
40 void
41 os_init0(const char *argv[], const char *envp[])
42 {}
43
44 void
45 os_init(const char *argv[], const char *envp[])
46 {
47 os_vm_page_size = vm_page_size;
48 }
49
50 os_vm_address_t
51 os_validate(vm_address_t addr, vm_size_t len)
52 {
53 kern_return_t res;
54
55 res = vm_allocate(task_self(), &addr, len, addr == NULL);
56
57 if (res != KERN_SUCCESS)
58 return 0;
59
60 segments = -1;
61
62 vm_protect(task_self(), addr, len, FALSE,
63 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
64
65 return addr;
66 }
67
68 void
69 os_invalidate(vm_address_t addr, vm_size_t len)
70 {
71 kern_return_t res;
72
73 res = vm_deallocate(task_self(), addr, len);
74
75 if (res != KERN_SUCCESS)
76 mach_error("Could not vm_allocate memory: ", res);
77
78 segments = -1;
79 }
80
81 vm_address_t
82 os_map(int fd, int offset, vm_address_t addr, vm_size_t len)
83 {
84 kern_return_t res;
85
86 res = map_fd(fd, offset, &addr, 0, len);
87
88 if (res != KERN_SUCCESS) {
89 char buf[256];
90
91 sprintf(buf, "Could not map_fd(%d, %d, 0x%08x, 0x%08x): ",
92 fd, offset, addr, len);
93 mach_error(buf, res);
94
95 lseek(fd, offset, L_SET);
96 read(fd, addr, len);
97 }
98
99 segments = -1;
100
101 vm_protect(task_self(), addr, len, FALSE,
102 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
103
104 return addr;
105 }
106
107 void
108 os_flush_icache(vm_address_t address, vm_size_t length)
109 {
110 #ifdef mips
111 vm_machine_attribute_val_t flush;
112 kern_return_t kr;
113
114 flush = MATTR_VAL_ICACHE_FLUSH;
115
116 kr = vm_machine_attribute(task_self(), address, length,
117 MATTR_CACHE, &flush);
118 if (kr != KERN_SUCCESS)
119 mach_error("Could not flush the instruction cache", kr);
120 #endif
121 }
122
123 void
124 os_protect(vm_address_t address, vm_size_t length, vm_prot_t protection)
125 {
126 vm_protect(task_self(), address, length, FALSE, protection);
127 }
128
129 boolean
130 valid_addr(test)
131 vm_address_t test;
132 {
133 vm_address_t addr;
134 vm_size_t size;
135 int bullshit;
136 int curseg;
137
138 if (segments == -1) {
139 addr = 0;
140 curseg = 0;
141
142 while (1) {
143 if (vm_region
144 (task_self(), &addr, &size, &bullshit, &bullshit, &bullshit,
145 &bullshit, &bullshit, &bullshit) != KERN_SUCCESS)
146 break;
147
148 if (curseg > 0
149 && addr_map[curseg - 1].start + addr_map[curseg - 1].length ==
150 addr) addr_map[curseg - 1].length += size;
151 else {
152 addr_map[curseg].start = addr;
153 addr_map[curseg].length = size;
154 curseg++;
155 }
156
157 addr += size;
158 }
159
160 segments = curseg;
161 }
162
163 for (curseg = 0; curseg < segments; curseg++)
164 if (addr_map[curseg].start <= test
165 && test < addr_map[curseg].start + addr_map[curseg].length)
166 return TRUE;
167 return FALSE;
168 }
169
170 #ifndef ibmrt
171 static void
172 sigbus_handler(int signal, int code, struct sigcontext *context)
173 {
174 if (!interrupt_maybe_gc(signal, code, context))
175 interrupt_handle_now(signal, code, context);
176 }
177 #endif
178
179 void
180 os_install_interrupt_handlers(void)
181 {
182 #ifndef ibmrt
183 interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
184 #endif
185 #ifdef mips
186 interrupt_install_low_level_handler(SIGSEGV, sigbus_handler);
187 #endif
188 }

  ViewVC Help
Powered by ViewVC 1.1.5