diff --git a/lisp/NetBSD-os.c b/lisp/NetBSD-os.c new file mode 100644 index 0000000000000000000000000000000000000000..57722a6b23d5104e2a6b3f814d6b2befecc0551a --- /dev/null +++ b/lisp/NetBSD-os.c @@ -0,0 +1,238 @@ +/* + * NetBSD-os.c. + * From OpenBSD-os.c 1.1 2001/12/06 19:15:44 pmai Exp + * From FreeBSD-os.c 1.6 2000/10/24 13:32:30 dtc Exp + * + * OS-dependent routines. This file (along with os.h) exports an + * OS-independent interface to the operating system VM facilities. + * Suprisingly, this interface looks a lot like the Mach interface + * (but simpler in some places). For some operating systems, a subset + * of these functions will have to be emulated. + * + * This is the OSF1 version. By Sean Hallgren. + * Much hacked by Paul Werkowski + * GENCGC support by Douglas Crosher, 1996, 1997. + * Frobbed for OpenBSD by Pierre R. Mai, 2001. + * Frobbed for NetBSD by Pierre R. Mai, 2002. + * + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/NetBSD-os.c,v 1.1 2002/01/28 20:19:39 pmai Exp $ + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/param.h> +#include <sys/file.h> +#include <errno.h> +#include "./signal.h" +#include "os.h" +#include "arch.h" +#include "globals.h" +#include "interrupt.h" +#include "lispregs.h" +#include "internals.h" + +#include <sys/types.h> +#include <signal.h> +/* #include <sys/sysinfo.h> */ +#include <sys/proc.h> +#include "validate.h" +size_t os_vm_page_size; + +#define DPRINTF(t,a) {if (t) fprintf a;} + +#if defined GENCGC +#include "gencgc.h" +#endif + + +void os_init(void) +{ + os_vm_page_size = OS_VM_DEFAULT_PAGESIZE; +} + +int sc_reg(struct sigcontext *c, int offset) +{ + switch(offset) + { + case 0: return c->sc_eax; + case 2: return c->sc_ecx; + case 4: return c->sc_edx; + case 6: return c->sc_ebx; + case 8: return c->sc_esp; + case 10: return c->sc_ebp; + case 12: return c->sc_esi; + case 14: return c->sc_edi; + } + return 0; +} + +void os_save_context(void) +{ + /* + * Called from interrupt handlers so C stuff knows things set in Lisp. + */ +} + +void os_set_context(void) +{ +} + +os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len) +{ + int flags = MAP_PRIVATE | MAP_ANONYMOUS; + + /* + * NetBSD 1.5.2 seems to insist on each mmap being less than 128MB. + * So we mmap in 64MB steps. This is probably inefficient, but the + * missing CR2 reporting in signal handlers already ensures that + * NetBSD/x86 is not a suitable platform for CMU CL as it stands. + */ + + if (addr) + flags |= MAP_FIXED; + else + flags |= MAP_VARIABLE; + + DPRINTF(0, (stderr, "os_validate %x %d =>", addr, len)); + + if (addr) + { + os_vm_address_t curaddr=addr; + + while (len>0) + { + os_vm_address_t resaddr; + int curlen=MIN(64*1024*1024,len); + + resaddr = mmap(curaddr, curlen, OS_VM_PROT_ALL, flags, -1, 0); + + if (resaddr == (os_vm_address_t) -1) + { + perror("mmap"); + + while (curaddr>addr) + { + curaddr-=64*1024*1024; + munmap(curaddr,64*1024*1024); + } + + return NULL; + } + + DPRINTF(0, (stderr, " %x", resaddr)); + + curaddr+=curlen; + len-=curlen; + } + + DPRINTF(0, (stderr, "\n")); + } + else + { + addr = mmap(0, len, OS_VM_PROT_ALL, flags, -1, 0); + + if (addr == (os_vm_address_t) -1) + { + perror("mmap"); + return NULL; + } + + DPRINTF(0, (stderr, " %x\n", addr)); + } + + return addr; +} + +void os_invalidate(os_vm_address_t addr, os_vm_size_t len) +{ + DPRINTF(0, (stderr, "os_invalidate %x %d\n", addr, len)); + + if (munmap(addr, len) == -1) + perror("munmap"); +} + +os_vm_address_t os_map(int fd, int offset, os_vm_address_t addr, + os_vm_size_t len) +{ + addr = mmap(addr, len, + OS_VM_PROT_ALL, + MAP_PRIVATE | MAP_FILE | MAP_FIXED, + fd, (off_t) offset); + + if (addr == (os_vm_address_t) -1) + perror("mmap"); + + return addr; +} + +void os_flush_icache(os_vm_address_t address, os_vm_size_t length) +{ +} + +void os_protect(os_vm_address_t address, os_vm_size_t length, + os_vm_prot_t prot) +{ + if (mprotect(address, length, prot) == -1) + perror("mprotect"); +} + + + +static boolean in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen) +{ + char* beg = (char*) sbeg; + char* end = (char*) sbeg + slen; + char* adr = (char*) a; + return (adr >= beg && adr < end); +} + +boolean valid_addr(os_vm_address_t addr) +{ + int ret; + os_vm_address_t newaddr; + newaddr = os_trunc_to_page(addr); + + if ( in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE) + || in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE ) + || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size ) + || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size ) + || in_range_p(addr, CONTROL_STACK_START , CONTROL_STACK_SIZE ) + || in_range_p(addr, BINDING_STACK_START , BINDING_STACK_SIZE )) + return TRUE; + return FALSE; +} + + +static void sigsegv_handler(HANDLER_ARGS) +{ + + /* + * Since NetBSD on x86 currently provides no way to get the faulting + * memory address (i.e. the contents of the CR2 register), the page + * protection mechanism of the generational GC currently can't be + * used (see gengc.c), hence we don't neet to do anything here. + * + * See OpenBSD-os.c for details of what should be here, once NetBSD + * provides siginfo_t. + */ + + SAVE_CONTEXT(); + + DPRINTF(0, (stderr, "sigsegv:\n")); + interrupt_handle_now(signal, code, context); +} + +static void sigbus_handler(HANDLER_ARGS) +{ + SAVE_CONTEXT(); + + DPRINTF(0, (stderr, "sigbus:\n")); + interrupt_handle_now(signal, code, context); +} + +void os_install_interrupt_handlers(void) +{ + interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler); + interrupt_install_low_level_handler(SIGBUS, sigbus_handler); +} diff --git a/lisp/gencgc.c b/lisp/gencgc.c index 3e03314c843766bab3c22a4aeef15585d294ee63..14bfb59133c4fe430fa30e22620aad19e81d1a5c 100644 --- a/lisp/gencgc.c +++ b/lisp/gencgc.c @@ -7,7 +7,7 @@ * * Douglas Crosher, 1996, 1997, 1998, 1999. * - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.c,v 1.25 2001/12/06 19:15:44 pmai Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.c,v 1.26 2002/01/28 20:19:39 pmai Exp $ * */ @@ -53,7 +53,13 @@ unsigned gencgc_verbose = 0; * To enable the use of page protection to help avoid the scavenging * of pages that don't have pointers to younger generations. */ +#ifdef __NetBSD__ +/* NetBSD on x86 has no way to retrieve the faulting address in the + * SIGSEGV handler, so for the moment we can't use page protection. */ +boolean enable_page_protection = FALSE; +#else boolean enable_page_protection = TRUE; +#endif /* * Hunt for pointers to old-space, when GCing generations >= verify_gen. @@ -85,9 +91,10 @@ boolean check_code_fixups = FALSE; /* * To enable unmapping of a page and re-mmaping it to have it zero filled. - * Note: this can waste a lot of swap on FreeBSD and OpenBSD(?) so don't unmap. + * Note: this can waste a lot of swap on FreeBSD and Open/NetBSD(?) so + * don't unmap. */ -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) boolean gencgc_unmap_zero = FALSE; #else boolean gencgc_unmap_zero = TRUE;