Add write-after-cycles, reset handling
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
#elif OPCODE_WORDSIZE == 4
|
||||
typedef uint32_t opcode_t;
|
||||
#else
|
||||
#error OPCODE_WORDSIZE must be one of 1,2,3,
|
||||
#error OPCODE_WORDSIZE must be one of 1,2,3,4
|
||||
#endif
|
||||
|
||||
|
||||
@@ -69,37 +69,4 @@ opcode_t extractOpcode(device_mem_t* devMem, prog_counter_t programCounter);
|
||||
|
||||
|
||||
|
||||
#define READ_MEM(__tgt, __mem, __segno, __addr, __cell_t) \
|
||||
{\
|
||||
uint64_t __globalAddr = __mem->memsegShifts[__segno] + __addr; \
|
||||
if (__mem->smartAddrReadHandlers[__globalAddr].func != NULL) \
|
||||
{ \
|
||||
__tgt = *(__cell_t*)__mem->smartAddrReadHandlers[__globalAddr].func(__mem->smartAddrReadHandlers[__globalAddr].ident, __addr, __mem->rawCells + __mem->memsegShifts[__segno]); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
__tgt = ((__cell_t*)__mem->cells[__segno])[__addr]; \
|
||||
} \
|
||||
__mem->memreadCellAddrs[__mem->memreadLen] = __globalAddr; \
|
||||
__mem->memreadLen += 1; \
|
||||
}
|
||||
|
||||
#define WRITE_MEM(__mem, __segno, __addr, __cell_t, __val) \
|
||||
{ \
|
||||
uint64_t __globalAddr = __mem->memsegShifts[__segno] + __addr; \
|
||||
if (__mem->smartAddrWriteHandlers[__globalAddr].func != NULL) \
|
||||
{ \
|
||||
__cell_t __dat = (__cell_t)(__val); \
|
||||
__mem->smartAddrWriteHandlers[__globalAddr].func(__mem->smartAddrWriteHandlers[__globalAddr].ident, __addr, __mem->rawCells + __mem->memsegShifts[__segno], (void*)&__dat); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
((__cell_t*)__mem->cells[__segno])[__addr] = (__cell_t)(__val); \
|
||||
} \
|
||||
__mem->memwriteCellAddrs[__mem->memwriteLen] = __globalAddr; \
|
||||
__mem->memwriteLen += 1; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // ifndef __INSTR_H__
|
||||
@@ -1,8 +1,12 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "device.h"
|
||||
#include "libhmmmm/mem.h"
|
||||
#include "mem.h"
|
||||
#include "mem_seg.h"
|
||||
#include "runner.h"
|
||||
#include "instr.h"
|
||||
#include "addrs.h"
|
||||
@@ -10,21 +14,26 @@
|
||||
|
||||
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;
|
||||
// uint64_t offset = 0;
|
||||
// for (uint8_t i = 0; i < seg; i++)
|
||||
// {
|
||||
// offset += spec->memSpecs[i]->len * spec->memSpecs[i]->wordLen;
|
||||
// }
|
||||
return spec->memSpecs[seg]->start + localaddr;
|
||||
}
|
||||
|
||||
|
||||
void freeDevMem(device_mem_t* devMem)
|
||||
{
|
||||
free(devMem->memsegShifts);
|
||||
free(devMem->memsegSizes);
|
||||
free(devMem->rawCells);
|
||||
free(devMem->memreadCellAddrs);
|
||||
free(devMem->memwriteCellAddrs);
|
||||
free(devMem->memwriteCellSegments);
|
||||
free(devMem->memwriteValues[0]);
|
||||
free(devMem->memwriteValues);
|
||||
free(devMem->memwriteWordLengths);
|
||||
free(devMem->cells);
|
||||
free(devMem->smartAddrReadHandlers);
|
||||
free(devMem->smartAddrWriteHandlers);
|
||||
@@ -46,13 +55,7 @@ void freeDevSpec(void* _specs)
|
||||
|
||||
device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
{
|
||||
if (devSpec->memSpecsCount < MEMDATA_OPSIZE)
|
||||
{
|
||||
sprintf(errbuf, "invalid amount of mem specs: %u", devSpec->memSpecsCount);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device_mem_t* devMem = (device_mem_t*)malloc(sizeof(device_mem_t));
|
||||
device_mem_t* devMem = (device_mem_t*)calloc(1, sizeof(device_mem_t));
|
||||
if (devMem == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate dev memory struct");
|
||||
@@ -62,14 +65,14 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
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;
|
||||
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);
|
||||
void* rawCells = (void*)calloc(memTotalSize, sizeof(void*));
|
||||
if (rawCells == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate raw memory buf %lu bytes", memTotalSize);
|
||||
@@ -82,7 +85,7 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
((uint8_t*)rawCells)[i] = 0;
|
||||
}
|
||||
|
||||
devMem->memsegShifts = malloc(devSpec->memSpecsCount * sizeof(uint64_t));
|
||||
devMem->memsegShifts = calloc(devSpec->memSpecsCount, sizeof(uint64_t));
|
||||
|
||||
if(devMem->memsegShifts == NULL)
|
||||
{
|
||||
@@ -92,7 +95,7 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void** cells = malloc(devSpec->memSpecsCount * sizeof(void*));
|
||||
void** cells = calloc(devSpec->memSpecsCount, sizeof(void*));
|
||||
|
||||
if (cells == NULL)
|
||||
{
|
||||
@@ -103,12 +106,7 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
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);
|
||||
char** cellNames = calloc(devSpec->memSpecsCount, sizeof(char*));
|
||||
|
||||
if(cellNames == NULL)
|
||||
{
|
||||
@@ -122,10 +120,18 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
|
||||
for(size_t i = 0; i < devSpec->memSpecsCount; i++)
|
||||
{
|
||||
cellNames[i] = devSpec->memSpecs[i]->name;
|
||||
// cellNames[i] = devSpec->memSpecs[i]->name;
|
||||
}
|
||||
|
||||
uint64_t* memreadCellAddrs = malloc(64 * sizeof(uint64_t));
|
||||
for (uint8_t i = 0; i < devSpec->memSpecsCount; i++)
|
||||
{
|
||||
printf("init seg \"%s\": %lu:%lu\n", devSpec->memSpecs[i]->name, devSpec->memSpecs[i]->start, devSpec->memSpecs[i]->len);
|
||||
cells[i] = &(((uint8_t*)rawCells)[devSpec->memSpecs[i]->start]);
|
||||
cellNames[i] = devSpec->memSpecs[i]->name;
|
||||
// cells[i] = (void*)((size_t)rawCells + (size_t)devSpec->memSpecs[i]->start);
|
||||
}
|
||||
|
||||
uint64_t* memreadCellAddrs = calloc(MEM_ACCESS_INTERCEPT_BUF_SIZE, sizeof(uint64_t));
|
||||
if (memreadCellAddrs == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate read interception addrs");
|
||||
@@ -136,7 +142,7 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
free(cellNames);
|
||||
return NULL;
|
||||
}
|
||||
uint64_t* memwriteCellAddrs = malloc(64 * sizeof(uint64_t));
|
||||
uint64_t* memwriteCellAddrs = calloc(MEM_ACCESS_INTERCEPT_BUF_SIZE, sizeof(uint64_t));
|
||||
|
||||
if (memwriteCellAddrs == NULL)
|
||||
{
|
||||
@@ -150,44 +156,132 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t smartAddrReadMask = 0;
|
||||
// memSegToGlobal(devSpec, MEMDATA_IO_REGS, 0x16)
|
||||
// | memSegToGlobal(devSpec, MEMDATA_IO_REGS, 0x17)
|
||||
// | memSegToGlobal(devSpec, MEMDATA_IO_REGS, 0x18);
|
||||
|
||||
uint64_t smartAddrWriteMask = 0;
|
||||
// memSegToGlobal(devSpec, MEMDATA_IO_REGS, 0x16)
|
||||
// | memSegToGlobal(devSpec, MEMDATA_IO_REGS, 0x17)
|
||||
// | memSegToGlobal(devSpec, MEMDATA_IO_REGS, 0x18);
|
||||
|
||||
mem_h_read_handler* smartAddrReadHandlers = malloc(sizeof(mem_h_read_handler) * memTotalSize);
|
||||
|
||||
|
||||
if (smartAddrReadHandlers == NULL)
|
||||
uint8_t* memwriteCellSegments = calloc(MEM_ACCESS_INTERCEPT_BUF_SIZE, sizeof(uint8_t));
|
||||
if(memwriteCellSegments == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate read interception handlers");
|
||||
free(memwriteCellAddrs);
|
||||
sprintf(errbuf, "unable to allocate write interception addrs");
|
||||
free(devMem->memsegShifts);
|
||||
free(devMem);
|
||||
free(rawCells);
|
||||
free(memreadCellAddrs);
|
||||
free(cells);
|
||||
free(cellNames);
|
||||
free(memwriteCellAddrs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem_h_write_handler* smartAddrWriteHandlers = malloc(sizeof(mem_h_write_handler) * memTotalSize);
|
||||
void** memwriteValues = calloc(MEM_ACCESS_INTERCEPT_BUF_SIZE, sizeof(void*));
|
||||
|
||||
if(memwriteValues == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate write interception addrs");
|
||||
free(devMem->memsegShifts);
|
||||
free(devMem);
|
||||
free(rawCells);
|
||||
free(memreadCellAddrs);
|
||||
free(cells);
|
||||
free(cellNames);
|
||||
free(memwriteCellAddrs);
|
||||
free(memwriteCellSegments);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t* memwriteValuesContainers = calloc(MEM_ACCESS_INTERCEPT_BUF_SIZE, sizeof(uint64_t));
|
||||
if(memwriteValuesContainers == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate write interception addrs");
|
||||
free(devMem->memsegShifts);
|
||||
free(devMem);
|
||||
free(rawCells);
|
||||
free(memreadCellAddrs);
|
||||
free(cells);
|
||||
free(cellNames);
|
||||
free(memwriteCellAddrs);
|
||||
free(memwriteCellSegments);
|
||||
free(memwriteValues);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < 64; i++)
|
||||
{
|
||||
memwriteValues[i] = &memwriteValuesContainers[i];
|
||||
}
|
||||
|
||||
uint8_t* memwriteWordLengths = calloc(MEM_ACCESS_INTERCEPT_BUF_SIZE, sizeof(uint8_t));
|
||||
if(memwriteWordLengths == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate write interception addrs");
|
||||
free(devMem->memsegShifts);
|
||||
free(devMem);
|
||||
free(rawCells);
|
||||
free(memreadCellAddrs);
|
||||
free(cells);
|
||||
free(cellNames);
|
||||
free(memwriteCellAddrs);
|
||||
free(memwriteCellSegments);
|
||||
free(memwriteValues);
|
||||
free(memwriteValuesContainers);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t smartAddrReadMask = 0;
|
||||
uint64_t smartAddrWriteMask = 0;
|
||||
mem_h_read_handler* smartAddrReadHandlers = calloc(memTotalSize, sizeof(mem_h_read_handler));
|
||||
|
||||
if(memwriteCellSegments == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate read interception handlers");
|
||||
free(devMem->memsegShifts);
|
||||
free(devMem);
|
||||
free(rawCells);
|
||||
free(memreadCellAddrs);
|
||||
free(cells);
|
||||
free(cellNames);
|
||||
free(memwriteCellAddrs);
|
||||
free(memwriteCellSegments);
|
||||
free(memwriteValues);
|
||||
free(memwriteValuesContainers);
|
||||
free(memwriteWordLengths);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem_h_write_handler* smartAddrWriteHandlers = calloc(memTotalSize, sizeof(mem_h_write_handler));
|
||||
|
||||
|
||||
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(memwriteCellAddrs);
|
||||
free(memwriteCellSegments);
|
||||
free(memwriteValues);
|
||||
free(memwriteValuesContainers);
|
||||
free(memwriteWordLengths);
|
||||
free(cells);
|
||||
free(cellNames);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t* memsegSizes = calloc(devSpec->memSpecsCount, sizeof(uint64_t));
|
||||
if(memsegSizes == NULL)
|
||||
{
|
||||
|
||||
sprintf(errbuf, "unable to allocate write interception handlers");
|
||||
free(smartAddrWriteHandlers);
|
||||
free(smartAddrReadHandlers);
|
||||
free(devMem->memsegShifts);
|
||||
free(devMem);
|
||||
free(rawCells);
|
||||
free(memreadCellAddrs);
|
||||
free(memwriteCellAddrs);
|
||||
free(memwriteCellSegments);
|
||||
free(memwriteValues);
|
||||
free(memwriteValuesContainers);
|
||||
free(memwriteWordLengths);
|
||||
free(cells);
|
||||
free(cellNames);
|
||||
return NULL;
|
||||
@@ -260,6 +354,9 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
devMem->rawCells = rawCells;
|
||||
devMem->memreadCellAddrs = memreadCellAddrs;
|
||||
devMem->memwriteCellAddrs = memwriteCellAddrs;
|
||||
devMem->memwriteCellSegments = memwriteCellSegments;
|
||||
devMem->memwriteWordLengths = memwriteWordLengths;
|
||||
devMem->memwriteValues = memwriteValues;
|
||||
devMem->memreadLen = 0;
|
||||
devMem->memwriteLen = 0;
|
||||
devMem->smartAddrReadMask = smartAddrReadMask;
|
||||
@@ -267,12 +364,34 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
devMem->smartAddrWriteMask = smartAddrWriteMask;
|
||||
devMem->smartAddrWriteHandlers = smartAddrWriteHandlers;
|
||||
devMem->memsegNames = cellNames;
|
||||
devMem->memsegSizes = memsegSizes;
|
||||
|
||||
for(uint8_t i = 0; i < devSpec->memSpecsCount; i++)
|
||||
memseg_metadata_t requiredSegments[] = MEMSEG_DEFINES;
|
||||
|
||||
for (uint8_t i = 0; i < devSpec->memSpecsCount; i++)
|
||||
{
|
||||
devMem->memsegShifts[i] = memSegToGlobal(devSpec, i, 0);
|
||||
|
||||
for(uint8_t j = 0; j < sizeof(requiredSegments) / sizeof(memseg_metadata_t); j++)
|
||||
{
|
||||
const memseg_metadata_t seg_def = requiredSegments[j];
|
||||
|
||||
if(strcmp(seg_def.name, devSpec->memSpecs[i]->name) == 0)
|
||||
{
|
||||
const uint8_t seg_id = seg_def.seg_id;
|
||||
devMem->memsegShifts[seg_id] = memSegToGlobal(devSpec, i, 0);
|
||||
devMem->memsegSizes[seg_id] = devSpec->memSpecs[i]->len;
|
||||
printf("set mem segment %d meta: +%lu/%lu \n", seg_id, devMem->memsegShifts[j], devMem->memsegSizes[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// for(uint8_t i = 0; i < devSpec->memSpecsCount; i++)
|
||||
// {
|
||||
// devMem->memsegShifts[i] = memSegToGlobal(devSpec, i, 0);
|
||||
// devMem->memsegSizes[i] = devSpec->memSpecs[i]->len;
|
||||
// }
|
||||
|
||||
setOpcodeSizes((uint8_t*)(devMem->cells[MEMDATA_OPSIZE]));
|
||||
|
||||
return devMem;
|
||||
@@ -282,12 +401,18 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||
uint8_t makeDeviceTick(device_public_context_t* devContext)
|
||||
{
|
||||
device_info_t* devInfo = (device_info_t*)devContext->deviceInfo;
|
||||
return makeTick(devInfo->pc, devInfo->instr, devInfo->deviceMem);
|
||||
prog_counter_t _pc;
|
||||
READ_MEM(_pc, devInfo->deviceMem, MEMSEG_PC_SEG_NUM, MEMSEG_PC_ADDR, prog_counter_t)
|
||||
// printf("old PC is %d\n", _pc);
|
||||
uint8_t ticks = makeTick(&_pc, devInfo->instr, devInfo->deviceMem);
|
||||
WRITE_MEM(devInfo->deviceMem, MEMSEG_PC_SEG_NUM, MEMSEG_PC_ADDR, prog_counter_t, _pc);
|
||||
// printf("new PC is %d\n", _pc);
|
||||
return ticks;
|
||||
}
|
||||
|
||||
device_info_t* initSpecs(device_specs_t* specs, char* errbuf)
|
||||
{
|
||||
device_info_t* devInfo = malloc(sizeof(device_info_t));
|
||||
device_info_t* devInfo = calloc(1, sizeof(device_info_t));
|
||||
if (devInfo == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate dev info");
|
||||
@@ -304,7 +429,7 @@ device_info_t* initSpecs(device_specs_t* specs, char* errbuf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
devInfo->pc = (prog_counter_t*)(devMem->rawCells + specs->pcAddr);
|
||||
devInfo->pc = &((prog_counter_t*)(devMem->cells[MEMSEG_PC_SEG_NUM]))[MEMSEG_PC_ADDR];
|
||||
*(devInfo->pc) = 0;
|
||||
devInfo->specs = specs;
|
||||
|
||||
@@ -334,12 +459,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;
|
||||
|
||||
@@ -351,29 +489,39 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
|
||||
}
|
||||
specCount++;
|
||||
}
|
||||
|
||||
const uint8_t providedSpecCount = 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);
|
||||
@@ -385,6 +533,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;
|
||||
@@ -392,59 +541,64 @@ 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++)
|
||||
for (uint8_t i = 0; i < providedSpecCount; i++)
|
||||
{
|
||||
uint8_t specNum = 0xFF;
|
||||
if (strcmp(segments[i]->name, "reg_gp") == 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_GP_REGS;
|
||||
}
|
||||
else if (strcmp(segments[i]->name, "reg_io") == 0)
|
||||
{
|
||||
specNum = MEMDATA_IO_REGS;
|
||||
}
|
||||
else if (strcmp(segments[i]->name, "ds") == 0)
|
||||
{
|
||||
specNum = MEMDATA_DS;
|
||||
}
|
||||
else if (strcmp(segments[i]->name, "ps") == 0)
|
||||
{
|
||||
specNum = MEMDATA_PS;
|
||||
}
|
||||
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) == 0)
|
||||
{
|
||||
if(specs->memSpecs[j]->name != NULL)
|
||||
printf("found seg \"%s\"\n", seg_def.name);
|
||||
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)
|
||||
{
|
||||
printf("seg executable req satisfyed (%d)\n", seg_def.is_executable);
|
||||
requiredSegmentsFoundMap[j] = 1;
|
||||
specNum = seg_def.seg_id;
|
||||
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) + 1));
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -452,48 +606,66 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
|
||||
specs->memSpecs[specNum]->start = segments[i]->start;
|
||||
specs->memSpecs[specNum]->len = segments[i]->len;
|
||||
specs->memSpecs[specNum]->wordLen = segments[i]->wordLen;
|
||||
printf("set segment %s :%lu->%lu/%d\n", segments[i]->name, segments[i]->start, segments[i]->len, segments[i]->wordLen);
|
||||
if(segments[i]->isExecutable)
|
||||
{
|
||||
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];
|
||||
printf("found segment that not specified: \"%s\"\n", seg_def.name);
|
||||
|
||||
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) + 1, 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 < 4)
|
||||
{
|
||||
sprintf(errbuf, "invalid amount of segments: must be 4");
|
||||
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;
|
||||
}
|
||||
printf("set all segments\n");
|
||||
|
||||
#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);
|
||||
|
||||
printf("parse specs done\n");
|
||||
return specs;
|
||||
}
|
||||
|
||||
@@ -526,8 +698,9 @@ 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)
|
||||
{
|
||||
|
||||
device_specs_t* specs = malloc(sizeof(device_specs_t));
|
||||
return NULL;
|
||||
//TODO
|
||||
device_specs_t* specs = calloc(1, sizeof(device_specs_t));
|
||||
if (specs == NULL)
|
||||
{
|
||||
return NULL;
|
||||
@@ -536,7 +709,7 @@ device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t
|
||||
|
||||
|
||||
specs->memSpecsCount = 4;
|
||||
specs->memSpecs = malloc(specs->memSpecsCount * sizeof(memseg_spec_t*));
|
||||
specs->memSpecs = calloc(specs->memSpecsCount, sizeof(memseg_spec_t*));
|
||||
if (specs->memSpecs == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate default mem segment specs");
|
||||
@@ -546,7 +719,7 @@ device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t
|
||||
|
||||
|
||||
specs->executableSegmentsCount = 1;
|
||||
specs->executableSegments = malloc(sizeof(uint8_t) * 1);
|
||||
specs->executableSegments = calloc(1, sizeof(uint8_t));
|
||||
if (specs->executableSegments == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate default executable segments");
|
||||
@@ -558,7 +731,7 @@ device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t
|
||||
|
||||
for (uint8_t i = 0; i < specs->memSpecsCount; i++)
|
||||
{
|
||||
specs->memSpecs[i] = malloc(sizeof(memseg_spec_t));
|
||||
specs->memSpecs[i] = calloc(1, sizeof(memseg_spec_t));
|
||||
if (specs->memSpecs[i] == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate default mem seg spec %u", i);
|
||||
@@ -614,119 +787,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->memSpecs[MEMDATA_OPSIZE]->len = ((opcode_t)~0);
|
||||
realSpecs->memSpecs[MEMDATA_OPSIZE]->start = maxAddr + PC_WORDSIZE;
|
||||
realSpecs->memSpecs[MEMDATA_OPSIZE]->wordLen = 1;
|
||||
realSpecs->memSpecs[MEMDATA_OPSIZE]->name = NULL;
|
||||
|
||||
realSpecs->memSpecs[specCount - 2]->len = 1;
|
||||
realSpecs->memSpecs[specCount - 2]->start = maxAddr;
|
||||
realSpecs->memSpecs[specCount - 2]->wordLen = PC_WORDSIZE;
|
||||
realSpecs->memSpecs[specCount - 2]->name = NULL;
|
||||
|
||||
|
||||
realSpecs->pcAddr = memSegToGlobal(realSpecs, pcSpecSegNum, 0);
|
||||
|
||||
device_public_context_t* pubDevContext = malloc(sizeof(device_public_context_t));
|
||||
device_public_context_t* pubDevContext = calloc(1, 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;
|
||||
}
|
||||
@@ -737,6 +809,10 @@ device_public_context_t* init(device_specs_t* specs, char* errbuf)
|
||||
return pubDevContext;
|
||||
}
|
||||
|
||||
uint8_t pubDeviceType()
|
||||
{
|
||||
return DEVICE_TYPE;
|
||||
}
|
||||
|
||||
size_t pubExtractPcounter(device_public_context_t* devContext)
|
||||
{
|
||||
@@ -757,8 +833,22 @@ uint8_t pubExtractPcounterSizeWords()
|
||||
return sizeof(prog_counter_t);
|
||||
}
|
||||
|
||||
uint8_t pubDeviceType()
|
||||
{
|
||||
return EXTENDED_DEVICE_TYPE_INSTR_SIMUL;
|
||||
}
|
||||
|
||||
|
||||
void reset (device_specs_t* specs, device_public_context_t* devInfo)
|
||||
{
|
||||
for(size_t i = 0; i < specs->memSpecsCount; i++)
|
||||
{
|
||||
if(i != MEMDATA_OPSIZE)
|
||||
{
|
||||
const memseg_spec_t* spec = specs->memSpecs[i];
|
||||
for(size_t j = 0; j < spec->len; j++)
|
||||
{
|
||||
((uint8_t*)devInfo->deviceMem->cells[i])[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
devInfo->deviceMem->memwriteLen = 0;
|
||||
devInfo->deviceMem->memreadLen = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user