add instr, manifest, dev_variant
This commit is contained in:
5
Makefile
5
Makefile
@@ -21,6 +21,9 @@ LIBS=
|
|||||||
STANDART=c23
|
STANDART=c23
|
||||||
OPTIMIZE=-Og
|
OPTIMIZE=-Og
|
||||||
TARGET=device
|
TARGET=device
|
||||||
|
ifeq ($(ARCH),)
|
||||||
|
ARCH := "template"
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
DEFINES=-DOPCODE_WORDSIZE=2 -DMEM_CELL_WORDS=1 -DPC_WORDSIZE=3 -DGP_REG_CELL_WORDS=1 -DIO_REG_CELL_WORDS=1 -DARCH=$(ARCH)
|
DEFINES=-DOPCODE_WORDSIZE=2 -DMEM_CELL_WORDS=1 -DPC_WORDSIZE=3 -DGP_REG_CELL_WORDS=1 -DIO_REG_CELL_WORDS=1 -DARCH=$(ARCH)
|
||||||
@@ -79,7 +82,7 @@ $(MANIFEST_BUILD_DIR)/MANIFEST.json: $(C_HEADERS) $(MANIFEST_TARGETS)
|
|||||||
|
|
||||||
$(MANIFEST_BUILD_DIR)/%.elf: $(MANIFEST_SRC_DIR)/%.c Makefile $(C_HEADERS) | $(MANIFEST_BUILD_DIR)
|
$(MANIFEST_BUILD_DIR)/%.elf: $(MANIFEST_SRC_DIR)/%.c Makefile $(C_HEADERS) | $(MANIFEST_BUILD_DIR)
|
||||||
@echo -e '\033[1;32mELF\t'$(OBJECTS)'\n\t\t\t->\t'$@'\033[0m'
|
@echo -e '\033[1;32mELF\t'$(OBJECTS)'\n\t\t\t->\t'$@'\033[0m'
|
||||||
@$(CC) $(MANIFEST_LFLAGS) $< $(LDLIBS) -I inc -o $@
|
@$(CC) $(MANIFEST_LFLAGS) $< $(DEFINES) $(LDLIBS) -I inc -o $@
|
||||||
|
|
||||||
$(BUILD_DIR):
|
$(BUILD_DIR):
|
||||||
@mkdir -p $(BUILD_DIR)
|
@mkdir -p $(BUILD_DIR)
|
||||||
|
|||||||
94
inc/instr.h
Normal file
94
inc/instr.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
#ifndef __INSTR_H__
|
||||||
|
#define __INSTR_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPCODE_WORDSIZE
|
||||||
|
#error OPCODE_WORDSIZE must be provided
|
||||||
|
// #define OPCODE_WORDSIZE 1
|
||||||
|
#endif
|
||||||
|
#if OPCODE_WORDSIZE == 1
|
||||||
|
typedef uint8_t opcode_t;
|
||||||
|
#elif OPCODE_WORDSIZE == 2
|
||||||
|
typedef uint16_t opcode_t;
|
||||||
|
#elif OPCODE_WORDSIZE == 3
|
||||||
|
typedef uint32_t opcode_t;
|
||||||
|
#elif OPCODE_WORDSIZE == 4
|
||||||
|
typedef uint32_t opcode_t;
|
||||||
|
#else
|
||||||
|
#error OPCODE_WORDSIZE must be one of 1,2,3,4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PC_WORDSIZE
|
||||||
|
#error PC_WORDSIZE must be provided
|
||||||
|
// #define PC_WORDSIZE 1
|
||||||
|
#endif
|
||||||
|
#if PC_WORDSIZE == 1
|
||||||
|
typedef uint8_t prog_counter_t;
|
||||||
|
#elif PC_WORDSIZE == 2
|
||||||
|
typedef uint16_t prog_counter_t;
|
||||||
|
#elif PC_WORDSIZE == 3
|
||||||
|
typedef uint32_t prog_counter_t;
|
||||||
|
#elif PC_WORDSIZE == 4
|
||||||
|
typedef uint32_t prog_counter_t;
|
||||||
|
#else
|
||||||
|
#error PC_WORDSIZE must be one of 1,2,3,4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t (*instr_h_func)(prog_counter_t*, device_mem_t*);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
instr_h_func h;
|
||||||
|
opcode_t base;
|
||||||
|
opcode_t argsMask;
|
||||||
|
uint8_t opcodeLen;
|
||||||
|
|
||||||
|
} instruction_metadata_t;
|
||||||
|
|
||||||
|
instr_h_func* genInstrArray(char* errbuf);
|
||||||
|
void setOpcodeSizes(uint8_t* opcodeSizes);
|
||||||
|
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__
|
||||||
13
inc/instr_map.h
Normal file
13
inc/instr_map.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef __INSTR_MAP_H__
|
||||||
|
#define __INSTR_MAP_H__
|
||||||
|
#include "instr.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "addrs.h"
|
||||||
|
|
||||||
|
uint8_t _nop (prog_counter_t* pcounter, device_mem_t* devMem);
|
||||||
|
|
||||||
|
#define HANDLER_REGISTERS {\
|
||||||
|
{&_nop, 0b0000000000000000, 0b1111111111111111, 2}}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
#ifndef __MEM_SEG_H__
|
#ifndef __MEM_SEG_H__
|
||||||
#define __MEM_SEG_H__
|
#define __MEM_SEG_H__
|
||||||
|
|
||||||
<<<<<<< HEAD
|
#include "../../../inc/libhmmmm.h"
|
||||||
#ifndef DEVICE_TYPE
|
|
||||||
#define DEVICE_TYPE EXTENDED_DEVICE_TYPE_DUMMY
|
|
||||||
#endif
|
|
||||||
=======
|
|
||||||
>>>>>>> 1f4cc4d (Initial commit)
|
|
||||||
|
|
||||||
// #define MEMSEG_PC_SEG_NUM 0
|
#ifndef DEVICE_TYPE
|
||||||
// #define MEMSEG_PC_ADDR 0
|
#define DEVICE_TYPE EXTENDED_DEVICE_TYPE_INSTR_SIMUL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define MEMSEG_PS 0
|
||||||
|
#define MEMDATA_PS MEMSEG_PS
|
||||||
|
|
||||||
|
|
||||||
|
#define MEMSEG_PC_SEG_NUM 1
|
||||||
|
#define MEMSEG_PC_ADDR 0
|
||||||
|
|
||||||
#define MEMSEG_DEFINES {\
|
#define MEMSEG_DEFINES {\
|
||||||
{0, "seg0", 1, 0, 0, 0}, \
|
{MEMSEG_PS, "PS", 2, 1024, 0, 1}, \
|
||||||
{1, "seg1", 1, 0, 0, 0}, \
|
{MEMSEG_PC_SEG_NUM, "PC", 2, 1, 1024 + MEMSEG_PC_ADDR + 1, 0} \
|
||||||
{2, "seg2", 1, 0, 0, 0}, \
|
|
||||||
{3, "seg3", 1, 0, 0, 0}, \
|
|
||||||
{4, "seg4", 1, 0, 0, 0}, \
|
|
||||||
{5, "seg5", 1, 0, 0, 0}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //ifndef __MEM_SEG_H__
|
#endif //ifndef __MEM_SEG_H__
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import sys
|
import sys
|
||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
@@ -11,11 +14,22 @@ def main():
|
|||||||
with open(manifest_dir + '/dev_type', 'r') as f:
|
with open(manifest_dir + '/dev_type', 'r') as f:
|
||||||
dev_type = f.read()
|
dev_type = f.read()
|
||||||
|
|
||||||
|
with open(manifest_dir + '/dev_variant', 'r') as f:
|
||||||
|
dev_variant = f.read()
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(SCRIPT_PATH + '/instructions.json', 'r') as f:
|
||||||
|
instructions = json.load(f)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'unable to read instructions file: {e}')
|
||||||
|
instructions = []
|
||||||
|
|
||||||
mem_segments = []
|
mem_segments = []
|
||||||
out_manifest = {
|
out_manifest = {
|
||||||
'mem_segments': mem_segments,
|
'mem_segments': mem_segments,
|
||||||
'dev_type': dev_type
|
'dev_type': dev_type,
|
||||||
|
'dev_variant': dev_variant,
|
||||||
|
'instructions': instructions
|
||||||
}
|
}
|
||||||
|
|
||||||
with open(manifest_dir + '/seg_data.csv', 'r', newline='') as csvfile:
|
with open(manifest_dir + '/seg_data.csv', 'r', newline='') as csvfile:
|
||||||
|
|||||||
@@ -17,13 +17,14 @@ int main(int argc, char** argv)
|
|||||||
const char *dirpath = argv[1];
|
const char *dirpath = argv[1];
|
||||||
const char *filename = "dev_type";
|
const char *filename = "dev_type";
|
||||||
|
|
||||||
char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 1, sizeof(char));
|
char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 2, sizeof(char));
|
||||||
if(tgtpath == NULL)
|
if(tgtpath == NULL)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(tgtpath, "%s/%s", dirpath, filename);
|
sprintf(tgtpath, "%s/%s", dirpath, filename);
|
||||||
|
tgtpath[strlen(dirpath) + strlen(filename) + 1] = 0;
|
||||||
|
|
||||||
FILE *fptr;
|
FILE *fptr;
|
||||||
|
|
||||||
|
|||||||
56
manifest_src/generate_dev_variant.c
Normal file
56
manifest_src/generate_dev_variant.c
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include "mem.h"
|
||||||
|
#include "mem_seg.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define STR(name) XSTR(name)
|
||||||
|
#define XSTR(name) #name
|
||||||
|
|
||||||
|
#ifndef ARCH
|
||||||
|
#pragma message "ARCH not set, using empty"
|
||||||
|
#define ARCH asdf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define __ARCH STR(ARCH)
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if(argc != 2)
|
||||||
|
{
|
||||||
|
printf("provide target directory\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *dirpath = argv[1];
|
||||||
|
const char *filename = "dev_variant";
|
||||||
|
|
||||||
|
char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 2, sizeof(char));
|
||||||
|
if(tgtpath == NULL)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(tgtpath, "%s/%s", dirpath, filename);
|
||||||
|
tgtpath[strlen(dirpath) + strlen(filename) + 1] = 0;
|
||||||
|
|
||||||
|
FILE *fptr;
|
||||||
|
|
||||||
|
fptr = fopen(tgtpath, "w");
|
||||||
|
|
||||||
|
if(fptr == NULL)
|
||||||
|
{
|
||||||
|
printf("errof opening file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* dev_variant = STR(ARCH);
|
||||||
|
fprintf(fptr, "%s", dev_variant);
|
||||||
|
|
||||||
|
|
||||||
|
fclose(fptr);
|
||||||
|
free(tgtpath);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -16,13 +16,14 @@ int main(int argc, char** argv)
|
|||||||
const char *dirpath = argv[1];
|
const char *dirpath = argv[1];
|
||||||
const char *filename = "seg_data.csv";
|
const char *filename = "seg_data.csv";
|
||||||
|
|
||||||
char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 1, sizeof(char));
|
char *tgtpath = (char*)calloc(strlen(dirpath) + strlen(filename) + 2, sizeof(char));
|
||||||
if(tgtpath == NULL)
|
if(tgtpath == NULL)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(tgtpath, "%s/%s", dirpath, filename);
|
sprintf(tgtpath, "%s/%s", dirpath, filename);
|
||||||
|
tgtpath[strlen(dirpath) + strlen(filename) + 1] = 0;
|
||||||
|
|
||||||
FILE *fptr;
|
FILE *fptr;
|
||||||
|
|
||||||
|
|||||||
@@ -730,11 +730,7 @@ device_public_context_t* init(device_specs_t* specs, char* errbuf)
|
|||||||
|
|
||||||
uint8_t pubDeviceType()
|
uint8_t pubDeviceType()
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
return DEVICE_TYPE;
|
return DEVICE_TYPE;
|
||||||
=======
|
|
||||||
return EXTENDED_DEVICE_TYPE_DUMMY;
|
|
||||||
>>>>>>> 1f4cc4d (Initial commit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
91
src/instr.c
Normal file
91
src/instr.c
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include "instr.h"
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "addrs.h"
|
||||||
|
|
||||||
|
#include "instr_map.h"
|
||||||
|
#include "mem_seg.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t _invalid_opcode(prog_counter_t* pcounter, device_mem_t* devMem)
|
||||||
|
{
|
||||||
|
opcode_t op = extractOpcode(devMem, *pcounter);
|
||||||
|
printf("Invalid opcode at 0x%016X: 0x%016X\n", *pcounter, op);
|
||||||
|
return (uint8_t)(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setCombinations(opcode_t base, opcode_t mask, instr_h_func* tgt, instr_h_func val)
|
||||||
|
{
|
||||||
|
opcode_t start_opcode = base;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
tgt[(start_opcode & mask) | base] = val;
|
||||||
|
start_opcode += 1;
|
||||||
|
} while(start_opcode < (base | mask));
|
||||||
|
tgt[(start_opcode & mask) | base] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setOpcodeSizes(uint8_t* opcodeSizes)
|
||||||
|
{
|
||||||
|
instruction_metadata_t metadataArray[] = HANDLER_REGISTERS;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ((opcode_t)~0); i++)
|
||||||
|
{
|
||||||
|
opcodeSizes[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for(size_t i = 0; i < sizeof(metadataArray) / sizeof(instruction_metadata_t); i++)
|
||||||
|
{
|
||||||
|
opcode_t start_opcode = metadataArray[i].base;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
opcodeSizes[(start_opcode & metadataArray[i].argsMask) | metadataArray[i].base] = metadataArray[i].opcodeLen;
|
||||||
|
start_opcode += 1;
|
||||||
|
} while(start_opcode < (metadataArray[i].base | metadataArray[i].argsMask));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
instr_h_func* genInstrArray(char* errbuf)
|
||||||
|
{
|
||||||
|
|
||||||
|
instruction_metadata_t metadataArray[] = HANDLER_REGISTERS;
|
||||||
|
|
||||||
|
instr_h_func* instrArray = calloc(((opcode_t)~0), sizeof(instr_h_func*));
|
||||||
|
if (instrArray == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "Unable to allocate instruction table");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ((opcode_t)~0); i++)
|
||||||
|
{
|
||||||
|
instrArray[i] = &_invalid_opcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for(size_t i = 0; i < sizeof(metadataArray) / sizeof(instruction_metadata_t); i++)
|
||||||
|
{
|
||||||
|
setCombinations(metadataArray[i].base, metadataArray[i].argsMask, instrArray, metadataArray[i].h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return instrArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
opcode_t extractOpcode(device_mem_t* devMem, prog_counter_t programCounter)
|
||||||
|
{
|
||||||
|
return ((opcode_t*)devMem->cells[MEMSEG_PS])[programCounter];
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pubExtractOpcode(device_mem_t* devMem, size_t _programCounter)
|
||||||
|
{
|
||||||
|
prog_counter_t programCounter = (prog_counter_t)(_programCounter);
|
||||||
|
return (size_t)(((opcode_t*)devMem->cells[MEMSEG_PS])[programCounter]);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user