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 #ifndef _MSC_VER
00027 # include "config.h"
00028 # include "bfd.h"
00029 #else
00030
00031 #endif
00032
00033 #include "avrdevice.h"
00034 #include "traceval.h"
00035 #include "helper.h"
00036 #include "global.h"
00037 #include "irqsystem.h"
00038 #include "systemclock.h"
00039 #include "avrerror.h"
00040 #include "avrmalloc.h"
00041 #include <assert.h>
00042
00043 #include "avrdevice_impl.h"
00044
00045 using namespace std;
00046
00047 const unsigned int AvrDevice::registerSpaceSize = 32;
00048 const unsigned int AvrDevice::totalIoSpace = 0x10000;
00049
00050 void AvrDevice::AddToResetList(Hardware *hw) {
00051 if(find(hwResetList.begin(), hwResetList.end(), hw) == hwResetList.end())
00052 hwResetList.push_back(hw);
00053 }
00054
00055 void AvrDevice::AddToCycleList(Hardware *hw) {
00056 if(find(hwCycleList.begin(), hwCycleList.end(), hw) == hwCycleList.end())
00057 hwCycleList.push_back(hw);
00058 }
00059
00060 void AvrDevice::RemoveFromCycleList(Hardware *hw) {
00061 vector<Hardware*>::iterator element;
00062 element=find(hwCycleList.begin(), hwCycleList.end(), hw);
00063 if(element != hwCycleList.end())
00064 hwCycleList.erase(element);
00065 }
00066
00067 #ifdef _MSC_VER
00068
00069
00070 #define EI_NIDENT 16
00071
00072 #define PT_NULL 0
00073 #define PT_LOAD 1
00074 #define PT_NOTE 4
00075 #define PT_SHLIB 5
00076 #define PT_PHDR 6
00077
00078 #define PF_X 1
00079 #define PF_W 2
00080 #define PF_R 4
00081
00082 typedef uint32_t Elf32_Addr;
00083 typedef uint16_t Elf32_Half;
00084 typedef uint32_t Elf32_Off;
00085 typedef int32_t Elf32_Sword;
00086 typedef uint32_t Elf32_Word;
00087
00088 typedef struct {
00089 unsigned char e_ident[EI_NIDENT];
00090 Elf32_Half e_type;
00091 Elf32_Half e_machine;
00092 Elf32_Word e_version;
00093 Elf32_Addr e_entry;
00094 Elf32_Off e_phoff;
00095 Elf32_Off e_shoff;
00096 Elf32_Word e_flags;
00097 Elf32_Half e_ehsize;
00098 Elf32_Half e_phentsize;
00099 Elf32_Half e_phnum;
00100 Elf32_Half e_shentsize;
00101 Elf32_Half e_shnum;
00102 Elf32_Half e_shstrndx;
00103 } Elf32_Ehdr;
00104
00105 typedef struct {
00106 Elf32_Word p_type;
00107 Elf32_Off p_offset;
00108 Elf32_Addr p_vaddr;
00109 Elf32_Addr p_paddr;
00110 Elf32_Word p_filesz;
00111 Elf32_Word p_memsz;
00112 Elf32_Word p_flags;
00113 Elf32_Word p_align;
00114 } Elf32_Phdr;
00115 #endif
00116
00117 void AvrDevice::Load(const char* fname) {
00118 actualFilename = fname;
00119
00120 #ifdef _MSC_VER
00121 FILE * f = fopen(fname, "rb");
00122 if(f == NULL)
00123 avr_error("Could not open file: %s", fname);
00124
00125 Elf32_Ehdr header;
00126 fread(&header, sizeof(header), 1, f);
00127 if(header.e_ident[0] != 0x7F || header.e_ident[1] != 'E'
00128 || header.e_ident[2] != 'L' || header.e_ident[3] != 'F')
00129 avr_error("File '%s' is not an ELF file", fname);
00130
00131 if(header.e_machine != 83)
00132 avr_error("ELF file '%s' is not for Atmel AVR architecture (%d)", fname, header.e_machine);
00133
00134 for(int i = 0; i < header.e_phnum; i++) {
00135 fseek(f, header.e_phoff + i * header.e_phentsize, SEEK_SET);
00136 Elf32_Phdr progHeader;
00137 fread(&progHeader, sizeof(progHeader), 1, f);
00138
00139 if(progHeader.p_type != PT_LOAD)
00140 continue;
00141 if((progHeader.p_flags & PF_X ) == 0 || (progHeader.p_flags & PF_R) == 0)
00142 continue;
00143 if(progHeader.p_vaddr >= 0x80ffff)
00144 continue;
00145 if(progHeader.p_filesz != progHeader.p_memsz) {
00146 avr_error("Segment sizes 0x%x and 0x%x in ELF file '%s' must be the same",
00147 progHeader.p_filesz, progHeader.p_memsz);
00148 }
00149 unsigned char * tmp = new unsigned char[progHeader.p_filesz];
00150 fseek(f, progHeader.p_offset, SEEK_SET);
00151 fread(tmp, progHeader.p_filesz, 1, f);
00152
00153 Flash->WriteMem(tmp, progHeader.p_vaddr, progHeader.p_filesz);
00154 delete [] tmp;
00155 }
00156
00157 fclose(f);
00158 #else
00159
00160
00161
00162
00163 bfd *abfd;
00164 asection *sec;
00165
00166 bfd_init();
00167 abfd=bfd_openr(fname, NULL);
00168
00169 if(abfd == NULL)
00170 avr_error("Could not open file: %s", fname);
00171
00172 if(bfd_check_format(abfd, bfd_object) == FALSE)
00173 avr_error("File '%s' isn't a elf object", fname);
00174
00175
00176 {
00177 long storage_needed;
00178 static asymbol **symbol_table;
00179 long number_of_symbols;
00180 long i;
00181
00182 storage_needed = bfd_get_symtab_upper_bound(abfd);
00183
00184 if(storage_needed < 0)
00185 avr_error("internal error: storage_needed < 0");
00186
00187 if(storage_needed == 0)
00188 return;
00189
00190 symbol_table = (asymbol **)malloc(storage_needed);
00191
00192 number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
00193
00194 if(number_of_symbols < 0)
00195 avr_error("internal error: number_of_symbols < 0");
00196
00197 for(i = 0; i < number_of_symbols; i++) {
00198
00199 if(!symbol_table[i]->section)
00200 continue;
00201 unsigned int lma = symbol_table[i]->section->lma;
00202 unsigned int vma = symbol_table[i]->section->vma;
00203
00204 if(vma < 0x7fffff) {
00205 pair<unsigned int, string> p((symbol_table[i]->value+lma) >> 1, symbol_table[i]->name);
00206
00207 Flash->AddSymbol(p);
00208 }
00209 else if(vma < 0x80ffff) {
00210 unsigned int offset = vma - 0x800000;
00211
00212 {
00213 pair<unsigned int, string> p(symbol_table[i]->value + offset, symbol_table[i]->name);
00214
00215 data->AddSymbol(p);
00216
00217 pair<unsigned int, string> pp(symbol_table[i]->value + lma, symbol_table[i]->name);
00218
00219 Flash->AddSymbol(pp);
00220 }
00221 }
00222 else if(vma < 0x81ffff) {
00223 unsigned int offset = vma - 0x810000;
00224 pair<unsigned int, string> p(symbol_table[i]->value + offset, symbol_table[i]->name);
00225
00226 eeprom->AddSymbol(p);
00227 }
00228 else
00229 avr_warning("Unknown symbol address range found!");
00230 }
00231 }
00232
00233 sec = abfd->sections;
00234
00235 while(sec != 0) {
00236 if(sec->flags & SEC_LOAD && sec->vma < 0x80ffff) {
00237 int size;
00238 size = sec->size;
00239 unsigned char *tmp = (unsigned char *)malloc(size);
00240 bfd_get_section_contents(abfd, sec, tmp, 0, size);
00241 Flash->WriteMem(tmp, sec->lma, size);
00242 free(tmp);
00243 }
00244
00245 if(sec->flags & SEC_LOAD && sec->vma >= 0x810000) {
00246 int size;
00247 size = sec->size;
00248 unsigned char *tmp = (unsigned char *)malloc(size);
00249 bfd_get_section_contents(abfd, sec, tmp, 0, size);
00250 unsigned int offset = sec->vma - 0x810000;
00251 eeprom->WriteMem(tmp, offset, size);
00252 free(tmp);
00253 }
00254 sec = sec->next;
00255 }
00256
00257 bfd_close(abfd);
00258 #endif
00259 }
00260
00261 #ifdef VI_BUG
00262 }
00263 #endif
00264
00265 void AvrDevice::SetClockFreq(SystemClockOffset nanosec) {
00266 clockFreq = nanosec;
00267 }
00268
00269 SystemClockOffset AvrDevice::GetClockFreq() {
00270 return clockFreq;
00271 }
00272
00273 Pin *AvrDevice::GetPin(const char *name) {
00274 Pin *ret = allPins[name];
00275 if(!ret)
00276 avr_error("unknown Pin requested! -> %s is not available", name);
00277 return ret;
00278 }
00279
00280 AvrDevice::~AvrDevice() {
00281
00282 dump_manager->unregisterAvrDevice(this);
00283
00284
00285 unsigned size = totalIoSpace - registerSpaceSize - iRamSize - eRamSize;
00286 for(unsigned idx = 0; idx < size; idx++)
00287 delete invalidRW[idx];
00288 delete [] invalidRW;
00289
00290
00291 for(unsigned idx = 0; idx < registerSpaceSize; idx++)
00292 delete rw[idx];
00293 size = registerSpaceSize + ioSpaceSize + iRamSize + eRamSize;
00294 for(unsigned idx = (registerSpaceSize + ioSpaceSize); idx < size; idx++)
00295 delete rw[idx];
00296
00297
00298 delete Flash;
00299 delete statusRegister;
00300 delete status;
00301 delete [] rw;
00302 delete data;
00303 }
00304
00308 class TwiceTV : public TraceValue {
00309 public:
00310 TwiceTV(const std::string &_name, TraceValue *_ref)
00311 : TraceValue(_ref->bits()+1, _name), ref(_ref) {}
00312
00313 virtual void cycle() {
00314 change(ref->value()*2);
00315 set_written();
00316 }
00317 private:
00318 TraceValue *ref;
00319 };
00320
00321
00322 AvrDevice::AvrDevice(unsigned int _ioSpaceSize,
00323 unsigned int IRamSize,
00324 unsigned int ERamSize,
00325 unsigned int flashSize):
00326 TraceValueRegister(),
00327 coreTraceGroup(this),
00328 abortOnInvalidAccess(false),
00329 iRamSize(IRamSize),
00330 eRamSize(ERamSize),
00331 ioSpaceSize(_ioSpaceSize),
00332 flagIWInstructions(true),
00333 flagJMPInstructions(true),
00334 flagIJMPInstructions(true),
00335 flagEIJMPInstructions(false),
00336 flagLPMInstructions(true),
00337 flagELPMInstructions(false),
00338 flagMULInstructions(true),
00339 flagMOVWInstruction(true),
00340 flagTiny10(false),
00341 flagTiny1x(false),
00342 flagXMega(false),
00343 instructionSEIJustEnabledInterrupts(false)
00344 {
00345 dump_manager = DumpManager::Instance();
00346 dump_manager->registerAvrDevice(this);
00347 DebugRecentJumpsIndex = 0;
00348
00349 TraceValue* pc_tracer=trace_direct(&coreTraceGroup, "PC", &cPC);
00350 coreTraceGroup.RegisterTraceValue(new TwiceTV(coreTraceGroup.GetTraceValuePrefix()+"PCb", pc_tracer));
00351 trace_on = 0;
00352
00353 data = new Data;
00354
00355
00356 rampz = NULL;
00357 eind = NULL;
00358
00359
00360 unsigned invalidSize = totalIoSpace - registerSpaceSize - IRamSize - ERamSize;
00361 rw = new RWMemoryMember* [totalIoSpace];
00362 invalidRW = new RWMemoryMember* [invalidSize];
00363
00364
00365 status = new HWSreg();
00366 if(status == NULL)
00367 avr_error("Not enough memory for HWSreg in AvrDevice::AvrDevice");
00368 statusRegister = new RWSreg(&coreTraceGroup, status);
00369 if(statusRegister == NULL)
00370 avr_error("Not enough memory for RWSreg in AvrDevice::AvrDevice");
00371
00372
00373 spmRegister = NULL;
00374
00375
00376 Flash = new AvrFlash(this, flashSize);
00377 if(Flash == NULL)
00378 avr_error("Not enough memory for Flash in AvrDevice::AvrDevice");
00379
00380
00381 unsigned currentOffset = 0;
00382 unsigned invalidRWOffset = 0;
00383
00384 for(unsigned ii = 0; ii < registerSpaceSize; ii++) {
00385 rw[currentOffset] = new RAM(&coreTraceGroup, "r", ii, registerSpaceSize);
00386 if(rw[currentOffset] == NULL)
00387 avr_error("Not enough memory for registers in AvrDevice::AvrDevice");
00388 currentOffset++;
00389 }
00390
00391
00392
00393
00394
00395
00396 for(unsigned ii = 0; ii < ioSpaceSize; ii++) {
00397 invalidRW[invalidRWOffset] = new InvalidMem(this, currentOffset);
00398 if(invalidRW[invalidRWOffset] == NULL)
00399 avr_error("Not enough memory for io space in AvrDevice::AvrDevice");
00400 rw[currentOffset] = invalidRW[invalidRWOffset];
00401 currentOffset++;
00402 invalidRWOffset++;
00403 }
00404
00405
00406 for(unsigned ii = 0; ii < IRamSize; ii++ ) {
00407 rw[currentOffset] = new RAM(&coreTraceGroup, "IRAM", ii, IRamSize);
00408 if(rw[currentOffset] == NULL)
00409 avr_error("Not enough memory for IRAM in AvrDevice::AvrDevice");
00410 currentOffset++;
00411 }
00412
00413
00414
00415 for(unsigned ii = 0; ii < ERamSize; ii++ ) {
00416 rw[currentOffset] = new RAM(&coreTraceGroup, "ERAM", ii, ERamSize);
00417 if(rw[currentOffset] == NULL)
00418 avr_error("Not enough memory for io space in AvrDevice::AvrDevice");
00419 currentOffset++;
00420 }
00421
00422 assert(currentOffset<=totalIoSpace);
00423
00424 for(; currentOffset < totalIoSpace; currentOffset++, invalidRWOffset++) {
00425 invalidRW[invalidRWOffset] = new InvalidMem(this, currentOffset);
00426 if(invalidRW[invalidRWOffset] == NULL)
00427 avr_error("Not enough memory for fill address space in AvrDevice::AvrDevice");
00428 rw[currentOffset] = invalidRW[invalidRWOffset];
00429 }
00430 }
00431
00432
00433 int AvrDevice::Step(bool &untilCoreStepFinished, SystemClockOffset *nextStepIn_ns) {
00434 if (cpuCycles<=0)
00435 cPC=PC;
00436 if(trace_on == 1) {
00437 traceOut << actualFilename << " ";
00438 traceOut << HexShort(cPC << 1) << dec << ": ";
00439
00440 string sym(Flash->GetSymbolAtAddress(cPC));
00441 traceOut << sym << " ";
00442 for (int len = sym.length(); len < 30;len++)
00443 traceOut << " " ;
00444 }
00445
00446 bool hwWait = false;
00447 for(unsigned i = 0; i < hwCycleList.size(); i++) {
00448 Hardware * p = hwCycleList[i];
00449 if (p->CpuCycle() > 0)
00450 hwWait = true;
00451 }
00452
00453 if(hwWait) {
00454 if(trace_on)
00455 traceOut << "CPU-Hold by IO-Hardware ";
00456 } else if(cpuCycles <= 0) {
00457
00458
00459 if(BP.end() != find(BP.begin(), BP.end(), PC)) {
00460 if(trace_on)
00461 traceOut << "Breakpoint found at 0x" << hex << PC << dec << endl;
00462 if(nextStepIn_ns != 0)
00463 *nextStepIn_ns=clockFreq;
00464 untilCoreStepFinished = !(cpuCycles > 0);
00465 dump_manager->cycle();
00466 return BREAK_POINT;
00467 }
00468
00469 if(EP.end() != find(EP.begin(), EP.end(), PC)) {
00470 if(global_verbose_on)
00471 cout << "Simulation finished!" << endl;
00472 SystemClock::Instance().stop();
00473 dump_manager->cycle();
00474 return 0;
00475 }
00476
00477 if(instructionSEIJustEnabledInterrupts) {
00478 instructionSEIJustEnabledInterrupts = false;
00479
00480 } else if(status->I == 1) {
00481 unsigned int actualIrqVector;
00482 unsigned int newIrqPc = irqSystem->GetNewPc(actualIrqVector);
00483 if(newIrqPc != 0xffffffff) {
00484 if(trace_on)
00485 traceOut << "IRQ DETECTED: VectorAddr: " << newIrqPc ;
00486
00487 irqSystem->IrqHandlerStarted(actualIrqVector);
00488 Funktor* fkt = new IrqFunktor(irqSystem, &HWIrqSystem::IrqHandlerFinished, actualIrqVector);
00489 stack->SetReturnPoint(stack->GetStackPointer(), fkt);
00490 stack->PushAddr(PC);
00491 cpuCycles = 4;
00492 status->I = 0;
00493 PC = newIrqPc - 1;
00494 }
00495 }
00496
00497 if(cpuCycles <= 0) {
00498 if((unsigned int)(PC << 1) >= (unsigned int)Flash->GetSize() ) {
00499 ostringstream os;
00500 os << actualFilename << " Simulation runs out of Flash Space at " << hex << (PC << 1);
00501 string s = os.str();
00502 if(trace_on)
00503 traceOut << s << endl;
00504 avr_error(s.c_str());
00505 }
00506
00507 DecodedInstruction *de = (Flash->GetInstruction(PC));
00508 if(trace_on) {
00509 cpuCycles = de->Trace();
00510 } else {
00511 cpuCycles = (*de)();
00512 }
00513
00514 statusRegister->trigger_change();
00515 }
00516
00517 PC++;
00518 cpuCycles--;
00519 } else {
00520 if(trace_on == 1)
00521 traceOut << "CPU-waitstate";
00522 cpuCycles--;
00523 }
00524
00525 if(nextStepIn_ns != NULL)
00526 *nextStepIn_ns = clockFreq;
00527
00528 if(trace_on == 1) {
00529 traceOut << endl;
00530 sysConHandler.TraceNextLine();
00531 }
00532
00533 untilCoreStepFinished = !((cpuCycles > 0) || hwWait);
00534 dump_manager->cycle();
00535 return (cpuCycles < 0) ? cpuCycles : 0;
00536 }
00537
00538 void AvrDevice::Reset() {
00539 PC_size = 2;
00540 PC = 0;
00541
00542 vector<Hardware *>::iterator ii;
00543 for(ii= hwResetList.begin(); ii != hwResetList.end(); ii++)
00544 (*ii)->Reset();
00545
00546 PC = 0; cPC=0;
00547 *status = 0;
00548
00549
00550 cpuCycles = 0;
00551 }
00552
00553 void AvrDevice::DeleteAllBreakpoints() {
00554 BP.erase(BP.begin(), BP.end());
00555 }
00556
00557 void AvrDevice::ReplaceIoRegister(unsigned int offset, RWMemoryMember *newMember) {
00558 if (offset >= ioSpaceSize + registerSpaceSize)
00559 avr_error("Could not replace register in non existing IoRegisterSpace");
00560 rw[offset] = newMember;
00561 }
00562
00563 bool AvrDevice::ReplaceMemRegister(unsigned int offset, RWMemoryMember *newMember) {
00564 if(offset < totalIoSpace) {
00565 rw[offset] = newMember;
00566 return true;
00567 }
00568 return false;
00569 }
00570
00571 RWMemoryMember* AvrDevice::GetMemRegisterInstance(unsigned int offset) {
00572 if(offset < totalIoSpace)
00573 return rw[offset];
00574 return NULL;
00575 }
00576
00577 void AvrDevice::RegisterTerminationSymbol(const char *symbol) {
00578 #ifdef _MSC_VER
00579 fprintf(stderr, "Fatal: Cannot specify terminating symbol. Loading symbols from ELF file is not implemented\n");
00580 assert(false);
00581 #endif
00582 unsigned int epa = Flash->GetAddressAtSymbol(symbol);
00583 EP.push_back(epa);
00584 }
00585
00586 void AvrDevice::DebugOnJump()
00587 {
00588 const int COUNT = sizeof DebugRecentJumps / sizeof DebugRecentJumps[0];
00589 DebugRecentJumpsIndex = (DebugRecentJumpsIndex + 1) % COUNT;
00590 DebugRecentJumps[DebugRecentJumpsIndex] = PC * 2;
00591 int next = (DebugRecentJumpsIndex + 1) % COUNT;
00592 DebugRecentJumps[next] = -1;
00593 }
00594
00595 unsigned char AvrDevice::GetRWMem(unsigned addr) {
00596 if(addr >= GetMemTotalSize())
00597 return 0;
00598 return *(rw[addr]);
00599 }
00600
00601 bool AvrDevice::SetRWMem(unsigned addr, unsigned char val) {
00602 if(addr >= GetMemTotalSize())
00603 return false;
00604 *(rw[addr]) = val;
00605 return true;
00606 }
00607
00608 unsigned char AvrDevice::GetCoreReg(unsigned addr) {
00609 assert(addr < registerSpaceSize);
00610 return *(rw[addr]);
00611 }
00612
00613 bool AvrDevice::SetCoreReg(unsigned addr, unsigned char val) {
00614 assert(addr < registerSpaceSize);
00615 *(rw[addr]) = val;
00616 return true;
00617 }
00618
00619 unsigned char AvrDevice::GetIOReg(unsigned addr) {
00620 assert(addr < ioSpaceSize);
00621 return *(rw[addr + registerSpaceSize]);
00622 }
00623
00624 bool AvrDevice::SetIOReg(unsigned addr, unsigned char val) {
00625 assert(addr < ioSpaceSize);
00626 *(rw[addr + registerSpaceSize]) = val;
00627 return true;
00628 }
00629
00630 bool AvrDevice::SetIORegBit(unsigned addr, unsigned bitaddr, bool bval) {
00631 assert(addr < 0x20);
00632 unsigned char val = *(rw[addr + registerSpaceSize]);
00633 if(bval)
00634 val |= 1 << bitaddr;
00635 else
00636 val &= ~(1 << bitaddr);
00637 *(rw[addr + registerSpaceSize]) = val;
00638 return true;
00639 }
00640
00641 unsigned AvrDevice::GetRegX(void) {
00642
00643 return (*(rw[27]) << 8) + *(rw[26]);
00644 }
00645
00646 unsigned AvrDevice::GetRegY(void) {
00647
00648 return (*(rw[29]) << 8) + *(rw[28]);
00649 }
00650
00651 unsigned AvrDevice::GetRegZ(void) {
00652
00653 return (*(rw[31]) << 8) + *(rw[30]);
00654 }
00655
00656