Add write-after-cycles, reset handling
This commit is contained in:
2
Makefile
2
Makefile
@@ -11,7 +11,7 @@ LIBS_HEADERS=deps/ $(OPENSSL_INCLUDE)
|
|||||||
SYSTEM_INCLUDES=-isystem deps/flatcc/include/ -isystem $(PROTO_INC_DIR)/
|
SYSTEM_INCLUDES=-isystem deps/flatcc/include/ -isystem $(PROTO_INC_DIR)/
|
||||||
STATIC_LIBS=crypto
|
STATIC_LIBS=crypto
|
||||||
STANDART=c23
|
STANDART=c23
|
||||||
OPTIMIZE=-O3
|
OPTIMIZE=-Og
|
||||||
TARGET=main
|
TARGET=main
|
||||||
|
|
||||||
FLATCC = deps/flatcc/bin/flatcc
|
FLATCC = deps/flatcc/bin/flatcc
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#elif OPCODE_WORDSIZE == 4
|
#elif OPCODE_WORDSIZE == 4
|
||||||
typedef uint32_t opcode_t;
|
typedef uint32_t opcode_t;
|
||||||
#else
|
#else
|
||||||
#error OPCODE_WORDSIZE must be one of 1,2,3,
|
#error OPCODE_WORDSIZE must be one of 1,2,3,4
|
||||||
#endif
|
#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__
|
#endif // ifndef __INSTR_H__
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "libhmmmm/mem.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "mem_seg.h"
|
||||||
#include "runner.h"
|
#include "runner.h"
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
#include "addrs.h"
|
#include "addrs.h"
|
||||||
@@ -10,21 +14,26 @@
|
|||||||
|
|
||||||
uint64_t memSegToGlobal(device_specs_t* spec, uint8_t seg, uint64_t localaddr)
|
uint64_t memSegToGlobal(device_specs_t* spec, uint8_t seg, uint64_t localaddr)
|
||||||
{
|
{
|
||||||
uint64_t offset = 0;
|
// uint64_t offset = 0;
|
||||||
for (uint8_t i = 0; i < seg; i++)
|
// for (uint8_t i = 0; i < seg; i++)
|
||||||
{
|
// {
|
||||||
offset += spec->memSpecs[i]->len * spec->memSpecs[i]->wordLen;
|
// offset += spec->memSpecs[i]->len * spec->memSpecs[i]->wordLen;
|
||||||
}
|
// }
|
||||||
return offset + localaddr;
|
return spec->memSpecs[seg]->start + localaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void freeDevMem(device_mem_t* devMem)
|
void freeDevMem(device_mem_t* devMem)
|
||||||
{
|
{
|
||||||
free(devMem->memsegShifts);
|
free(devMem->memsegShifts);
|
||||||
|
free(devMem->memsegSizes);
|
||||||
free(devMem->rawCells);
|
free(devMem->rawCells);
|
||||||
free(devMem->memreadCellAddrs);
|
free(devMem->memreadCellAddrs);
|
||||||
free(devMem->memwriteCellAddrs);
|
free(devMem->memwriteCellAddrs);
|
||||||
|
free(devMem->memwriteCellSegments);
|
||||||
|
free(devMem->memwriteValues[0]);
|
||||||
|
free(devMem->memwriteValues);
|
||||||
|
free(devMem->memwriteWordLengths);
|
||||||
free(devMem->cells);
|
free(devMem->cells);
|
||||||
free(devMem->smartAddrReadHandlers);
|
free(devMem->smartAddrReadHandlers);
|
||||||
free(devMem->smartAddrWriteHandlers);
|
free(devMem->smartAddrWriteHandlers);
|
||||||
@@ -46,13 +55,7 @@ void freeDevSpec(void* _specs)
|
|||||||
|
|
||||||
device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
||||||
{
|
{
|
||||||
if (devSpec->memSpecsCount < MEMDATA_OPSIZE)
|
device_mem_t* devMem = (device_mem_t*)calloc(1, sizeof(device_mem_t));
|
||||||
{
|
|
||||||
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)
|
if (devMem == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate dev memory struct");
|
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;
|
uint64_t memTotalSize = 0;
|
||||||
for (uint8_t i = 0; i < devSpec->memSpecsCount; i++)
|
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)
|
if (memTotalSize < tmp)
|
||||||
{
|
{
|
||||||
memTotalSize = tmp;
|
memTotalSize = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* rawCells = (void*)malloc(memTotalSize);
|
void* rawCells = (void*)calloc(memTotalSize, sizeof(void*));
|
||||||
if (rawCells == NULL)
|
if (rawCells == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate raw memory buf %lu bytes", memTotalSize);
|
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;
|
((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)
|
if(devMem->memsegShifts == NULL)
|
||||||
{
|
{
|
||||||
@@ -92,7 +95,7 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void** cells = malloc(devSpec->memSpecsCount * sizeof(void*));
|
void** cells = calloc(devSpec->memSpecsCount, sizeof(void*));
|
||||||
|
|
||||||
if (cells == NULL)
|
if (cells == NULL)
|
||||||
{
|
{
|
||||||
@@ -103,12 +106,7 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t i = 0; i < devSpec->memSpecsCount; i++)
|
char** cellNames = calloc(devSpec->memSpecsCount, sizeof(char*));
|
||||||
{
|
|
||||||
cells[i] = rawCells + devSpec->memSpecs[i]->start;
|
|
||||||
}
|
|
||||||
|
|
||||||
char** cellNames = malloc(sizeof(char*) * devSpec->memSpecsCount);
|
|
||||||
|
|
||||||
if(cellNames == NULL)
|
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++)
|
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)
|
if (memreadCellAddrs == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate read interception addrs");
|
sprintf(errbuf, "unable to allocate read interception addrs");
|
||||||
@@ -136,7 +142,7 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
|||||||
free(cellNames);
|
free(cellNames);
|
||||||
return NULL;
|
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)
|
if (memwriteCellAddrs == NULL)
|
||||||
{
|
{
|
||||||
@@ -150,44 +156,132 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t smartAddrReadMask = 0;
|
uint8_t* memwriteCellSegments = calloc(MEM_ACCESS_INTERCEPT_BUF_SIZE, sizeof(uint8_t));
|
||||||
// memSegToGlobal(devSpec, MEMDATA_IO_REGS, 0x16)
|
if(memwriteCellSegments == NULL)
|
||||||
// | 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)
|
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate read interception handlers");
|
sprintf(errbuf, "unable to allocate write interception addrs");
|
||||||
free(memwriteCellAddrs);
|
|
||||||
free(devMem->memsegShifts);
|
free(devMem->memsegShifts);
|
||||||
free(devMem);
|
free(devMem);
|
||||||
free(rawCells);
|
free(rawCells);
|
||||||
free(memreadCellAddrs);
|
free(memreadCellAddrs);
|
||||||
free(cells);
|
free(cells);
|
||||||
free(cellNames);
|
free(cellNames);
|
||||||
|
free(memwriteCellAddrs);
|
||||||
return NULL;
|
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)
|
if (smartAddrWriteHandlers == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate write interception handlers");
|
sprintf(errbuf, "unable to allocate write interception handlers");
|
||||||
free(smartAddrReadHandlers);
|
free(smartAddrReadHandlers);
|
||||||
free(memwriteCellAddrs);
|
|
||||||
free(devMem->memsegShifts);
|
free(devMem->memsegShifts);
|
||||||
free(devMem);
|
free(devMem);
|
||||||
free(rawCells);
|
free(rawCells);
|
||||||
free(memreadCellAddrs);
|
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(cells);
|
||||||
free(cellNames);
|
free(cellNames);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -260,6 +354,9 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
|||||||
devMem->rawCells = rawCells;
|
devMem->rawCells = rawCells;
|
||||||
devMem->memreadCellAddrs = memreadCellAddrs;
|
devMem->memreadCellAddrs = memreadCellAddrs;
|
||||||
devMem->memwriteCellAddrs = memwriteCellAddrs;
|
devMem->memwriteCellAddrs = memwriteCellAddrs;
|
||||||
|
devMem->memwriteCellSegments = memwriteCellSegments;
|
||||||
|
devMem->memwriteWordLengths = memwriteWordLengths;
|
||||||
|
devMem->memwriteValues = memwriteValues;
|
||||||
devMem->memreadLen = 0;
|
devMem->memreadLen = 0;
|
||||||
devMem->memwriteLen = 0;
|
devMem->memwriteLen = 0;
|
||||||
devMem->smartAddrReadMask = smartAddrReadMask;
|
devMem->smartAddrReadMask = smartAddrReadMask;
|
||||||
@@ -267,12 +364,34 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
|||||||
devMem->smartAddrWriteMask = smartAddrWriteMask;
|
devMem->smartAddrWriteMask = smartAddrWriteMask;
|
||||||
devMem->smartAddrWriteHandlers = smartAddrWriteHandlers;
|
devMem->smartAddrWriteHandlers = smartAddrWriteHandlers;
|
||||||
devMem->memsegNames = cellNames;
|
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]));
|
setOpcodeSizes((uint8_t*)(devMem->cells[MEMDATA_OPSIZE]));
|
||||||
|
|
||||||
return devMem;
|
return devMem;
|
||||||
@@ -282,12 +401,18 @@ device_mem_t* genDevMem(device_specs_t* devSpec, char* errbuf)
|
|||||||
uint8_t makeDeviceTick(device_public_context_t* devContext)
|
uint8_t makeDeviceTick(device_public_context_t* devContext)
|
||||||
{
|
{
|
||||||
device_info_t* devInfo = (device_info_t*)devContext->deviceInfo;
|
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* 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)
|
if (devInfo == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate dev info");
|
sprintf(errbuf, "unable to allocate dev info");
|
||||||
@@ -304,7 +429,7 @@ device_info_t* initSpecs(device_specs_t* specs, char* errbuf)
|
|||||||
return NULL;
|
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->pc) = 0;
|
||||||
devInfo->specs = specs;
|
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)
|
device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
|
||||||
{
|
{
|
||||||
conf_mem_seg_t** segments = devConf->memConf->memSegConfs;
|
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)
|
if (specs == NULL)
|
||||||
{
|
{
|
||||||
error("unable to allocate mem specs struct", errbuf);
|
error("unable to allocate mem specs struct", errbuf);
|
||||||
return NULL;
|
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;
|
uint8_t specCount = 0;
|
||||||
specs->executableSegmentsCount = 0;
|
specs->executableSegmentsCount = 0;
|
||||||
|
|
||||||
@@ -351,29 +489,39 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
|
|||||||
}
|
}
|
||||||
specCount++;
|
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->memSpecsCount = specCount;
|
||||||
|
|
||||||
specs->memSpecs = malloc(specCount * sizeof(memseg_spec_t*));
|
specs->memSpecs = calloc(specCount, sizeof(memseg_spec_t*));
|
||||||
if (specs->memSpecs == NULL)
|
if (specs->memSpecs == NULL)
|
||||||
{
|
{
|
||||||
free(specs);
|
free(specs);
|
||||||
|
free(requiredSegmentsFoundMap);
|
||||||
error("unable to allocate mem segment specs", errbuf);
|
error("unable to allocate mem segment specs", errbuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
specs->executableSegments = malloc(sizeof(uint8_t) * specs->executableSegmentsCount);
|
specs->executableSegments = calloc(specs->executableSegmentsCount, sizeof(uint8_t));
|
||||||
if (specs->executableSegments == NULL)
|
if (specs->executableSegments == NULL)
|
||||||
{
|
{
|
||||||
error("unable to allocate mem executable specs", errbuf);
|
error("unable to allocate mem executable specs", errbuf);
|
||||||
free(specs->memSpecs);
|
free(specs->memSpecs);
|
||||||
free(specs);
|
free(specs);
|
||||||
|
free(requiredSegmentsFoundMap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < specCount; i++)
|
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)
|
if (spec == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate spec %d", i);
|
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->memSpecs);
|
||||||
free(specs->executableSegments);
|
free(specs->executableSegments);
|
||||||
free(specs);
|
free(specs);
|
||||||
|
free(requiredSegmentsFoundMap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
spec->name = NULL;
|
spec->name = NULL;
|
||||||
@@ -392,59 +541,64 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
|
|||||||
specs->memSpecs[i] = spec;
|
specs->memSpecs[i] = spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t foundSegments = 0;
|
|
||||||
uint8_t executableSegmentsFound = 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;
|
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;
|
const memseg_metadata_t seg_def = requiredSegments[j];
|
||||||
}
|
|
||||||
else if (strcmp(segments[i]->name, "reg_io") == 0)
|
if(strcmp(seg_def.name, segments[i]->name) == 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++)
|
|
||||||
{
|
{
|
||||||
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;
|
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)
|
if(specs->memSpecs[specNum]->name == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate spec %d name", i);
|
sprintf(errbuf, "unable to allocate spec %d name", i);
|
||||||
for(size_t j = 0; j < specCount; j++)
|
freeDevSpec(specs);
|
||||||
{
|
free(requiredSegmentsFoundMap);
|
||||||
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;
|
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]->start = segments[i]->start;
|
||||||
specs->memSpecs[specNum]->len = segments[i]->len;
|
specs->memSpecs[specNum]->len = segments[i]->len;
|
||||||
specs->memSpecs[specNum]->wordLen = segments[i]->wordLen;
|
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)
|
if(segments[i]->isExecutable)
|
||||||
{
|
{
|
||||||
specs->executableSegments[executableSegmentsFound] = specNum;
|
specs->executableSegments[executableSegmentsFound] = specNum;
|
||||||
executableSegmentsFound++;
|
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)
|
if(executableSegmentsFound < specs->executableSegmentsCount)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "Not all executable segments found");
|
sprintf(errbuf, "Not all executable segments found");
|
||||||
for(size_t j = 0; j < specCount; j++)
|
freeDevSpec(specs);
|
||||||
{
|
free(requiredSegmentsFoundMap);
|
||||||
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundSegments < 4)
|
printf("set all segments\n");
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#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;
|
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_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount, char* errbuf)
|
||||||
{
|
{
|
||||||
|
return NULL;
|
||||||
device_specs_t* specs = malloc(sizeof(device_specs_t));
|
//TODO
|
||||||
|
device_specs_t* specs = calloc(1, sizeof(device_specs_t));
|
||||||
if (specs == NULL)
|
if (specs == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -536,7 +709,7 @@ device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t
|
|||||||
|
|
||||||
|
|
||||||
specs->memSpecsCount = 4;
|
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)
|
if (specs->memSpecs == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate default mem segment specs");
|
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->executableSegmentsCount = 1;
|
||||||
specs->executableSegments = malloc(sizeof(uint8_t) * 1);
|
specs->executableSegments = calloc(1, sizeof(uint8_t));
|
||||||
if (specs->executableSegments == NULL)
|
if (specs->executableSegments == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate default executable segments");
|
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++)
|
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)
|
if (specs->memSpecs[i] == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate default mem seg spec %u", i);
|
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)
|
device_public_context_t* init(device_specs_t* specs, char* errbuf)
|
||||||
{
|
{
|
||||||
if (specs->memSpecsCount >= 0xFF - 2)
|
device_public_context_t* pubDevContext = calloc(1, sizeof(device_public_context_t));
|
||||||
{
|
|
||||||
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));
|
|
||||||
if (pubDevContext == NULL)
|
if (pubDevContext == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate public context");
|
sprintf(errbuf, "unable to allocate public context");
|
||||||
freeDevSpec(realSpecs);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char initErrbuf[200];
|
char initErrbuf[200];
|
||||||
device_info_t* devInfo = initSpecs(realSpecs, initErrbuf);
|
device_info_t* devInfo = initSpecs(specs, initErrbuf);
|
||||||
if (devInfo == NULL)
|
if (devInfo == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to init specs: %s", initErrbuf);
|
sprintf(errbuf, "unable to init specs: %s", initErrbuf);
|
||||||
freeDevSpec(realSpecs);
|
|
||||||
free(pubDevContext);
|
free(pubDevContext);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -737,6 +809,10 @@ device_public_context_t* init(device_specs_t* specs, char* errbuf)
|
|||||||
return pubDevContext;
|
return pubDevContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t pubDeviceType()
|
||||||
|
{
|
||||||
|
return DEVICE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
size_t pubExtractPcounter(device_public_context_t* devContext)
|
size_t pubExtractPcounter(device_public_context_t* devContext)
|
||||||
{
|
{
|
||||||
@@ -757,8 +833,22 @@ uint8_t pubExtractPcounterSizeWords()
|
|||||||
return sizeof(prog_counter_t);
|
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;
|
||||||
|
}
|
||||||
28
inc/config.h
28
inc/config.h
@@ -1,31 +1,7 @@
|
|||||||
#ifndef __HMMMM_CONFIG_H__
|
#ifndef __HMMMM_CONFIG_H__
|
||||||
#define __HMMMM_CONFIG_H__
|
#define __HMMMM_CONFIG_H__
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char* name;
|
|
||||||
size_t start;
|
|
||||||
size_t len;
|
|
||||||
uint8_t wordLen;
|
|
||||||
uint8_t isExecutable;
|
|
||||||
} conf_mem_seg_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
conf_mem_seg_t** memSegConfs;
|
|
||||||
} conf_mem_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char** id;
|
|
||||||
char** clockId;
|
|
||||||
uint64_t clockDivider;
|
|
||||||
uint64_t clockMultipler;
|
|
||||||
conf_mem_t* memConf;
|
|
||||||
char* libPath;
|
|
||||||
} conf_dev_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "pub/libhmmmm/config.h"
|
||||||
|
|
||||||
void freeMemSegConf(conf_mem_seg_t* memSegConf);
|
void freeMemSegConf(conf_mem_seg_t* memSegConf);
|
||||||
void freeMemConf(conf_mem_t* memConf);
|
void freeMemConf(conf_mem_t* memConf);
|
||||||
@@ -33,4 +9,4 @@ void freeConf(conf_dev_t* conf);
|
|||||||
void freeComposeId(char** id);
|
void freeComposeId(char** id);
|
||||||
uint8_t compareComposeId(char** idA, char** idB);
|
uint8_t compareComposeId(char** idA, char** idB);
|
||||||
|
|
||||||
#endif // ifndef __HMMMM_CONFIG_H__
|
#endif
|
||||||
@@ -24,6 +24,7 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint8_t* resetRequest;
|
||||||
uint8_t* emulState;
|
uint8_t* emulState;
|
||||||
uint64_t* clockCounter;
|
uint64_t* clockCounter;
|
||||||
LinkedListEntry** clientsHead;
|
LinkedListEntry** clientsHead;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef __HMMMMM__
|
#ifndef __HMMMMM__
|
||||||
#define __HMMMMM__
|
#define __HMMMMM__
|
||||||
#include "libhmmmm.h"
|
#include "pub/libhmmmm/device.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -25,6 +25,7 @@ typedef struct {
|
|||||||
void (*freeDevMem)(device_mem_t* mem);
|
void (*freeDevMem)(device_mem_t* mem);
|
||||||
void (*fillSmartReadSpecs)(void* specs, smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount);
|
void (*fillSmartReadSpecs)(void* specs, smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount);
|
||||||
void (*fillSmartWriteSpecs)(void* specs, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount);
|
void (*fillSmartWriteSpecs)(void* specs, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount);
|
||||||
|
void (*reset)(void* specs, device_public_context_t* devInfo);
|
||||||
} device_lib_t;
|
} device_lib_t;
|
||||||
|
|
||||||
device_lib_t* loadDeviceLib(const char *libpath, char* errbuf);
|
device_lib_t* loadDeviceLib(const char *libpath, char* errbuf);
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#ifndef __LIB_HMMMMM__
|
|
||||||
#define __LIB_HMMMMM__
|
|
||||||
|
|
||||||
#include "libmem.h"
|
|
||||||
#include "libdevice.h"
|
|
||||||
|
|
||||||
#define EXTENDED_DEVICE_TYPE_DUMMY 0
|
|
||||||
#define EXTENDED_DEVICE_TYPE_INSTR_SIMUL 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // ifndef __LIB_HMMMMM__
|
|
||||||
52
inc/libmem.h
52
inc/libmem.h
@@ -1,52 +0,0 @@
|
|||||||
#ifndef __LIBMEM_H__
|
|
||||||
#define __LIBMEM_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define GET_BIT(n, b) ((n >> b) & 1)
|
|
||||||
|
|
||||||
// Internal mem handlers
|
|
||||||
typedef void* (*mem_h_read_func)(uint64_t ident, uint64_t addr, void* rawCells);
|
|
||||||
typedef void (*mem_h_write_func)(uint64_t ident, uint64_t addr, void* rawCells, void* data);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
mem_h_read_func func;
|
|
||||||
uint64_t ident;
|
|
||||||
} mem_h_read_handler;
|
|
||||||
typedef struct {
|
|
||||||
mem_h_write_func func;
|
|
||||||
uint64_t ident;
|
|
||||||
} mem_h_write_handler;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
void* rawCells;
|
|
||||||
void** cells;
|
|
||||||
uint64_t smartAddrReadMask;
|
|
||||||
uint64_t smartAddrWriteMask;
|
|
||||||
mem_h_read_handler* smartAddrReadHandlers;
|
|
||||||
mem_h_write_handler* smartAddrWriteHandlers;
|
|
||||||
char** memsegNames;
|
|
||||||
uint64_t* memsegShifts;
|
|
||||||
uint64_t* memreadCellAddrs;
|
|
||||||
uint64_t* memwriteCellAddrs;
|
|
||||||
uint8_t memreadLen;
|
|
||||||
uint8_t memwriteLen;
|
|
||||||
} device_mem_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint64_t start;
|
|
||||||
uint64_t len;
|
|
||||||
uint8_t wordLen;
|
|
||||||
char* name;
|
|
||||||
} memseg_spec_t;
|
|
||||||
|
|
||||||
|
|
||||||
// External handlers
|
|
||||||
typedef void* (*ext_h_read_func)(uint64_t addr, void* rawCells, void* devContext);
|
|
||||||
typedef void (*ext_h_write_func)(uint64_t addr, void* rawCells, void* data, void* devContext);
|
|
||||||
|
|
||||||
#endif // ifndef __LIBMEM_H__
|
|
||||||
29
inc/pub/libhmmmm/config.h
Normal file
29
inc/pub/libhmmmm/config.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __HMMMM_PUB_LIB_CONFIG_H__
|
||||||
|
#define __HMMMM_PUB_LIB_CONFIG_H__
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* name;
|
||||||
|
size_t start;
|
||||||
|
size_t len;
|
||||||
|
uint8_t wordLen;
|
||||||
|
uint8_t isExecutable;
|
||||||
|
} conf_mem_seg_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
conf_mem_seg_t** memSegConfs;
|
||||||
|
} conf_mem_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char** id;
|
||||||
|
char** clockId;
|
||||||
|
uint64_t clockDivider;
|
||||||
|
uint64_t clockMultipler;
|
||||||
|
conf_mem_t* memConf;
|
||||||
|
char* libPath;
|
||||||
|
} conf_dev_t;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ifndef __HMMMM_PUB_LIB_CONFIG_H__
|
||||||
@@ -2,10 +2,15 @@
|
|||||||
#define __LIBDEVICE_H__
|
#define __LIBDEVICE_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "libmem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
#define SMART_ADDR_TYPE_GLOBAL 1
|
#define SMART_ADDR_TYPE_GLOBAL 1
|
||||||
#define SMART_ADDR_TYPE_SEGMENTED 2
|
#define SMART_ADDR_TYPE_SEGMENTED 2
|
||||||
|
|
||||||
|
#define EXTENDED_DEVICE_TYPE_DUMMY 0
|
||||||
|
#define EXTENDED_DEVICE_TYPE_INSTR_SIMUL 1
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
96
inc/pub/libhmmmm/mem.h
Normal file
96
inc/pub/libhmmmm/mem.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#ifndef __HMMMM_PUB_MEM_H__
|
||||||
|
#define __HMMMM_PUB_MEM_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define GET_BIT(n, b) ((uint8_t)((n >> b) & 1))
|
||||||
|
|
||||||
|
#define MEM_ACCESS_INTERCEPT_BUF_SIZE 64
|
||||||
|
|
||||||
|
// Internal mem handlers
|
||||||
|
typedef void* (*mem_h_read_func)(uint64_t ident, uint64_t addr, void* rawCells);
|
||||||
|
typedef void (*mem_h_write_func)(uint64_t ident, uint64_t addr, void* rawCells, void* data);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mem_h_read_func func;
|
||||||
|
uint64_t ident;
|
||||||
|
} mem_h_read_handler;
|
||||||
|
typedef struct {
|
||||||
|
mem_h_write_func func;
|
||||||
|
uint64_t ident;
|
||||||
|
} mem_h_write_handler;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void* rawCells;
|
||||||
|
void** cells;
|
||||||
|
uint64_t smartAddrReadMask;
|
||||||
|
uint64_t smartAddrWriteMask;
|
||||||
|
mem_h_read_handler* smartAddrReadHandlers;
|
||||||
|
mem_h_write_handler* smartAddrWriteHandlers;
|
||||||
|
char** memsegNames;
|
||||||
|
uint64_t* memsegShifts;
|
||||||
|
uint64_t* memsegSizes;
|
||||||
|
uint64_t* memreadCellAddrs;
|
||||||
|
uint8_t* memwriteWordLengths;
|
||||||
|
uint8_t* memwriteCellSegments;
|
||||||
|
uint64_t* memwriteCellAddrs;
|
||||||
|
void** memwriteValues;
|
||||||
|
uint8_t memreadLen;
|
||||||
|
uint8_t memwriteLen;
|
||||||
|
} device_mem_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t start;
|
||||||
|
uint64_t len;
|
||||||
|
uint8_t wordLen;
|
||||||
|
char* name;
|
||||||
|
} memseg_spec_t;
|
||||||
|
|
||||||
|
|
||||||
|
// External handlers
|
||||||
|
typedef void* (*ext_h_read_func)(uint64_t addr, void* rawCells, void* devContext);
|
||||||
|
typedef void (*ext_h_write_func)(uint64_t addr, void* rawCells, void* data, void* devContext);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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]);*/ \
|
||||||
|
__tgt = 0;\
|
||||||
|
} \
|
||||||
|
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 = ((uint64_t)(__mem->memsegShifts[__segno]) + (uint64_t)(__addr)); \
|
||||||
|
if (0 && __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 if(0) \
|
||||||
|
{ \
|
||||||
|
((__cell_t*)__mem->cells[__segno])[__addr] = (__cell_t)(__val); \
|
||||||
|
} \
|
||||||
|
__mem->memwriteCellAddrs[__mem->memwriteLen] = __addr; \
|
||||||
|
__mem->memwriteCellSegments[__mem->memwriteLen] = __segno; \
|
||||||
|
__mem->memwriteWordLengths[__mem->memwriteLen] = sizeof(__cell_t); \
|
||||||
|
*((__cell_t*)__mem->memwriteValues[__mem->memwriteLen]) = (__cell_t)(__val); \
|
||||||
|
__mem->memwriteLen += 1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ifndef __HMMMM_PUB_MEM_H__
|
||||||
41
src/hmmmm.c
41
src/hmmmm.c
@@ -10,6 +10,7 @@ typedef size_t (*_dlib_pubExtractOpcode_t)(device_mem_t* devMem, size_t _program
|
|||||||
typedef uint8_t(*_dlib_pubExtractPcounterSizeWords_t)();
|
typedef uint8_t(*_dlib_pubExtractPcounterSizeWords_t)();
|
||||||
|
|
||||||
typedef device_public_context_t* (*_dlib_dev_init_t)(void* specs, char* errbuf);
|
typedef device_public_context_t* (*_dlib_dev_init_t)(void* specs, char* errbuf);
|
||||||
|
typedef void (*_dlib_dev_reset_t)(void* specs, device_public_context_t* devInfo);
|
||||||
|
|
||||||
typedef uint8_t (*_dlib_makeDeviceTick_t)(device_public_context_t* devInfo);
|
typedef uint8_t (*_dlib_makeDeviceTick_t)(device_public_context_t* devInfo);
|
||||||
|
|
||||||
@@ -98,7 +99,8 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
void *handle = dlopen(libpath, RTLD_NOW);
|
void *handle = dlopen(libpath, RTLD_NOW);
|
||||||
|
|
||||||
if (!handle) {
|
if (!handle)
|
||||||
|
{
|
||||||
const char *dlerr = dlerror();
|
const char *dlerr = dlerror();
|
||||||
snprintf(errbuf, 1024, "unable to open dl handle: %s", dlerr);
|
snprintf(errbuf, 1024, "unable to open dl handle: %s", dlerr);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -110,7 +112,8 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
_dlib_dev_init_t _dlib_dev_init = (_dlib_dev_init_t)(uintptr_t)dlsym(handle, "init");
|
_dlib_dev_init_t _dlib_dev_init = (_dlib_dev_init_t)(uintptr_t)dlsym(handle, "init");
|
||||||
|
|
||||||
const char *dlsym_init_error = dlerror();
|
const char *dlsym_init_error = dlerror();
|
||||||
if (dlsym_init_error) {
|
if (dlsym_init_error)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unable to find init symbol: %s", dlsym_init_error);
|
snprintf(errbuf, 1024, "unable to find init symbol: %s", dlsym_init_error);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -121,7 +124,8 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
|
|
||||||
const char *dlsym_maketick_error = dlerror();
|
const char *dlsym_maketick_error = dlerror();
|
||||||
if (dlsym_maketick_error) {
|
if (dlsym_maketick_error)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unable to find makeDeviceTick symbol: %s", dlsym_maketick_error);
|
snprintf(errbuf, 1024, "unable to find makeDeviceTick symbol: %s", dlsym_maketick_error);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -133,7 +137,8 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
_dlib_parseSpecsFromConfig_t _dlib_parseSpecsFromConfig = (_dlib_parseSpecsFromConfig_t)(uintptr_t)dlsym(handle, "parseSpecsFromConfig");
|
_dlib_parseSpecsFromConfig_t _dlib_parseSpecsFromConfig = (_dlib_parseSpecsFromConfig_t)(uintptr_t)dlsym(handle, "parseSpecsFromConfig");
|
||||||
|
|
||||||
const char *_dlib_parseSpecsFromConfig_error = dlerror();
|
const char *_dlib_parseSpecsFromConfig_error = dlerror();
|
||||||
if (_dlib_parseSpecsFromConfig_error) {
|
if (_dlib_parseSpecsFromConfig_error)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unable to find parseSpecsFromConfig symbol: %s", _dlib_parseSpecsFromConfig_error);
|
snprintf(errbuf, 1024, "unable to find parseSpecsFromConfig symbol: %s", _dlib_parseSpecsFromConfig_error);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -145,7 +150,8 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
_dlib_fillSmartReadSpecs_t _dlib_fillSmartReadSpecs = (_dlib_fillSmartReadSpecs_t)(uintptr_t)dlsym(handle, "fillSmartReadSpecs");
|
_dlib_fillSmartReadSpecs_t _dlib_fillSmartReadSpecs = (_dlib_fillSmartReadSpecs_t)(uintptr_t)dlsym(handle, "fillSmartReadSpecs");
|
||||||
|
|
||||||
const char *_dlib_fillSmartReadSpecs_error = dlerror();
|
const char *_dlib_fillSmartReadSpecs_error = dlerror();
|
||||||
if (_dlib_fillSmartReadSpecs_error) {
|
if (_dlib_fillSmartReadSpecs_error)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unable to find fillSmartReadSpecs symbol: %s", _dlib_fillSmartReadSpecs_error);
|
snprintf(errbuf, 1024, "unable to find fillSmartReadSpecs symbol: %s", _dlib_fillSmartReadSpecs_error);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -157,7 +163,8 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
_dlib_fillSmartWriteSpecs_t _dlib_fillSmartWriteSpecs = (_dlib_fillSmartWriteSpecs_t)(uintptr_t)dlsym(handle, "fillSmartWriteSpecs");
|
_dlib_fillSmartWriteSpecs_t _dlib_fillSmartWriteSpecs = (_dlib_fillSmartWriteSpecs_t)(uintptr_t)dlsym(handle, "fillSmartWriteSpecs");
|
||||||
|
|
||||||
const char *_dlib_fillSmartWriteSpecs_error = dlerror();
|
const char *_dlib_fillSmartWriteSpecs_error = dlerror();
|
||||||
if (_dlib_fillSmartWriteSpecs_error) {
|
if (_dlib_fillSmartWriteSpecs_error)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unable to find fillSmartWriteSpecs symbol: %s", _dlib_fillSmartWriteSpecs_error);
|
snprintf(errbuf, 1024, "unable to find fillSmartWriteSpecs symbol: %s", _dlib_fillSmartWriteSpecs_error);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -168,7 +175,8 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
_dlib_deviceType_t _dlib_deviceType = (_dlib_deviceType_t)(uintptr_t)dlsym(handle, "pubDeviceType");
|
_dlib_deviceType_t _dlib_deviceType = (_dlib_deviceType_t)(uintptr_t)dlsym(handle, "pubDeviceType");
|
||||||
|
|
||||||
const char *dlib_deviceType_error = dlerror();
|
const char *dlib_deviceType_error = dlerror();
|
||||||
if (dlib_deviceType_error) {
|
if (dlib_deviceType_error)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unable to find pubDeviceType symbol: %s", dlib_deviceType_error);
|
snprintf(errbuf, 1024, "unable to find pubDeviceType symbol: %s", dlib_deviceType_error);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -181,7 +189,8 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
_dlib_freeSpecs_t _dlib_freeSpecs = (_dlib_freeSpecs_t)(uintptr_t)dlsym(handle, "freeDevSpecs");
|
_dlib_freeSpecs_t _dlib_freeSpecs = (_dlib_freeSpecs_t)(uintptr_t)dlsym(handle, "freeDevSpecs");
|
||||||
|
|
||||||
const char *dlib_freeSpecs_error = dlerror();
|
const char *dlib_freeSpecs_error = dlerror();
|
||||||
if (dlib_freeSpecs_error) {
|
if (dlib_freeSpecs_error)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unable to find freeSpecs symbol: %s", dlib_freeSpecs_error);
|
snprintf(errbuf, 1024, "unable to find freeSpecs symbol: %s", dlib_freeSpecs_error);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -189,10 +198,23 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_dev_reset_t _dlib_reset = (_dlib_dev_reset_t)(uintptr_t)dlsym(handle, "reset");
|
||||||
|
|
||||||
|
const char *dlib_dev_reset_t_error = dlerror();
|
||||||
|
if (dlib_dev_reset_t_error)
|
||||||
|
{
|
||||||
|
snprintf(errbuf, 1024, "unable to find reset symbol: %s", dlib_dev_reset_t_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_dlib_freeDevMem_t _dlib_freeDevMem = (_dlib_freeDevMem_t)(uintptr_t)dlsym(handle, "freeDevMem");
|
_dlib_freeDevMem_t _dlib_freeDevMem = (_dlib_freeDevMem_t)(uintptr_t)dlsym(handle, "freeDevMem");
|
||||||
|
|
||||||
const char *dlib_freeDevMem_error = dlerror();
|
const char *dlib_freeDevMem_error = dlerror();
|
||||||
if (dlib_freeDevMem_error) {
|
if (dlib_freeDevMem_error)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unable to find freeDevMem symbol: %s", dlib_freeDevMem_error);
|
snprintf(errbuf, 1024, "unable to find freeDevMem symbol: %s", dlib_freeDevMem_error);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -207,6 +229,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
dev->fillSmartWriteSpecs = _dlib_fillSmartWriteSpecs;
|
dev->fillSmartWriteSpecs = _dlib_fillSmartWriteSpecs;
|
||||||
dev->freeSpecs = _dlib_freeSpecs;
|
dev->freeSpecs = _dlib_freeSpecs;
|
||||||
dev->freeDevMem = _dlib_freeDevMem;
|
dev->freeDevMem = _dlib_freeDevMem;
|
||||||
|
dev->reset = _dlib_reset;
|
||||||
|
|
||||||
uint8_t devType = _dlib_deviceType();
|
uint8_t devType = _dlib_deviceType();
|
||||||
|
|
||||||
|
|||||||
212
src/main.c
212
src/main.c
@@ -331,9 +331,12 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
|||||||
// printf("No stream regs\n");
|
// printf("No stream regs\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StreamReg** dispatchRegs = malloc(sizeof(StreamReg*) * deviceRegs->regCount);
|
|
||||||
NULL_GUARD(dispatchRegs);
|
StreamReg* dispatchRegs[1024 * 16];
|
||||||
|
// StreamReg** dispatchRegs = malloc(sizeof(StreamReg*) * deviceRegs->regCount);
|
||||||
|
// NULL_GUARD(dispatchRegs);
|
||||||
size_t dispatchRegsCnt = 0;
|
size_t dispatchRegsCnt = 0;
|
||||||
|
// uint8_t dispatchedRegMap[1024 * 16] = {0};
|
||||||
|
|
||||||
for(size_t i = 0; i < addrsLen; i++)
|
for(size_t i = 0; i < addrsLen; i++)
|
||||||
{
|
{
|
||||||
@@ -343,8 +346,18 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
|||||||
StreamReg* reg = &deviceRegs->regs[regIdx];
|
StreamReg* reg = &deviceRegs->regs[regIdx];
|
||||||
if(reg->mode == mode)
|
if(reg->mode == mode)
|
||||||
{
|
{
|
||||||
if(reg->startGlobalAddr <= addr && reg->startGlobalAddr + reg->segLen >= addr)
|
if(reg->startGlobalAddr <= addr && addr <= reg->startGlobalAddr + reg->segLen)
|
||||||
{
|
{
|
||||||
|
// if(dispatchedRegMap[reg->regId] == 1)
|
||||||
|
// {
|
||||||
|
// // break;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// dispatchRegs[dispatchRegsCnt] = reg;
|
||||||
|
// dispatchedRegMap[reg->regId] = 1;
|
||||||
|
// dispatchRegsCnt++;
|
||||||
|
// }
|
||||||
uint8_t isDuplicate = 0;
|
uint8_t isDuplicate = 0;
|
||||||
for(size_t j = 0; j < dispatchRegsCnt; j++)
|
for(size_t j = 0; j < dispatchRegsCnt; j++)
|
||||||
{
|
{
|
||||||
@@ -357,6 +370,7 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
|||||||
if(!isDuplicate)
|
if(!isDuplicate)
|
||||||
{
|
{
|
||||||
dispatchRegs[dispatchRegsCnt] = reg;
|
dispatchRegs[dispatchRegsCnt] = reg;
|
||||||
|
// dispatchedRegMap[reg->regId] = 1;
|
||||||
dispatchRegsCnt++;
|
dispatchRegsCnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,7 +387,7 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
|||||||
{
|
{
|
||||||
dispatchStreamSegment(emulContext, dispatchRegs[i], mem);
|
dispatchStreamSegment(emulContext, dispatchRegs[i], mem);
|
||||||
}
|
}
|
||||||
free(dispatchRegs);
|
// free(dispatchRegs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -466,9 +480,11 @@ int main(int argc, char** argv)
|
|||||||
LinkedListEntry* clientsLinkedListHead = NULL;
|
LinkedListEntry* clientsLinkedListHead = NULL;
|
||||||
|
|
||||||
uint64_t clockCounter = 0;
|
uint64_t clockCounter = 0;
|
||||||
|
uint8_t resetRequest = 0;
|
||||||
|
|
||||||
uint8_t utilizedFlag = 0;
|
uint8_t utilizedFlag = 0;
|
||||||
EmulContext emulContext = {
|
EmulContext emulContext = {
|
||||||
|
&resetRequest,
|
||||||
&emulState,
|
&emulState,
|
||||||
&clockCounter,
|
&clockCounter,
|
||||||
&clientsLinkedListHead,
|
&clientsLinkedListHead,
|
||||||
@@ -534,9 +550,11 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
ptQueueElem* regQueueTail = regQ->tail;
|
ptQueueElem* regQueueTail = regQ->tail;
|
||||||
|
|
||||||
uint8_t clients_try_timer = 1;
|
uint16_t clients_try_timer = 1000;
|
||||||
|
|
||||||
uint64_t lastTickAt = getCurrentUsec();
|
uint64_t lastTickAt = getCurrentUsec();
|
||||||
|
uint64_t lastTickCountWindowAt = getCurrentUsec();
|
||||||
|
uint64_t lastTickCounter = 0;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
@@ -552,58 +570,178 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if (clients_try_timer == 0)
|
if (clients_try_timer == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(getCurrentUsec() - lastTickCountWindowAt > 1000000)
|
||||||
|
{
|
||||||
|
// uint64_t dtimeUs = getCurrentUsec() - lastTickCountWindowAt;
|
||||||
|
// lastTickCountWindowAt = getCurrentUsec();
|
||||||
|
// uint64_t dtick = clockCounter - lastTickCounter;
|
||||||
|
// lastTickCounter = clockCounter;
|
||||||
|
// double rate = ((double)dtick) / (((double)dtimeUs) / 1000000);
|
||||||
|
// printf("clock rate: %f\n", rate);
|
||||||
|
}
|
||||||
|
|
||||||
handleAllClients(&emulContext);
|
handleAllClients(&emulContext);
|
||||||
clients_try_timer = 1;
|
clients_try_timer = 1000;
|
||||||
|
uint8_t readReqIdx = atomic_load(&outBufs.readRequestIdx);
|
||||||
|
// uint8_t readReqIdx = outBufs.readRequestIdx;
|
||||||
|
if(readReqIdx == outBufs.currWritingIdx || outBufs.bufs[outBufs.currWritingIdx].size >= outBufs.bufs[outBufs.currWritingIdx].allocatedSize / 2)
|
||||||
|
{
|
||||||
|
uint8_t newWriteIdx = outBufs.currWritingIdx + 1;
|
||||||
|
if(outBufs.bufs[outBufs.currWritingIdx].size != 0 || readReqIdx != newWriteIdx)
|
||||||
|
{
|
||||||
|
if(newWriteIdx >= outBufs.buffersCount)
|
||||||
|
{
|
||||||
|
newWriteIdx = 0;
|
||||||
|
}
|
||||||
|
while(readReqIdx == newWriteIdx)
|
||||||
|
{
|
||||||
|
my_sleep(100);
|
||||||
|
readReqIdx = atomic_load(&outBufs.readRequestIdx);
|
||||||
|
}
|
||||||
|
atomic_store(&outBufs.currWritingIdx, newWriteIdx);
|
||||||
|
outBufs.bufs[outBufs.currWritingIdx].size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clients_try_timer--;
|
clients_try_timer--;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t readReqIdx = atomic_load(&outBufs.readRequestIdx);
|
if(resetRequest)
|
||||||
if(readReqIdx == outBufs.currWritingIdx || outBufs.bufs[outBufs.currWritingIdx].size >= outBufs.bufs[outBufs.currWritingIdx].allocatedSize / 2)
|
|
||||||
{
|
{
|
||||||
uint8_t newWriteIdx = outBufs.currWritingIdx + 1;
|
for(size_t di = 0; di < emulContext.devicesCount; di++)
|
||||||
if(outBufs.bufs[outBufs.currWritingIdx].size != 0 || readReqIdx != newWriteIdx)
|
|
||||||
{
|
{
|
||||||
if(newWriteIdx >= outBufs.buffersCount)
|
device_handle_t* dev = (device_handle_t*)emulContext.deviceHandles[di];
|
||||||
{
|
dev->lib->reset(dev->specs, dev->ctx);
|
||||||
newWriteIdx = 0;
|
dev->clockCycleCounter = 0;
|
||||||
}
|
dev->clockCycleLimit = 0;
|
||||||
while(readReqIdx == newWriteIdx)
|
|
||||||
{
|
|
||||||
my_sleep(100000);
|
|
||||||
readReqIdx = atomic_load(&outBufs.readRequestIdx);
|
|
||||||
}
|
|
||||||
atomic_store(&outBufs.currWritingIdx, newWriteIdx);
|
|
||||||
outBufs.bufs[outBufs.currWritingIdx].size = 0;
|
|
||||||
}
|
}
|
||||||
|
clockCounter = 0;
|
||||||
|
resetRequest = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint64_t now = emulContext.simRateLimit > 0? getCurrentUsec() : 0;
|
uint64_t now = emulContext.simRateLimit > 0? getCurrentUsec() : 0;
|
||||||
if(emulState == EMUL_STATE_STOP)
|
// if(emulState == EMUL_STATE_STOP)
|
||||||
{
|
// {
|
||||||
clockCounter = 0;
|
// clockCounter = 0;
|
||||||
}
|
// }
|
||||||
else if(emulState == EMUL_STATE_EXEC && emulContext.devicesCount > 0 && (emulContext.simRateLimit == 0 || now - lastTickAt >= 1000000 / emulContext.simRateLimit))
|
if(emulState == EMUL_STATE_EXEC && emulContext.devicesCount > 0 && (emulContext.simRateLimit == 0 || (double)(now - lastTickAt) >= 1000000.0 / (double)emulContext.simRateLimit))
|
||||||
{
|
{
|
||||||
|
// printf("\n\ntick %lu\n", clockCounter);
|
||||||
|
|
||||||
|
|
||||||
|
for(size_t di = 0; di < emulContext.devicesCount; di++)
|
||||||
|
{
|
||||||
|
device_handle_t* dev = (device_handle_t*)emulContext.deviceHandles[di];
|
||||||
|
if (clockCounter % dev->clockDivider == 0)
|
||||||
|
{
|
||||||
|
if(dev->clockCycleCounter > 0)
|
||||||
|
{
|
||||||
|
dev->clockCycleCounter--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t di = 0; di < emulContext.devicesCount; di++)
|
||||||
|
{
|
||||||
|
device_handle_t* dev = (device_handle_t*)emulContext.deviceHandles[di];
|
||||||
|
device_mem_t* devMem = dev->ctx->deviceMem;
|
||||||
|
if(dev->clockCycleCounter == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(devMem->memwriteLen > 0)
|
||||||
|
{
|
||||||
|
// printf("device %lu has %d writes\n", di, devMem->memwriteLen);
|
||||||
|
uint64_t globalWriteAddrs[MEM_ACCESS_INTERCEPT_BUF_SIZE] = {0};
|
||||||
|
for(size_t i = 0; i < devMem->memwriteLen; i++)
|
||||||
|
{
|
||||||
|
const uint8_t seg = devMem->memwriteCellSegments[i];
|
||||||
|
const uint8_t wordLen = devMem->memwriteWordLengths[i];
|
||||||
|
const uint64_t addr = devMem->memwriteCellAddrs[i];
|
||||||
|
void* val = devMem->memwriteValues[i];
|
||||||
|
|
||||||
|
// const uint64_t segLen = devMem->memsegSizes[seg];
|
||||||
|
|
||||||
|
// // device_specs_t* spec = dev->specs;
|
||||||
|
// // spec
|
||||||
|
|
||||||
|
// if(addr >= segLen)
|
||||||
|
// {
|
||||||
|
// printf("write out of bounds of segment of len %lu: [%d].%lu\n", segLen, seg, addr);
|
||||||
|
// emulState = EMUL_STATE_PAUSE;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
{
|
||||||
|
switch(wordLen)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
((uint8_t*)(devMem->cells[seg]))[addr] = *((uint8_t*)val);
|
||||||
|
// printf("[DEV/WRITE] %d -> [%d].%lu\n", *(uint8_t*)val, seg, addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
((uint16_t*)(devMem->cells[seg]))[addr] = *((uint16_t*)val);
|
||||||
|
// printf("[DEV/WRITE] %d -> [%d].%lu\n", *(uint16_t*)val, seg, addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
((uint32_t*)(devMem->cells[seg]))[addr] = *((uint32_t*)val);
|
||||||
|
// printf("[DEV/WRITE] %d -> [%d].%lu\n", *(uint32_t*)val, seg, addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
((uint64_t*)(devMem->cells[seg]))[addr] = *((uint64_t*)val);
|
||||||
|
// printf("[DEV/WRITE] %lu -> [%d].%lu\n", *(uint64_t*)val, seg, addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
printf("invalid word size: %d\n", wordLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
globalWriteAddrs[i] = devMem->memsegShifts[seg] + addr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatchMemAccessNotifications(&emulContext, emulContext.deviceStreamRegs[di], devMem, globalWriteAddrs, (size_t)devMem->memwriteLen, STREAM_MODE_WRITE);
|
||||||
|
devMem->memwriteLen = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// printf("device %lu has no writes\n", di);
|
||||||
|
}
|
||||||
|
if(devMem->memreadLen > 0)
|
||||||
|
{
|
||||||
|
dispatchMemAccessNotifications(&emulContext, emulContext.deviceStreamRegs[di], devMem, devMem->memreadCellAddrs, (size_t)devMem->memreadLen, STREAM_MODE_READ);
|
||||||
|
devMem->memreadLen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (size_t di = 0; di < emulContext.devicesCount; di++)
|
for (size_t di = 0; di < emulContext.devicesCount; di++)
|
||||||
{
|
{
|
||||||
device_handle_t* dev = (device_handle_t*)emulContext.deviceHandles[di];
|
device_handle_t* dev = (device_handle_t*)emulContext.deviceHandles[di];
|
||||||
|
|
||||||
if (clockCounter % dev->clockDivider == 0)
|
if (clockCounter % dev->clockDivider == 0)
|
||||||
{
|
{
|
||||||
// printf("clock device %lu\n", di);
|
if(dev->clockCycleCounter == 0)
|
||||||
device_mem_t* devMem = dev->ctx->deviceMem;
|
{
|
||||||
devMem->memreadLen = 0;
|
// printf("clock device %lu\n", di);
|
||||||
devMem->memwriteLen = 0;
|
// device_mem_t* devMem = dev->ctx->deviceMem;
|
||||||
|
|
||||||
dev->lib->makeDeviceTick(dev->ctx);
|
dev->clockCycleCounter = dev->lib->makeDeviceTick(dev->ctx);
|
||||||
|
}
|
||||||
dispatchMemAccessNotifications(&emulContext, emulContext.deviceStreamRegs[di], devMem, devMem->memreadCellAddrs, (size_t)devMem->memreadLen, STREAM_MODE_READ);
|
|
||||||
dispatchMemAccessNotifications(&emulContext, emulContext.deviceStreamRegs[di], devMem, devMem->memwriteCellAddrs, (size_t)devMem->memwriteLen, STREAM_MODE_WRITE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clockCounter++;
|
clockCounter++;
|
||||||
@@ -615,7 +753,7 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
else if(!utilizedFlag)
|
else if(!utilizedFlag)
|
||||||
{
|
{
|
||||||
my_sleep(1000);
|
// my_sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ void dispatchOutgoingMessage(OutgoingBuffers* outBufs, ws_cli_conn_t clientIdx,
|
|||||||
if(p->size + 1 >= p->allocatedSize)
|
if(p->size + 1 >= p->allocatedSize)
|
||||||
{
|
{
|
||||||
// printf("\t>>Reallocating buf %d\n", outBufs->currWritingIdx);
|
// printf("\t>>Reallocating buf %d\n", outBufs->currWritingIdx);
|
||||||
OutgoingMessage* newPtr = realloc(p->ptr, sizeof(OutgoingMessage) * p->allocatedSize * 2);
|
OutgoingMessage* newPtr = realloc(p->ptr, sizeof(OutgoingMessage) * p->allocatedSize * 5);
|
||||||
NULL_GUARD(newPtr);
|
NULL_GUARD(newPtr);
|
||||||
p->ptr = newPtr;
|
p->ptr = newPtr;
|
||||||
p->allocatedSize = p->allocatedSize * 2;
|
p->allocatedSize = p->allocatedSize * 5;
|
||||||
}
|
}
|
||||||
OutgoingMessage* outmsg = &((OutgoingMessage*)p->ptr)[p->size];
|
OutgoingMessage* outmsg = &((OutgoingMessage*)p->ptr)[p->size];
|
||||||
outmsg->msg = msg;
|
outmsg->msg = msg;
|
||||||
|
|||||||
@@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
void handleCloseClient(EmulContext* emulContext, ClientContext* ctx)
|
void handleCloseClient(EmulContext* emulContext, ClientContext* ctx)
|
||||||
{
|
{
|
||||||
if (ctx->streamRegIterator > 0) {
|
// if (ctx->streamRegIterator > 0) {
|
||||||
unregisterClientStreams(emulContext, ctx);
|
unregisterClientStreams(emulContext, ctx);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +45,8 @@ void handleRegEvent(EmulContext* emulContext, ClientRegistrationEvent* ev)
|
|||||||
{
|
{
|
||||||
LinkedListEntry* clientEntry = *emulContext->clientsHead;
|
LinkedListEntry* clientEntry = *emulContext->clientsHead;
|
||||||
while (clientEntry != NULL) {
|
while (clientEntry != NULL) {
|
||||||
if (clientEntry->payload == ev->ctx) {
|
if (clientEntry->payload == ev->ctx)
|
||||||
|
{
|
||||||
printf("close client %lu\n", ev->ctx->clientId);
|
printf("close client %lu\n", ev->ctx->clientId);
|
||||||
handleCloseClient(emulContext, ev->ctx);
|
handleCloseClient(emulContext, ev->ctx);
|
||||||
removeLinkedListEntry(emulContext->clientsHead, clientEntry);
|
removeLinkedListEntry(emulContext->clientsHead, clientEntry);
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ static int load_devices_recursive(
|
|||||||
char initErrBuf[256];
|
char initErrBuf[256];
|
||||||
|
|
||||||
dev->ctx = dev->lib->init(dev->specs, initErrBuf);
|
dev->ctx = dev->lib->init(dev->specs, initErrBuf);
|
||||||
if (!dev->ctx) {
|
if (!dev->ctx)
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "error while loading device %lu: %s", st->count, initErrBuf);
|
snprintf(errbuf, 1024, "error while loading device %lu: %s", st->count, initErrBuf);
|
||||||
closeBaseDevice(dev);
|
closeBaseDevice(dev);
|
||||||
free(dev);
|
free(dev);
|
||||||
@@ -160,9 +161,11 @@ static int load_devices_recursive(
|
|||||||
hmmmm_config_MemSegment_vec_t dev_segs =
|
hmmmm_config_MemSegment_vec_t dev_segs =
|
||||||
hmmmm_config_BaseDeviceConfig_mem_segments(base);
|
hmmmm_config_BaseDeviceConfig_mem_segments(base);
|
||||||
size_t nseg = dev_segs ? hmmmm_config_MemSegment_vec_len(dev_segs) : 0;
|
size_t nseg = dev_segs ? hmmmm_config_MemSegment_vec_len(dev_segs) : 0;
|
||||||
if (nseg > MAX_SEGMENTS) nseg = MAX_SEGMENTS;
|
// if (nseg > MAX_SEGMENTS) nseg = MAX_SEGMENTS;
|
||||||
|
|
||||||
st->seg_counts[idx] = nseg;
|
st->seg_counts[idx] = nseg;
|
||||||
for (size_t si = 0; si < nseg; si++) {
|
for (size_t si = 0; si < nseg; si++)
|
||||||
|
{
|
||||||
hmmmm_config_MemSegment_table_t seg =
|
hmmmm_config_MemSegment_table_t seg =
|
||||||
hmmmm_config_MemSegment_vec_at(dev_segs, si);
|
hmmmm_config_MemSegment_vec_at(dev_segs, si);
|
||||||
flatbuffers_string_t sname = hmmmm_config_MemSegment_name(seg);
|
flatbuffers_string_t sname = hmmmm_config_MemSegment_name(seg);
|
||||||
@@ -172,18 +175,22 @@ static int load_devices_recursive(
|
|||||||
// Copy path
|
// Copy path
|
||||||
st->path_lens[idx] = st->depth;
|
st->path_lens[idx] = st->depth;
|
||||||
st->paths[idx] = calloc(st->depth + 1, sizeof(char*));
|
st->paths[idx] = calloc(st->depth + 1, sizeof(char*));
|
||||||
if (!st->paths[idx]) {
|
if (!st->paths[idx])
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "alloc path array");
|
snprintf(errbuf, 1024, "alloc path array");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (size_t p = 0; p < st->depth; p++) {
|
for (size_t p = 0; p < st->depth; p++)
|
||||||
|
{
|
||||||
st->paths[idx][p] = strdup(st->path_stack[p]);
|
st->paths[idx][p] = strdup(st->path_stack[p]);
|
||||||
}
|
}
|
||||||
st->paths[idx][st->depth] = NULL;
|
st->paths[idx][st->depth] = NULL;
|
||||||
|
|
||||||
st->count++;
|
st->count++;
|
||||||
|
|
||||||
} else if (ctype == hmmmm_config_DeviceConfig_ComposeDeviceConfig) {
|
}
|
||||||
|
else if (ctype == hmmmm_config_DeviceConfig_ComposeDeviceConfig)
|
||||||
|
{
|
||||||
hmmmm_config_ComposeDeviceConfig_table_t child =
|
hmmmm_config_ComposeDeviceConfig_table_t child =
|
||||||
(hmmmm_config_ComposeDeviceConfig_table_t)
|
(hmmmm_config_ComposeDeviceConfig_table_t)
|
||||||
hmmmm_config_DeviceEntry_config(entry);
|
hmmmm_config_DeviceEntry_config(entry);
|
||||||
@@ -191,7 +198,9 @@ static int load_devices_recursive(
|
|||||||
if (load_devices_recursive(child, st, errbuf) != 0) {
|
if (load_devices_recursive(child, st, errbuf) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
snprintf(errbuf, 1024, "unknown device config type %u", ctype);
|
snprintf(errbuf, 1024, "unknown device config type %u", ctype);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -472,21 +481,27 @@ static int apply_intercepts(
|
|||||||
|
|
||||||
static void free_old_config(EmulContext* emulContext)
|
static void free_old_config(EmulContext* emulContext)
|
||||||
{
|
{
|
||||||
if (emulContext->devicesCount == 0) return;
|
if (emulContext->devicesCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Free intercept context array (single contiguous allocation)
|
// Free intercept context array (single contiguous allocation)
|
||||||
if (emulContext->interceptCtxs) {
|
if (emulContext->interceptCtxs)
|
||||||
|
{
|
||||||
free(emulContext->interceptCtxs);
|
free(emulContext->interceptCtxs);
|
||||||
emulContext->interceptCtxs = NULL;
|
emulContext->interceptCtxs = NULL;
|
||||||
emulContext->interceptCtxCount = 0;
|
emulContext->interceptCtxCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < emulContext->devicesCount; i++) {
|
for (size_t i = 0; i < emulContext->devicesCount; i++)
|
||||||
|
{
|
||||||
device_handle_t* dev = (device_handle_t*)emulContext->deviceHandles[i];
|
device_handle_t* dev = (device_handle_t*)emulContext->deviceHandles[i];
|
||||||
closeBaseDevice(dev);
|
closeBaseDevice(dev);
|
||||||
free(dev);
|
free(dev);
|
||||||
|
|
||||||
if (emulContext->deviceStreamRegs[i]) {
|
if (emulContext->deviceStreamRegs[i])
|
||||||
|
{
|
||||||
free(emulContext->deviceStreamRegs[i]->regs);
|
free(emulContext->deviceStreamRegs[i]->regs);
|
||||||
free(emulContext->deviceStreamRegs[i]);
|
free(emulContext->deviceStreamRegs[i]);
|
||||||
}
|
}
|
||||||
@@ -501,7 +516,8 @@ static void free_old_config(EmulContext* emulContext)
|
|||||||
emulContext->devicesCount = 0;
|
emulContext->devicesCount = 0;
|
||||||
emulContext->simRateLimit = 0;
|
emulContext->simRateLimit = 0;
|
||||||
|
|
||||||
if (emulContext->deviceIdMappingMsg) {
|
if (emulContext->deviceIdMappingMsg)
|
||||||
|
{
|
||||||
free(emulContext->deviceIdMappingMsg);
|
free(emulContext->deviceIdMappingMsg);
|
||||||
emulContext->deviceIdMappingMsg = NULL;
|
emulContext->deviceIdMappingMsg = NULL;
|
||||||
emulContext->deviceIdMappingMsgLen = 0;
|
emulContext->deviceIdMappingMsgLen = 0;
|
||||||
@@ -701,6 +717,22 @@ void handleConfigCtrlMessage(
|
|||||||
|
|
||||||
// Build DeviceIdMappingNotif and broadcast to all connected clients
|
// Build DeviceIdMappingNotif and broadcast to all connected clients
|
||||||
size_t msg_len;
|
size_t msg_len;
|
||||||
|
printf("fuck!\n");
|
||||||
|
|
||||||
|
|
||||||
|
for(size_t i = 0; i < emulContext->devicesCount; i++)
|
||||||
|
{
|
||||||
|
device_handle_t* handl = emulContext->deviceHandles[i];
|
||||||
|
for(size_t j = 0; j < st.seg_counts[i]; j++)
|
||||||
|
{
|
||||||
|
if(st.seg_names[i][j])
|
||||||
|
{
|
||||||
|
free(st.seg_names[i][j]);
|
||||||
|
}
|
||||||
|
printf("setting device %lu segment %lu name: \"%s\"\n", i, j, handl->ctx->deviceMem->memsegNames[j]);
|
||||||
|
st.seg_names[i][j] = strdup(handl->ctx->deviceMem->memsegNames[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
uint8_t* out = fb_build_config_device_id_mapping(
|
uint8_t* out = fb_build_config_device_id_mapping(
|
||||||
nonce, st.paths, st.path_lens, st.seg_names, st.seg_counts, dc, &msg_len);
|
nonce, st.paths, st.path_lens, st.seg_names, st.seg_counts, dc, &msg_len);
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ void handleIncomingCtrlMessage(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(state_op == EMUL_STATE_OP_RESET)
|
||||||
|
{
|
||||||
|
*emulContext->resetRequest = 1;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t new_state = switchNewEmulState(*emulContext->emulState, state_op);
|
uint8_t new_state = switchNewEmulState(*emulContext->emulState, state_op);
|
||||||
*emulContext->emulState = new_state;
|
*emulContext->emulState = new_state;
|
||||||
printf("[CTRL/EXEC] state -> %u\n", new_state);
|
printf("[CTRL/EXEC] state -> %u\n", new_state);
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "base_device.h"
|
||||||
#include "proto/msg.h"
|
#include "proto/msg.h"
|
||||||
#include "proto/dial.h"
|
#include "proto/dial.h"
|
||||||
#include "mem_reader.h"
|
#include "mem_reader.h"
|
||||||
|
#include "pub/libhmmmm/mem.h"
|
||||||
|
|
||||||
// #define DEVICE_MEM_SIZE ((size_t)(256 * 1024))
|
// #define DEVICE_MEM_SIZE ((size_t)(256 * 1024))
|
||||||
|
|
||||||
@@ -29,7 +31,7 @@ void handleIncomingMemMessage(
|
|||||||
hmmmm_mem_MemClientMessage_payload(msg);
|
hmmmm_mem_MemClientMessage_payload(msg);
|
||||||
|
|
||||||
uint32_t dev_id = hmmmm_mem_MemReadRequest_device_id(req);
|
uint32_t dev_id = hmmmm_mem_MemReadRequest_device_id(req);
|
||||||
uint32_t seg_id = hmmmm_mem_MemReadRequest_seg_id(req);
|
volatile uint32_t seg_id = hmmmm_mem_MemReadRequest_seg_id(req);
|
||||||
uint32_t offset = hmmmm_mem_MemReadRequest_offset(req);
|
uint32_t offset = hmmmm_mem_MemReadRequest_offset(req);
|
||||||
uint32_t length = hmmmm_mem_MemReadRequest_length(req);
|
uint32_t length = hmmmm_mem_MemReadRequest_length(req);
|
||||||
|
|
||||||
@@ -41,14 +43,25 @@ void handleIncomingMemMessage(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = (uint32_t)(((size_t)offset) + emulContext->devicesMemSegAddrs[dev_id][seg_id]);
|
// offset = (uint32_t)(((size_t)offset) + emulContext->devicesMemSegAddrs[dev_id][seg_id]);
|
||||||
|
|
||||||
// if ((size_t)offset + (size_t)length > DEVICE_MEM_SIZE) {
|
// if ((size_t)offset + (size_t)length > DEVICE_MEM_SIZE) {
|
||||||
// printf("[MEM/READ] out of bounds\n");
|
// printf("[MEM/READ] out of bounds\n");
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
printf("[MEM/READ] from %d/%d+%d:%d\n", dev_id, seg_id, offset, length);
|
||||||
|
|
||||||
|
device_handle_t* handl = emulContext->deviceHandles[dev_id];
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t* base = handl->ctx->deviceMem->cells[seg_id]; //emulContext->devicesMem[dev_id] + handl->ctx->deviceMem->memsegShifts[seg_id];
|
||||||
|
|
||||||
|
for(size_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
printf("%02X ", (base + offset)[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
const uint8_t* base = emulContext->devicesMem[dev_id];
|
|
||||||
size_t out_len;
|
size_t out_len;
|
||||||
uint8_t* out = fb_build_mem_read_response(
|
uint8_t* out = fb_build_mem_read_response(
|
||||||
nonce, *emulContext->clockCounter,
|
nonce, *emulContext->clockCounter,
|
||||||
@@ -81,7 +94,12 @@ void handleIncomingMemMessage(
|
|||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
uint8_t* base = emulContext->devicesMem[dev_id];
|
// device_mem_t* devMem = emulContext->devicesMem[dev_id];
|
||||||
|
|
||||||
|
device_handle_t* handl = emulContext->deviceHandles[dev_id];
|
||||||
|
|
||||||
|
printf("[MEM/WRITE] from %d/%d+%d:%lu\n", dev_id, seg_id, offset, data_len);
|
||||||
|
uint8_t* base = handl->ctx->deviceMem->cells[seg_id]; // emulContext->devicesMem[dev_id] + handl->ctx->deviceMem->memsegShifts[seg_id];
|
||||||
memcpy(base + offset, data, data_len);
|
memcpy(base + offset, data, data_len);
|
||||||
|
|
||||||
size_t out_len;
|
size_t out_len;
|
||||||
|
|||||||
@@ -40,22 +40,27 @@ void unregisterClientStreams(EmulContext* emulContext, ClientContext* ctx)
|
|||||||
for (size_t deviceId = 0; deviceId < emulContext->devicesCount; deviceId++) {
|
for (size_t deviceId = 0; deviceId < emulContext->devicesCount; deviceId++) {
|
||||||
DeviceSegStreamReg* deviceRegs = emulContext->deviceStreamRegs[deviceId];
|
DeviceSegStreamReg* deviceRegs = emulContext->deviceStreamRegs[deviceId];
|
||||||
|
|
||||||
StreamReg* newRegs = malloc(sizeof(StreamReg) * deviceRegs->regCount);
|
StreamReg* newRegs = calloc(deviceRegs->allocatedSize, sizeof(StreamReg));
|
||||||
NULL_GUARD(newRegs);
|
NULL_GUARD(newRegs);
|
||||||
size_t newCount = 0;
|
size_t newCount = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < deviceRegs->regCount; i++) {
|
for (size_t i = 0; i < deviceRegs->regCount; i++)
|
||||||
|
{
|
||||||
StreamReg* reg = &deviceRegs->regs[i];
|
StreamReg* reg = &deviceRegs->regs[i];
|
||||||
if (reg->clientContext->clientId != ctx->clientId) {
|
if (reg->clientContext->clientId != ctx->clientId)
|
||||||
|
{
|
||||||
newRegs[newCount++] = *reg;
|
newRegs[newCount++] = *reg;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("Removing stream reg [%u] for client %lu\n",
|
printf("Removing stream reg [%u] for client %lu\n",
|
||||||
reg->regId, ctx->clientId);
|
reg->regId, ctx->clientId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(deviceRegs->regs);
|
StreamReg* oldRegs = deviceRegs->regs;
|
||||||
deviceRegs->regCount = newCount;
|
deviceRegs->regCount = newCount;
|
||||||
deviceRegs->regs = newRegs;
|
deviceRegs->regs = newRegs;
|
||||||
|
free(oldRegs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ void onWsClose(ws_cli_conn_t client)
|
|||||||
with_lock(&ctx->registerMutex)
|
with_lock(&ctx->registerMutex)
|
||||||
{
|
{
|
||||||
int exitCode = ptQueuePush(ctx->regQueue, ev, errbuf);
|
int exitCode = ptQueuePush(ctx->regQueue, ev, errbuf);
|
||||||
if (exitCode) {
|
if (exitCode)
|
||||||
|
{
|
||||||
panic("Unable to push to reg queue: %s\n", errbuf);
|
panic("Unable to push to reg queue: %s\n", errbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user