From 216db3882529b389b29cb99554b4a5cd75f57e38 Mon Sep 17 00:00:00 2001 From: nikto_b Date: Sun, 19 Jan 2025 14:31:35 +0300 Subject: [PATCH] Initial commit --- .gitignore | 4 + Makefile | 79 ++++++ config.toml | 23 ++ inc/addrs.h | 7 + inc/device.h | 52 ++++ inc/mem.h | 61 +++++ inc/runner.h | 10 + src/device.c | 693 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/mem.c | 10 + src/runner.c | 8 + 10 files changed, 947 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 config.toml create mode 100644 inc/addrs.h create mode 100644 inc/device.h create mode 100644 inc/mem.h create mode 100644 inc/runner.h create mode 100644 src/device.c create mode 100644 src/mem.c create mode 100644 src/runner.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee82039 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode +.ccls-cache +out +compile_commands.json diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5f704dd --- /dev/null +++ b/Makefile @@ -0,0 +1,79 @@ +INCLUDES=-Iinc -I. + +# BUILD_DIR=out + +ifeq ($(BUILD_DIR),) +BUILD_DIR := out +endif + +SRC_DIR=src +INC_DIR=inc +CC=gcc +OBJDUMP=objdump +LIBS= +STANDART=c23 +OPTIMIZE=-Og +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) +C_HEADERS=$(wildcard $(INC_DIR)/*.h) + +C_INCLUDES=-I$(INC_DIR)/ + +DISABLE_FLAGS=-Wno-unused-variable -Wno-unused-parameter -Wno-write-strings -Wno-pointer-arith -Wno-analyzer-use-of-uninitialized-value +PEDANTIC_FLAGS=-pedantic -pedantic-errors $(DISABLE_FLAGS) -Wall -Wcast-align -Wcast-qual -Wconversion -Wduplicated-branches -Wduplicated-cond -Werror -Wextra -Wfloat-equal -Wlogical-op -Wpedantic -Wredundant-decls -Wsign-conversion +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 + + + +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +vpath %.h $(sort $(dir $(C_HEADERS))) + +rebuild: clean | build + +all: + +build: date Dir $(C_HEADERS) target + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + @echo -e '\033[1;32mCC ('$(ARCH)')\t'$<'\t->\t'$@'\033[0m' + @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ + @$(OBJDUMP) -d -S $@ > $(BUILD_DIR)/$(notdir $(<:.c=.casm)) + +target: date $(BUILD_DIR)/$(TARGET).so + +$(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 + + + +BuildDir: + @mkdir -p $(BUILD_DIR) + +SrcDir: + @mkdir -p $(SRC_DIR) + +IncDir: + @mkdir -p $(INC_DIR) + +Dir: BuildDir SrcDir IncDir + +.PHONY: clean +clean: + @rm -rf $(BUILD_DIR)/* + @echo -e '\033[0;31mCleaned\033[0m' + +.NOTPARALLEL: date target rebuild +date: + @echo -e '\033[1;32m'"Starting build at " | tr -d '\n' + @date + @echo -e '\033[0m' + diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..3e0f9a2 --- /dev/null +++ b/config.toml @@ -0,0 +1,23 @@ +[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/addrs.h b/inc/addrs.h new file mode 100644 index 0000000..c5295f8 --- /dev/null +++ b/inc/addrs.h @@ -0,0 +1,7 @@ +#ifndef __ADDRS_H__ +#define __ADDRS_H__ + +#define MEMDATA_IO_REGS 0 +#define MEMDATA_EXTSTATE 1 + +#endif // ifndef __ADDRS_H__ \ No newline at end of file diff --git a/inc/device.h b/inc/device.h new file mode 100644 index 0000000..f290805 --- /dev/null +++ b/inc/device.h @@ -0,0 +1,52 @@ +#ifndef __DEVICE_H__ +#define __DEVICE_H__ + +#include +#include "runner.h" +#include "addrs.h" +#include "mem.h" +#include "../../../inc/config.h" +#include "../../../inc/libhmmmm.h" +#include "../../../inc/libdevice.h" + +#define SMART_ADDR_TYPE_GLOBAL 1 +#define SMART_ADDR_TYPE_SEGMENTED 2 + + + +typedef struct +{ + memseg_spec_t** memSpecs; + uint8_t memSpecsCount; + uint64_t pcAddr; + uint8_t* executableSegments; + uint8_t executableSegmentsCount; + smart_read_spec_t* smartReadSpecs; + uint64_t smartReadSpecsCount; + smart_write_spec_t* smartWriteSpecs; + uint64_t smartWriteSpecsCount; +} device_specs_t; + +typedef struct +{ + device_mem_t* deviceMem; + device_specs_t* specs; +} device_info_t; + + + +// device_public_context_t* init(device_specs_t* specs, smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount); +device_public_context_t* init(device_specs_t* specs, char* errbuf); +device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount, char* errbuf); +uint8_t makeDeviceTick(device_public_context_t* devContext); + +device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf); + +device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf); +void fillSmartReadSpecs(device_specs_t* specs, smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount); +void fillSmartWriteSpecs(device_specs_t* specs, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount); +void freeDevSpec(void* specs); +void freeDevMem(device_mem_t* devMem); + +#endif // ifndef __DEVICE_H__ + diff --git a/inc/mem.h b/inc/mem.h new file mode 100644 index 0000000..5f5a4c7 --- /dev/null +++ b/inc/mem.h @@ -0,0 +1,61 @@ +#ifndef __MEM_H__ +#define __MEM_H__ + +#include +#include +#include "../../../inc/libhmmmm.h" + +#ifndef RAM_CELL_WORDS + #define RAM_CELL_WORDS 1 +#endif +#if RAM_CELL_WORDS == 1 +typedef uint8_t ram_cell_t; +#endif +#if RAM_CELL_WORDS == 2 +typedef uint16_t ram_cell_t; +#endif +#if RAM_CELL_WORDS == 3 +typedef uint32_t ram_cell_t; +#endif +#if RAM_CELL_WORDS == 4 +typedef uint32_t ram_cell_t; +#endif + +#ifndef GP_REG_CELL_WORDS + #define GP_REG_CELL_WORDS 1 +#endif +#if GP_REG_CELL_WORDS == 1 +typedef uint8_t gp_reg_cell_t; +#endif +#if GP_REG_CELL_WORDS == 2 +typedef uint16_t gp_reg_cell_t; +#endif +#if GP_REG_CELL_WORDS == 3 +typedef uint32_t gp_reg_cell_t; +#endif +#if GP_REG_CELL_WORDS == 4 +typedef uint32_t gp_reg_cell_t; +#endif + +#ifndef IO_REG_CELL_WORDS + #define IO_REG_CELL_WORDS 1 +#endif +#if IO_REG_CELL_WORDS == 1 +typedef uint8_t io_reg_cell_t; +#endif +#if IO_REG_CELL_WORDS == 2 +typedef uint16_t io_reg_cell_t; +#endif +#if IO_REG_CELL_WORDS == 3 +typedef uint32_t io_reg_cell_t; +#endif +#if IO_REG_CELL_WORDS == 4 +typedef uint32_t io_reg_cell_t; +#endif + + + +void* default_addr_read_handler(uint64_t ident, uint64_t addr, void* rawCells); +void default_addr_write_handler(uint64_t ident, uint64_t addr, void* rawCells, void* data); + +#endif // ifndef __MEM_H__ diff --git a/inc/runner.h b/inc/runner.h new file mode 100644 index 0000000..2a35e61 --- /dev/null +++ b/inc/runner.h @@ -0,0 +1,10 @@ +#ifndef __RUNNER_H__ +#define __RUNNER_H__ + +#include +#include "mem.h" + +uint8_t makeTick(device_mem_t* devMem); + + +#endif // ifndef __RUNNER_H__ \ No newline at end of file diff --git a/src/device.c b/src/device.c new file mode 100644 index 0000000..a171200 --- /dev/null +++ b/src/device.c @@ -0,0 +1,693 @@ +#include +#include +#include + +#include "device.h" +#include "mem.h" +#include "runner.h" +#include "addrs.h" + + +uint64_t memSegToGlobal(device_specs_t* spec, uint8_t seg, uint64_t localaddr) +{ + uint64_t offset = 0; + for (uint8_t i = 0; i < seg; i++) + { + offset += spec->memSpecs[i]->len * spec->memSpecs[i]->wordLen; + } + return offset + localaddr; +} + + +void freeDevMem(device_mem_t* devMem) +{ + free(devMem->memsegShifts); + free(devMem->rawCells); + free(devMem->memreadCellAddrs); + free(devMem->memwriteCellAddrs); + free(devMem->cells); + free(devMem->smartAddrReadHandlers); + free(devMem->smartAddrWriteHandlers); + free(devMem); +} + +void freeDevSpec(void* _specs) +{ + device_specs_t* specs = _specs; + for (uint8_t i = 0; i < specs->memSpecsCount; i++) + { + free(specs->memSpecs[i]); + } + free(specs->memSpecs); + free(specs->executableSegments); + free(specs); +} + + +device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf) +{ + if (devSpec->memSpecsCount < 2) + { + sprintf(errbuf, "invalid amount of mem specs: %u", devSpec->memSpecsCount); + return NULL; + } + + device_mem_t* devMem = (device_mem_t*)malloc(sizeof(device_mem_t)); + if (devMem == NULL) + { + sprintf(errbuf, "unable to allocate dev memory struct"); + return NULL; + } + + uint64_t memTotalSize = 0; + for (uint8_t i = 0; i < devSpec->memSpecsCount; i++) + { + size_t tmp = devSpec->memSpecs[i]->start + devSpec->memSpecs[i]->len * devSpec->memSpecs[i]->wordLen; + if (memTotalSize < tmp) + { + memTotalSize = tmp; + } + } + + void* rawCells = (void*)malloc(memTotalSize); + if (rawCells == NULL) + { + sprintf(errbuf, "unable to allocate raw memory buf"); + free(devMem); + return NULL; + } + + for (size_t i = 0; i < memTotalSize; i++) + { + ((uint8_t*)rawCells)[i] = 0; + } + + devMem->memsegShifts = malloc(devSpec->memSpecsCount * sizeof(uint64_t)); + + if(devMem->memsegShifts == NULL) + { + sprintf(errbuf, "unable to allocate segment shift buffers"); + free(rawCells); + free(devMem); + return NULL; + } + + void** cells = malloc(devSpec->memSpecsCount * sizeof(void*)); + + if (cells == NULL) + { + sprintf(errbuf, "unable to allocate segment pointers"); + free(rawCells); + free(devMem->memsegShifts); + free(devMem); + return NULL; + } + + for (uint8_t i = 0; i < devSpec->memSpecsCount; i++) + { + cells[i] = rawCells + devSpec->memSpecs[i]->start; + } + + char** cellNames = malloc(sizeof(char*) * devSpec->memSpecsCount); + + if(cellNames == NULL) + { + sprintf(errbuf, "unable to allocate segment names map"); + free(devMem->memsegShifts); + free(devMem); + free(rawCells); + free(cells); + return NULL; + } + + for(size_t i = 0; i < devSpec->memSpecsCount; i++) + { + cellNames[i] = devSpec->memSpecs[i]->name; + } + + uint64_t* memreadCellAddrs = malloc(64 * sizeof(uint64_t)); + if (memreadCellAddrs == NULL) + { + sprintf(errbuf, "unable to allocate read interception addrs"); + free(devMem->memsegShifts); + free(devMem); + free(rawCells); + free(cells); + free(cellNames); + return NULL; + } + uint64_t* memwriteCellAddrs = malloc(64 * sizeof(uint64_t)); + + if (memwriteCellAddrs == NULL) + { + sprintf(errbuf, "unable to allocate write interception addrs"); + free(devMem->memsegShifts); + free(devMem); + free(rawCells); + free(memreadCellAddrs); + free(cells); + free(cellNames); + return NULL; + } + + uint64_t smartAddrReadMask = 0; + uint64_t smartAddrWriteMask = 0; + mem_h_read_handler* smartAddrReadHandlers = malloc(sizeof(mem_h_read_handler) * memTotalSize); + + + if (smartAddrReadHandlers == NULL) + { + sprintf(errbuf, "unable to allocate read interception handlers"); + free(memwriteCellAddrs); + free(devMem->memsegShifts); + free(devMem); + free(rawCells); + free(memreadCellAddrs); + free(cells); + free(cellNames); + return NULL; + } + + mem_h_write_handler* smartAddrWriteHandlers = malloc(sizeof(mem_h_write_handler) * memTotalSize); + + + if (smartAddrWriteHandlers == NULL) + { + sprintf(errbuf, "unable to allocate write interception handlers"); + free(smartAddrReadHandlers); + free(memwriteCellAddrs); + free(devMem->memsegShifts); + free(devMem); + free(rawCells); + free(memreadCellAddrs); + free(cells); + free(cellNames); + return NULL; + } + + + for(uint64_t i = 0; i < memTotalSize; i++) + { + smartAddrReadHandlers[i].func = default_addr_read_handler; + smartAddrReadHandlers[i].ident = 0; + + smartAddrWriteHandlers[i].func = default_addr_write_handler; + smartAddrWriteHandlers[i].ident = 0; + } + + + for(uint64_t i = 0; i < memTotalSize; i++) + { + if((i & smartAddrReadMask) == smartAddrReadMask) + { + smartAddrReadHandlers[i].func = default_addr_read_handler; + } + } + + + if (devSpec->smartReadSpecsCount > 0) + { + for(uint64_t i = 0; i < devSpec->smartReadSpecsCount; i++) + { + smart_read_spec_t t = devSpec->smartReadSpecs[i]; + uint64_t addr; + if (t.addrType == SMART_ADDR_TYPE_GLOBAL) + { + addr = t.addr; + } + else + { + addr = memSegToGlobal(devSpec, t.segno, t.localAddr); + } + smartAddrReadHandlers[addr].func = *t.handler; + smartAddrReadHandlers[addr].ident = t.ident; + smartAddrReadMask |= addr; + } + } + + + if (devSpec->smartWriteSpecsCount > 0) + { + for(uint64_t i = 0; i < devSpec->smartWriteSpecsCount; i++) + { + smart_write_spec_t t = devSpec->smartWriteSpecs[i]; + + uint64_t addr; + if (t.addrType == SMART_ADDR_TYPE_GLOBAL) + { + addr = t.addr; + } + else + { + addr = memSegToGlobal(devSpec, t.segno, t.localAddr); + } + smartAddrWriteHandlers[addr].func = *t.handler; + smartAddrWriteHandlers[addr].ident = t.ident; + smartAddrWriteMask |= t.addr; + } + } + + + devMem->cells = cells; + devMem->rawCells = rawCells; + devMem->memreadCellAddrs = memreadCellAddrs; + devMem->memwriteCellAddrs = memwriteCellAddrs; + devMem->memreadLen = 0; + devMem->memwriteLen = 0; + devMem->smartAddrReadMask = smartAddrReadMask; + devMem->smartAddrReadHandlers = smartAddrReadHandlers; + devMem->smartAddrWriteMask = smartAddrWriteMask; + devMem->smartAddrWriteHandlers = smartAddrWriteHandlers; + devMem->memsegNames = cellNames; + + for(uint8_t i = 0; i < devSpec->memSpecsCount; i++) + { + devMem->memsegShifts[i] = memSegToGlobal(devSpec, i, 0); + } + + return devMem; +} + + +uint8_t makeDeviceTick(device_public_context_t* devContext) +{ + device_info_t* devInfo = (device_info_t*)devContext->deviceInfo; + return makeTick(devInfo->deviceMem); +} + +device_info_t* initSpecs(device_specs_t* specs, char* errbuf) +{ + device_info_t* devInfo = malloc(sizeof(device_info_t)); + if (devInfo == NULL) + { + sprintf(errbuf, "unable to allocate dev info"); + return NULL; + } + + char genErrBuf[200]; + device_mem_t* devMem = genDevMem(specs, genErrBuf); + + if (devMem == NULL) + { + sprintf(errbuf, "unable to generate device memory: %s", genErrBuf); + free(devInfo); + return NULL; + } + + devInfo->specs = specs; + devInfo->deviceMem = devMem; + + return devInfo; +} + +void error(const char* err, char* errbuf) +{ + strcpy(errbuf, err); +} + +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)); + if (specs == NULL) + { + error("unable to allocate mem specs struct", errbuf); + return NULL; + } + uint8_t specCount = 0; + specs->executableSegmentsCount = 0; + + while (segments[specCount] != NULL) + { + if(segments[specCount]->isExecutable) + { + specs->executableSegmentsCount++; + } + specCount++; + } + specs->memSpecsCount = specCount; + + specs->memSpecs = malloc(specCount * sizeof(memseg_spec_t*)); + if (specs->memSpecs == NULL) + { + free(specs); + error("unable to allocate mem segment specs", errbuf); + return NULL; + } + + specs->executableSegments = malloc(sizeof(uint8_t) * specs->executableSegmentsCount); + if (specs->executableSegments == NULL) + { + error("unable to allocate mem executable specs", errbuf); + free(specs->memSpecs); + free(specs); + return NULL; + } + + + for (uint8_t i = 0; i < specCount; i++) + { + memseg_spec_t* spec = (memseg_spec_t*)malloc(sizeof(memseg_spec_t)); + if (spec == NULL) + { + sprintf(errbuf, "unable to allocate spec %d", i); + + for (uint8_t j = 0; j < i; j++) + { + free(specs->memSpecs[j]); + } + free(specs->memSpecs); + free(specs->executableSegments); + free(specs); + return NULL; + } + spec->name = NULL; + + 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) + { + 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++) + { + if(specs->memSpecs[j]->name != NULL) + { + free(specs->memSpecs[j]->name); + } + free(specs->memSpecs[j]); + } + free(specs->executableSegments); + free(specs->memSpecs); + free(specs); + return NULL; + } + specs->memSpecs[specNum]->name = malloc(sizeof(char) * strlen(segments[i]->name)); + 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); + return NULL; + } + + strcpy(specs->memSpecs[specNum]->name, segments[i]->name); + specs->memSpecs[specNum]->start = segments[i]->start; + specs->memSpecs[specNum]->len = segments[i]->len; + specs->memSpecs[specNum]->wordLen = segments[i]->wordLen; + if(segments[i]->isExecutable) + { + specs->executableSegments[executableSegmentsFound] = specNum; + executableSegmentsFound++; + } + foundSegments += 1; + } + + 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); + 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; + } + + return specs; +} + +void freeDevSpecs(device_specs_t* specs) +{ + 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); +} + +void fillSmartReadSpecs(device_specs_t* specs, smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount) +{ + specs->smartReadSpecs = smartReadSpecs; + specs->smartReadSpecsCount = smartReadSpecsCount; +} + +void fillSmartWriteSpecs(device_specs_t* specs, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount) +{ + specs->smartWriteSpecs = smartWriteSpecs; + specs->smartWriteSpecsCount = smartWriteSpecsCount; +} + +device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount, char* errbuf) +{ + + device_specs_t* specs = malloc(sizeof(device_specs_t)); + if (specs == NULL) + { + return NULL; + } + + + + specs->memSpecsCount = 4; + specs->memSpecs = malloc(specs->memSpecsCount * sizeof(memseg_spec_t*)); + if (specs->memSpecs == NULL) + { + sprintf(errbuf, "unable to allocate default mem segment specs"); + free(specs); + return NULL; + } + + + specs->executableSegmentsCount = 1; + specs->executableSegments = malloc(sizeof(uint8_t) * 1); + if (specs->executableSegments == NULL) + { + sprintf(errbuf, "unable to allocate default executable segments"); + free(specs->memSpecs); + free(specs); + return NULL; + } + specs->executableSegments[0] = 0; + + for (uint8_t i = 0; i < specs->memSpecsCount; i++) + { + specs->memSpecs[i] = malloc(sizeof(memseg_spec_t)); + if (specs->memSpecs[i] == NULL) + { + sprintf(errbuf, "unable to allocate default mem seg spec %u", i); + for (uint8_t j = 0; j < i; j++) + { + free(specs->memSpecs[j]); + } + free(specs->memSpecs); + free(specs->executableSegments); + free(specs); + return NULL; + } + } + + specs->smartReadSpecs = smartReadSpecs; + specs->smartReadSpecsCount = smartReadSpecsCount; + + specs->smartWriteSpecs = smartWriteSpecs; + specs->smartWriteSpecsCount = smartWriteSpecsCount; + + specs->memSpecs[0]->len = 255; + specs->memSpecs[0]->start = 0; + specs->memSpecs[0]->wordLen = 1; + + specs->memSpecs[1]->len = 1; + specs->memSpecs[1]->start = 256; + specs->memSpecs[1]->wordLen = 1; + + + char initErrbuf[200]; + device_public_context_t* ret = init(specs, initErrbuf); + + if (ret == NULL) + { + sprintf(errbuf, "unable to init default: %s", initErrbuf); + freeDevSpec(specs); + return NULL; + } + free(specs->memSpecs); + free(specs->executableSegments); + free(specs); + + return ret; +} + + +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); + if (devInfo == NULL) + { + sprintf(errbuf, "unable to init specs: %s", initErrbuf); + freeDevSpec(realSpecs); + free(pubDevContext); + return NULL; + } + + pubDevContext->deviceInfo = (void*)devInfo; + pubDevContext->deviceMem = devInfo->deviceMem; + + return pubDevContext; +} + +uint8_t pubDeviceType() +{ + return EXTENDED_DEVICE_TYPE_DUMMY; +} + diff --git a/src/mem.c b/src/mem.c new file mode 100644 index 0000000..4c154ff --- /dev/null +++ b/src/mem.c @@ -0,0 +1,10 @@ +#include "mem.h" + +// fallback handler that acts like &rawCells[addr] +void* default_addr_read_handler(uint64_t ident, uint64_t addr, void* rawCells) +{ + return (rawCells + addr); +} + +// empty handler cuz void* data size depends on a usage context +void default_addr_write_handler(uint64_t ident, uint64_t addr, void* rawCells, void* data) {} \ No newline at end of file diff --git a/src/runner.c b/src/runner.c new file mode 100644 index 0000000..19fe92d --- /dev/null +++ b/src/runner.c @@ -0,0 +1,8 @@ +#include "runner.h" +#include + + +uint8_t makeTick(device_mem_t* devMem) +{ + return 0; +}