Clean up RCS ids
[projects/cmucl/cmucl.git] / src / lisp / OpenBSD-os.c
CommitLineData
195461c1 1/*
2 * OpenBSD-os.c.
3 * From FreeBSD-os.c 1.6 2000/10/24 13:32:30 dtc 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 * Frobbed for OpenBSD by Pierre R. Mai, 2001.
15 *
195461c1 16 */
17
18#include <stdio.h>
19#include <sys/param.h>
20#include <sys/file.h>
21#include <errno.h>
195461c1 22#include "os.h"
23#include "arch.h"
24#include "globals.h"
25#include "interrupt.h"
26#include "lispregs.h"
27#include "internals.h"
28
29#include <sys/types.h>
30#include <signal.h>
31/* #include <sys/sysinfo.h> */
32#include <sys/proc.h>
33#include "validate.h"
34vm_size_t os_vm_page_size;
35
195461c1 36#if defined GENCGC
37#include "gencgc.h"
38#endif
195461c1 39\f
9a8c1c2f 40
41void
dafb9e03 42os_init0(const char *argv[], const char *envp[])
43{}
44
45void
0f0aed07 46os_init(const char *argv[], const char *envp[])
195461c1 47{
9a8c1c2f 48 os_vm_page_size = OS_VM_DEFAULT_PAGESIZE;
195461c1 49}
50
3e4590e7 51int *
9a8c1c2f 52sc_reg(struct sigcontext *c, int offset)
195461c1 53{
9a8c1c2f 54 switch (offset) {
55 case 0:
3e4590e7 56 return &c->sc_eax;
9a8c1c2f 57 case 2:
3e4590e7 58 return &c->sc_ecx;
9a8c1c2f 59 case 4:
3e4590e7 60 return &c->sc_edx;
9a8c1c2f 61 case 6:
3e4590e7 62 return &c->sc_ebx;
9a8c1c2f 63 case 8:
3e4590e7 64 return &c->sc_esp;
9a8c1c2f 65 case 10:
3e4590e7 66 return &c->sc_ebp;
9a8c1c2f 67 case 12:
3e4590e7 68 return &c->sc_esi;
9a8c1c2f 69 case 14:
3e4590e7 70 return &c->sc_edi;
195461c1 71 }
3e4590e7 72 return (int *) 0;
195461c1 73}
74
9a8c1c2f 75os_vm_address_t
76os_validate(os_vm_address_t addr, os_vm_size_t len)
195461c1 77{
1e078503 78 int flags = MAP_PRIVATE | MAP_ANON;
195461c1 79
9a8c1c2f 80 if (addr)
81 flags |= MAP_FIXED;
195461c1 82
9a8c1c2f 83 DPRINTF(0, (stderr, "os_validate %x %d => ", addr, len));
195461c1 84
9a8c1c2f 85 addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
195461c1 86
9a8c1c2f 87 if (addr == (os_vm_address_t) - 1) {
88 perror("mmap");
89 return NULL;
195461c1 90 }
91
9a8c1c2f 92 DPRINTF(0, (stderr, "%x\n", addr));
195461c1 93
9a8c1c2f 94 return addr;
195461c1 95}
96
9a8c1c2f 97void
98os_invalidate(os_vm_address_t addr, os_vm_size_t len)
195461c1 99{
9a8c1c2f 100 DPRINTF(0, (stderr, "os_invalidate %x %d\n", addr, len));
195461c1 101
9a8c1c2f 102 if (munmap(addr, len) == -1)
103 perror("munmap");
195461c1 104}
105
9a8c1c2f 106os_vm_address_t
107os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
195461c1 108{
9a8c1c2f 109 addr = mmap(addr, len,
110 OS_VM_PROT_ALL,
111 MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd, (off_t) offset);
195461c1 112
9a8c1c2f 113 if (addr == (os_vm_address_t) - 1)
114 perror("mmap");
195461c1 115
9a8c1c2f 116 return addr;
195461c1 117}
118
9a8c1c2f 119void
120os_flush_icache(os_vm_address_t address, os_vm_size_t length)
195461c1 121{
122}
123
9a8c1c2f 124void
125os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
195461c1 126{
9a8c1c2f 127 if (mprotect(address, length, prot) == -1)
128 perror("mprotect");
195461c1 129}
195461c1 130\f
131
9a8c1c2f 132
133static boolean
134in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
195461c1 135{
9a8c1c2f 136 char *beg = (char *) sbeg;
137 char *end = (char *) sbeg + slen;
138 char *adr = (char *) a;
139
140 return (adr >= beg && adr < end);
195461c1 141}
142
9a8c1c2f 143boolean
144valid_addr(os_vm_address_t addr)
195461c1 145{
9a8c1c2f 146 int ret;
147 os_vm_address_t newaddr;
148
149 newaddr = os_trunc_to_page(addr);
150
151 if (in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
152 || in_range_p(addr, STATIC_SPACE_START, STATIC_SPACE_SIZE)
153 || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size)
154 || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size)
155 || in_range_p(addr, CONTROL_STACK_START, CONTROL_STACK_SIZE)
156 || in_range_p(addr, BINDING_STACK_START, BINDING_STACK_SIZE))
157 return TRUE;
158 return FALSE;
195461c1 159}
195461c1 160\f
9a8c1c2f 161
162static void
163sigsegv_handler(HANDLER_ARGS)
195461c1 164{
165#if defined GENCGC
9a8c1c2f 166 caddr_t fault_addr = code->si_addr;
195461c1 167
168#if SIGSEGV_VERBOSE
9a8c1c2f 169 fprintf(stderr, "Signal %d, fault_addr=%x, page_index=%d:\n",
170 signal, fault_addr, page_index);
195461c1 171#endif
172
97083c55 173 if (gc_write_barrier(code->si_addr))
9a8c1c2f 174 return;
195461c1 175#endif
176
9a8c1c2f 177 SAVE_CONTEXT();
195461c1 178
9a8c1c2f 179 DPRINTF(0, (stderr, "sigsegv:\n"));
180 interrupt_handle_now(signal, code, context);
195461c1 181}
182
9a8c1c2f 183static void
184sigbus_handler(HANDLER_ARGS)
195461c1 185{
9a8c1c2f 186 SAVE_CONTEXT();
195461c1 187
9a8c1c2f 188 DPRINTF(0, (stderr, "sigbus:\n"));
189 interrupt_handle_now(signal, code, context);
195461c1 190}
191
9a8c1c2f 192void
193os_install_interrupt_handlers(void)
195461c1 194{
9a8c1c2f 195 interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler);
196 interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
195461c1 197}