xref: /plan9/sys/src/cmd/ki/mem.c (revision bd389b369d90320ffee8121f40c4c30619f88097)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
4*bd389b36SDavid du Colombier #include <mach.h>
53e12c5d1SDavid du Colombier #define Extern extern
63e12c5d1SDavid du Colombier #include "sparc.h"
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier extern ulong	textbase;
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier ulong
ifetch(ulong addr)113e12c5d1SDavid du Colombier ifetch(ulong addr)
123e12c5d1SDavid du Colombier {
133e12c5d1SDavid du Colombier 	uchar *va;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier 	if(addr&3) {
163e12c5d1SDavid du Colombier 		Bprint(bioout, "instruction_address_not_aligned [addr %.8lux]\n", addr);
173e12c5d1SDavid du Colombier 		longjmp(errjmp, 0);
183e12c5d1SDavid du Colombier 	}
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier 	if(icache.on)
213e12c5d1SDavid du Colombier 		updateicache(addr);
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier 	va = vaddr(addr);
243e12c5d1SDavid du Colombier 	iprof[(addr-textbase)/PROFGRAN]++;
253e12c5d1SDavid du Colombier 
263e12c5d1SDavid du Colombier 	va += addr&(BY2PG-1);
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier 	return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3];
293e12c5d1SDavid du Colombier }
303e12c5d1SDavid du Colombier 
313e12c5d1SDavid du Colombier ulong
getmem_4(ulong addr)323e12c5d1SDavid du Colombier getmem_4(ulong addr)
333e12c5d1SDavid du Colombier {
343e12c5d1SDavid du Colombier 	ulong val;
353e12c5d1SDavid du Colombier 	int i;
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier 	val = 0;
383e12c5d1SDavid du Colombier 	for(i = 0; i < 4; i++)
393e12c5d1SDavid du Colombier 		val = val<<8 | getmem_b(addr++);
403e12c5d1SDavid du Colombier 	return val;
413e12c5d1SDavid du Colombier }
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier ulong
getmem_2(ulong addr)443e12c5d1SDavid du Colombier getmem_2(ulong addr)
453e12c5d1SDavid du Colombier {
463e12c5d1SDavid du Colombier 	ulong val;
473e12c5d1SDavid du Colombier 
483e12c5d1SDavid du Colombier 	val = getmem_b(addr);
493e12c5d1SDavid du Colombier 	val = val<<8 | getmem_b(addr+1);
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier 	return val;
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier 
543e12c5d1SDavid du Colombier ulong
getmem_w(ulong addr)553e12c5d1SDavid du Colombier getmem_w(ulong addr)
563e12c5d1SDavid du Colombier {
573e12c5d1SDavid du Colombier 	uchar *va;
583e12c5d1SDavid du Colombier 
593e12c5d1SDavid du Colombier 	if(addr&3) {
603e12c5d1SDavid du Colombier 		Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", addr);
613e12c5d1SDavid du Colombier 		longjmp(errjmp, 0);
623e12c5d1SDavid du Colombier 	}
633e12c5d1SDavid du Colombier 	if(membpt)
643e12c5d1SDavid du Colombier 		brkchk(addr, Read);
653e12c5d1SDavid du Colombier 
663e12c5d1SDavid du Colombier 	va = vaddr(addr);
673e12c5d1SDavid du Colombier 	va += addr&(BY2PG-1);
683e12c5d1SDavid du Colombier 
693e12c5d1SDavid du Colombier 	return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3];;
703e12c5d1SDavid du Colombier }
713e12c5d1SDavid du Colombier 
723e12c5d1SDavid du Colombier ushort
getmem_h(ulong addr)733e12c5d1SDavid du Colombier getmem_h(ulong addr)
743e12c5d1SDavid du Colombier {
753e12c5d1SDavid du Colombier 	uchar *va;
763e12c5d1SDavid du Colombier 
773e12c5d1SDavid du Colombier 	if(addr&1) {
783e12c5d1SDavid du Colombier 		Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", addr);
793e12c5d1SDavid du Colombier 		longjmp(errjmp, 0);
803e12c5d1SDavid du Colombier 	}
813e12c5d1SDavid du Colombier 	if(membpt)
823e12c5d1SDavid du Colombier 		brkchk(addr, Read);
833e12c5d1SDavid du Colombier 
843e12c5d1SDavid du Colombier 	va = vaddr(addr);
853e12c5d1SDavid du Colombier 	va += addr&(BY2PG-1);
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier 	return va[0]<<8 | va[1];
883e12c5d1SDavid du Colombier }
893e12c5d1SDavid du Colombier 
903e12c5d1SDavid du Colombier uchar
getmem_b(ulong addr)913e12c5d1SDavid du Colombier getmem_b(ulong addr)
923e12c5d1SDavid du Colombier {
933e12c5d1SDavid du Colombier 	uchar *va;
943e12c5d1SDavid du Colombier 
953e12c5d1SDavid du Colombier 	if(membpt)
963e12c5d1SDavid du Colombier 		brkchk(addr, Read);
973e12c5d1SDavid du Colombier 
983e12c5d1SDavid du Colombier 	va = vaddr(addr);
993e12c5d1SDavid du Colombier 	va += addr&(BY2PG-1);
1003e12c5d1SDavid du Colombier 	return va[0];
1013e12c5d1SDavid du Colombier }
1023e12c5d1SDavid du Colombier 
1033e12c5d1SDavid du Colombier void
putmem_w(ulong addr,ulong data)1043e12c5d1SDavid du Colombier putmem_w(ulong addr, ulong data)
1053e12c5d1SDavid du Colombier {
1063e12c5d1SDavid du Colombier 	uchar *va;
1073e12c5d1SDavid du Colombier 
1083e12c5d1SDavid du Colombier 	if(addr&3) {
1093e12c5d1SDavid du Colombier 		Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", addr);
1103e12c5d1SDavid du Colombier 		longjmp(errjmp, 0);
1113e12c5d1SDavid du Colombier 	}
1123e12c5d1SDavid du Colombier 
1133e12c5d1SDavid du Colombier 	va = vaddr(addr);
1143e12c5d1SDavid du Colombier 	va += addr&(BY2PG-1);
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier 	va[0] = data>>24;
1173e12c5d1SDavid du Colombier 	va[1] = data>>16;
1183e12c5d1SDavid du Colombier 	va[2] = data>>8;
1193e12c5d1SDavid du Colombier 	va[3] = data;
1203e12c5d1SDavid du Colombier 	if(membpt)
1213e12c5d1SDavid du Colombier 		brkchk(addr, Write);
1223e12c5d1SDavid du Colombier }
1233e12c5d1SDavid du Colombier void
putmem_b(ulong addr,uchar data)1243e12c5d1SDavid du Colombier putmem_b(ulong addr, uchar data)
1253e12c5d1SDavid du Colombier {
1263e12c5d1SDavid du Colombier 	uchar *va;
1273e12c5d1SDavid du Colombier 
1283e12c5d1SDavid du Colombier 	va = vaddr(addr);
1293e12c5d1SDavid du Colombier 	va += addr&(BY2PG-1);
1303e12c5d1SDavid du Colombier 	va[0] = data;
1313e12c5d1SDavid du Colombier 	if(membpt)
1323e12c5d1SDavid du Colombier 		brkchk(addr, Write);
1333e12c5d1SDavid du Colombier }
1343e12c5d1SDavid du Colombier 
1353e12c5d1SDavid du Colombier void
putmem_h(ulong addr,short data)1363e12c5d1SDavid du Colombier putmem_h(ulong addr, short data)
1373e12c5d1SDavid du Colombier {
1383e12c5d1SDavid du Colombier 	uchar *va;
1393e12c5d1SDavid du Colombier 
1403e12c5d1SDavid du Colombier 	if(addr&1) {
1413e12c5d1SDavid du Colombier 		Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", addr);
1423e12c5d1SDavid du Colombier 		longjmp(errjmp, 0);
1433e12c5d1SDavid du Colombier 	}
1443e12c5d1SDavid du Colombier 
1453e12c5d1SDavid du Colombier 	va = vaddr(addr);
1463e12c5d1SDavid du Colombier 	va += addr&(BY2PG-1);
1473e12c5d1SDavid du Colombier 	va[0] = data>>8;
1483e12c5d1SDavid du Colombier 	va[1] = data;
1493e12c5d1SDavid du Colombier 	if(membpt)
1503e12c5d1SDavid du Colombier 		brkchk(addr, Write);
1513e12c5d1SDavid du Colombier }
1523e12c5d1SDavid du Colombier 
1533e12c5d1SDavid du Colombier char *
memio(char * mb,ulong mem,int size,int dir)1543e12c5d1SDavid du Colombier memio(char *mb, ulong mem, int size, int dir)
1553e12c5d1SDavid du Colombier {
1563e12c5d1SDavid du Colombier 	int i;
1573e12c5d1SDavid du Colombier 	char *buf, c;
1583e12c5d1SDavid du Colombier 
1593e12c5d1SDavid du Colombier 	if(mb == 0)
1603e12c5d1SDavid du Colombier 		mb = emalloc(size);
1613e12c5d1SDavid du Colombier 
1623e12c5d1SDavid du Colombier 	buf = mb;
1633e12c5d1SDavid du Colombier 	switch(dir) {
1643e12c5d1SDavid du Colombier 	default:
1653e12c5d1SDavid du Colombier 		fatal(0, "memio");
1663e12c5d1SDavid du Colombier 	case MemRead:
1673e12c5d1SDavid du Colombier 		while(size--)
1683e12c5d1SDavid du Colombier 			*mb++ = getmem_b(mem++);
1693e12c5d1SDavid du Colombier 		break;
1703e12c5d1SDavid du Colombier 	case MemReadstring:
1713e12c5d1SDavid du Colombier 		for(;;) {
1723e12c5d1SDavid du Colombier 			if(size-- == 0) {
1733e12c5d1SDavid du Colombier 				Bprint(bioout, "memio: user/kernel copy too long for mipsim\n");
1743e12c5d1SDavid du Colombier 				longjmp(errjmp, 0);
1753e12c5d1SDavid du Colombier 			}
1763e12c5d1SDavid du Colombier 			c = getmem_b(mem++);
1773e12c5d1SDavid du Colombier 			*mb++ = c;
1783e12c5d1SDavid du Colombier 			if(c == '\0')
1793e12c5d1SDavid du Colombier 				break;
1803e12c5d1SDavid du Colombier 		}
1813e12c5d1SDavid du Colombier 		break;
1823e12c5d1SDavid du Colombier 	case MemWrite:
1833e12c5d1SDavid du Colombier 		for(i = 0; i < size; i++)
1843e12c5d1SDavid du Colombier 			putmem_b(mem++, *mb++);
1853e12c5d1SDavid du Colombier 		break;
1863e12c5d1SDavid du Colombier 	}
1873e12c5d1SDavid du Colombier 	return buf;
1883e12c5d1SDavid du Colombier }
1893e12c5d1SDavid du Colombier 
1903e12c5d1SDavid du Colombier void *
vaddr(ulong addr)1913e12c5d1SDavid du Colombier vaddr(ulong addr)
1923e12c5d1SDavid du Colombier {
1933e12c5d1SDavid du Colombier 	Segment *s, *es;
1943e12c5d1SDavid du Colombier 	int off, foff, l, n;
1953e12c5d1SDavid du Colombier 	uchar **p, *a;
1963e12c5d1SDavid du Colombier 
1973e12c5d1SDavid du Colombier 	es = &memory.seg[Nseg];
1983e12c5d1SDavid du Colombier 	for(s = memory.seg; s < es; s++) {
1993e12c5d1SDavid du Colombier 		if(addr >= s->base && addr < s->end) {
2003e12c5d1SDavid du Colombier 			s->refs++;
2013e12c5d1SDavid du Colombier 			off = (addr-s->base)/BY2PG;
2023e12c5d1SDavid du Colombier 			p = &s->table[off];
2033e12c5d1SDavid du Colombier 			if(*p)
2043e12c5d1SDavid du Colombier 				return *p;
2053e12c5d1SDavid du Colombier 			s->rss++;
2063e12c5d1SDavid du Colombier 			switch(s->type) {
2073e12c5d1SDavid du Colombier 			default:
2083e12c5d1SDavid du Colombier 				fatal(0, "vaddr");
2093e12c5d1SDavid du Colombier 			case Text:
2103e12c5d1SDavid du Colombier 				*p = emalloc(BY2PG);
2113e12c5d1SDavid du Colombier 				if(seek(text, s->fileoff+(off*BY2PG), 0) < 0)
2123e12c5d1SDavid du Colombier 					fatal(1, "vaddr text seek");
2133e12c5d1SDavid du Colombier 				if(read(text, *p, BY2PG) < 0)
2143e12c5d1SDavid du Colombier 					fatal(1, "vaddr text read");
2153e12c5d1SDavid du Colombier 				return *p;
2163e12c5d1SDavid du Colombier 			case Data:
2173e12c5d1SDavid du Colombier 				*p = emalloc(BY2PG);
2183e12c5d1SDavid du Colombier 				foff = s->fileoff+(off*BY2PG);
2193e12c5d1SDavid du Colombier 				if(seek(text, foff, 0) < 0)
2203e12c5d1SDavid du Colombier 					fatal(1, "vaddr text seek");
2213e12c5d1SDavid du Colombier 				n = read(text, *p, BY2PG);
2223e12c5d1SDavid du Colombier 				if(n < 0)
2233e12c5d1SDavid du Colombier 					fatal(1, "vaddr text read");
2243e12c5d1SDavid du Colombier 				if(foff + n > s->fileend) {
2253e12c5d1SDavid du Colombier 					l = BY2PG - (s->fileend-foff);
2263e12c5d1SDavid du Colombier 					a = *p+(s->fileend-foff);
2273e12c5d1SDavid du Colombier 					memset(a, 0, l);
2283e12c5d1SDavid du Colombier 				}
2293e12c5d1SDavid du Colombier 				return *p;
2303e12c5d1SDavid du Colombier 			case Bss:
2313e12c5d1SDavid du Colombier 			case Stack:
2323e12c5d1SDavid du Colombier 				*p = emalloc(BY2PG);
2333e12c5d1SDavid du Colombier 				return *p;
2343e12c5d1SDavid du Colombier 			}
2353e12c5d1SDavid du Colombier 		}
2363e12c5d1SDavid du Colombier 	}
2373e12c5d1SDavid du Colombier 	Bprint(bioout, "data_access_MMU_miss [addr 0x%.8lux]\n", addr);
2383e12c5d1SDavid du Colombier 	longjmp(errjmp, 0);
2393e12c5d1SDavid du Colombier 	return 0;		/*to stop compiler whining*/
2403e12c5d1SDavid du Colombier }
241