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.
8 * This is the Mach version.
18 #include "interrupt.h"
22 static struct segment {
26 static int segments = -1;
28 vm_size_t os_vm_page_size;
30 #if defined(i386) || defined(parisc)
34 return mach_task_self();
39 os_init0(const char *argv[], const char *envp[])
43 os_init(const char *argv[], const char *envp[])
45 os_vm_page_size = vm_page_size;
49 os_validate(vm_address_t addr, vm_size_t len)
53 res = vm_allocate(task_self(), &addr, len, addr == NULL);
55 if (res != KERN_SUCCESS)
60 vm_protect(task_self(), addr, len, FALSE,
61 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
67 os_invalidate(vm_address_t addr, vm_size_t len)
71 res = vm_deallocate(task_self(), addr, len);
73 if (res != KERN_SUCCESS)
74 mach_error("Could not vm_allocate memory: ", res);
80 os_map(int fd, int offset, vm_address_t addr, vm_size_t len)
84 res = map_fd(fd, offset, &addr, 0, len);
86 if (res != KERN_SUCCESS) {
89 sprintf(buf, "Could not map_fd(%d, %d, 0x%08x, 0x%08x): ",
90 fd, offset, addr, len);
93 lseek(fd, offset, L_SET);
99 vm_protect(task_self(), addr, len, FALSE,
100 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
106 os_flush_icache(vm_address_t address, vm_size_t length)
109 vm_machine_attribute_val_t flush;
112 flush = MATTR_VAL_ICACHE_FLUSH;
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);
122 os_protect(vm_address_t address, vm_size_t length, vm_prot_t protection)
124 vm_protect(task_self(), address, length, FALSE, protection);
136 if (segments == -1) {
142 (task_self(), &addr, &size, &bullshit, &bullshit, &bullshit,
143 &bullshit, &bullshit, &bullshit) != KERN_SUCCESS)
147 && addr_map[curseg - 1].start + addr_map[curseg - 1].length ==
148 addr) addr_map[curseg - 1].length += size;
150 addr_map[curseg].start = addr;
151 addr_map[curseg].length = size;
161 for (curseg = 0; curseg < segments; curseg++)
162 if (addr_map[curseg].start <= test
163 && test < addr_map[curseg].start + addr_map[curseg].length)
170 sigbus_handler(int signal, int code, struct sigcontext *context)
172 if (!interrupt_maybe_gc(signal, code, context))
173 interrupt_handle_now(signal, code, context);
178 os_install_interrupt_handlers(void)
181 interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
184 interrupt_install_low_level_handler(SIGSEGV, sigbus_handler);