Commit 319779f020f9dc15902dadad8a9ebb059118dfa4
receivedSun, 27. Nov 2022, 18:52:35 (by user sx)
Sun, 27 Nov 2022 17:52:35 +0000 (18:52 +0100)
authorManfred Steiner <sx@htl-kaindorf.at>
Sun, 27 Nov 2022 17:52:17 +0000 (18:52 +0100)
committerManfred Steiner <sx@htl-kaindorf.at>
Sun, 27 Nov 2022 17:52:17 +0000 (18:52 +0100)
5 files changed:
examples/simuc/.gitignore
examples/simuc/Makefile
examples/simuc/src/simavr/simavr.cpp
simavr/.gitignore
simavr/sim/sim_elf.c

index d1ad022ed0a24a0b16efabfd3e12e28d580b51c2..5489810b69a1e95135a248f267e7e79cba3d9c25 100644 (file)
@@ -1,4 +1,7 @@
 dist/**
 build/**
 dpkg/**/*.deb
+dpkg/**/usr/share/htl-simuc/simuc
+dpkg/**/usr/share/htl-simuc/simavr
+dpkg/**/DEBIAN/control
 **/*.vcd
index 456d1d5f919487c2a2923434af9821fec49483ed..e06b0fef900cacb1778be8c14d0d214e8b5a8931 100644 (file)
@@ -15,9 +15,9 @@ CFLAGS = -Os -Wall
 X_CFLAGS = -Os -g -Wall
 
 
-dist/simuc: build/main.o build/sim.o build/simavr.o build/error.o build/uart_pty.o
+dist/simuc: build/main.o build/sim.o build/simavr.o build/error.o build/uart_pty.o ../../simavr/obj-$(shell gcc -dumpmachine)/libsimavr.a
        #g++ -o $@ -g -Wall -gdwarf-2 $^ -Wl,-rpath,$(CURDIR) -L$(CURDIR) -lsimavr  -lpthread -lutil
-       g++ -o $@ -g -Wall -gdwarf-2 $^ ../../simavr/obj-$(shell gcc -dumpmachine)/libsimavr.a -lelf -lpthread -lutil
+       g++ -o $@ -g -Wall -gdwarf-2 $^ -lelf -lpthread -lutil
 
 
 #dist/libsim.so: build/sim.o build/simavr.o build/error.o build/uart_pty.o
index ba63390ab80a1878488daad630eed16f725b2e6c..1945ad5d6f630a034156028fc2a54a84adba7108 100644 (file)
@@ -60,6 +60,10 @@ void SimAvr::load (struct StartParameters *params) {
                startParameters = params;
                firmware = (elf_firmware_t *) malloc(sizeof(elf_firmware_t));
                std::string filename = std::string(params->filename);
+               if (params->mmcu != NULL) {
+                       // elf_read_firmware needs mmcu to malloc proper flash size
+                       strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu));
+               }
                if (firmware == NULL || elf_read_firmware(filename.c_str(), firmware) != 0) {
                        throw std::logic_error(error(AT, "elf_read_firmware() from %s fails", filename.c_str()));
                }
index 5587c974ed0ac9c8d243dc1e6ad6f8ea9c0b0bea..3a85b15999733f46bf563b9254326ad2a3018daf 100644 (file)
@@ -1,3 +1,4 @@
 sim_core_decl.h
 sim_core_config.h
-.vscode/*
\ No newline at end of file
+.gdb_history
+.vscode/*
index df69b8121a13314523ae2080905b69ad4362e1ab..371b9dba19fc77a3aab46ba1807d671eca08ce59 100644 (file)
@@ -291,7 +291,7 @@ elf_copy_segment(int fd, Elf32_Phdr *php, uint8_t **dest)
                                rv, php->p_filesz, php->p_vaddr, php->p_offset);
                return -1;
        }
-       AVR_LOG(NULL, LOG_DEBUG, "Loaded %d bytes at %x\n",
+       AVR_LOG(NULL, LOG_DEBUG, "Loaded %d bytes at 0x%04x\n",
                        php->p_filesz, php->p_vaddr);
        return 0;
 }
@@ -373,18 +373,42 @@ elf_read_firmware(
                        continue;
                if (php->p_vaddr < 0x800000) {
                        /* Explicit flash section. Load it. */
