simulavr  1.1.0
flash.cpp
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
5  * Copyright (C) 2001, 2002, 2003 Klaus Rudolph
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  ****************************************************************************
22  *
23  * $Id$
24  */
25 
26 #include <assert.h>
27 #include <iostream>
28 #include <fstream>
29 #include <sstream>
30 
31 
32 
33 #include "flash.h"
34 #include "helper.h"
35 #include "memory.h"
36 #include "avrerror.h"
37 
39  for(unsigned int addr = 0; addr < size ; addr += 2)
40  Decode(addr);
41 }
42 
44  Memory(_size),
45  core(c),
46  DecodedMem(_size),
47  flashLoaded(false) {
48  for(unsigned int tt = 0; tt < size; tt++)
49  myMemory[tt] = 0xff; // Safeguard, will be decoded as avr_op_ILLEGAL
50  rww_lock = 0;
51  // initialize DecodedMem
52  Decode();
53 }
54 
56  for(unsigned int i = 0; i < size; i++) {
57  if(DecodedMem[i] != NULL)
58  delete DecodedMem[i]; // delete Instruction
59  }
60 }
61 
62 void AvrFlash::WriteMem(const unsigned char *src, unsigned int offset, unsigned int secSize) {
63  for(unsigned tt = 0; tt < secSize; tt += 2) {
64  if(tt + offset < size) {
65  assert(tt+offset+1<size);
66  *(myMemory + tt + offset) = src[tt + 1];
67  *(myMemory + tt + 1 + offset) = src[tt];
68  }
69  }
70  Decode(offset, secSize);
71  flashLoaded = true;
72 }
73 
74 void AvrFlash::WriteMemByte(unsigned char val, unsigned int offset) {
75  assert(offset < size); // in bytes
76  *(myMemory + offset) = val;
77  flashLoaded = true;
78 }
79 
81  if(IsRWWLock(pc * 2))
82  avr_error("flash is locked (RWW lock)");
83  return DecodedMem[pc];
84 }
85 
86 unsigned char AvrFlash::ReadMem(unsigned int offset) {
87  if(IsRWWLock(offset)) {
88  avr_warning("flash is locked (RWW lock)");
89  return 0;
90  }
91  return myMemory[offset];
92 }
93 
94 unsigned int AvrFlash::ReadMemWord(unsigned int offset) {
95  // example: "lds r24, 0x013B" is 91 80 01 3b, we return 0x013B.
96  assert(offset < size); // in bytes
97  if(IsRWWLock(offset)) {
98  avr_warning("flash is locked (RWW lock)");
99  return 0;
100  }
101  return (myMemory[offset] << 8) + myMemory[offset + 1];
102 }
103 
104 void AvrFlash::Decode(unsigned int offset, int secSize) {
105  for(; (offset < size) && (secSize > 0); offset += 2, secSize -= 2)
106  Decode(offset);
107 }
108 
109 void AvrFlash::Decode(unsigned int addr) {
110  assert((unsigned)addr < size);
111  assert((addr % 2) == 0);
112  word opcode = (myMemory[addr] << 8) + myMemory[addr + 1];
113  unsigned int index = addr / 2;
114  if(DecodedMem[index] != NULL)
115  delete DecodedMem[index]; //delete old Instruction here
116  DecodedMem[index] = lookup_opcode(opcode, core); //and set new one
117 }
118 
131 bool AvrFlash::LooksLikeContextSwitch(unsigned int addr) const
132 {
133  assert(addr < size);
134  word index = addr/2;
135  DecodedInstruction * instr = DecodedMem[index];
136  avr_op_OUT * out_instr = dynamic_cast<avr_op_OUT*>(instr);
137  if(out_instr == NULL)
138  return false;
139  bool is_SPL = (out_instr->ioreg == 0x3d); // SPL register (0x5d)
140  bool is_SPH = (out_instr->ioreg == 0x3e); // SPH register (0x5e)
141  if(! is_SPH && ! is_SPL)
142  return false;
143 
144  unsigned char out_R = out_instr->R1; // We have "OUT SP, R"
145 
146  for(int i = 1; i < 8 && i <= index; i++) {
147  instr = DecodedMem[index - i];
148  byte Rlo = instr->GetModifiedR(); // "sbiw r28:r29, 42" returns 28
149  byte Rhi = instr->GetModifiedRHi(); // "sbiw r28:r29, 42" returns 29
150  if(out_R == Rlo || (is_SPH && out_R == Rhi)) {
151  // TODO: LD, LDD, LDS indicate switch (not LDI)
152  return false; // The "OUT" insn is in prologue/epilogue.
153  }
154  }
155 
156  return true;
157 }
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
unsigned char * myMemory
Definition: memory.h:45
virtual unsigned char GetModifiedR() const
If this instruction modifies a R0-R31 register then return its number, otherwise -1.
Definition: decoder.h:57
unsigned char byte
Definition: types.h:26
unsigned short word
Definition: types.h:27
unsigned int ReadMemWord(unsigned int addr)
Definition: flash.cpp:94
void WriteMem(const unsigned char *src, unsigned int addr, unsigned int secSize)
Definition: flash.cpp:62
unsigned char ioreg
Definition: decoder.h:1378
virtual unsigned char GetModifiedRHi() const
If this instruction modifies a pair of R0-R31 registers then ...
Definition: decoder.h:59
AvrFlash(AvrDevice *c, int size)
Definition: flash.cpp:43
void WriteMemByte(unsigned char val, unsigned int address)
Definition: flash.cpp:74
AvrDevice * core
Definition: flash.h:41
#define avr_error(...)
Definition: avrerror.h:135
std::vector< DecodedInstruction * > DecodedMem
Definition: flash.h:42
bool flashLoaded
Flag, true if there was a write to Flash after constructor call (program load)
Definition: flash.h:44
DecodedInstruction * GetInstruction(unsigned int pc)
Definition: flash.cpp:80
unsigned int rww_lock
When Flash write is in progress then addresses below this are inaccesible, otherwise 0...
Definition: flash.h:43
bool IsRWWLock(unsigned int addr)
Definition: flash.h:79
~AvrFlash()
Definition: flash.cpp:55
Base class of core instruction.
Definition: decoder.h:39
unsigned char R1
Definition: decoder.h:1379
unsigned int size
Definition: memory.h:41
bool LooksLikeContextSwitch(unsigned int addr) const
Definition: flash.cpp:131
void Decode()
Definition: flash.cpp:38
unsigned char ReadMem(unsigned int addr)
Definition: flash.cpp:86
Hold a memory block and symbol informations.
Definition: memory.h:38
#define avr_warning(...)
Definition: avrerror.h:133
DecodedInstruction * lookup_opcode(word opcode, AvrDevice *core)
Translates an opcode to a instance of DecodedInstruction.
Definition: decoder.cpp:1949