diff --git a/.gitignore b/.gitignore index ee82039..e5af0f5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .ccls-cache out compile_commands.json +compile_commands.json +.cache diff --git a/Makefile b/Makefile index 5f704dd..5c04933 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,12 @@ INCLUDES=-Iinc -I. ifeq ($(BUILD_DIR),) BUILD_DIR := out endif +ifeq ($(MANIFEST_BUILD_DIR),) +MANIFEST_BUILD_DIR := out/manifest +endif SRC_DIR=src +MANIFEST_SRC_DIR=manifest_src INC_DIR=inc CC=gcc OBJDUMP=objdump @@ -19,6 +23,7 @@ TARGET=device DEFINES=-DOPCODE_WORDSIZE=2 -DMEM_CELL_WORDS=1 -DPC_WORDSIZE=3 -DGP_REG_CELL_WORDS=1 -DIO_REG_CELL_WORDS=1 -DARCH=$(ARCH) C_SOURCES=$(wildcard $(SRC_DIR)/*.c) +MANIFEST_C_SOURCES=$(wildcard $(MANIFEST_SRC_DIR)/*.c) C_HEADERS=$(wildcard $(INC_DIR)/*.h) C_INCLUDES=-I$(INC_DIR)/ @@ -29,10 +34,12 @@ ANALYZER_FLAGS=-fanalyzer LSECTIONS=-ffunction-sections -fdata-sections -Wl,--gc-sections CFLAGS=$(C_DEFS) -g $(C_INCLUDES) $(DEFINES) $(OPTIMIZE) --std=$(STANDART) $(PEDANTIC_FLAGS) $(ANALYZER_FLAGS) -fPIC LFLAGS=$(OPTIMIZE) -g $(PEDANTIC_FLAGS) $(DEFINES) -flto -fuse-linker-plugin $(LSECTIONS) -lm $(LIBS) -fPIC -shared +MANIFEST_LFLAGS=$(OPTIMIZE) -g $(PEDANTIC_FLAGS) $(DEFINES) -flto -fuse-linker-plugin $(LSECTIONS) -lm $(LIBS) -fPIC OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +MANIFEST_TARGETS = $(addprefix $(MANIFEST_BUILD_DIR)/,$(notdir $(MANIFEST_C_SOURCES:.c=.elf))) vpath %.c $(sort $(dir $(C_SOURCES))) vpath %.h $(sort $(dir $(C_HEADERS))) @@ -53,8 +60,24 @@ $(BUILD_DIR)/$(TARGET).so: $(OBJECTS) @echo -e '\033[1;32mELF ('$(ARCH)')\t'$(OBJECTS)'\n\t\t\t->\t'$@'\033[0m' @$(CC) $(LFLAGS) $(OBJECTS) -o $(BUILD_DIR)/$(TARGET).so +manifest: $(MANIFEST_TARGETS) + @for elf in $(MANIFEST_TARGETS); do \ + echo -e "\033[1;32mRUN\t$$elf\033[0m"; \ + $$elf $(MANIFEST_BUILD_DIR) || { echo -e "\033[0;31merror running $$elf\033[0m"; exit 1; }; \ + done + +$(MANIFEST_BUILD_DIR)/%.elf: $(MANIFEST_SRC_DIR)/%.c Makefile | $(MANIFEST_BUILD_DIR) + @echo -e '\033[1;32mELF\t'$(OBJECTS)'\n\t\t\t->\t'$@'\033[0m' + @$(CC) $(MANIFEST_LFLAGS) $< $(LDLIBS) -I inc -o $@ + +$(BUILD_DIR): + @mkdir -p $(BUILD_DIR) + +$(MANIFEST_BUILD_DIR): + @mkdir -p $(MANIFEST_BUILD_DIR) + BuildDir: @mkdir -p $(BUILD_DIR) diff --git a/config.toml b/config.toml deleted file mode 100644 index 3e0f9a2..0000000 --- a/config.toml +++ /dev/null @@ -1,23 +0,0 @@ -[dev] -libpath = "out/device.so" - - - -[mem.ext_reg_io] -start = 0 -len = 255 -wordLen = 1 - -[mem.extstate] -start = 256 -len = 1 -wordLen = 1 - -[mem.variables] -PIN = 0 -PORT = 1 -DDR = 2 - - - - diff --git a/inc/mem.h b/inc/mem.h index 5f5a4c7..9b72bfb 100644 --- a/inc/mem.h +++ b/inc/mem.h @@ -53,6 +53,17 @@ typedef uint32_t io_reg_cell_t; typedef uint32_t io_reg_cell_t; #endif +typedef struct +{ + uint8_t seg_id; + char* name; + uint8_t word_len; + uint64_t default_size; + uint64_t default_addr; + uint8_t is_executable; +} memseg_metadata_t; + + void* default_addr_read_handler(uint64_t ident, uint64_t addr, void* rawCells); diff --git a/inc/mem_seg.h b/inc/mem_seg.h new file mode 100644 index 0000000..27112e3 --- /dev/null +++ b/inc/mem_seg.h @@ -0,0 +1,17 @@ +#ifndef __MEM_SEG_H__ +#define __MEM_SEG_H__ + + +// #define MEMSEG_PC_SEG_NUM 0 +// #define MEMSEG_PC_ADDR 0 + +#define MEMSEG_DEFINES {\ + {0, "seg0", 1, 0, 0, 0}, \ + {1, "seg1", 1, 0, 0, 0}, \ + {2, "seg2", 1, 0, 0, 0}, \ + {3, "seg3", 1, 0, 0, 0}, \ + {4, "seg4", 1, 0, 0, 0}, \ + {5, "seg5", 1, 0, 0, 0}, \ +} + +#endif //ifndef __MEM_SEG_H__ \ No newline at end of file diff --git a/manifest_src/generate_manifest_segments_defines.c b/manifest_src/generate_manifest_segments_defines.c new file mode 100644 index 0000000..fafd5be --- /dev/null +++ b/manifest_src/generate_manifest_segments_defines.c @@ -0,0 +1,53 @@ +#include "mem.h" +#include "mem_seg.h" +#include +#include +#include + + +int main(int argc, char** argv) +{ + if(argc != 2) + { + printf("provide target directory\n"); + return 1; + } + + const char *dirpath = argv[1]; + const char *filename = "seg_data.csv"; + + char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 1, sizeof(char)); + if(tgtpath == NULL) + { + return 1; + } + + sprintf(tgtpath, "%s/%s", dirpath, filename); + + FILE *fptr; + + fptr = fopen(tgtpath, "w"); + + if(fptr == NULL) + { + printf("errof opening file\n"); + return 1; + } + + memseg_metadata_t requiredSegments[] = MEMSEG_DEFINES; + + + fprintf(fptr, "seg_id;name;word_len;default_size;default_addr;is_executable\n"); + + + for(size_t i = 0; i < sizeof(requiredSegments)/sizeof(memseg_metadata_t); i++) + { + const memseg_metadata_t seg_def = requiredSegments[i]; + fprintf(fptr, "%d;%s;%d;%lu;%lu;%d\n", seg_def.seg_id, seg_def.name, seg_def.word_len, seg_def.default_size, seg_def.default_addr, seg_def.is_executable); + } + + + fclose(fptr); + free(tgtpath); + return 0; +} \ No newline at end of file diff --git a/src/device.c b/src/device.c index a171200..c73b29a 100644 --- a/src/device.c +++ b/src/device.c @@ -1,9 +1,11 @@ #include #include +#include #include #include "device.h" #include "mem.h" +#include "mem_seg.h" #include "runner.h" #include "addrs.h" @@ -308,12 +310,25 @@ void error(const char* err, char* errbuf) device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf) { conf_mem_seg_t** segments = devConf->memConf->memSegConfs; - device_specs_t* specs = malloc(sizeof(device_specs_t)); + device_specs_t* specs = calloc(1, sizeof(device_specs_t)); if (specs == NULL) { error("unable to allocate mem specs struct", errbuf); return NULL; } + + + memseg_metadata_t requiredSegments[] = MEMSEG_DEFINES; + uint8_t* requiredSegmentsFoundMap = (uint8_t*)calloc(sizeof(requiredSegments) / sizeof(memseg_metadata_t), sizeof(uint8_t)); + + if(requiredSegmentsFoundMap == NULL) + { + error("unable to allocate found map", errbuf); + free(specs); + return NULL; + } + + uint8_t specCount = 0; specs->executableSegmentsCount = 0; @@ -325,29 +340,37 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf) } specCount++; } + + if(specCount < sizeof(requiredSegments)/sizeof(memseg_metadata_t)) + { + specCount = sizeof(requiredSegments)/sizeof(memseg_metadata_t); + } + specs->memSpecsCount = specCount; - specs->memSpecs = malloc(specCount * sizeof(memseg_spec_t*)); + specs->memSpecs = calloc(specCount, sizeof(memseg_spec_t*)); if (specs->memSpecs == NULL) { free(specs); + free(requiredSegmentsFoundMap); error("unable to allocate mem segment specs", errbuf); return NULL; } - specs->executableSegments = malloc(sizeof(uint8_t) * specs->executableSegmentsCount); + specs->executableSegments = calloc(specs->executableSegmentsCount, sizeof(uint8_t)); if (specs->executableSegments == NULL) { error("unable to allocate mem executable specs", errbuf); free(specs->memSpecs); free(specs); + free(requiredSegmentsFoundMap); return NULL; } for (uint8_t i = 0; i < specCount; i++) { - memseg_spec_t* spec = (memseg_spec_t*)malloc(sizeof(memseg_spec_t)); + memseg_spec_t* spec = (memseg_spec_t*)calloc(1, sizeof(memseg_spec_t)); if (spec == NULL) { sprintf(errbuf, "unable to allocate spec %d", i); @@ -359,6 +382,7 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf) free(specs->memSpecs); free(specs->executableSegments); free(specs); + free(requiredSegmentsFoundMap); return NULL; } spec->name = NULL; @@ -366,51 +390,62 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf) specs->memSpecs[i] = spec; } - uint8_t foundSegments = 0; uint8_t executableSegmentsFound = 0; for (uint8_t i = 0; i < specCount; i++) { uint8_t specNum = 0xFF; - if (strcmp(segments[i]->name, "ext_reg_io") == 0) + uint8_t is_error = 0; + uint8_t seek_found = 0; + + for(uint8_t j = 0; j < sizeof(requiredSegments) / sizeof(memseg_metadata_t); j++) { - specNum = MEMDATA_IO_REGS; - } - else if (strcmp(segments[i]->name, "extstate") == 0) - { - specNum = MEMDATA_EXTSTATE; - } - else - { - sprintf(errbuf, "invalid segment: %s", segments[i]->name); - for(size_t j = 0; j < specCount; j++) + const memseg_metadata_t seg_def = requiredSegments[j]; + + if(strcmp(seg_def.name, segments[i]->name)) { - if(specs->memSpecs[j]->name != NULL) + const uint8_t is_found = requiredSegmentsFoundMap[j]; + if(is_found) { - free(specs->memSpecs[j]->name); + is_error = 1; + sprintf(errbuf, "duplicate segment %s", seg_def.name); } - free(specs->memSpecs[j]); + else + { + if(seg_def.is_executable == segments[i]->isExecutable || segments[i]->isExecutable) + { + requiredSegmentsFoundMap[j] = 1; + specNum = j; + seek_found = 1; + } + else + { + is_error = 1; + sprintf(errbuf, "segment %s must be executable", seg_def.name); + } + } + break; } - free(specs->executableSegments); - free(specs->memSpecs); - free(specs); + } + + if(seek_found == 0) + { + is_error = 1; + sprintf(errbuf, "unsupported memory segment: %s", segments[i]->name); + } + + if(is_error) + { + freeDevSpec(specs); + free(requiredSegmentsFoundMap); return NULL; } - specs->memSpecs[specNum]->name = malloc(sizeof(char) * strlen(segments[i]->name)); + specs->memSpecs[specNum]->name = calloc(strlen(segments[i]->name), sizeof(char)); if(specs->memSpecs[specNum]->name == NULL) { sprintf(errbuf, "unable to allocate spec %d name", i); - for(size_t j = 0; j < specCount; j++) - { - if(specs->memSpecs[j]->name != NULL) - { - free(specs->memSpecs[j]->name); - } - free(specs->memSpecs[j]); - } - free(specs->executableSegments); - free(specs->memSpecs); - free(specs); + freeDevSpec(specs); + free(requiredSegmentsFoundMap); return NULL; } @@ -423,42 +458,55 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf) specs->executableSegments[executableSegmentsFound] = specNum; executableSegmentsFound++; } - foundSegments += 1; + } + + for(uint8_t i = 0; i < sizeof(requiredSegments)/sizeof(memseg_metadata_t); i++) + { + if(requiredSegmentsFoundMap[i] == 0) + { + const memseg_metadata_t seg_def = requiredSegments[i]; + + specs->memSpecs[seg_def.seg_id]->start = seg_def.default_addr; + specs->memSpecs[seg_def.seg_id]->len = seg_def.default_size; + specs->memSpecs[seg_def.seg_id]->wordLen = seg_def.word_len; + + specs->memSpecs[seg_def.seg_id]->name = calloc(strlen(seg_def.name), sizeof(char)); + + if(specs->memSpecs[seg_def.seg_id]->name == NULL) + { + sprintf(errbuf, "unable to allocate spec %d name", i); + freeDevSpec(specs); + free(requiredSegmentsFoundMap); + return NULL; + } + + strcpy(specs->memSpecs[seg_def.seg_id]->name, seg_def.name); + + + if(seg_def.is_executable) + { + specs->executableSegments[executableSegmentsFound] = seg_def.seg_id; + executableSegmentsFound++; + } + } } if(executableSegmentsFound < specs->executableSegmentsCount) { sprintf(errbuf, "Not all executable segments found"); - for(size_t j = 0; j < specCount; j++) - { - if(specs->memSpecs[j]->name != NULL) - { - free(specs->memSpecs[j]->name); - } - free(specs->memSpecs[j]); - } - free(specs->executableSegments); - free(specs->memSpecs); - free(specs); + freeDevSpec(specs); + free(requiredSegmentsFoundMap); return NULL; } - if (foundSegments < 2) - { - sprintf(errbuf, "invalid amount of segments: must be 2"); - for(size_t k = 0; k < specs->memSpecsCount; k++) - { - if(specs->memSpecs[k]->name != NULL) - { - free(specs->memSpecs[k]->name); - } - free(specs->memSpecs[k]); - } - free(specs->executableSegments); - free(specs->memSpecs); - free(specs); - return NULL; - } + #ifdef MEMSEG_PC_SEG_NUM + #ifndef MEMSEG_PC_ADDR + specs->pcAddr = memSegToGlobal(specs, MEMSEG_PC_SEG_NUM, 0); + #else + specs->pcAddr = memSegToGlobal(specs, MEMSEG_PC_SEG_NUM, MEMSEG_PC_ADDR); + #endif + #endif + free(requiredSegmentsFoundMap); return specs; } @@ -492,7 +540,8 @@ void fillSmartWriteSpecs(device_specs_t* specs, smart_write_spec_t* smartWriteSp device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount, char* errbuf) { - + return NULL; + //TODO device_specs_t* specs = malloc(sizeof(device_specs_t)); if (specs == NULL) { @@ -573,109 +622,18 @@ device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t device_public_context_t* init(device_specs_t* specs, char* errbuf) { - if (specs->memSpecsCount >= 0xFF - 2) - { - sprintf(errbuf, "Too many mem specifications"); - return NULL; - } - - device_specs_t* realSpecs = malloc(sizeof(device_specs_t)); - if (realSpecs == NULL) - { - sprintf(errbuf, "unable to allocate spec struct"); - return NULL; - } - - uint8_t specCount = specs->memSpecsCount + 2; - realSpecs->memSpecsCount = specCount; - realSpecs->memSpecs = (memseg_spec_t**)malloc(realSpecs->memSpecsCount * sizeof(memseg_spec_t*)); - if (realSpecs->memSpecs == NULL) - { - sprintf(errbuf, "unable to allocate mem specs"); - free(realSpecs); - return NULL; - } - - realSpecs->executableSegments = malloc(sizeof(uint8_t) * specs->executableSegmentsCount); - if (realSpecs->executableSegments == NULL) - { - sprintf(errbuf, "unable to allocate executable segments"); - free(realSpecs->memSpecs); - free(realSpecs); - return NULL; - } - for (uint8_t i = 0; i < specs->executableSegmentsCount; i++) - { - realSpecs->executableSegments[i] = specs->executableSegments[i]; - } - realSpecs->executableSegmentsCount = specs->executableSegmentsCount; - - - realSpecs->smartReadSpecs = specs->smartReadSpecs; - realSpecs->smartReadSpecsCount = specs->smartReadSpecsCount; - - realSpecs->smartWriteSpecs = specs->smartWriteSpecs; - realSpecs->smartWriteSpecsCount = specs->smartWriteSpecsCount; - - uint64_t maxAddr = 0; - - - - for (uint8_t i = 0; i < specCount; i++) - { - memseg_spec_t *segSpec = (memseg_spec_t*)malloc(sizeof(memseg_spec_t)); - realSpecs->memSpecs[i] = segSpec; - if (segSpec == NULL) - { - - sprintf(errbuf, "unable to allocate mem spec segment %u", i); - for (uint8_t j = 0; j < i; j++) - { - free(realSpecs->memSpecs[j]); - } - free(realSpecs->memSpecs); - free(realSpecs->executableSegments); - free(realSpecs); - return NULL; - } - - if (i < specCount - 2) - { - realSpecs->memSpecs[i]->name = specs->memSpecs[i]->name; - realSpecs->memSpecs[i]->len = specs->memSpecs[i]->len; - realSpecs->memSpecs[i]->start = specs->memSpecs[i]->start; - realSpecs->memSpecs[i]->wordLen = specs->memSpecs[i]->wordLen; - uint64_t testMaxAddr = realSpecs->memSpecs[i]->start + (realSpecs->memSpecs[i]->len * realSpecs->memSpecs[i]->wordLen); - if (testMaxAddr > maxAddr) - { - maxAddr = testMaxAddr; - } - } - - } - - - - - uint8_t pcSpecSegNum = specs->memSpecsCount; - - - realSpecs->pcAddr = memSegToGlobal(realSpecs, pcSpecSegNum, 0); - device_public_context_t* pubDevContext = malloc(sizeof(device_public_context_t)); if (pubDevContext == NULL) { sprintf(errbuf, "unable to allocate public context"); - freeDevSpec(realSpecs); return NULL; } char initErrbuf[200]; - device_info_t* devInfo = initSpecs(realSpecs, initErrbuf); + device_info_t* devInfo = initSpecs(specs, initErrbuf); if (devInfo == NULL) { sprintf(errbuf, "unable to init specs: %s", initErrbuf); - freeDevSpec(realSpecs); free(pubDevContext); return NULL; }