+                       if (firmware->flash == NULL) {
+                               firmware->flashbase = 0;
+                               firmware->flashsize = php->p_vaddr + php->p_filesz;
+                               firmware->flash = malloc(firmware->flashsize);
+                               memset(firmware->flash, 0xff, firmware->flashsize);
+                               uint8_t *where = firmware->flash + php->p_vaddr;
+                               elf_copy_segment(fd, php, &where);
+
+                       } else {
+                               long gapSize = php->p_vaddr - firmware->flashsize;
+                               if (gapSize < 0) {
+                                       AVR_LOG(NULL, LOG_ERROR,
+                                               "Overlapping flash sections!\n");
+                                       return -1;
+                               } else  if (gapSize > 0) {
+                                       firmware->flash = realloc(firmware->flash,php->p_vaddr );
+                                       uint8_t *where = firmware->flash + firmware->flashsize;
+                                       memset(where, 0xff, gapSize);
+                                       firmware->flashsize = php->p_vaddr;
+                               }
+                               firmware->flash = realloc(firmware->flash,
+                                                                                 firmware->flashsize + php->p_filesz);
+                               if (!firmware->flash)
+                                       return -1;
+                               uint8_t *where = firmware->flash + firmware->flashsize;
+                               elf_copy_segment(fd, php, &where);
+                               firmware->flashsize += php->p_filesz;
+                       }
 
-                       if (elf_handle_segment(fd, php, &firmware->flash, "Flash"))
-                               continue;
-                       firmware->flashsize = php->p_filesz;
-                       firmware->flashbase = php->p_vaddr;
                } else if (php->p_vaddr < 0x810000) {
                        /* Data space.  If there are initialised variables, treat
                         * them as extra initialised flash.  The C startup function
                         * understands that and will copy them to RAM.
                         */
 
-                       if (firmware->flash) {
+                       if (firmware->flash != NULL) {
                                uint8_t *where;
 
                                firmware->flash = realloc(firmware->flash,
@@ -393,6 +417,7 @@ elf_read_firmware(
                                        return -1;
                                where = firmware->flash + firmware->flashsize;
                                elf_copy_segment(fd, php, &where);
+                               AVR_LOG(NULL, LOG_DEBUG, ".data section %d bytes copied to flash at 0x%04x\n", php->p_filesz, firmware->flashsize);
                                firmware->flashsize += php->p_filesz;
                        } else {
                                /* If this ever happens, add a second pass. */
@@ -421,6 +446,27 @@ elf_read_firmware(
                }
        }
 
+       avr_t *avr = avr_make_mcu_by_name(firmware->mmcu);
+       if (avr != NULL) {
+               if (firmware->flash == NULL) {
+                       AVR_LOG(NULL, LOG_ERROR,
+                                       "no flash!\n",
+                                       php->p_filesz, php->p_vaddr);
+                       return -1;
+               } else {
+                       long gapSize = avr->flashend + 1 - firmware->flashsize;
+                       if (gapSize < 0) {
+                               AVR_LOG(NULL, LOG_ERROR,
+                                       "flash size 0x%04x too large for selected mmcu device %s!\n", firmware->flashsize, firmware->mmcu);
+                               return -1;
+                       } else  if (gapSize > 0) {
+                               firmware->flash = realloc(firmware->flash, firmware->flashsize + gapSize);
+                               uint8_t *where = firmware->flash + firmware->flashsize;
+                               memset(where, 0xff, gapSize);
+                               firmware->flashsize += gapSize;
+                       }
+               }
+       }
        /* Scan the section table for .mmcu magic and symbols. */
 
        while ((scn = elf_nextscn(elf, scn)) != NULL) {
@@ -493,6 +539,9 @@ elf_read_firmware(
                }
 #endif // ELF_SYMBOLS
        }
+       if (firmware->flash != NULL) {
+               AVR_LOG(NULL, LOG_DEBUG, "end of flash initialization (size=0x%04x)\n", firmware->flashsize);
+       }
        elf_end(elf);
        close(fd);
        return 0;