diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ki/mem.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ki/mem.c')
-rwxr-xr-x | sys/src/cmd/ki/mem.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/sys/src/cmd/ki/mem.c b/sys/src/cmd/ki/mem.c new file mode 100755 index 000000000..0ab7d580b --- /dev/null +++ b/sys/src/cmd/ki/mem.c @@ -0,0 +1,240 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <mach.h> +#define Extern extern +#include "sparc.h" + +extern ulong textbase; + +ulong +ifetch(ulong addr) +{ + uchar *va; + + if(addr&3) { + Bprint(bioout, "instruction_address_not_aligned [addr %.8lux]\n", addr); + longjmp(errjmp, 0); + } + + if(icache.on) + updateicache(addr); + + va = vaddr(addr); + iprof[(addr-textbase)/PROFGRAN]++; + + va += addr&(BY2PG-1); + + return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3]; +} + +ulong +getmem_4(ulong addr) +{ + ulong val; + int i; + + val = 0; + for(i = 0; i < 4; i++) + val = val<<8 | getmem_b(addr++); + return val; +} + +ulong +getmem_2(ulong addr) +{ + ulong val; + + val = getmem_b(addr); + val = val<<8 | getmem_b(addr+1); + + return val; +} + +ulong +getmem_w(ulong addr) +{ + uchar *va; + + if(addr&3) { + Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", addr); + longjmp(errjmp, 0); + } + if(membpt) + brkchk(addr, Read); + + va = vaddr(addr); + va += addr&(BY2PG-1); + + return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3];; +} + +ushort +getmem_h(ulong addr) +{ + uchar *va; + + if(addr&1) { + Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", addr); + longjmp(errjmp, 0); + } + if(membpt) + brkchk(addr, Read); + + va = vaddr(addr); + va += addr&(BY2PG-1); + + return va[0]<<8 | va[1]; +} + +uchar +getmem_b(ulong addr) +{ + uchar *va; + + if(membpt) + brkchk(addr, Read); + + va = vaddr(addr); + va += addr&(BY2PG-1); + return va[0]; +} + +void +putmem_w(ulong addr, ulong data) +{ + uchar *va; + + if(addr&3) { + Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", addr); + longjmp(errjmp, 0); + } + + va = vaddr(addr); + va += addr&(BY2PG-1); + + va[0] = data>>24; + va[1] = data>>16; + va[2] = data>>8; + va[3] = data; + if(membpt) + brkchk(addr, Write); +} +void +putmem_b(ulong addr, uchar data) +{ + uchar *va; + + va = vaddr(addr); + va += addr&(BY2PG-1); + va[0] = data; + if(membpt) + brkchk(addr, Write); +} + +void +putmem_h(ulong addr, short data) +{ + uchar *va; + + if(addr&1) { + Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", addr); + longjmp(errjmp, 0); + } + + va = vaddr(addr); + va += addr&(BY2PG-1); + va[0] = data>>8; + va[1] = data; + if(membpt) + brkchk(addr, Write); +} + +char * +memio(char *mb, ulong mem, int size, int dir) +{ + int i; + char *buf, c; + + if(mb == 0) + mb = emalloc(size); + + buf = mb; + switch(dir) { + default: + fatal(0, "memio"); + case MemRead: + while(size--) + *mb++ = getmem_b(mem++); + break; + case MemReadstring: + for(;;) { + if(size-- == 0) { + Bprint(bioout, "memio: user/kernel copy too long for mipsim\n"); + longjmp(errjmp, 0); + } + c = getmem_b(mem++); + *mb++ = c; + if(c == '\0') + break; + } + break; + case MemWrite: + for(i = 0; i < size; i++) + putmem_b(mem++, *mb++); + break; + } + return buf; +} + +void * +vaddr(ulong addr) +{ + Segment *s, *es; + int off, foff, l, n; + uchar **p, *a; + + es = &memory.seg[Nseg]; + for(s = memory.seg; s < es; s++) { + if(addr >= s->base && addr < s->end) { + s->refs++; + off = (addr-s->base)/BY2PG; + p = &s->table[off]; + if(*p) + return *p; + s->rss++; + switch(s->type) { + default: + fatal(0, "vaddr"); + case Text: + *p = emalloc(BY2PG); + if(seek(text, s->fileoff+(off*BY2PG), 0) < 0) + fatal(1, "vaddr text seek"); + if(read(text, *p, BY2PG) < 0) + fatal(1, "vaddr text read"); + return *p; + case Data: + *p = emalloc(BY2PG); + foff = s->fileoff+(off*BY2PG); + if(seek(text, foff, 0) < 0) + fatal(1, "vaddr text seek"); + n = read(text, *p, BY2PG); + if(n < 0) + fatal(1, "vaddr text read"); + if(foff + n > s->fileend) { + l = BY2PG - (s->fileend-foff); + a = *p+(s->fileend-foff); + memset(a, 0, l); + } + return *p; + case Bss: + case Stack: + *p = emalloc(BY2PG); + return *p; + } + } + } + Bprint(bioout, "data_access_MMU_miss [addr 0x%.8lux]\n", addr); + longjmp(errjmp, 0); + return 0; /*to stop compiler whining*/ +} |