1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00

memory, stack, dumping

This commit is contained in:
julianb0 2019-05-16 16:48:45 +02:00
parent 72f27a22c3
commit b324b120fc
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
10 changed files with 195 additions and 68 deletions

View File

@ -3,10 +3,10 @@
all: k.exe
src = instr/instrs.c karch/decd.c karch/main.c karch/regs.c
src = instr/instrs.c karch/decd.c karch/main.c karch/regs.c karch/dump.c
obj = $(patsubst %.c,%.o,$(src))
%.o: %.c instrs/i_arch.h */*.h */*.c
%.o: %.c instrs/i_arch.h */*.h $(src)
@gcc -O2 -Wall -I./karch -c $< -o $@
instrs/i_arch.h: instr/INSTRS instr/instrs.py

View File

@ -38,5 +38,13 @@ mov r i
mov r m
mov m r
mov m i
mov m m
xchg r r
xchg r i
xchg r m
xchg m r
xchg m i
cli
sti

View File

@ -2,6 +2,10 @@
// See the LICENSE file in the project root for more information.
#include "instrs.h"
#include "arch_i.h"
#define _NEED_ARCH_I
#include "arch_i.h"
IMPL_START_0(nop)
{
@ -79,6 +83,17 @@ IMPL_START_2(xchg)
}
IMPL_OUT;
#define _NEED_ARCH_I
#include "arch_i.h"
IMPL_START_0(cli)
{
CHK_SUPERV();
ctx->r[FLG].val &= ~(1L<<63);
}
IMPL_END;
IMPL_START_0(sti)
{
CHK_SUPERV();
ctx->r[FLG].val |= 1L<<63;
}
IMPL_END;

View File

@ -11,19 +11,38 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
{ \
ulong v1 = (p1->type == A_REG ? ctx->r[p1->val].val : p1->val); \
if (p1->mem) v1 = readmem64(ctx, v1 + p1->off); \
#define IMPL_START_2(name) \
void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
{ \
ulong v1 = (p1->type == A_REG ? ctx->r[p1->val].val : p1->val); \
ulong v2 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val); \
if (p1->mem) v1 = readmem64(ctx, v1 + p1->off); \
if (p2->mem) v2 = readmem64(ctx, v2 + p2->off); \
#define IMPL_START_3(name) \
void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
{ \
ulong v2 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val); \
if (p2->mem) v2 = readmem64(ctx, v2 + p2->off); \
#define IMPL_OUT \
assert(p1->type == A_REG); \
ctx->r[p1->val].val = v1; \
assert(p1->type == A_REG || p1->mem); \
if (p1->mem) { \
ulong addr = p1->type == A_REG ? ctx->r[p1->val].val : p1->val; \
writemem64(ctx, v1, addr); \
} \
else ctx->r[p1->val].val = v1; \
} \
#define IMPL_END \
}
#define CHK_SUPERV() \
do { \
if ((ctx->r[FLG].val & (1L << 62)) == 1) { \
_except(ctx, E_SYS, "Supervisor-only INSTR"); \
} \
} while (0)

View File

@ -28,39 +28,43 @@ for _, line in enumerate(fi):
if line[0] == '#' or line[0] == ' ' or line[0] == '\n':
continue
tok = line.split(' ')
tok = line.strip().split(' ')
if len(tok) == 1:
name = tok[0].strip()
name = tok[0]
p1 = "NOPRM"
p2 = "NOPRM"
elif len(tok) == 2:
name = "{}_{}".format(tok[0], tok[1].strip())
p1 = getflag(tok[1].strip())
p1 = getflag(tok[1])
p2 = "NOPRM"
elif len(tok) == 3:
name = "{}_{}_{}".format(tok[0], tok[1], tok[2].strip())
p1 = getflag(tok[1])
p2 = getflag(tok[2].strip())
p2 = getflag(tok[2])
else:
name = "__ERROR__"
p1 = "__ERROR__"
p2 = "__ERROR__"
hd.write("#define I_{} {}\n".format(name.upper(), count))
hd.write("#ifdef _NEED_ARCH_I\n")
hd.write('{{ "{}", "{}", {}, {}, i_{} }},\n'\
.format(tok[0].strip(), name, p1, p2, tok[0]))
.format(tok[0], name, p1, p2, tok[0]))
hd.write("#else\n")
hd.write("#define I_{} {}\n".format(name.upper(), count))
hd.write("extern void i_{}(ctx_t *, acc_t *, acc_t *);\n"
.format(tok[0]))
hd.write("#endif\n\n")
count = count + 1
hd.write("#define NINSTRS {}\n\n".format(count))
hd.write("#ifdef _NEED_ARCH_I\n")
hd.write("};\n")
hd.write("#else\n")
hd.write("#define NINSTRS {}\n\n".format(count))
hd.write("#endif\n")
hd.close()

View File

@ -32,7 +32,7 @@ enum
R08, R09, R10, R11, R12, R13, R14, R15,
K00, K01, K02, K03, K04, K05, K06, K07,
CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7,
RIP, FLG, RET,
RIP, FLG,
NREGS
};
@ -54,13 +54,17 @@ struct reg_t
ulong flags;
};
enum { A_MEM=0x7000 };
// A_REG is implicit
// A_MEM denotes a memory access
// A_OFF is A_MEM but a 16-bit offset is expected immediatly next
enum { A_REG=0, A_MEM=0x7000, A_OFF, A_IMM16, A_IMM32, A_IMM64 };
struct acc_t
{
bool mem;
enum { A_REG=0, A_IMM16=0x7001, A_IMM32, A_IMM64 } type;
bool mem; // A_MEM?
uint type;
ulong val;
short off;
};
enum { NOPREF, PREF_REP=0x8000, PREF_LOCK, NPREFS };
@ -105,7 +109,10 @@ enum
NEXCPTS
};
void dumpregs(ctx_t *ctx);
void dumpregs(ctx_t *);
void dumpinstr(ctx_t *, ulong, ushort, acc_t *, acc_t *);
void dumpmem(ctx_t *, ulong, ulong);
void dumpfwstack(ctx_t *);
static inline void _except(ctx_t *ctx, int code, char *fmt, ...)
{
@ -120,6 +127,8 @@ static inline void _except(ctx_t *ctx, int code, char *fmt, ...)
log("\n");
dumpregs(ctx);
dumpfwstack(ctx);
free(ctx->mp);
exit(code+1);
}
@ -132,16 +141,19 @@ void decode(ctx_t *ctx);
#define addr2real(p) ((p) - MEMOFF)
#define real2addr(p) ((p) + MEMOFF)
// Address of boot firmware stack
#define FWSTACK (MEMOFF * 2) // 2MB
static inline ulong readmem64(ctx_t *ctx, ulong addr)
{
ulong real = addr2real(addr);
if (addr % alignof(ulong) > 0) {
_except(ctx, E_ALI, "Non-aligned memory access");
_except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real);
}
if (addr < MEMOFF || real >= MEMSIZE) {
_except(ctx, E_ACC, "Accessing inexistent memory");
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
}
ulong val = (ulong)ctx->mp[real++];
@ -152,5 +164,23 @@ static inline ulong readmem64(ctx_t *ctx, ulong addr)
return val;
}
static inline void writemem64(ctx_t *ctx, ulong val, ulong addr)
{
ulong real = addr2real(addr);
if (addr % alignof(ulong) > 0) {
_except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real);
}
if (addr < MEMOFF || real >= MEMSIZE) {
_except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real);
}
ctx->mp[real++] = val >> 48;
ctx->mp[real++] = (val >> 32) & 0xFFFF;
ctx->mp[real++] = (val >> 16) & 0xFFFF;
ctx->mp[real++] = val & 0xFFFF;
}
#include "../instr/arch_i.h"

View File

@ -14,6 +14,13 @@ void scan_param(ctx_t *ctx, acc_t *p)
if (c == A_MEM) {
p->mem = 1;
p->off = 0;
c = ctx->get(ctx);
}
else if (c == A_OFF) {
p->mem = 1;
p->off = (short)ctx->get(ctx);
c = ctx->get(ctx);
}
@ -48,49 +55,6 @@ void scan_param(ctx_t *ctx, acc_t *p)
}
}
void dumpregs(ctx_t *ctx)
{
int i;
reg_t *r;
for (i = 0; i < NREGS; i++) {
if (i > 0 && i % 4 == 0)
log("\n");
r = &ctx->r[i];
log("%s=0x%016lX ", r->name, r->val);
}
log("\n");
}
void dumpinstr(ctx_t *ctx, ulong rip, ushort c, acc_t *p1, acc_t *p2)
{
acc_t *p = 0;
instr_t *i = &ctx->i[c];
log("0x%016lX: %s", rip, i->name);
if (i->prm1 != NOPRM)
p = p1;
lp:
if (p != 0) {
if (p->mem) log("[");
if (p->type == A_REG)
log(" %s", ctx->r[p->val].name);
else
log(" 0x%lX", p->val);
if (p->mem) log("]");
if (p == p1 && i->prm2 != NOPRM) {
p = p2;
goto lp;
}
}
log("\n");
}
void decode(ctx_t *ctx)
{
instr_t *i;

81
karch/dump.c Normal file
View File

@ -0,0 +1,81 @@
// 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 "arch.h"
void dumpregs(ctx_t *ctx)
{
int i;
reg_t *r;
log("\nRegisters:\n");
log("rip=0x%016lX flg=0x%016lX", ctx->r[RIP].val, ctx->r[FLG].val);
for (i = 0; i < K00; i++) {
if (i % 4 == 0)
log("\n");
r = &ctx->r[i];
log("%s=0x%016lX ", r->name, r->val);
}
log("\n");
}
void dumpmem(ctx_t *ctx, ulong start, ulong size)
{
uint i;
for (i = 0; i < size/sizeof(ushort); i++) {
if (i % 4 == 0) {
if (i > 0) {
if (i % 8 == 0) log("\n");
else log(" ");
}
log("[0x%08lX]=0x", start + i * 2);
}
log("%04hX", ctx->mp[addr2real(start) + i]);
}
log("\n");
}
void dumpfwstack(ctx_t *ctx)
{
log("\nFirmware stack:\n");
dumpmem(ctx, FWSTACK, 128);
}
void dumpinstr(ctx_t *ctx, ulong rip, ushort c, acc_t *p1, acc_t *p2)
{
acc_t *p = 0;
instr_t *i = &ctx->i[c];
log("0x%016lX: %s", rip, i->name);
if (i->prm1 != NOPRM)
p = p1;
lp:
if (p != 0) {
if (p->mem) log(" [");
else log(" ");
if (p->type == A_REG)
log("%s", ctx->r[p->val].name);
else
log("0x%lX", p->val);
if (p->mem) {
if (p->off)
log("+%hd", p->off);
log("]");
}
if (p == p1 && i->prm2 != NOPRM) {
p = p2;
log(",");
goto lp;
}
}
log("\n");
}

View File

@ -3,8 +3,15 @@
#include "arch.h"
// Boot firware, loaded at MEMOFF (1MB)
ushort fwprog[] = {
I_MOV_R_I, RBP, A_IMM16, MEMOFF+sizeof(fwprog)+0xFF,
I_MOV_R_I, RBP, A_IMM32, FWSTACK>>16, FWSTACK&0xFF,
I_MOV_R_I, RSP, A_IMM32, FWSTACK>>16, FWSTACK&0xFF,
I_MOV_M_I, A_MEM, RBP, A_IMM16, 0xAC,
I_SUB_R_I, RBP, A_IMM16, 8,
I_ADD_M_R, A_OFF, 8, RBP, RSP,
I_MOV_R_M, RAX, A_MEM, RBP,
};
ushort bget(ctx_t *ctx)

View File

@ -39,6 +39,5 @@ reg_t arch_r[NREGS] =
{ "cr7", "Control register 7", 0, CTL },
{ "rip", "Instruction pointer", 0, RES },
{ "flg", "Flags register", 0, RES },
{ "ret", "Return address", 0, RES },
};