URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cpu/] [common/] [abstract.c] - Rev 206
Go to most recent revision | Compare with Previous | Blame | View Log
/* abstract.c -- Abstract entities Copyright (C) 1999 Damjan Lampret, lampret@opencores.org This file is part of OpenRISC 1000 Architectural Simulator. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Abstract memory and routines that go with this. I need to add all sorts of other abstract entities. Currently we have only memory. */ #include <stdio.h> #include <ctype.h> #include <string.h> #include "config.h" #include "sim-config.h" #include "parse.h" #include "abstract.h" #include "arch.h" #include "trace.h" #include "execute.h" #include "sprs.h" #include "stats.h" #include "except.h" #include "debug_unit.h" #include "opcode/or32.h" extern unsigned long reg[]; extern unsigned long pc_phy; extern char *disassembled; static char* build_format(int len,char* buffer,int offset,unsigned char* data) { int i; char sTemp[256]; sprintf(buffer," %4x: ",offset); for(i=0;i<16;i++) { if(i < len) { sprintf(sTemp,"%02x",data[i]); strcat(buffer,sTemp); } else strcat(buffer," "); if(i & 0x01) strcat(buffer," "); } strcat(buffer," %s\n"); } static char* BytesToAscii(char* s,int len,char* buffer) { int i; for(i=0;i<len;i++) buffer[i] = isprint(s[i]) ? s[i] : '.'; buffer[i] = '\0'; return buffer; } static void DumpAsciiToDescriptor(int fd,char* buffer,int len) { int i; char format_buf[256]; char ascii_buf[256]; char* format; char sTemp[256]; sprintf(sTemp," 00 02 04 06 08 0A 0C 0E ASCII\n"); write(fd,sTemp,strlen(sTemp)); sprintf(sTemp," ----- ---- ---- ---- ---- ---- ---- ---- ---- ----------------\n"); write(fd,sTemp,strlen(sTemp)); for(i=0;i<len;i+=16,buffer+=16) { int max = len-i; if(max > 16) max = 16; format = build_format(max,format_buf,i,buffer); sprintf(sTemp,format,BytesToAscii((char*)buffer,max,ascii_buf)); write(fd,sTemp,strlen(sTemp)); } } static void DebugDump() { char buffer[1024]; unsigned long startmem = reg[1]; int i; printf(" r0 r1 r2 r3 r4 r5 r6 r7\n"); printf("-------- -------- -------- -------- -------- -------- -------- --------\n"); printf("%08x %08x %08x %08x %08x %08x %08x %08x\n\n",reg[0],reg[1],reg[2], reg[3],reg[4],reg[5],reg[6],reg[7]); printf(" r8 r9 r10 r11 r12 r13 r14 r15\n"); printf("-------- -------- -------- -------- -------- -------- -------- --------\n"); printf("%08x %08x %08x %08x %08x %08x %08x %08x\n\n",reg[8],reg[9],reg[10], reg[11],reg[12],reg[13],reg[14],reg[15]); for(i=0;i<sizeof(buffer);i++) { if(startmem+i >= MEMORY_START + MEMORY_LEN) break; buffer[i] = mem[startmem+i].data; } printf("Hex dump of stack memory:\n"); DumpAsciiToDescriptor(fileno(stdout),buffer,i); } /* This is an abstract+physical memory array rather than only physical memory array */ struct mem_entry mem[MEMORY_LEN]; /* Pointer to memory area descriptions that are assigned to individual peripheral devices. */ struct dev_memarea *dev_list; void dumpmemory(unsigned int from, unsigned int to, int disasm) { unsigned int i, j; struct label_entry *tmp; int breakpoint = 0; for(i = from; i < to && i < (MEMORY_START + MEMORY_LEN);) { int breakpoint; unsigned int _insn = eval_mem32(i, &breakpoint); int index = insn_decode (_insn); int len = insn_len(index); if (!len) len = 8; printf("\n%.8x: ", i); for (j = 0; j < len; j++) { if (disasm) { tmp = mem[i+j].label; for(; tmp; tmp = tmp->next) printf(" %s%s", tmp->name, LABELEND_CHAR); printf("%02x", (unsigned char)mem[i+j].data); } else { /* don't print ascii chars below 0x20. */ if (mem[i+j].data < 0x20) printf("%02x ", (unsigned char)mem[i+j].data); else printf("%02x'%c' ", (unsigned char)mem[i+j].data, mem[i+j].data); } } if (disasm && index >= 0) { disassemble_insn (_insn); printf(" %s", disassembled); } i += len; } } /* Searches mem array for a particular label and returns label's address. If label does not exist, returns 0. */ unsigned long eval_label(char *label) { int i; char *plus; char *minus; int positive_offset = 0; int negative_offset = 0; struct label_entry *tmp; if (plus = strchr(label, '+')) { *plus = '\0'; positive_offset = atoi(++plus); } if (minus = strchr(label, '-')) { *minus = '\0'; negative_offset = atoi(++minus); } for(i = 0; i < (MEMORY_START + MEMORY_LEN); i++) { tmp = mem[i].label; for(; tmp; tmp = tmp->next) if (strcmp(label, tmp->name) == 0) { debug("eval_label(%s) => 0x%x\n", label, i+positive_offset-negative_offset); return i+positive_offset-negative_offset; } } printf("\nINTERNAL ERROR: undefined label %s\n", label); cont_run = 0; return 0; } /* Calls IMMU translation routines before simulating insn cache for virtually indexed insn cache or after simulating insn cache for physically indexed insn cache. It returns physical address. */ unsigned long simulate_ic_mmu_fetch(unsigned long virtaddr) { if (config.ic.tagtype == NONE) return virtaddr; else if (config.ic.tagtype == VIRTUAL) { ic_simulate_fetch(virtaddr); return immu_translate(virtaddr); } else if (config.dc.tagtype == PHYSICAL) { unsigned long phyaddr = immu_translate(virtaddr); ic_simulate_fetch(phyaddr); return phyaddr; } else { printf("INTERNAL ERROR: Unknown insn cache type.\n"); cont_run = 0; } return -1; } /* Calls DMMU translation routines (load cycles) before simulating data cache for virtually indexed data cache or after simulating data cache for physically indexed data cache. It returns physical address. */ unsigned long simulate_dc_mmu_load(unsigned long virtaddr) { if (config.dc.tagtype == NONE) return virtaddr; else if (config.dc.tagtype == VIRTUAL) { dc_simulate_read(virtaddr); return dmmu_translate(virtaddr); } else if (config.dc.tagtype == PHYSICAL) { unsigned long phyaddr = dmmu_translate(virtaddr); dc_simulate_read(phyaddr); return phyaddr; } else { printf("INTERNAL ERROR: Unknown data cache type.\n"); cont_run = 0; } return -1; } /* Calls DMMU translation routines (store cycles) before simulating data cache for virtually indexed data cache or after simulating data cache for physically indexed data cache. It returns physical address. */ unsigned long simulate_dc_mmu_store(unsigned long virtaddr) { if (config.dc.tagtype == NONE) return virtaddr; else if (config.dc.tagtype == VIRTUAL) { dc_simulate_write(virtaddr); return dmmu_translate(virtaddr); } else if (config.dc.tagtype == PHYSICAL) { unsigned long phyaddr = dmmu_translate(virtaddr); dc_simulate_write(phyaddr); return phyaddr; } else { printf("INTERNAL ERROR: Unknown data cache type.\n"); cont_run = 0; } return -1; } /* Register read and write function for a memory area (used by peripheral devices like 16450 UART etc.) */ void register_memoryarea(unsigned long baseaddr, unsigned long size, unsigned long (readfunc)(unsigned long), void (writefunc)(unsigned long, unsigned long)) { struct dev_memarea **pptmp; /* Go to the end of the list. */ for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next); *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea)); (*pptmp)->baseaddr = baseaddr; (*pptmp)->size = size; (*pptmp)->readfunc = readfunc; (*pptmp)->writefunc = writefunc; (*pptmp)->next = NULL; return; } /* Check if access is to registered area of memory. */ struct dev_memarea *verify_memoryarea(unsigned long addr) { struct dev_memarea *ptmp; /* Check list of registered devices. */ for(ptmp = dev_list; ptmp; ptmp = ptmp->next) if (addr >= ptmp->baseaddr && addr < (ptmp->baseaddr + ptmp->size)) return ptmp; return NULL; } /* Returns 32-bit values from mem array. Big endian version. */ unsigned long eval_mem32(unsigned long memaddr,int* breakpoint) { unsigned long temp; struct dev_memarea *dev; slp_checkaccess(memaddr, SLP_MEMREAD); memaddr = simulate_dc_mmu_load(memaddr); *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */ return evalsim_mem32(memaddr,breakpoint); } unsigned long evalsim_mem32(unsigned long memaddr,int* breakpoint) { unsigned long temp; struct dev_memarea *dev; if (memaddr < (MEMORY_START + MEMORY_LEN)) { temp = mem[memaddr].data << 24; temp += mem[memaddr + 1].data << 16; temp += mem[memaddr + 2].data << 8; temp += mem[memaddr + 3].data; } else if (dev = verify_memoryarea(memaddr)) { temp = dev->readfunc(memaddr); } else { printf("EXCEPTION @ <0x%06x>: read out of memory (32-bit access to %.8lx)\n", pc_phy, memaddr); DebugDump(); cont_run = 0; temp = 0; } *breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */ return temp; } /* Returns 16-bit values from mem array. Big endian version. */ unsigned short eval_mem16(unsigned long memaddr,int* breakpoint) { memaddr = simulate_dc_mmu_load(memaddr); *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */ return evalsim_mem16(memaddr,breakpoint); } unsigned short evalsim_mem16(unsigned long memaddr,int* breakpoint) { unsigned short temp; if (memaddr < (MEMORY_START + MEMORY_LEN)) { temp = ((unsigned short)(mem[memaddr].data << 8) & 0xff00); temp += ((unsigned short)mem[memaddr + 1].data & 0x00ff); } else { printf("EXCEPTION @ <0x%06x>: read out of memory (16-bit access to %.8lx)\n", pc_phy,memaddr); DebugDump(); cont_run = 0; temp = 0; } *breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */ return temp; } /* Returns 8-bit values from mem array. */ unsigned char eval_mem8(unsigned long memaddr,int* breakpoint) { memaddr = simulate_dc_mmu_load(memaddr); *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */ return evalsim_mem8(memaddr,breakpoint); } unsigned char evalsim_mem8(unsigned long memaddr,int* breakpoint) { unsigned char temp; if (memaddr < (MEMORY_START + MEMORY_LEN)) { temp = (unsigned char)mem[memaddr].data; } else { printf("EXCEPTION @ <0x%06x>: read out of memory (8-bit access to %.8lx)\n", pc_phy,memaddr); DebugDump(); cont_run = 0; temp = 0; } *breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */ return temp; } /* Set mem, 32-bit. Big endian version. */ void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint) { slp_checkaccess(memaddr, SLP_MEMWRITE); memaddr = simulate_dc_mmu_store(memaddr); *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */ *breakpoint += CheckDebugUnit(DebugStoreData,value); setsim_mem32(memaddr, value); return; } void setsim_mem32(unsigned long memaddr, unsigned long value) { struct dev_memarea *dev; if (memaddr < (MEMORY_START + MEMORY_LEN)) { mem[memaddr].data = (value >> 24); mem[memaddr + 1].data = (char)(value >> 16); mem[memaddr + 2].data = (char)(value >> 8); mem[memaddr + 3].data = (char)(value); } else if (dev = verify_memoryarea(memaddr)) { dev->writefunc(memaddr, value); } else { printf("EXCEPTION @ <0x%06x>: write out of memory (32-bit access to %.8lx)\n", pc_phy, memaddr); DebugDump(); cont_run = 0; } return; } /* Set mem, 16-bit. Big endian version. */ void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint) { memaddr = simulate_dc_mmu_store(memaddr); *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */ *breakpoint += CheckDebugUnit(DebugStoreData,value); setsim_mem16(memaddr, value); return; } void setsim_mem16(unsigned long memaddr, unsigned short value) { if (memaddr < (MEMORY_START + MEMORY_LEN)) { mem[memaddr].data = (value >> 8); mem[memaddr + 1].data = (char)(value); } else { printf("EXCEPTION @ <0x%06x>: write out of memory (16-bit access to %.8lx)\n",pc_phy, memaddr); DebugDump(); cont_run = 0; } return; } /* Set mem, 8-bit. */ void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint) { memaddr = simulate_dc_mmu_store(memaddr); *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */ *breakpoint += CheckDebugUnit(DebugStoreData,value); setsim_mem8(memaddr, value); return; } void setsim_mem8(unsigned long memaddr, unsigned char value) { if (memaddr < (MEMORY_START + MEMORY_LEN)) { mem[memaddr].data = value; } else { printf("EXCEPTION @ <0x%06x>: write out of memory (8-bit access to %.8lx)\n", pc_phy,memaddr); DebugDump(); cont_run = 0; } return; }
Go to most recent revision | Compare with Previous | Blame | View Log