refactor config loading

This commit is contained in:
2026-04-08 23:12:40 +03:00
parent 9d55a87200
commit b5162a19e8
7 changed files with 219 additions and 178 deletions

View File

@@ -1,9 +1,11 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "device.h"
#include "mem.h"
#include "mem_seg.h"
#include "runner.h"
#include "addrs.h"
@@ -308,12 +310,25 @@ void error(const char* err, char* errbuf)
device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
{
conf_mem_seg_t** segments = devConf->memConf->memSegConfs;
device_specs_t* specs = malloc(sizeof(device_specs_t));
device_specs_t* specs = calloc(1, sizeof(device_specs_t));
if (specs == NULL)
{
error("unable to allocate mem specs struct", errbuf);
return NULL;
}
memseg_metadata_t requiredSegments[] = MEMSEG_DEFINES;
uint8_t* requiredSegmentsFoundMap = (uint8_t*)calloc(sizeof(requiredSegments) / sizeof(memseg_metadata_t), sizeof(uint8_t));
if(requiredSegmentsFoundMap == NULL)
{
error("unable to allocate found map", errbuf);
free(specs);
return NULL;
}
uint8_t specCount = 0;
specs->executableSegmentsCount = 0;
@@ -325,29 +340,37 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
}
specCount++;
}
if(specCount < sizeof(requiredSegments)/sizeof(memseg_metadata_t))
{
specCount = sizeof(requiredSegments)/sizeof(memseg_metadata_t);
}
specs->memSpecsCount = specCount;
specs->memSpecs = malloc(specCount * sizeof(memseg_spec_t*));
specs->memSpecs = calloc(specCount, sizeof(memseg_spec_t*));
if (specs->memSpecs == NULL)
{
free(specs);
free(requiredSegmentsFoundMap);
error("unable to allocate mem segment specs", errbuf);
return NULL;
}
specs->executableSegments = malloc(sizeof(uint8_t) * specs->executableSegmentsCount);
specs->executableSegments = calloc(specs->executableSegmentsCount, sizeof(uint8_t));
if (specs->executableSegments == NULL)
{
error("unable to allocate mem executable specs", errbuf);
free(specs->memSpecs);
free(specs);
free(requiredSegmentsFoundMap);
return NULL;
}
for (uint8_t i = 0; i < specCount; i++)
{
memseg_spec_t* spec = (memseg_spec_t*)malloc(sizeof(memseg_spec_t));
memseg_spec_t* spec = (memseg_spec_t*)calloc(1, sizeof(memseg_spec_t));
if (spec == NULL)
{
sprintf(errbuf, "unable to allocate spec %d", i);
@@ -359,6 +382,7 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
free(specs->memSpecs);
free(specs->executableSegments);
free(specs);
free(requiredSegmentsFoundMap);
return NULL;
}
spec->name = NULL;
@@ -366,51 +390,62 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
specs->memSpecs[i] = spec;
}
uint8_t foundSegments = 0;
uint8_t executableSegmentsFound = 0;
for (uint8_t i = 0; i < specCount; i++)
{
uint8_t specNum = 0xFF;
if (strcmp(segments[i]->name, "ext_reg_io") == 0)
uint8_t is_error = 0;
uint8_t seek_found = 0;
for(uint8_t j = 0; j < sizeof(requiredSegments) / sizeof(memseg_metadata_t); j++)
{
specNum = MEMDATA_IO_REGS;
}
else if (strcmp(segments[i]->name, "extstate") == 0)
{
specNum = MEMDATA_EXTSTATE;
}
else
{
sprintf(errbuf, "invalid segment: %s", segments[i]->name);
for(size_t j = 0; j < specCount; j++)
const memseg_metadata_t seg_def = requiredSegments[j];
if(strcmp(seg_def.name, segments[i]->name))
{
if(specs->memSpecs[j]->name != NULL)
const uint8_t is_found = requiredSegmentsFoundMap[j];
if(is_found)
{
free(specs->memSpecs[j]->name);
is_error = 1;
sprintf(errbuf, "duplicate segment %s", seg_def.name);
}
free(specs->memSpecs[j]);
else
{
if(seg_def.is_executable == segments[i]->isExecutable || segments[i]->isExecutable)
{
requiredSegmentsFoundMap[j] = 1;
specNum = j;
seek_found = 1;
}
else
{
is_error = 1;
sprintf(errbuf, "segment %s must be executable", seg_def.name);
}
}
break;
}
free(specs->executableSegments);
free(specs->memSpecs);
free(specs);
}
if(seek_found == 0)
{
is_error = 1;
sprintf(errbuf, "unsupported memory segment: %s", segments[i]->name);
}
if(is_error)
{
freeDevSpec(specs);
free(requiredSegmentsFoundMap);
return NULL;
}
specs->memSpecs[specNum]->name = malloc(sizeof(char) * strlen(segments[i]->name));
specs->memSpecs[specNum]->name = calloc(strlen(segments[i]->name), sizeof(char));
if(specs->memSpecs[specNum]->name == NULL)
{
sprintf(errbuf, "unable to allocate spec %d name", i);
for(size_t j = 0; j < specCount; j++)
{
if(specs->memSpecs[j]->name != NULL)
{
free(specs->memSpecs[j]->name);
}
free(specs->memSpecs[j]);
}
free(specs->executableSegments);
free(specs->memSpecs);
free(specs);
freeDevSpec(specs);
free(requiredSegmentsFoundMap);
return NULL;
}
@@ -423,42 +458,55 @@ device_specs_t* parseSpecsFromConfig(const conf_dev_t* devConf, char* errbuf)
specs->executableSegments[executableSegmentsFound] = specNum;
executableSegmentsFound++;
}
foundSegments += 1;
}
for(uint8_t i = 0; i < sizeof(requiredSegments)/sizeof(memseg_metadata_t); i++)
{
if(requiredSegmentsFoundMap[i] == 0)
{
const memseg_metadata_t seg_def = requiredSegments[i];
specs->memSpecs[seg_def.seg_id]->start = seg_def.default_addr;
specs->memSpecs[seg_def.seg_id]->len = seg_def.default_size;
specs->memSpecs[seg_def.seg_id]->wordLen = seg_def.word_len;
specs->memSpecs[seg_def.seg_id]->name = calloc(strlen(seg_def.name), sizeof(char));
if(specs->memSpecs[seg_def.seg_id]->name == NULL)
{
sprintf(errbuf, "unable to allocate spec %d name", i);
freeDevSpec(specs);
free(requiredSegmentsFoundMap);
return NULL;
}
strcpy(specs->memSpecs[seg_def.seg_id]->name, seg_def.name);
if(seg_def.is_executable)
{
specs->executableSegments[executableSegmentsFound] = seg_def.seg_id;
executableSegmentsFound++;
}
}
}
if(executableSegmentsFound < specs->executableSegmentsCount)
{
sprintf(errbuf, "Not all executable segments found");
for(size_t j = 0; j < specCount; j++)
{
if(specs->memSpecs[j]->name != NULL)
{
free(specs->memSpecs[j]->name);
}
free(specs->memSpecs[j]);
}
free(specs->executableSegments);
free(specs->memSpecs);
free(specs);
freeDevSpec(specs);
free(requiredSegmentsFoundMap);
return NULL;
}
if (foundSegments < 2)
{
sprintf(errbuf, "invalid amount of segments: must be 2");
for(size_t k = 0; k < specs->memSpecsCount; k++)
{
if(specs->memSpecs[k]->name != NULL)
{
free(specs->memSpecs[k]->name);
}
free(specs->memSpecs[k]);
}
free(specs->executableSegments);
free(specs->memSpecs);
free(specs);
return NULL;
}
#ifdef MEMSEG_PC_SEG_NUM
#ifndef MEMSEG_PC_ADDR
specs->pcAddr = memSegToGlobal(specs, MEMSEG_PC_SEG_NUM, 0);
#else
specs->pcAddr = memSegToGlobal(specs, MEMSEG_PC_SEG_NUM, MEMSEG_PC_ADDR);
#endif
#endif
free(requiredSegmentsFoundMap);
return specs;
}
@@ -492,7 +540,8 @@ void fillSmartWriteSpecs(device_specs_t* specs, smart_write_spec_t* smartWriteSp
device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount, char* errbuf)
{
return NULL;
//TODO
device_specs_t* specs = malloc(sizeof(device_specs_t));
if (specs == NULL)
{
@@ -573,109 +622,18 @@ device_public_context_t* initDefault(smart_read_spec_t* smartReadSpecs, uint64_t
device_public_context_t* init(device_specs_t* specs, char* errbuf)
{
if (specs->memSpecsCount >= 0xFF - 2)
{
sprintf(errbuf, "Too many mem specifications");
return NULL;
}
device_specs_t* realSpecs = malloc(sizeof(device_specs_t));
if (realSpecs == NULL)
{
sprintf(errbuf, "unable to allocate spec struct");
return NULL;
}
uint8_t specCount = specs->memSpecsCount + 2;
realSpecs->memSpecsCount = specCount;
realSpecs->memSpecs = (memseg_spec_t**)malloc(realSpecs->memSpecsCount * sizeof(memseg_spec_t*));
if (realSpecs->memSpecs == NULL)
{
sprintf(errbuf, "unable to allocate mem specs");
free(realSpecs);
return NULL;
}
realSpecs->executableSegments = malloc(sizeof(uint8_t) * specs->executableSegmentsCount);
if (realSpecs->executableSegments == NULL)
{
sprintf(errbuf, "unable to allocate executable segments");
free(realSpecs->memSpecs);
free(realSpecs);
return NULL;
}
for (uint8_t i = 0; i < specs->executableSegmentsCount; i++)
{
realSpecs->executableSegments[i] = specs->executableSegments[i];
}
realSpecs->executableSegmentsCount = specs->executableSegmentsCount;
realSpecs->smartReadSpecs = specs->smartReadSpecs;
realSpecs->smartReadSpecsCount = specs->smartReadSpecsCount;
realSpecs->smartWriteSpecs = specs->smartWriteSpecs;
realSpecs->smartWriteSpecsCount = specs->smartWriteSpecsCount;
uint64_t maxAddr = 0;
for (uint8_t i = 0; i < specCount; i++)
{
memseg_spec_t *segSpec = (memseg_spec_t*)malloc(sizeof(memseg_spec_t));
realSpecs->memSpecs[i] = segSpec;
if (segSpec == NULL)
{
sprintf(errbuf, "unable to allocate mem spec segment %u", i);
for (uint8_t j = 0; j < i; j++)
{
free(realSpecs->memSpecs[j]);
}
free(realSpecs->memSpecs);
free(realSpecs->executableSegments);
free(realSpecs);
return NULL;
}
if (i < specCount - 2)
{
realSpecs->memSpecs[i]->name = specs->memSpecs[i]->name;
realSpecs->memSpecs[i]->len = specs->memSpecs[i]->len;
realSpecs->memSpecs[i]->start = specs->memSpecs[i]->start;
realSpecs->memSpecs[i]->wordLen = specs->memSpecs[i]->wordLen;
uint64_t testMaxAddr = realSpecs->memSpecs[i]->start + (realSpecs->memSpecs[i]->len * realSpecs->memSpecs[i]->wordLen);
if (testMaxAddr > maxAddr)
{
maxAddr = testMaxAddr;
}
}
}
uint8_t pcSpecSegNum = specs->memSpecsCount;
realSpecs->pcAddr = memSegToGlobal(realSpecs, pcSpecSegNum, 0);
device_public_context_t* pubDevContext = malloc(sizeof(device_public_context_t));
if (pubDevContext == NULL)
{
sprintf(errbuf, "unable to allocate public context");
freeDevSpec(realSpecs);
return NULL;
}
char initErrbuf[200];
device_info_t* devInfo = initSpecs(realSpecs, initErrbuf);
device_info_t* devInfo = initSpecs(specs, initErrbuf);
if (devInfo == NULL)
{
sprintf(errbuf, "unable to init specs: %s", initErrbuf);
freeDevSpec(realSpecs);
free(pubDevContext);
return NULL;
}