kvisc/vm/pc/main.c

166 lines
2.7 KiB
C

// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <sys/time.h>
#include <signal.h>
#include <pc/dev.h>
#define FWPROGSIZE (1024 * 1024 * 1024)
static ssize_t fwsize;
static ushort *fwprog;
ushort bget(ctx_t *ctx)
{
ulong addr = rip + cr1;
if (addr2real(addr) >= ctx->mz) {
_except(ctx, E_ACC, "Executing out of memory: "
"rip=0x%lX cr1=0x%lX",
rip, cr1);
}
ushort c = ctx->mp[addr2real(addr)];
//log("bget 0x%lX: 0x%lX\n", addr, c);
rip += 2;
return c;
}
ctx_t main_ctx;
void sigcommon(void)
{
dying = 1;
enable_stdin_echoing();
//
// Shut down devices
//
devfiniall(&main_ctx);
exit(-13);
}
void sigint(int _)
{
sigcommon();
}
void sigsegv(int _)
{
log("Segmentation fault\n");
sigcommon();
}
void main_loop(void)
{
//
// Start decoding
//
while (1) {
decode(&main_ctx);
if (main_ctx.step)
getchar();
}
}
int main(int argc, char **argv)
{
FILE *fwfile;
main_ctx.r = arch_r;
main_ctx.i = arch_i;
//
// srand
//
struct timeval time;
gettimeofday(&time, NULL);
srandom((time.tv_sec * 1000) + (time.tv_usec / 1000));
//
// Signal handling
//
signal(SIGINT, sigint);
signal(SIGBUS, sigsegv);
signal(SIGSEGV, sigsegv);
//
// Load program
//
if (argc < 3) {
log("Not enough arguments\n");
exit(-3);
}
create_symtab(argv[2]);
fwfile = fopen(argv[1], "rb");
if (!fwfile) {
log("Couldn't open program file\n");
exit(-2);
}
fwprog = malloc(FWPROGSIZE);
if (!fwprog) {
log("Couldn't allocate firmware buffer\n");
exit(-1);
}
fwsize = fread(fwprog, 1, FWPROGSIZE, fwfile);
if (fwsize < 2) {
log("Program file too small or empty\n");
free(fwprog);
exit(-3);
}
fclose(fwfile);
//
// Register frame allocation
//
main_ctx.rf = calloc(NREGS, sizeof(ulong));
//
// Memory allocation
//
main_ctx.mp = malloc(MEMSIZE + 16);
main_ctx.mz = MEMSIZE;
main_ctx.get = bget;
main_ctx.rf[RIP] = MEMOFF;
if (main_ctx.mp == 0) {
log("Couldn't allocate RAM\n");
free(main_ctx.rf);
free(fwprog);
exit(-1);
}
memcpy(&main_ctx.mp[addr2real(main_ctx.rf[RIP])], fwprog, fwsize);
//
// Devices initialization
//
main_ctx.dh = 0;
if (devinitall(&main_ctx) < 0) {
log("Couldn't initialize devices\n");
free(main_ctx.rf);
free(fwprog);
exit(-10);
}
disable_stdin_echoing();
main_loop();
}