This commit is contained in:
julianb0 2019-06-05 19:31:48 +02:00
parent eb23154e70
commit 51f91c8fb1
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
14 changed files with 441 additions and 12 deletions

View File

@ -4,6 +4,7 @@
all: kas
kpc:
@rm -f vm/a.out
@cd vm && make --no-print-directory
kas: kpc as/k-as.py as/regs.lst

View File

@ -233,6 +233,24 @@ def parse_preproc(line):
assert(written == 8)
pdata += written
# buffer / bss
elif tok[2][0] == '[':
assert(tok[2][-1] == ']')
s = tok[2][1:-1].strip()
if not is_number(s):
print("Invalid bss format: {}".format(line))
leave()
sys.exit(1)
i = int(s, base=0)
i = i + (8 - i % 8)
written = b_data.write(bytearray(i))
assert(written == i)
pdefs[label + "_len"] = s
pdata += written
# string data
elif tok[2][0] in "'\"":
s = tok[2].strip()

View File

@ -7,10 +7,20 @@
main:
enter
mov ax0, .buf
devctl 0, 1
mov ax0, .buf
call print
prn 10
leave
ret
.buf = [32]
test:
enter
mov ax0, .msg
call print
@ -28,13 +38,11 @@ main:
mov ax1, .msg
call strcmp
movt rax, rbx
leave
ret
.msg = "HelloWorld :)"
.buf = "!!!!!!!!!!!!!"
.buf = [32]
;
; Exit function

View File

