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