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