1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
This commit is contained in:
julianb0 2019-06-19 21:41:22 +02:00
parent 6f5a453fec
commit 6f8a5d1f76
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
21 changed files with 280 additions and 243 deletions

View File

@ -5,6 +5,5 @@
; Main function
;
main:
call showoff
ret

View File

@ -10,14 +10,17 @@ FLAGS=-O2 -g -Wall -fno-builtin-log -I.
dv_src = $(shell ls dv/*.c)
in_src = $(shell ls in/*.c)
pc_src = $(shell ls pc/*.c)
cn_src = $(shell ls cn/*.c)
obj = $(patsubst %.c,$(OBJDIR)/%.o,$(dv_src))
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(in_src))
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(pc_src))
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(cn_src))
dep = $(patsubst %.c,$(OBJDIR)/%.d,$(dv_src))
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(in_src))
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(pc_src))
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(cn_src))
# Color codes
CL='\033[0;32m'
@ -51,6 +54,6 @@ clean:
@rm -f $(OBJDIR)/*/*.d
k.exe: in/instrs.lst $(obj)
@gcc -O2 -Wall $(obj) -o k.exe
@gcc -O2 -lSDL2 -Wall $(obj) -o k.exe
@echo ${CL2}[$@] ${CL}made successfully.${CL3}

View File

@ -82,13 +82,13 @@ itoa_test 1052600
devtest 1052764
str_test 1052848
main 1053184
errno 1053208
trap0_test.msg 1053216
printf_test.fmt 1053239
printf_test.str 1053287
strchr_test.str 1053295
itoa_test.buf 1053311
devtest.buf 1053351
str_test.msg 1053391
str_test.buf1 1053407
str_test.buf2 1053447
errno 1053192
trap0_test.msg 1053200
printf_test.fmt 1053223
printf_test.str 1053271
strchr_test.str 1053279
itoa_test.buf 1053295
devtest.buf 1053335
str_test.msg 1053375
str_test.buf1 1053391
str_test.buf2 1053431

16
vm/cn/console.c Normal file
View File

@ -0,0 +1,16 @@
// 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 <cn/console.h>
void console_init(ctx_t *ctx)
{
/*
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
log("Couldn't initialize SDL: %s", SDL_GetError());
}
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);*/
}

10
vm/cn/console.h Normal file
View File

@ -0,0 +1,10 @@
// 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 <pc/arch.h>
//#include <SDL2/SDL.h>
void console_init(ctx_t *ctx);

View File

@ -366,129 +366,21 @@ enter i
#
leave
#---------------------------------------------------------------------------#
# String manipulation instructions #
#---------------------------------------------------------------------------#
#
# PUSH value onto stack
#
# RSP = RSP - 8
# *RSP = $1
#
push rim
#
# Store value into string (STOSx)
# POP value from stack
#
# [%1] = $2
# IF (DF == 0) THEN
# %str = %str + sizeof(x)
# ELSE
# %str = %str - sizeof(x)
# FI
# $1 = *RSP
# RSP = RSP + 8
#
# When no parameters are given, %str = RDI and $val = RAX
# When one parameter is given, %str = RDI and $val = $1
# When two parameters are given, %str = $1 and $val = $2
#
stosb r rim
stosw r rim
stosl r rim
stosq r rim
#
# Load value from string (LODSx)
#
# $1 = [%2]
# IF (DF == 0) THEN
# %str = %str + sizeof(x)
# ELSE
# %str = %str - sizeof(x)
# FI
#
# Preserves CF, OF and SF
# Sets ZF according to the loaded value
#
lodsb r r
lodsw r r
lodsl r r
lodsq r r
#
# Scan string for a particular value (SCASx)
#
# CMP([%1], $2)
#
# IF ([%1] == 0) THEN
# ZF = 1
# ELIF (ZF == 0) THEN
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# FI
# FI
#
# Sets CF, OF and SF according to the result of the comparison
# Sets ZF according to whether [%1] and $2 are equal, OR if [%1] is null
#
# Notes:
# - Does not move past the value when found
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
#
scasb r rim
scasw r rim
scasl r rim
scasq r rim
#
# Compare bytes in strings (CMPSx)
#
# CMP([%1], [%2])
#
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# %2 = %2 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# %2 = %2 - sizeof(x)
# FI
#
# Sets CF, OF, ZF and SF according to the result of the comparison
#
# Moves past the compared values in any case!
#
cmpsb r r
cmpsw r r
cmpsl r r
cmpsq r r
#
# Safe compare bytes in strings (CMPZSx)
#
# Behaves precisely like CMPSx, except in the following case:
# - If both [%1] and [%2] are zero, clears ZF (indicating NOT EQUAL)
#
# This prevents 'CMPZSx.REP.Z' from looping infinitely when both strings
# have the exact same content; this allows for short strcmp's
#
cmpzsb r r
cmpzsw r r
cmpzsl r r
cmpzsq r r
#
# Move value from string to string (MOVSx)
#
# [%1] = [%1]
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# %2 = %2 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# %2 = %2 - sizeof(x)
# FI
#
# Preserves CF, OF and SF
# Sets ZF according to the moved value
#
movsb r r
movsw r r
movsl r r
movsq r r
pop rm
#---------------------------------------------------------------------------#
# Supervisor only instructions #
@ -683,34 +575,128 @@ clr
cla
#---------------------------------------------------------------------------#
# Deprecated instruction #
# String manipulation instructions #
#---------------------------------------------------------------------------#
#
# PUSH value onto stack
# Store value into string (STOSx)
#
# RSP = RSP - 8
# *RSP = $1
# [%1] = $2
# IF (DF == 0) THEN
# %str = %str + sizeof(x)
# ELSE
# %str = %str - sizeof(x)
# FI
#
# Throws:
# #STA if RBP MOD 8 > 0
# #STA if RSP MOD 8 > 0
# #STU if RSP > RBP
# When no parameters are given, %str = RDI and $val = RAX
# When one parameter is given, %str = RDI and $val = $1
# When two parameters are given, %str = $1 and $val = $2
#
!push rim
stosb r rim
stosw r rim
stosl r rim
stosq r rim
#
# POP value from stack
# Load value from string (LODSx)
#
# $1 = *RSP
# RSP = RSP + 8
# $1 = [%2]
# IF (DF == 0) THEN
# %str = %str + sizeof(x)
# ELSE
# %str = %str - sizeof(x)
# FI
#
# Throws:
# #STA if RBP MOD 8 > 0
# #STA if RSP MOD 8 > 0
# #STU if RSP >= RBP
# Preserves CF, OF and SF
# Sets ZF according to the loaded value
#
!pop rm
lodsb r r
lodsw r r
lodsl r r
lodsq r r
#
# Scan string for a particular value (SCASx)
#
# CMP([%1], $2)
#
# IF ([%1] == 0) THEN
# ZF = 1
# ELIF (ZF == 0) THEN
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# FI
# FI
#
# Sets CF, OF and SF according to the result of the comparison
# Sets ZF according to whether [%1] and $2 are equal, OR if [%1] is null
#
# Notes:
# - Does not move past the value when found
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
#
scasb r rim
scasw r rim
scasl r rim
scasq r rim
#
# Compare bytes in strings (CMPSx)
#
# CMP([%1], [%2])
#
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# %2 = %2 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# %2 = %2 - sizeof(x)
# FI
#
# Sets CF, OF, ZF and SF according to the result of the comparison
#
# Moves past the compared values in any case!
#
cmpsb r r
cmpsw r r
cmpsl r r
cmpsq r r
#
# Safe compare bytes in strings (CMPZSx)
#
# Behaves precisely like CMPSx, except in the following case:
# - If both [%1] and [%2] are zero, clears ZF (indicating NOT EQUAL)
#
# This prevents 'CMPZSx.REP.Z' from looping infinitely when both strings
# have the exact same content; this allows for short strcmp's
#
cmpzsb r r
cmpzsw r r
cmpzsl r r
cmpzsq r r
#
# Move value from string to string (MOVSx)
#
# [%1] = [%1]
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# %2 = %2 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# %2 = %2 - sizeof(x)
# FI
#
# Preserves CF, OF and SF
# Sets ZF according to the moved value
#
movsb r r
movsw r r
movsl r r
movsq r r
#---------------------------------------------------------------------------#

View File

@ -5,11 +5,11 @@
IMPL_START_0(break)
{
log("\nExecuting BREAK INSTR\n");
trace("\nExecuting BREAK INSTR\n");
dumpregs(ctx);
getchar();
log("Resuming execution\n");
trace("Resuming execution\n");
}
IMPL_END;

View File

@ -18,6 +18,7 @@ IMPL_END;
IMPL_START_0(cpuid)
{
rax = rdx = 0;
}
IMPL_END;
@ -49,8 +50,8 @@ IMPL_OUT;
IMPL_START_1(prn)
{
if (p1->mlen > 1) {
log("prn warning: large access size\n");
if (p1->mlen > 4) {
trace("prn warning: large access size\n");
}
putchar((int)v1);
}

View File

@ -3,8 +3,6 @@
#include <in/instrs.h>
//----------------------------------------------------------------------------//
IMPL_START_1(trap)
{
if (v1 > 255)
@ -14,7 +12,6 @@ IMPL_START_1(trap)
}
IMPL_END;
//----------------------------------------------------------------------------//
// XXX more checks

View File

@ -32,7 +32,8 @@ typedef struct acc_t acc_t;
typedef struct arch_t arch_t;
typedef struct dev_t dev_t;
void log(const char *, ...);
void logerr(const char *, ...);
void trace(const char *, ...);
void vlog(const char *, va_list);
#define KARCH_MAJOR 0
@ -69,6 +70,8 @@ struct ctx_t
#define R(X) ctx->rf[X]
void die(int code) __attribute__((__noreturn__));
void dumpregs(ctx_t *);
void dumpinstr(ctx_t *, ulong, uint, ushort, acc_t *, acc_t *);
void dumpmem(ctx_t *, ulong, ulong);
@ -85,6 +88,7 @@ void disable_stdin_echoing(void);
#include <pc/except.h>
#include <in/arch_i.h>
extern ctx_t main_ctx;
extern reg_t arch_r[NREGS];
extern instr_t arch_i[NINSTRS];

View File

@ -161,7 +161,13 @@ void decode(ctx_t *ctx)
uchar f1 = 0, f2 = 0;
ulong pc = rip;
/*
sym_t *sym = find_sym_by_addr(pc);
if (sym)
trace("0x%lX: %s:\n", pc, sym->name);
*/
// Instruction counter
ctx->ninstrs++;

View File

@ -25,7 +25,7 @@ int devinitall(ctx_t *ctx)
size_t it;
for (it = 0; arch_d[it] != NULL; it++) {
// log("Adding device %s\n", arch_d[it]->name);
// trace("Adding device %s\n", arch_d[it]->name);
if (devinit(ctx, arch_d[it]) < 0)
return -1;
}

25
vm/pc/die.c Normal file
View File

@ -0,0 +1,25 @@
// 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 <pc/dev.h>
void die(int code)
{
dying = 1;
enable_stdin_echoing();
if (main_ctx.mp)
free(main_ctx.mp);
//
// Shut down devices
//
if (devfiniall(&main_ctx) < 0)
{
logerr("Couldn't deinitialize devices\n");
exit(-100 - code);
}
exit(code);
}

View File

@ -28,46 +28,46 @@ void dump_instr(ctx_t *ctx,
uint cond,
ulong pc)
{
log("0x%lX:\t", pc);
trace("0x%lX:\t", pc);
if (lock)
log("lock");
trace("lock");
log("%s", in->name);
trace("%s", in->name);
if (rep)
log(".rep");
trace(".rep");
if (cond)
{
log(".");
trace(".");
if (cond & (1 << 4))
{
cond &= ~(1 << 4);
log("n");
trace("n");
}
assert(cond <= sizeof(cond_suffixes)/sizeof(char *));
log("%s", cond_suffixes[cond]);
trace("%s", cond_suffixes[cond]);
}
if (!rep) log("\t\t");
if (!rep) trace("\t\t");
else
log("\t");
trace("\t");
if (p1)
{
dump_acc(ctx, p1);
if (p2) {
log(", ");
trace(", ");
dump_acc(ctx, p2);
}
}
log("\n");
trace("\n");
}
void dump_acc(ctx_t *ctx, acc_t *p)
@ -76,60 +76,60 @@ void dump_acc(ctx_t *ctx, acc_t *p)
sym_t *sym;
if (p->type == A_REG)
log("%s", ctx->r[p->reg].name);
trace("%s", ctx->r[p->reg].name);
else if (p->type == A_IMM64)
{
if (p->val < 0xA)
log("%lu", p->val);
trace("%lu", p->val);
else
{
sym = find_sym_by_addr(p->val);
if (sym)
log("$%s(0x%lX)", sym->name, sym->addr);
trace("$%s(0x%lX)", sym->name, sym->addr);
else
log("0x%lX", p->val);
trace("0x%lX", p->val);
}
}
else
{
log("%c[", getmempref(p->mlen));
trace("%c[", getmempref(p->mlen));
mfmt = p->type & AM_MFMT_MASK;
if (mfmt == AM_IMM64)
log("0x%lX]", p->addr);
trace("0x%lX]", p->addr);
else if (mfmt == AM_RR)
{
if (p->reg1 && p->reg2)
log("%s+%s]", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
trace("%s+%s]", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
else log("%s]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
else trace("%s]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
}
else if (mfmt == AM_RRI)
{
if (p->reg1 && p->reg2)
log("%s+%s+%hd]", ctx->r[p->reg1].name,
trace("%s+%s+%hd]", ctx->r[p->reg1].name,
ctx->r[p->reg2].name, p->imm2);
else log("%s+%hd]",
else trace("%s+%hd]",
ctx->r[p->reg1 ? p->reg1 : p->reg2].name, p->imm2);
}
else if (mfmt == AM_RRII)
{
if (p->reg1)
log("%s+%s*%u+%hd]",
trace("%s+%s*%u+%hd]",
ctx->r[p->reg1].name,
ctx->r[p->reg2].name,
p->imm1, p->imm2);
else
log("%s*%u+%hd]",
trace("%s*%u+%hd]",
ctx->r[p->reg2].name,
p->imm1, p->imm2);
}

View File

@ -13,13 +13,13 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
ulong orig_frame;
log("\nException %u - ", code);
logerr("\nException %u - ", code);
va_start(ap, fmt);
vlog(fmt, ap);
va_end(ap);
log("\n\n");
logerr("\n\n");
//
// Interrupted earlier?
@ -27,7 +27,7 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
if (dying)
{
log("Exception thrown while dying=1\n");
logerr("Exception thrown while dying=1\n");
enable_stdin_echoing();
exit(-12);
}
@ -94,23 +94,9 @@ actually_die:
dying = 1;
enable_stdin_echoing();
dumpregs(ctx);
log("\n");
trace("\n");
if (ctx->mp)
free(ctx->mp);
//
// Shut down devices
//
if (devfiniall(ctx) < 0)
{
log("Couldn't deinitialize devices\n");
exit(-100 - code);
}
exit(code);
die(code);
}

View File

@ -3,7 +3,16 @@
#include <pc/arch.h>
void log(const char *fmt, ...)
void trace(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
void logerr(const char *fmt, ...)
{
va_list ap;

View File

@ -2,9 +2,10 @@
// See the LICENSE file in the project root for more information.
#include <sys/time.h>
#include <signal.h>
#include <pc/dev.h>
#include <cn/console.h>
#define FWPROGSIZE (1024 * 1024 * 1024)
static ssize_t fwsize;
@ -33,16 +34,7 @@ ctx_t main_ctx;
void sigcommon(void)
{
dying = 1;
enable_stdin_echoing();
//
// Shut down devices
//
devfiniall(&main_ctx);
exit(-13);
die(-13);
}
void sigint(int _)
@ -52,7 +44,7 @@ void sigint(int _)
void sigsegv(int _)
{
log("Segmentation fault\n");
logerr("Segmentation fault\n");
sigcommon();
}
@ -94,7 +86,7 @@ int main(int argc, char **argv)
// Load program
//
if (argc < 3) {
log("Not enough arguments\n");
logerr("Not enough arguments\n");
exit(-3);
}
@ -103,21 +95,21 @@ int main(int argc, char **argv)
fwfile = fopen(argv[1], "rb");
if (!fwfile) {
log("Couldn't open program file\n");
logerr("Couldn't open program file\n");
exit(-2);
}
fwprog = malloc(FWPROGSIZE);
if (!fwprog) {
log("Couldn't allocate firmware buffer\n");
logerr("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");
logerr("Program file too small or empty\n");
free(fwprog);
exit(-3);
}
@ -140,7 +132,7 @@ int main(int argc, char **argv)
main_ctx.rf[RIP] = MEMOFF;
if (main_ctx.mp == 0) {
log("Couldn't allocate RAM\n");
logerr("Couldn't allocate RAM\n");
free(main_ctx.rf);
free(fwprog);
exit(-1);
@ -153,12 +145,15 @@ int main(int argc, char **argv)
//
main_ctx.dh = 0;
if (devinitall(&main_ctx) < 0) {
log("Couldn't initialize devices\n");
logerr("Couldn't initialize devices\n");
free(main_ctx.rf);
free(fwprog);
exit(-10);
}
// To be moved to some screen device
console_init(&main_ctx);
disable_stdin_echoing();
main_loop();
}

View File

@ -134,7 +134,7 @@ ulong readmem(ctx_t *ctx, ulong addr, uint len)
case 8:
return readmem64(ctx, real, addr);
default: log("readmem() bad length %d!\n", len); abort();
default: logerr("readmem() bad length %d!\n", len); abort();
}
return val;
@ -152,7 +152,7 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
case 2: writemem16(ctx, val, real, addr); break;
case 4: writemem32(ctx, val, real, addr); break;
case 8: writemem64(ctx, val, real, addr); break;
default: log("writemem() bad length %d!\n", len); abort();
default: logerr("writemem() bad length %d!\n", len); abort();
}
}
@ -173,7 +173,7 @@ ulong readmemzx(ctx_t *ctx, ulong addr, uint len)
case 4: return readmem32(ctx, real, addr); break;
case 8: return readmem64(ctx, real, addr); break;
default: log("readmem() bad length %d!\n", len); abort();
default: logerr("readmemzx() bad length %d!\n", len); abort();
}
}
@ -187,7 +187,7 @@ void writememzx(ctx_t *ctx, ulong val, ulong addr, uint len)
case 2: writemem16(ctx, val, real, addr); break;
case 4: writemem32(ctx, val, real, addr); break;
case 8: writemem64(ctx, val, real, addr); break;
default: log("writemem() bad length %d!\n", len); abort();
default: logerr("writememzx() bad length %d!\n", len); abort();
}
}

View File

@ -74,9 +74,9 @@ reg_t arch_r[] =
#define DUMPREGS(down, up) \
for (i = down; i <= up; i++) { \
if (i % 4 == 0) \
log("\n"); \
trace("\n"); \
r = &ctx->r[i]; \
log("%s=0x%-16lX ", r->name, R(i)); \
trace("%s=0x%-16lX ", r->name, R(i)); \
} \
extern size_t rfs_current_idx;
@ -86,30 +86,30 @@ void dumpregs(ctx_t *ctx)
int i;
reg_t *r;
log("Current RFRAME index: #%u\n", rfs_current_idx);
trace("Current RFRAME index: #%u\n", rfs_current_idx);
DUMPREGS(RAX, RDI);
DUMPREGS(AX0, AX3);
DUMPREGS(LX0, LX3);
log("\n");
trace("\n");
DUMPREGS(NX0, NX3);
DUMPREGS(SA0, SA3);
DUMPREGS(CR0, CR3);
DUMPREGS(CR4, CR7);
log("\n\nrip=0x%-16lX rsp=0x%-16lX rbp=0x%-16lX rx0=%-16lu\n\n",
rip, rsp, rbp, ctx->ninstrs);
trace("\n\nrip=0x%-16lX rsp=0x%-16lX rbp=0x%-16lX rx0=%-16lu\n\n",
rip, rsp, rbp, ctx->ninstrs);
log("CF=%x OF=%x\n"
"ZF=%x SF=%x\n"
"PF=%x DF=%x\n"
"IF=%x UF=%x\n",
!!(flg&CF), !!(flg&OF),
!!(flg&ZF), !!(flg&SF),
!!(flg&PF), !!(flg&DF),
!!(cr0&IF), !!(cr0&UF));
trace("CF=%x OF=%x\n"
"ZF=%x SF=%x\n"
"PF=%x DF=%x\n"
"IF=%x UF=%x\n",
!!(flg&CF), !!(flg&OF),
!!(flg&ZF), !!(flg&SF),
!!(flg&PF), !!(flg&DF),
!!(cr0&IF), !!(cr0&UF));
assert(inv == 0);
}

View File

@ -27,8 +27,8 @@ enum
// CR0 register
enum
{
UF = 1 << 15, // User-mode flag
IF = 1 << 16, // Interrupts enable flag
IF = 1 << 0, // Interrupts-enable flag
UF = 1 << 1, // User-mode flag
};
struct reg_t

View File

@ -14,7 +14,7 @@ int create_symtab(const char *name)
if (!tab)
{
log("Couldn't open symtab\n");
logerr("Couldn't open symtab\n");
return -1;
}
@ -24,9 +24,9 @@ int create_symtab(const char *name)
if (prev_addr >= addr)
{
log("Symbol addresses in symbol table not in increasing order\n");
log("Previous symbol: '%s' '%lu'\n", symtab[it-1].name, prev_addr);
log("Current symbol: '%s' '%lu'\n", buf, addr);
logerr("Symbol addresses in symbol table not in increasing order\n");
logerr("Previous symbol: '%s' '%lu'\n", symtab[it-1].name, prev_addr);
logerr("Current symbol: '%s' '%lu'\n", buf, addr);
exit(-55);
}