Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <mach.h>
5
#define Extern extern
6
#include "mips.h"
7
 
8
extern ulong	textbase;
9
 
10
ulong
11
ifetch(ulong addr)
12
{
13
	uchar *va;
14
 
15
	if(addr&3) {
16
		Bprint(bioout, "Address error (I-fetch) vaddr %.8lux\n", addr);
17
		longjmp(errjmp, 0);
18
	}
19
 
20
	if(icache.on)
21
		updateicache(addr);
22
 
23
	iprof[(addr-textbase)/PROFGRAN]++;
24
 
25
	va = vaddr(addr);
26
	va += addr&(BY2PG-1);
27
 
28
	return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3];
29
}
30
 
31
ulong
32
getmem_4(ulong addr)
33
{
34
	ulong val;
35
	int i;
36
 
37
	val = 0;
38
	for(i = 0; i < 4; i++)
39
		val = val<<8 | getmem_b(addr++);
40
	return val;
41
}
42
 
43
ulong
44
getmem_2(ulong addr)
45
{
46
	ulong val;
47
 
48
	val = getmem_b(addr);
49
	val = val<<8 | getmem_b(addr+1);
50
 
51
	return val;
52
}
53
 
54
ulong
55
getmem_w(ulong addr)
56
{
57
	uchar *va;
58
 
59
	if(addr&3) {
60
		Bprint(bioout, "Address error (Load) vaddr %.8lux\n", addr);
61
		longjmp(errjmp, 0);
62
	}
63
	if(membpt)
64
		brkchk(addr, Read);
65
 
66
	va = vaddr(addr);
67
	va += addr&(BY2PG-1);
68
 
69
	return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3];;
70
}
71
 
72
ushort
73
getmem_h(ulong addr)
74
{
75
	uchar *va;
76
 
77
	if(addr&1) {
78
		Bprint(bioout, "Address error (Load) vaddr %.8lux\n", addr);
79
		longjmp(errjmp, 0);
80
	}
81
	if(membpt)
82
		brkchk(addr, Read);
83
 
84
	va = vaddr(addr);
85
	va += addr&(BY2PG-1);
86
 
87
	return va[0]<<8 | va[1];
88
}
89
 
90
uchar
91
getmem_b(ulong addr)
92
{
93
	uchar *va;
94
 
95
	if(membpt)
96
		brkchk(addr, Read);
97
 
98
	va = vaddr(addr);
99
	va += addr&(BY2PG-1);
100
	return va[0];
101
}
102
 
103
void
104
putmem_w(ulong addr, ulong data)
105
{
106
	uchar *va;
107
 
108
	if(addr&3) {
109
		Bprint(bioout, "Address error (Store) vaddr %.8lux\n", addr);
110
		longjmp(errjmp, 0);
111
	}
112
 
113
	va = vaddr(addr);
114
	va += addr&(BY2PG-1);
115
 
116
	va[0] = data>>24;
117
	va[1] = data>>16;
118
	va[2] = data>>8;
119
	va[3] = data;
120
	if(membpt)
121
		brkchk(addr, Write);
122
}
123
void
124
putmem_b(ulong addr, uchar data)
125
{
126
	uchar *va;
127
 
128
	va = vaddr(addr);
129
	va += addr&(BY2PG-1);
130
	va[0] = data;
131
	if(membpt)
132
		brkchk(addr, Write);
133
}
134
 
135
void
136
putmem_h(ulong addr, short data)
137
{
138
	uchar *va;
139
 
140
	if(addr&1) {
141
		Bprint(bioout, "Address error (Store) vaddr %.8lux\n", addr);
142
		longjmp(errjmp, 0);
143
	}
144
 
145
	va = vaddr(addr);
146
	va += addr&(BY2PG-1);
147
	va[0] = data>>8;
148
	va[1] = data;
149
	if(membpt)
150
		brkchk(addr, Write);
151
}
152
 
