/* Copyright (C) 1994 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "priv.h" #define EXC_TABLE_SIZE 1024 /* Ack!XXX -- should be dynamically sized! */ /* This is the table of addresses for which we should report faults back to the faulting thread. */ static struct { struct pager *p; vm_offset_t pager_offset; void *offset; long length; } memory_fault_table[EXC_TABLE_SIZE]; static spin_lock_t memory_fault_lock; /* Mark the memory at ADDR continuing for LEN bytes as mapped from pager P at offset OFF. Call when vm_map-ing part of the disk. CAVEAT: addr must not be zero. */ void diskfs_register_memory_fault_area (struct pager *p, vm_address_t off, void *addr, long len) { int i; assert (addr); spin_lock (&memory_fault_lock); for (i = 0; i < EXC_TABLE_SIZE; i++) if (!memory_fault_table[i].offset) { memory_fault_table[i].p = p; memory_fault_table[i].pager_offset = off; memory_fault_table[i].offset = addr; memory_fault_table[i].length = len; spin_unlock (&memory_fault_lock); return; } assert (0); } /* Mark the memory at ADDR continuing for LEN bytes as no longer mapped from the disk. Call when vm_unmap-ing part of the disk. */ void diskfs_unregister_memory_fault_area (void *addr, long len) { int i; assert (addr); spin_lock (&memory_fault_lock); for (i = 0; i < EXC_TABLE_SIZE; i++) if (memory_fault_table[i].offset == addr && memory_fault_table[i].length == len) { memory_fault_table[i].offset = 0; spin_unlock (&memory_fault_lock); return; } assert (0); } /* Set up the exception handling system. */ void init_exceptions () { int i; for (i = 0; i < EXC_TABLE_SIZE; i++) memory_fault_table[i].offset = 0; spin_lock_init (&memory_fault_lock); #if notdebugging mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &excport); mach_port_insert_right (mach_task_self (), excport, excport, MACH_MSG_TYPE_MAKE_SEND); task_get_special_port (mach_task_self (), TASK_EXCEPTION_PORT, &oldexcport); task_set_special_port (mach_task_self (), TASK_EXCEPTION_PORT, excport); mach_port_deallocate (mach_task_self (), excport); #endif }