00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <assert.h>
00027 #include <iostream>
00028 #include <fstream>
00029 #include <sstream>
00030
00031
00032
00033 #include "flash.h"
00034 #include "helper.h"
00035 #include "memory.h"
00036 #include "avrerror.h"
00037
00038 void AvrFlash::Decode(){
00039 for(unsigned int addr = 0; addr < size ; addr += 2)
00040 Decode(addr);
00041 }
00042
00043 AvrFlash::AvrFlash(AvrDevice *c, int _size):
00044 Memory(_size),
00045 core(c),
00046 DecodedMem(_size),
00047 flashLoaded(false) {
00048 for(unsigned int tt = 0; tt < size; tt++)
00049 myMemory[tt] = 0xff;
00050 rww_lock = 0;
00051
00052 Decode();
00053 }
00054
00055 AvrFlash::~AvrFlash() {
00056 for(unsigned int i = 0; i < size; i++) {
00057 if(DecodedMem[i] != NULL)
00058 delete DecodedMem[i];
00059 }
00060 }
00061
00062 void AvrFlash::WriteMem(unsigned char *src, unsigned int offset, unsigned int secSize) {
00063 for(unsigned tt = 0; tt < secSize; tt += 2) {
00064 if(tt + offset < size) {
00065 assert(tt+offset+1<size);
00066 *(myMemory + tt + offset) = src[tt + 1];
00067 *(myMemory + tt + 1 + offset) = src[tt];
00068 }
00069 }
00070 Decode(offset, secSize);
00071 flashLoaded = true;
00072 }
00073
00074 void AvrFlash::WriteMemByte(unsigned char val, unsigned int offset) {
00075 assert(offset < size);
00076 *(myMemory + offset) = val;
00077 flashLoaded = true;
00078 }
00079
00080 DecodedInstruction* AvrFlash::GetInstruction(unsigned int pc) {
00081 if(IsRWWLock(pc * 2))
00082 avr_error("flash is locked (RWW lock)");
00083 return DecodedMem[pc];
00084 }
00085
00086 unsigned char AvrFlash::ReadMem(unsigned int offset) {
00087 if(IsRWWLock(offset)) {
00088 avr_warning("flash is locked (RWW lock)");
00089 return 0;
00090 }
00091 return myMemory[offset];
00092 }
00093
00094 unsigned int AvrFlash::ReadMemWord(unsigned int offset) {
00095
00096 assert(offset < size);
00097 if(IsRWWLock(offset)) {
00098 avr_warning("flash is locked (RWW lock)");
00099 return 0;
00100 }
00101 return (myMemory[offset] << 8) + myMemory[offset + 1];
00102 }
00103
00104 void AvrFlash::Decode(unsigned int offset, int secSize) {
00105 for(; (offset < size) && (secSize > 0); offset += 2, secSize -= 2)
00106 Decode(offset);
00107 }
00108
00109 void AvrFlash::Decode(unsigned int addr) {
00110 assert(0 <= addr && (unsigned)addr < size);
00111 assert((addr % 2) == 0);
00112 word opcode = (myMemory[addr] << 8) + myMemory[addr + 1];
00113 unsigned int index = addr / 2;
00114 if(DecodedMem[index] != NULL)
00115 delete DecodedMem[index];
00116 DecodedMem[index] = lookup_opcode(opcode, core);
00117 }
00118
00131 bool AvrFlash::LooksLikeContextSwitch(unsigned int addr) const
00132 {
00133 assert(addr < size);
00134 word index = addr/2;
00135 DecodedInstruction * instr = DecodedMem[index];
00136 avr_op_OUT * out_instr = dynamic_cast<avr_op_OUT*>(instr);
00137 if(out_instr == NULL)
00138 return false;
00139 bool is_SPL = (out_instr->ioreg == 0x3d);
00140 bool is_SPH = (out_instr->ioreg == 0x3e);
00141 if(! is_SPH && ! is_SPL)
00142 return false;
00143
00144 unsigned char out_R = out_instr->R1;
00145
00146 for(int i = 1; i < 8 && i <= index; i++) {
00147 instr = DecodedMem[index - i];
00148 byte Rlo = instr->GetModifiedR();
00149 byte Rhi = instr->GetModifiedRHi();
00150 if(out_R == Rlo || is_SPH && out_R == Rhi) {
00151
00152 return false;
00153 }
00154 }
00155
00156 return true;
00157 }