simulavr  1.1.0
flashprog.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 "flashprog.h"
27 #include "avrdevice.h"
28 #include "systemclock.h"
29 #include "avrmalloc.h"
30 #include "flash.h"
31 
32 //#include <iostream>
33 //using namespace std;
34 
39 }
40 
41 void FlashProgramming::SetRWWLock(unsigned int addr) {
42  // no op, if not in ATMega mode
43  if(!isATMega)
44  return;
45  // set lock, if addr in RWW area
46  if(addr < (nrww_addr * 2)) {
47  spmcr_val |= 0x40;
49  }
50 }
51 
53  unsigned int pgsz,
54  unsigned int nrww,
55  int mode):
56  Hardware(c),
57  pageSize(pgsz),
58  nrww_addr(nrww),
59  core(c),
60  spmcr_reg(c, "SPMCR",
62 {
63  // initialize hidden buffer
64  tempBuffer = avr_new(unsigned char, pgsz * 2);
65  for(unsigned int i = 0; i < (pageSize * 2); i++)
66  tempBuffer[i] = 0xff;
67 
68  // set masks and modes
69  isATMega = (mode & SPM_MEGA_MODE) == SPM_MEGA_MODE;
70  spmcr_opr_bits = 0x1f;
71  if((mode & SPM_SIG_OPR) == SPM_SIG_OPR)
72  // extra operation on bit 5 available
73  spmcr_opr_bits |= 0x20;
75  if(isATMega)
76  // ATMega support SPMIE bit
77  spmcr_valid_bits |= 0x80;
78 
79  // reset processing engine
80  Reset();
81 
82  // add to cycle list
83  core->AddToCycleList(this);
84 }
85 
88 }
89 
91  // SPM or LPM enable timeout
92  if(opr_enable_count > 0) {
94  if(opr_enable_count == 0)
96  }
97  // process CPU lock
98  if(action == SPM_ACTION_LOCKCPU) {
99  if(SystemClock::Instance().GetCurrentTime() < timeout)
100  return 1;
102  }
103  return 0;
104 }
105 
107  spmcr_val = 0;
108  opr_enable_count = 0;
111  timeout = 0;
112 }
113 
114 unsigned char FlashProgramming::LPM_action(unsigned int xaddr, unsigned int addr) {
115  return 0;
116 }
117 
118 int FlashProgramming::SPM_action(unsigned int data, unsigned int xaddr, unsigned int addr) {
119 
120  // do nothing, if called from RWW section
121  unsigned int pc = core->PC;
122  if(pc < nrww_addr)
123  return 0; // SPM operation is disabled, if executed from RWW section
124 
125  // calculate full address (RAMPZ:Z)
126  addr = (addr & 0xffff) + (xaddr << 16);
127 
128  // process/start prepared operation
129  if(action == SPM_ACTION_PREPARE) {
130  opr_enable_count = 0;
131  if(spm_opr == SPM_OPS_UNLOCKRWW) {
133  spmcr_val &= ~0x40;
134  core->Flash->SetRWWLock(0);
135  //cout << "unlock rww: [0x" << hex << addr << "]" << endl;
136  return 0; // is this right, 1 cpu clock for this operation?
137  }
139  // calculate page offset
140  addr = addr & 0xfffe; // ignore LSB
141  addr &= (pageSize * 2) - 1;
142  // store data to buffer at offset
143  tempBuffer[addr] = data & 0xff;
144  tempBuffer[addr + 1] = (data >> 8) & 0xff;
145  // signal: operation done.
147  //cout << "store buffer: [0x" << hex << addr << "]=0x" << hex << data << endl;
148  return 2; // is this right, 3 cpu clocks for this operation?
149  }
151  // calculate page address
152  addr &= ~((pageSize * 2) - 1);
153  // store temp buffer to flash
154  core->Flash->WriteMem(tempBuffer, addr, pageSize * 2);
155  // calculate system time, where operation is finished
157  // lock cpu while writing flash
159  // lock RWW, if necessary
160  SetRWWLock(addr);
161  //cout << "write buffer: [0x" << hex << addr << "]" << endl;
162  return 0; // cpu clocks will be extended by CpuCycle calls
163  }
164  if(spm_opr == SPM_OPS_ERASE) {
165  // calculate page address
166  addr &= ~((pageSize * 2) - 1);
167  // erase temp. buffer and store to flash
168  for(unsigned int i = 0; i < (pageSize * 2); i++)
169  tempBuffer[i] = 0xff;
170  core->Flash->WriteMem(tempBuffer, addr, pageSize * 2);
171  // calculate system time, where operation is finished
173  // lock cpu while erasing flash
175  // lock RWW, if necessary
176  SetRWWLock(addr);
177  //cout << "erase page: [0x" << hex << addr << "]" << endl;
178  return 0; // cpu clocks will be extended by CpuCycle calls
179  }
180  //cout << "unhandled spm-action(0x" << hex << data << ",0x" << hex << addr << ")" << endl;
182  }
183  return 0;
184 }
185 
186 void FlashProgramming::SetSpmcr(unsigned char v) {
188 
189  // calculate operation
190  if(action == SPM_ACTION_NOOP) {
191  opr_enable_count = 4;
193  switch(spmcr_val & spmcr_opr_bits) {
194  case 0x1:
196  break;
197 
198  case 0x3:
200  break;
201 
202  case 0x5:
204  break;
205 
206  case 0x9:
208  break;
209 
210  case 0x11:
211  if(isATMega)
213  else
215  break;
216 
217  case 0x21:
219  break;
220 
221  default:
223  if(!(spmcr_val & 0x1)) {
224  opr_enable_count = 0;
226  }
227  break;
228  }
229  }
230  //cout << "spmcr=0x" << hex << (unsigned int)spmcr_val << "," << action << "," << spm_opr << endl;
231 }
232 
234  fuseBitsSize(2),
235  fuseBits(0xfffffffd),
236  nrwwAddr(0),
237  nrwwSize(0),
238  bitPosBOOTSZ(-1),
239  bitPosBOOTRST(-1),
240  flagBOOTRST(true),
241  valueBOOTSZ(0)
242 {
243  // do nothing!
244 }
245 
246 void AvrFuses::SetFuseConfiguration(int size, unsigned long defvalue) {
247  fuseBitsSize = size;
248  fuseBits = defvalue;
249 }
250 
251 bool AvrFuses::LoadFuses(const unsigned char *buffer, int size) {
252  int fSize = ((fuseBitsSize - 1) / 8) + 1;
253 
254  // check buffer size
255  if(fSize != size)
256  return false;
257 
258  // store fuse values
259  fuseBits = 0;
260  for(int i = (fSize - 1); i >= 0; --i) {
261  fuseBits <<= 8;
262  fuseBits |= buffer[i];
263  }
264 
265  // update fuse values for some fuse bits
267  flagBOOTRST = ((fuseBits >> bitPosBOOTRST) & 0x1) == 0x1;
268  if(bitPosBOOTSZ != -1 && bitPosBOOTSZ < fuseBitsSize)
269  valueBOOTSZ = (fuseBits >> bitPosBOOTSZ) & 0x3;
270 
271  return true;
272 }
273 
274 void AvrFuses::SetBootloaderConfig(unsigned addr, int size, int bPosBOOTSZ, int bPosBOOTRST) {
275  nrwwAddr = addr;
276  nrwwSize = size;
277  bitPosBOOTSZ = bPosBOOTSZ;
278  bitPosBOOTRST = bPosBOOTRST;
279 }
280 
281 unsigned int AvrFuses::GetBLSStart(void) {
282  unsigned int addr = nrwwAddr;
283  unsigned int size = nrwwSize;
284 
285  if(addr == 0)
286  // if SPM functionality enabled and no rww functionality available, full flash is
287  // used as nrww area, so "BLS" starts from flash start
288  return 0;
289  if(valueBOOTSZ == 0)
290  return addr;
291  size >>= 1;
292  addr += size;
293  if(valueBOOTSZ == 1)
294  return addr;
295  size >>= 1;
296  addr += size;
297  if(valueBOOTSZ == 2)
298  return addr;
299  size >>= 1;
300  return addr + size;
301 }
302 
303 unsigned int AvrFuses::GetResetAddr(void) {
304  if(flagBOOTRST)
305  return 0;
306  else
307  return GetBLSStart();
308 }
309 
311  lockBitsSize(2),
312  lockBits(0xff)
313 {
314  // do nothing!
315 }
316 
318  lockBitsSize = size;
319 }
320 
321 bool AvrLockBits::LoadLockBits(const unsigned char *buffer, int size) {
322  int lBSize = 1; // current not more than 8 bit!
323  // check buffer size
324  if(lBSize != size)
325  return false;
326  // load lock bits
327  lockBits = buffer[0];
328  return true;
329 }
330 
331 void AvrLockBits::SetLockBits(unsigned char bits) {
332  // bits can only set to 0, not back to 1 by this operation! Unused bits are set to 1.
333  lockBits = (lockBits & bits) | ~((1 << lockBitsSize) - 1);
334 }
335 
336 // EOF
AvrFlash * Flash
Definition: avrdevice.h:98
FlashProgramming(AvrDevice *c, unsigned int pgsz, unsigned int nrww, int mode)
Create a instance of FlashProgramming class.
Definition: flashprog.cpp:52
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
void AddToCycleList(Hardware *hw)
Definition: avrdevice.cpp:51
AvrFuses(void)
Definition: flashprog.cpp:233
unsigned char spmcr_opr_bits
mask for operation bits, including SPMEN bit
Definition: flashprog.h:62
unsigned char * tempBuffer
hidden buffer for flash page operations
Definition: flashprog.h:69
SystemClockOffset GetCurrentTime() const
Returns the current simulation time.
Definition: systemclock.h:95
int lockBitsSize
count of lock bits
Definition: flashprog.h:141
void avr_free(void *ptr)
Free malloc&#39;d memory.
Definition: avrmalloc.cpp:182
void WriteMem(const unsigned char *src, unsigned int addr, unsigned int secSize)
Definition: flash.cpp:62
bool isATMega
Flag: true, if in ATMega mode, if false, it&#39;s ATTiny mode.
Definition: flashprog.h:70
int valueBOOTSZ
value of BOOTSZ fuse bits
Definition: flashprog.h:110
int bitPosBOOTRST
bit position BOOTRST fuses (1 Bit) in fuseBits
Definition: flashprog.h:108
unsigned char spmcr_valid_bits
mask for valid bits
Definition: flashprog.h:63
bool flagBOOTRST
value of BOOTRST fuse bit
Definition: flashprog.h:109
unsigned char LPM_action(unsigned int xaddr, unsigned int addr)
Definition: flashprog.cpp:114
void SetFuseConfiguration(int size, unsigned long defvalue)
Configure fuses.
Definition: flashprog.cpp:246
AvrLockBits(void)
Definition: flashprog.cpp:310
unsigned char lockBits
lock bits data
Definition: flashprog.h:142
void SetLockBits(unsigned char bits)
Set lock bits (from a SPM instruction)
Definition: flashprog.cpp:331
unsigned int GetBLSStart(void)
Get start address of bootloader section.
Definition: flashprog.cpp:281
bool LoadLockBits(const unsigned char *buffer, int size)
Initialize lock bits from elf, checks proper size.
Definition: flashprog.cpp:321
SystemClockOffset timeout
system time till operation run
Definition: flashprog.h:68
int opr_enable_count
enable counter for SPM operation
Definition: flashprog.h:64
unsigned char spmcr_val
holds the register value
Definition: flashprog.h:61
SPM_OPStype spm_opr
selected SPM operation
Definition: flashprog.h:66
void SetRWWLock(unsigned int addr)
Definition: flash.h:83
static SystemClock & Instance()
Returns the central SystemClock instance for the application.
SPM_ACTIONtype action
state of the processing engine
Definition: flashprog.h:65
void ClearOperationBits(void)
Definition: flashprog.cpp:35
unsigned int GetResetAddr(void)
Get reset address.
Definition: flashprog.cpp:303
void SetLockBitsConfiguration(int size)
Configure lock bits.
Definition: flashprog.cpp:317
unsigned int CpuCycle()
Definition: flashprog.cpp:90
#define avr_new(type, count)
Macro for allocating memory.
Definition: avrmalloc.h:40
unsigned int nrwwSize
size of NRWW section in byte
Definition: flashprog.h:106
void SetRWWLock(unsigned int addr)
Definition: flashprog.cpp:41
void SetSpmcr(unsigned char v)
Definition: flashprog.cpp:186
int bitPosBOOTSZ
bit position BOOTSZ fuses (2 Bit) in fuseBits
Definition: flashprog.h:107
Provides the programming engine for flash self programming.
Definition: flashprog.h:38
void SetBootloaderConfig(unsigned addr, int size, int bPosBOOTSZ, int bPosBOOTRST)
Set bootloader support configuration.
Definition: flashprog.cpp:274
int SPM_action(unsigned int data, unsigned int xaddr, unsigned int addr)
Definition: flashprog.cpp:118
unsigned int pageSize
page size in words
Definition: flashprog.h:59
unsigned int nrwwAddr
start address NRWW section
Definition: flashprog.h:105
unsigned int nrww_addr
start address of non RWW area of flash (word address)
Definition: flashprog.h:60
unsigned int PC
Definition: avrdevice.h:93
unsigned char GetSpmcr()
Definition: flashprog.h:93
bool LoadFuses(const unsigned char *buffer, int size)
Initialize fuses from elf, checks proper size.
Definition: flashprog.cpp:251
int fuseBitsSize
count of bits in fuses
Definition: flashprog.h:103
AvrDevice * core
link to AvrDevice
Definition: flashprog.h:67
unsigned long fuseBits
fuse data
Definition: flashprog.h:104
IOReg< FlashProgramming > spmcr_reg
Definition: flashprog.h:95