@ -6,26 +6,30 @@ all: k.exe
.PHONY: clean
.INTERMEDIATE: %.o
dv_src = $(shell ls dv/*.c)
in_src = $(shell ls in/*.c)
pc_src = $(shell ls pc/*.c)
obj = pc/disd.o $(patsubst %.c,%.o,$(pc_src)) $(patsubst %.c,%.o,$(in_src))
obj = pc/disd.o
obj += $(patsubst %.c,%.o,$(dv_src))
obj += $(patsubst %.c,%.o,$(in_src))
obj += $(patsubst %.c,%.o,$(pc_src))
FLAGS=-O2 -g -Wall -fno-builtin-log -I.
pc/disd.o: i_arch.h */*.h pc/decd.c
pc/disd.o: in/i_arch.h */*.h pc/decd.c
@cc $(FLAGS) -D_NEED_DISASM -c pc/decd.c -o $@
%.o: %.c i_arch.h */*.h $(src)
%.o: %.c in/i_arch.h */*.h $(src)
@cc $(FLAGS) -c $< -o $@
i_arch.h: in/INSTRS in/arch_i.py
in/i_arch.h: in/INSTRS in/arch_i.py
@cd in && python3 arch_i.py
clean:
@rm -f */*.o in/arch_i.h
k.exe: i_arch.h $(obj)
k.exe: in/i_arch.h $(obj)
@gcc -O2 -Wall $(obj) -o k.exe
@rm in/arch_i.h
@rm -f */*.o

39
vm/dv/DEVAPI Normal file
View File

@ -0,0 +1,39 @@
# The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information.
To communicate with devices, use:
devctl #dev #slot
iocall #dev #slot
This will call a function from the device's slot table.
It will take registers ax0-ax7 as its parameters, and
return a value in rdx:rax.
The return value in rax is a status value:
≥0 ok (>0 only if meaningful)
-1 unspecified error
-2 no such device
-3 device powered off
-4 device fatal error
-5 device not plugged
-6 no such function slot
-7 slot not implemented
-8 slot reserved
-9 invalid parameters
-10 to -256 (reserved)
< -256 (left to device)
The slots for "devctl" are architecture-rerserved.
They consist of the following functions:
Slot Param (ax0) Description
0 ptr Write device type into buffer
1 ptr Write device name into buffer
2 ptr Write device model into buffer
3 ptr Write device vendor into buffer
4 rax=major, rdx=minor
5 rax=feats, rdx=revis
6-31 (reserved)
The slots for "iocall" are device-defined. (They correspond
to the "fslots" array of the dev_t structure.) See that
particular device's documentation (if any).

17
vm/dv/cpu.c Normal file
View File

@ -0,0 +1,17 @@
// 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 <dv/dev.h>
dev_t cpudev =
{
.type = "cpu",
.name = "K-CPU",
.modl = "K-CPU",
.vend = "The OS/K Team",
.major = 0,
.minor = 1,
.revis = 0,
};

128
vm/dv/dev.c Normal file
View File

@ -0,0 +1,128 @@
// 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 <dv/dev.h>
static_assert(sizeof(dev_t) % 8 == 0, "");
dev_t *devalloc(void)
{
return calloc(sizeof(dev_t)/sizeof(ulong), sizeof(ulong));
}
void devfree(dev_t *dev)
{
assert(dev != NULL);
free(dev);
}
dev_t *devget(ctx_t *ctx, int idx)
{
if (idx < 0)
return NULL;
int i;
dev_t *dev;
for (i = 0, dev = ctx->dh; dev && i != idx; dev = dev->next, i++);
return dev;
}
void devattach(ctx_t *ctx, dev_t *dev)
{
dev_t *it;
assert(dev != NULL);
if (ctx->dh) {
for (it = ctx->dh; it->next != NULL; it = it->next);
it->next = dev;
}
else ctx->dh = dev;
}
int devinit(ctx_t *ctx, dev_t *dev)
{
if (!dev || dev->state != DEVPWOF)
return -1;
if (dev->fpwon)
dev->fpwon(ctx, dev);
else dev->state = DEVGOOD;
if (!(dev->state == DEVPLUG || dev->state == DEVGOOD))
return -1;
dev->id = random();
devattach(ctx, dev);
return 0;
}
// NEVER detach while some assembly code
// may still be running on the vm!
void devdetach(ctx_t *ctx, dev_t *dev)
{
dev_t *it;
assert(dev != NULL);
if (dev == ctx->dh) {
ctx->dh = dev->next;
}
for (it = ctx->dh; it; it = it->next) {
if (!it)
break;
if (it->next == dev) {
it->next = dev->next;
break;
}
}
}
int devfini(ctx_t *ctx, dev_t *dev)
{
if (dev->state == DEVPWOF || dev->state == DEVFERR) {
goto err;
}
if (dev->fpwoff)
dev->fpwoff(ctx, dev);
else dev->state = DEVPWOF;
if (dev->state != DEVPWOF)
goto err;
devdetach(ctx, dev);
return 0;
err:
devdetach(ctx, dev);
return -1;
}
int devinitall(ctx_t *ctx)
{
return devinit(ctx, &cpudev);
}
int devfiniall(ctx_t *ctx)
{
int failed = 0;
while (ctx->dh)
if (devfini(ctx, ctx->dh) < 0)
failed = -1;
return failed;
}

61
vm/dv/dev.h Normal file
View File

@ -0,0 +1,61 @@
// 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>
#define DEVLEN 32
#define DEVSLOTS 256
typedef void (*devfn_t)(ctx_t *, dev_t *);
enum
{
DEVPWOF, // Power off
DEVPLUG, // Unplugged or plugging
DEVGOOD, // Plugged and working
DEVFERR, // Fatal error
};
struct dev_t
{
dev_t *next;
char type[DEVLEN];
char name[DEVLEN];
char modl[DEVLEN];
char vend[DEVLEN];
int major;
int minor;
int revis;
ulong feats;
long id;
uint state;
void *data;
devfn_t fpwon;
devfn_t fpwoff;
devfn_t fplug;
devfn_t funplug;
devfn_t fslots[DEVSLOTS];
};
dev_t *devalloc(void);
void devfree(dev_t *);
dev_t *devget(ctx_t *, int);
void devattach(ctx_t *, dev_t *);
void devdetach(ctx_t *, dev_t *);
int devinit(ctx_t *, dev_t *);
int devfini(ctx_t *, dev_t *);
int devinitall(ctx_t *);
int devfiniall(ctx_t *);
extern dev_t cpudev;

90
vm/dv/devctl.c Normal file
View File

@ -0,0 +1,90 @@
// 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 <dv/dev.h>
#include <in/instrs.h>
//
// code common to devctl and iocall
//
dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
{
dev_t *dev = devget(ctx, v1);
if (!dev)
rax = -2;
else if (dev->state == DEVPWOF)
rax = -3;
else if (dev->state == DEVFERR)
rax = -4;
else if (dev->state == DEVPLUG)
rax = -5;
else
return dev;
return NULL;
}
void copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str)
{
for (; *str && maxn > 0; str++, addr++, maxn--) {
writemem8(ctx, *str, addr);
}
writemem8(ctx, 0, addr);
}
IMPL_START_2(devctl)
{
CHK_SUPERV();
dev_t *dev = devctl_common(ctx, v1, v2);
if (dev == NULL)
return;
switch (v2) {
case 0:
copystr(ctx, ax0, DEVLEN, dev->type);
break;
case 1:
copystr(ctx, ax0, DEVLEN, dev->name);
break;
case 2:
copystr(ctx, ax0, DEVLEN, dev->modl);
break;
case 3:
copystr(ctx, ax0, DEVLEN, dev->vend);
break;
case 4:
rax = dev->major;
rdx = dev->minor;
break;
case 5:
rax = dev->feats;
rdx = dev->revis;
break;
default:
rax = -6;
break;
}
}
IMPL_END;
IMPL_START_2(iocall)
{
CHK_SUPERV();
}
IMPL_END;

View File

@ -177,6 +177,9 @@ popf
cli
sti
devctl rim rim
iocall rim rim
#
# Misc. instructions
#

View File

@ -1,6 +1,11 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#ifndef _ARCH_H
#define _ARCH_H
#define dev_t stddev_t
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@ -8,6 +13,7 @@
#include <assert.h>
#include <stdarg.h>
#undef dev_t
#define packed __attribute__ ((__packed__))
#define static_assert _Static_assert
#define alignof _Alignof
@ -23,6 +29,7 @@ typedef struct ctx_t ctx_t;
typedef struct instr_t instr_t;
typedef struct acc_t acc_t;
typedef struct arch_t arch_t;
typedef struct dev_t dev_t;
void log(const char *, ...);
void vlog(const char *, va_list);
@ -101,6 +108,9 @@ struct ctx_t
// For disassembly
FILE *disf;
// Devices list head
dev_t *dh;
};
#define R(X) ctx->r[X].val
@ -160,3 +170,5 @@ void writemem(ctx_t *, ulong val, ulong addr, uint len);
extern reg_t arch_r[NREGS];
extern instr_t arch_i[NINSTRS];
#endif

View File

@ -1,7 +1,7 @@
// 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 <dv/dev.h>
void _except(ctx_t *ctx, int code, char *fmt, ...)
{
@ -22,6 +22,12 @@ void _except(ctx_t *ctx, int code, char *fmt, ...)
if (ctx->mp)
free(ctx->mp);
if (devfiniall(ctx) < 0) {
log("Couldn't deinitialize devices\n");
exit(-100 - code);
}
exit(code);
}

View File

@ -1,7 +1,8 @@
// 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 <dv/dev.h>
#include <sys/time.h>
#define FWPROGSIZE (1024 * 1024 * 1024)
static ssize_t fwsize;
@ -40,11 +41,17 @@ ushort dget(ctx_t *ctx)
return fwprog[i++];
}
ctx_t main_ctx;
int main(int argc, char **argv)
{
ctx_t main_ctx;
FILE *fwfile;
struct timeval time;
gettimeofday(&time, NULL);
srandom((time.tv_sec * 1000) + (time.tv_usec / 1000));
main_ctx.r = arch_r;
main_ctx.i = arch_i;
@ -91,6 +98,12 @@ int main(int argc, char **argv)
memcpy(&main_ctx.mp[addr2real(main_ctx.r[RIP].val)], fwprog, fwsize);
main_ctx.dh = 0;
if (devinitall(&main_ctx) < 0) {
log("Couldn't initialize devices\n");
exit(-10);
}
while (1) {
decode(&main_ctx);
}

View File

@ -24,9 +24,26 @@ enum
NX0, NX1, NX2, NX3,
NX4, NX5, NX6, NX7,
#define nx0 R(NX0)
#define nx1 R(NX1)
#define nx2 R(NX2)
#define nx3 R(NX3)
#define nx4 R(NX4)
#define nx5 R(NX5)
#define nx6 R(NX6)
#define nx7 R(NX7)
AX0, AX1, AX2, AX3,
AX4, AX5, AX6, AX7,
#define ax0 R(AX0)
#define ax1 R(AX1)
#define ax2 R(AX2)
#define ax3 R(AX3)
#define ax4 R(AX4)
#define ax5 R(AX5)
#define ax6 R(AX6)
#define ax7 R(AX7)
CR0, CR1, CR2, CR3,
CR4, CR5, CR6, CR7,
@ -34,9 +51,21 @@ enum
#define cr1 R(CR1)
#define cr2 R(CR2)
#define cr3 R(CR3)
#define cr4 R(CR4)
#define cr5 R(CR5)
#define cr6 R(CR6)
#define cr7 R(CR7)
SA0, SA1, SA2, SA3,
SA4, SA5, SA6, SA7,
#define sa0 R(SA0)
#define sa1 R(SA1)
#define sa2 R(SA2)
#define sa3 R(SA3)
#define sa4 R(SA4)
#define sa5 R(SA5)
#define sa6 R(SA6)
#define sa7 R(SA7)
NREGS
};