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:
parent
72f27a22c3
commit
b324b120fc
4
Makefile
4
Makefile
@ -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
|
||||
|
10
instr/INSTRS
10
instr/INSTRS
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
44
karch/arch.h
44
karch/arch.h
@ -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"
|
||||
|
||||
|
50
karch/decd.c
50
karch/decd.c
@ -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
81
karch/dump.c
Normal 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");
|
||||
}
|
@ -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)
|
||||
|
@ -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 },
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user