Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/5i/mem.c – Rev 2

Subversion Repositories planix.SVN

Rev

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