~kris/9p

9hist

dc74f7055908f67de349d2951e16e3645ae99c27 — David du Colombier 35 years ago 1c2496c
Plan 9 from Bell Labs 1991-06-13
4 files changed, 189 insertions(+), 5 deletions(-)

A pc/mem.h
M pc/mmu.c
A pc/trap.c
M port/devroot.c
A pc/mem.h => pc/mem.h +99 -0
@@ 0,0 1,99 @@
#define SELGDT	(0<<3)	/* selector is in gdt */
#define	SELLDT	(1<<3)	/* selector is in ldt */

#define SELECTOR(i, t, p)	(((i)<<4) | (t) | (p))

/*
 *  segment descriptor/gate
 */
typedef struct Segdesc	Segdesc;
struct Segdesc
{
	ulong	d0;
	ulong	d1;
};
#define SEGDATA	(0x10<<8)	/* data/stack segment */
#define SEGEXEC	(0x18<<8)	/* executable segment */
#define SEGCG	(0x0C<<8)	/* call gate */
#define	SEGIG	(0x0E<<8)	/* interrupt gate */
#define SEGTG	(0x0F<<8)	/* task gate */

#define SEGP	(1<<15)		/* segment present */
#define SEGPL(x) ((x)<<13)	/* priority level */
#define SEGB	(1<<22)		/* granularity 1==4k (for expand-down) */
#define SEGG	(1<<23)		/* granularity 1==4k (for other) */
#define SEGE	(1<<10)		/* expand down */
#define SEGW	(1<<9)		/* writable (for data/stack) */
#define	SEGR	(1<<9)		/* readable (for code) */
#define SEGD	(1<<22)		/* default 1==32bit (for code) */

/*
 *  gate initializers
 */
#define TRAPGATE(s,o,p)	{ (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGTG, (o)&0xFFFF|((s)<<16) }
#define INTRGATE(s,o,p)	{ (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGIG, (o)&0xFFFF|((s)<<16) }
#define CALLGATE(s,o,p)	{ (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGCG, (o)&0xFFFF|((s)<<16) }

/*
 *  segment descriptor initializers
 */
#define	DATASEG(p) 	{ SEGG|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW, 0xFFFF }
#define	EXECSEG(p) 	{ SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR, 0xFFFF }

/*
 *  known segments (in GDT) and their selectors
 */
enum
{
	NULLSEG=0,	/* null segment */
	KESEG=	1,	/* kernel executable */	
	KDSEG=	2,	/* kernel data/stack */
	UESEG=	3,	/* user executable */
	UDSEG=	4,	/* user data/stack */
	SYSGATE=5,	/* system call gate */
};
#define NULLSEL	SELECTOR(NULLSEG, SELGDT, 0)
#define KESEL	SELECTOR(KESEG, SELGDT, 0)
#define KDSEL	SELECTOR(KDSEG, SELGDT, 0)
#define KSSEL	SELECTOR(KDSEG, SELGDT, 0)
#define UESEL	SELECTOR(UESEG, SELGDT, 3)
#define UDSEL	SELECTOR(UDSEG, SELGDT, 3)
#define USSEL	SELECTOR(UDSEG, SELGDT, 3)

/*
 *  task state segment.  Plan 9 ignores all the task switching goo and just
 *  uses the tss for esp0 and ss0 on gate's into the kernel, interrupts,
 *  and exceptions.  The rest is completely ignored.
 *
 *  This means that we only need one tss in the whole system.
 */
typedef struct Tss	Tss;
struct Tss
{
	ulong	backlink;	/* unused */
	ulong	esp0;		/* pl0 stack pointer */
	ulong	ss0;		/* pl0 stack selector */
	ulong	esp1;		/* pl1 stack pointer */
	ulong	ss1;		/* pl1 stack selector */
	ulong	esp2;		/* pl2 stack pointer */
	ulong	ss2;		/* pl2 stack selector */
	ulong	cr3;		/* page table descriptor */
	ulong	eip;		/* instruction pointer */
	ulong	eflags;		/* processor flags */
	ulong	eax;		/* general (hah?) registers */
	ulong 	ecx;
	ulong	edx;
	ulong	ebx;
	ulong	esp;
	ulong	ebp;
	ulong	esi;
	ulong	edi;
	ulong	es;		/* segment selectors */
	ulong	cs;
	ulong	ss;
	ulong	ds;
	ulong	fs;
	ulong	gs;
	ulong	ldt;		/* local descriptor table */
	ulong	iomap;		/* io map base */
};

