ref: c5b0ea7305dca401bedaa2a88a6816ff96ae51d0
parent: 04b419c602ed75deaed50b89fa164660fd679e8f
author: 9ferno <[email protected]>
date: Sun Jan 23 06:33:47 EST 2022
moving towards forth userspace
--- a/os/pc64/main.c
+++ b/os/pc64/main.c
@@ -1,4 +1,5 @@
#include "u.h"
+#include "tos.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
@@ -298,8 +299,16 @@
o->pgrp->dot = cclone(o->pgrp->slash);
chandevinit();
+/* print("devtab\n");
+ for(int i=0; devtab[i] != nil; i++){
+ print(" i %d devtab[i] 0x%p dc %d name %s\n", i, devtab[i], devtab[i]->dc, devtab[i]->name);
+ print(" reset 0x%p init 0x%p shutdown 0x%p\n", devtab[i]->reset, devtab[i]->init, devtab[i]->shutdown);
+ print(" attach 0x%p walk 0x%p stat 0x%p\n", devtab[i]->attach, devtab[i]->walk, devtab[i]->stat);
+ print(" open 0x%p create 0x%p close 0x%p\n", devtab[i]->open, devtab[i]->create, devtab[i]->close);
+ print(" read 0x%p bread 0x%p write 0x%p\n", devtab[i]->read, devtab[i]->bread, devtab[i]->write);
+ }*/
- if(!waserror()){
+ if(waserror() == 0){
ksetenv("cputype", "am64", 0);
//snprint(buf, sizeof(buf), "amd64 %s", conffile);
//ksetenv("terminal", buf, 0);
@@ -306,10 +315,11 @@
setconfenv();
poperror();
}
+ kproc("alarm", alarmkproc, 0, 0);
- poperror();
-
- disinit("/osinit.dis");
+ /* disinit("/osinit.dis"); */
+ /* init0 will never return */
+ panic("init0");
}
void
@@ -318,9 +328,9 @@
Proc *p;
Osenv *o;
- while((p = newproc()) == nil){
-/* TODO freebroken(); */
- resrcwait("no procs for userinit");
+ up = nil;
+ if((p = newproc()) == nil){
+ panic("no procs for userinit");
}
o = p->env;
@@ -329,10 +339,7 @@
o->pgrp = newpgrp();
kstrdup(&o->user, eve);
- strcpy(p->text, "interp");
-
- pidalloc(p);
-
+ strcpy(p->text, "*init*");
/*
* Kernel Stack
*
@@ -340,7 +347,9 @@
* 8 bytes for gotolabel's return PC
*/
p->sched.pc = (uintptr)init0;
- p->sched.sp = (uintptr)p->kstack+KSTACK-sizeof(uintptr);
+ p->sched.sp = (uintptr)p->kstack+KSTACK-sizeof(uintptr) - sizeof(Tos) -sizeof(uintptr)/* for the string "boot" */;
+ ((uintptr*)p->sched.sp)[0] = 0;
+ strcpy((char*)p->sched.sp+1,"boot");
ready(p);
}
--- a/os/pc64/mem.h
+++ b/os/pc64/mem.h
@@ -78,7 +78,7 @@
#define CPU0MACH (KDZERO+0x2000ull) /* Mach for bootstrap processor (BSP) */
#define CPU0END (KDZERO+0x12000ull) /* CPU0MACH + (MACHSIZE = 64 KiB = 0x10 000) */
/* MACHSIZE includes stack size */
-#define CPU0SP (KDZERO+0x12000ull)
+#define CPU0SP CPU0END
#define FFSTART (KDZERO+0x12000ull) /* FF stacks, system variables, tib, word buffer */
#define FFEND (KDZERO+0x15000ull) /* 3 pages */
/* 1 PD table has 512 entries
@@ -205,6 +205,8 @@
#define RMACH R15 /* m-> */
#define RUSER R14 /* up-> */
+
+#define USTKTOP (up->kstack+KSTACK)
/* forth locations */
/*
--- a/os/pc64/pc64
+++ b/os/pc64/pc64
@@ -145,6 +145,7 @@
dial
dis
discall
+ edf
exception
exportfs
inferno
--- a/os/port/alarm.c
+++ b/os/port/alarm.c
@@ -24,7 +24,7 @@
continue;
if((long)(now - when) < 0)
break;
-/* TODO if(!canqlock(&rp->debug))
+ if(!canqlock(&rp->debug))
break;
if(rp->alarm != 0){
postnote(rp, 0, "alarm", NUser);
@@ -31,7 +31,6 @@
rp->alarm = 0;
}
qunlock(&rp->debug);
-*/
}
alarms.head = rp;
qunlock(&alarms);
--- a/os/port/devforth.c
+++ b/os/port/devforth.c
@@ -331,8 +331,8 @@
{
up->type = Forth;
- loadforthdictionary((u8*)fmem);
/* load dictionary */
+ loadforthdictionary((u8*)fmem);
print("forthentry pid %d forthmem 0x%zx end 0x%zx forthmem+RSTACK 0x%zx\n",
up->pid, (intptr)fmem, ((intptr*)fmem)[1], (intptr)fmem+RSTACK);
DBG("fentries[0].name %s\n", fentries[0].hdr.name);
@@ -360,7 +360,7 @@
}
void
-startforthproc(Proc *p, Params *params)
+initializeforthproc(Proc *p, Params *params)
{
Pgrp *pg;
Fgrp *fg;
@@ -402,6 +402,9 @@
if(params->shmem == 0 || params->shmem == 2){
p->shm = nil;
}else if(params->shmem == 1){
+ if(up->shm == nil)
+ up->shm = shmgrpnew();
+
p->shm = up->shm;
incref(up->shm);
}
@@ -508,7 +511,7 @@
qunlock(&p->debug);
p->psstate = nil;
- print("startforthproc: ready p->pid %d\n", p->pid);
+ print("initializeforthproc: ready p->pid %d\n", p->pid);
ready(p);
}
@@ -759,6 +762,36 @@
error(Eperm);
}
+Proc *
+newforthproc(void)
+{
+ Proc *p;
+
+ flock();
+ if(waserror()){
+ funlock();
+ nexterror();
+ }
+ while((p = newproc()) == nil){
+ freebroken();
+ resrcwait("no procs for kproc");
+ }
+ p->fstarted = 0; /* until the pctl message comes through */
+ kstrdup(&p->env->user, up->env->user);
+
+ if(fhead == nil){
+ fhead = ftail = p;
+ }else{
+ ftail->fnext = p;
+ p->fprev = ftail;
+ ftail = p;
+ }
+ nforthprocs++;
+ funlock();
+ poperror();
+ return p;
+}
+
/*
Opening the new file creates a forth process. The file
descriptor returned from the open(2) will point to the con-
@@ -801,29 +834,9 @@
return tc;
}
- flock();
- if(waserror()){
- funlock();
- nexterror();
- }
if(QID(c->qid) == Qnew){
- while((p = newproc()) == nil){
- /* TODO freebroken(); */
- resrcwait("no procs for kproc");
- }
- p->fstarted = 0; /* until the pctl message comes through */
+ p = newforthproc();
c->aux = p;
- kstrdup(&p->env->user, up->env->user);
-
- if(fhead == nil){
- fhead = ftail = p;
- }else{
- ftail->fnext = p;
- p->fprev = ftail;
- ftail = p;
- }
- nforthprocs++;
-
slot = procindex(p->pid);
if(slot < 0)
panic("forthopen");
@@ -836,8 +849,6 @@
" c->aux 0x%p\n",
p->pid, slot, SLOT(c->qid), chanpath(c), c->aux);
}
- funlock();
- poperror();
p = proctab(SLOT(c->qid));
eqlock(&p->debug);
@@ -1006,7 +1017,7 @@
((char*)buf)[n] = '\0';
DBG("forthwrite n %d buf %s\n", n, buf);
params = parseparams(buf);
- startforthproc(f, ¶ms);
+ initializeforthproc(f, ¶ms);
}else
error(Ebadctl);
break;
--- a/os/port/devproc.c
+++ b/os/port/devproc.c
@@ -850,7 +850,7 @@
x = strtoull(f[2], &q, 0);
if(f[2] == q || *q != 0 || x > (uintptr)-wq->addr) error("invalid length");
wq->len = x;
- /*if(wq->addr + wq->len > USTKTOP) error("bad address");*/
+ if(wq->addr + wq->len > (uintptr)USTKTOP) error("bad address");
wq++;
}
nwp = wq - (wp + nwp0);
--- a/os/port/portclock.c
+++ b/os/port/portclock.c
@@ -5,6 +5,7 @@
#include "fns.h"
#include "io.h"
#include "ureg.h"
+#include "tos.h"
struct Timers
{
@@ -146,7 +147,7 @@
if(m->proc)
m->proc->pc = ur->pc;
- /* accounttime(); */
+ accounttime();
kmapinval();
if(kproftick != nil)
@@ -155,19 +156,17 @@
if(active.machs[m->machno] == 0)
return;
- if(active.exiting) {
- print("someone's exiting\n");
+ if(active.exiting)
exit(0);
- }
if(m->machno == 0)
checkalarms();
if(up && up->state == Running){
- if(anyready()){
- sched();
- splhi();
- }
+ /* user profiling clock */
+ Tos *tos = (Tos*)(USTKTOP-sizeof(Tos));
+ tos->clock += TK2MS(1);
+ hzsched(); /* in proc.c */
}
}
--- a/os/port/portdat.h
+++ b/os/port/portdat.h
@@ -595,11 +595,17 @@
/* inferno uses Osenv for environment information. It is cheaper to create
* new processes with a default environment (spawn, not fork)
+ *
+ * When using forth for the userspace, forth's stack is in fmem.
+ * The kstack is used for everything else. Hence, there is no
+ * stack switching to kstack on a syscall. Forth uses
+ * DX and R8 for stack manipulations to avoid
+ * messing around with SP.
*/
struct Proc
{
Label sched; /* known to l.s */
- char *kstack; /* known to l.s */
+ char *kstack; /* known to l.s in 9front to switch to the kernel stack on syscallentry */
Mach *mach; /* machine running this proc */
char *text;
char *user; /* inferno uses Osenv.user */
--- a/os/port/portfns.h
+++ b/os/port/portfns.h
@@ -1,8 +1,10 @@
+void accounttime(void);
Timer* addclock0link(void (*)(void), int);
Path* addelem(Path *p, char *s, Chan *from);
void addprog(Proc*);
void addrootfile(char*, uchar*, ulong);
Block* adjustblock(Block*, int);
+void alarmkproc(void*);
Block* allocb(int);
int anyhigher(void);
int anyready(void);
@@ -115,6 +117,7 @@
void free(void*);
void freeb(Block*);
void freeblist(Block*);
+int freebroken(void);
void freeskey(Signerkey*);
void getcolor(u32, u32*, u32*, u32*);
uintptr getmalloctag(void*);
@@ -125,6 +128,7 @@
void (*hwrandbuf)(void*, u32);
void hnputl(void*, u32);
void hnputs(void*, u16);
+void hzsched(void);
Block* iallocb(int);
void iallocsummary(void);
void ilock(Lock*);
@@ -200,6 +204,7 @@
Egrp* newegrp(void);
Fgrp* newfgrp(Fgrp*);
int newfd(Chan*, int);
+Proc * newforthproc(void);
Mhead* newmhead(Chan*);
Mount* newmount(Chan*, int, char*);
Path* newpath(char*);
--- a/os/port/proc.c
+++ b/os/port/proc.c
@@ -664,6 +664,7 @@
/*
* not using memset 0 on the Proc structure
* to avoid leaking KSTACK
+TODO fpusetup() and procsetup() of 9front
*/
Proc*
newproc(void)
@@ -697,6 +698,12 @@
p->env->errstr = p->env->errbuf0;
p->env->syserrstr = p->env->errbuf1;
+ /*
+ * a user process. kproc() can change it as it needs.
+ */
+ up->kp = 0;
+ up->noswap = 0;
+ up->privatemem = 0;
/* sched params */
p->mp = 0;
p->wired = 0;
@@ -708,9 +715,7 @@
pidalloc(p);
if(p->pid == 0)
panic("pidalloc");
- if(p->kstack == 0)
- p->kstack = smalloc(KSTACK);
- addprog(p);
+ /* addprog(p); no more dis */
return p;
}