Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/irix-os.c,v 1.1 1994/07/05 16:09:23 hallgren 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 IRIX version. By Sean Hallgren.
*
*/
#include <stdio.h>
#include <sys/file.h>
#include <errno.h>
#include "./signal.h"
#include "os.h"
#include "arch.h"
#include "interrupt.h"
#include "lispregs.h"
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <sys/proc.h>
/* #define DEBUG */
os_vm_size_t os_vm_page_size=(-1);
int zero_fd;
void
os_init()
{
zero_fd = open("/dev/zero",O_RDONLY);
os_vm_page_size=getpagesize();
}
os_vm_address_t
os_validate(os_vm_address_t addr, os_vm_size_t len)
{
int flags = MAP_PRIVATE|MAP_AUTORESRV;
#ifdef DEBUG
printf("os_validate: addr = %x, len = %x\n",addr,len);
#endif
if(addr) flags|=MAP_FIXED;
if((addr=mmap(addr,len,OS_VM_PROT_ALL,flags,zero_fd,0)) ==
(os_vm_address_t) -1)
perror("mmap");
return addr;
}
void
os_invalidate(os_vm_address_t addr, os_vm_size_t len)
{
#ifdef DEBUG
printf("os_invalidate: addr = %x, len = %x\n",addr,len);
#endif
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)
{
#ifdef DEBUG
printf("os_map: fd = %d, offset = %d, addr = %x, len = %x\n",fd,offset,addr,len);
#endif
if((addr=mmap(addr,len,OS_VM_PROT_ALL,MAP_PRIVATE|MAP_FIXED,fd,
(off_t) offset)) == (os_vm_address_t) -1)
perror("mmap");
return addr;
}
void
sanctify_for_execution(os_vm_address_t addr, os_vm_size_t len)
{
char* end_addr = addr+len;
addr = os_trunc_to_page(addr);
len = end_addr - addr;
if(mprotect(addr,len,OS_VM_PROT_ALL)== -1)
perror("mprotect");
}
void
os_flush_icache(os_vm_address_t address, os_vm_size_t length)
{
sanctify_for_execution(address,length);
}
void
os_protect(os_vm_address_t addr, os_vm_size_t len, os_vm_prot_t prot)
{
if(mprotect(addr, len, prot) == -1)
perror("mprotect");
}
boolean
valid_addr(os_vm_address_t addr)
{
}
static void
sigbus_handler(int signal, int code, struct sigcontext *context)
{
if(!interrupt_maybe_gc(signal, code, context))
interrupt_handle_now(signal, code, context);
}
static void
sigsegv_handler(int signal, int code, struct sigcontext *context)
{
if(!interrupt_maybe_gc(signal, code, context))
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);
}