M pc/mmu.c => pc/mmu.c +12 -5
@@ 5,9 5,16 @@
#include	"fns.h"
#include	"io.h"



void
mapstack(Proc *p)
/*
 *  global descriptor table describing all segments
 */
Segdesc gdt[1024] =
{
}
[NULLSEG]	{ 0, 0},		/* null descriptor */
[KESEG]		EXECSEG(0),		/* kernel code */
[KDSEG]		DATASEG(0),		/* kernel data/stack */
[UESEG]		EXECSEG(3),		/* user code */
[UDSEG]		DATASEG(3),		/* user data/stack */
[SYSGATE]	CALLGATE(KESEG, syscall, 3),	/* call gate for system calls */
		{ 0, 0},		/* the rest */
};

A pc/trap.c => pc/trap.c +65 -0
@@ 0,0 1,65 @@
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"

void	ediv(void);
void	edebug(void);
void	enmi(void);
void	ebp(void);
void	eover(void);
void	ebound(void);
void	ebadop(void);
void	enoco(void);
void	edfault(void);
void	enoway(void);
void	etss(void);
void	enoseg(void);
void	estack(void);
void	eprot(void);
void	efault(void);

/*
 *  exception types
 */
enum {
	Ediv=	0,	/* divide error */
	Edebug=	1,	/* debug exceptions */
	Enmi=	2,	/* non-maskable interrupt */
	Ebp=	3,	/* INT 3 */
	Eover=	4,	/* overflow */
	Ebound=	5,	/* bounds check */
	Ebadop=	6,	/* invalid opcode */
	Enoco=	7,	/* coprocessor not available */
	Edfault=8,	/* double fault */
	Etss=	10,	/* invalid tss */
	Enoseg=	11,	/* segment not present */
	Estack=	12,	/* stack exception */
	Eprot=	13,	/* general protection */
	Efault=	14,	/* page fault */
	Eco=	16,	/* coprocessor error */
};

/*
 *  exception/trap gates
 */
Segdesc ilt[256] =
{
[Ediv]		TRAPGATE(KESEL, ediv, 3),
[Edebug]	TRAPGATE(KESEL, edebug, 3),
[Enmi]		INTRGATE(KESEL, enmi, 3),
[Ebp]		TRAPGATE(KESEL, ebp, 3),
[Eover]		TRAPGATE(KESEL, eover, 3),
[Ebound]	TRAPGATE(KESEL, ebound, 3),
[Ebadop]	TRAPGATE(KESEL, ebadop, 3),
[Enoco]		TRAPGATE(KESEL, enoco, 3),
[Edfault]	TRAPGATE(KESEL, edfault, 3),
[Etss]		TRAPGATE(KESEL, etss, 3),
[Enoseg]	TRAPGATE(KESEL, enoseg, 3),
[Estack]	TRAPGATE(KESEL, estack, 3),
[Eprot]		TRAPGATE(KESEL, eprot, 3),
[Efault]	TRAPGATE(KESEL, efault, 3),
[Eco]		TRAPGATE(KESEL, eco, 3),
};

M port/devroot.c => port/devroot.c +13 -0
@@ 11,6 11,7 @@ enum{
	Qbin,
	Qboot,
	Qcfs,
	Qcryptfs,
	Qdev,
	Qenv,
	Qproc,


@@ 19,6 20,9 @@ enum{
extern long	cfslen;
extern ulong	cfscode[];

extern long	cryptfslen;
extern ulong	cryptfscode[];


Dirtab rootdir[]={
	"bin",		{Qbin|CHDIR},	0,			0700,


@@ 26,6 30,7 @@ Dirtab rootdir[]={
	"dev",		{Qdev|CHDIR},	0,			0700,
	"env",		{Qenv|CHDIR},	0,			0700,
	"proc",		{Qproc|CHDIR},	0,			0700,
	"cryptfs",	{Qcryptfs},	0,			0700,
	"cfs",		{Qcfs},		0,			0700,
};



@@ 113,6 118,14 @@ rootread(Chan *c, void *buf, long n, ulong offset)
		memmove(buf, ((char*)cfscode)+offset, n);
		return n;

	case Qcryptfs:		/* cryptfs */
		if(offset >= cryptfslen)
			return 0;
		if(offset+n > cryptfslen)
			n = cryptfslen - offset;
		memmove(buf, ((char*)cryptfscode)+offset, n);
		return n;

	case Qdev:
		return 0;
	}