153
char *
154
memio(char *mb, ulong mem, int size, int dir)
155
{
156
	int i;
157
	char *buf, c;
158
 
159
	if(mb == 0)
160
		mb = emalloc(size);
161
 
162
	buf = mb;
163
	switch(dir) {
164
	default:
165
		fatal(0, "memio");
166
	case MemRead:
167
		while(size--)
168
			*mb++ = getmem_b(mem++);
169
		break;
170
	case MemReadstring:
171
		for(;;) {
172
			if(size-- == 0) {
173
				Bprint(bioout, "memio: user/kernel copy too long for mipsim\n");
174
				longjmp(errjmp, 0);
175
			}
176
			c = getmem_b(mem++);
177
			*mb++ = c;
178
			if(c == '\0')
179
				break;
180
		}
181
		break;
182
	case MemWrite:
183
		for(i = 0; i < size; i++)
184
			putmem_b(mem++, *mb++);
185
		break;
186
	}
187
	return buf;
188
}
189
 
190
void
191
dotlb(ulong vaddr)
192
{
193
	ulong *l, *e;
194
 
195
	vaddr &= ~(BY2PG-1);
196
 
197
	e = &tlb.tlbent[tlb.tlbsize];
198
	for(l = tlb.tlbent; l < e; l++)
199
		if(*l == vaddr) {
200
			tlb.hit++;
201
			return;
202
		}
203
 
204
	tlb.miss++;
205
	tlb.tlbent[lnrand(tlb.tlbsize)] = vaddr;
206
}
207
 
208
void*
209
vaddr1(ulong addr)
210
{
211
	Segment *s, *es;
212
	int off, foff, l, n;
213
	uchar **p, *a;
214
 
215
	if(tlb.on)
216
		dotlb(addr);
217
 
218
	es = &memory.seg[Nseg];
219
	for(s = memory.seg; s < es; s++) {
220
		if(addr >= s->base && addr < s->end) {
221
			s->refs++;
222
			off = (addr-s->base)/BY2PG;
223
			p = &s->table[off];
224
			if(*p)
225
				return *p;
226
			s->rss++;
227
			switch(s->type) {
228
			default:
229
				fatal(0, "vaddr");
230
			case Text:
231
				*p = emalloc(BY2PG);
232
				if(seek(text, s->fileoff+(off*BY2PG), 0) < 0)
233
					fatal(1, "vaddr text seek");
234
				if(read(text, *p, BY2PG) < 0)
235
					fatal(1, "vaddr text read");
236
				return *p;
237
			case Data:
238
				*p = emalloc(BY2PG);
239
				foff = s->fileoff+(off*BY2PG);
240
				if(seek(text, foff, 0) < 0)
241
					fatal(1, "vaddr text seek");
242
				n = read(text, *p, BY2PG);
243
				if(n < 0)
244
					fatal(1, "vaddr text read");
245
				if(foff + n > s->fileend) {
246
					l = BY2PG - (s->fileend-foff);
247
					a = *p+(s->fileend-foff);
248
					memset(a, 0, l);
249
				}
250
				return *p;
251
			case Bss:
252
			case Stack:
253
				*p = emalloc(BY2PG);
254
				return *p;
255
			}
256
		}
257
	}
258
	return 0;
259
}
260
 
261
void*
262
vaddr(ulong addr)
263
{
264
	void *v;
265
 
266
	v = vaddr1(addr);
267
	if(v == 0) {
268
		Bprint(bioout, "User TLB miss vaddr 0x%.8lux\n", addr);
269
		longjmp(errjmp, 0);
270
	}
271
	return v;
272
}
273
 
274
int
275
badvaddr(ulong addr, int n)
276
{
277
	void *v;
278
 
279
	if(addr & (n-1))
280
		return 1;
281
	v = vaddr1(addr);
282
	if(v == 0)
283
		return 1;
284
	return 0;
285
}