Clean up RCS ids
[projects/cmucl/cmucl.git] / src / lisp / osf1-os.c
1 /*
2  *
3  * OS-dependent routines.  This file (along with os.h) exports an
4  * OS-independent interface to the operating system VM facilities.
5  * Suprisingly, this interface looks a lot like the Mach interface
6  * (but simpler in some places).  For some operating systems, a subset
7  * of these functions will have to be emulated.
8  *
9  * This is the OSF1 version.  By Sean Hallgren.
10  *
11  */
12
13 #include <stdio.h>
14 #include <sys/file.h>
15 #include <errno.h>
16 #include <signal.h>
17 #include "os.h"
18 #include "arch.h"
19 #include "interrupt.h"
20 #include "lispregs.h"
21 #include <sys/types.h>
22 #include <sys/sysinfo.h>
23 #include <sys/proc.h>
24
25 vm_size_t os_vm_page_size;
26
27 void
28 os_init0(const char *argv[], const char *envp[])
29 {}
30
31 void
32 os_init(const char *argv[], const char *envp[])
33 {
34     int buf[2] = { SSIN_UACPROC, UAC_SIGBUS | UAC_NOPRINT };
35     int error;
36
37     os_vm_page_size = OS_VM_DEFAULT_PAGESIZE;
38     if (setsysinfo(SSI_NVPAIRS, buf, 1, NULL, NULL) == -1)
39         perror("setsysinfo");
40 }
41
42 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
43 {
44     int flags = MAP_PRIVATE | MAP_ANONYMOUS;
45
46     if (addr)
47         flags |= MAP_FIXED;
48     else
49         flags |= MAP_VARIABLE;
50
51     if ((addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0)) ==
52         (os_vm_address_t) - 1)
53         perror("mmap");
54
55     return addr;
56 }
57
58 void
59 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
60 {
61     if (munmap(addr, len) == -1)
62         perror("munmap");
63 }
64
65 os_vm_address_t
66 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
67 {
68     if (
69         (addr =
70          mmap(addr, len, OS_VM_PROT_ALL, MAP_PRIVATE | MAP_FILE | MAP_FIXED, fd,
71               (off_t) offset)) == (os_vm_address_t) - 1)
72         perror("mmap");
73
74     return addr;
75 }
76
77 void
78 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
79 {
80 }
81
82 void
83 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
84 {
85     if (mprotect(address, length, prot) == -1)
86         perror("mprotect");
87 }
88
89 boolean valid_addr(os_vm_address_t addr)
90 {
91     int ret;
92     os_vm_address_t newaddr;
93
94     newaddr = os_trunc_to_page(addr);
95     if ((ret = mvalid(newaddr, newaddr - addr + 4, OS_VM_PROT_ALL)) == 0)
96         return TRUE;
97     else if (errno == EINVAL)
98         perror("mvalid");
99     return FALSE;
100 }
101
102 static void
103 sigbus_handler(int signal, int code, struct sigcontext *context)
104 {
105     context->sc_pc -= 4;        /* pc is +4 on bus error!?!!? */
106     if (arch_get_bad_addr(signal, code, context) &&
107         context->sc_regs[reg_ALLOC] & 2) {
108         context->sc_regs[reg_ALLOC] -= 2;
109         interrupt_handle_pending(context);
110     } else
111         interrupt_handle_now(signal, code, context);
112 }
113
114 static void
115 sigsegv_handler(int signal, int code, struct sigcontext *context)
116 {
117     if (!interrupt_maybe_gc(signal, code, context))
118         interrupt_handle_now(signal, code, context);
119 }
120
121 void
122 os_install_interrupt_handlers(void)
123 {
124     interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler);
125     interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
126 }