code: 9ferno

Download patch

ref: c5b0ea7305dca401bedaa2a88a6816ff96ae51d0
parent: 04b419c602ed75deaed50b89fa164660fd679e8f
author: 9ferno <gophone2015@gmail.com>
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, &params);
+			initializeforthproc(f, &params);
 		}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;
 }