From c7621a8e78f15d605eac30505ce7f56b2e5262ce Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 10 Feb 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-02-10 --- pc/fns.h | 2 -- pc/mmu.c | 28 ---------------------------- pc/segment.h | 12 ++---------- port/fault.c | 21 ++++++++++++++++----- port/page.c | 25 +++++++++++++++++++++---- port/portdat.h | 34 ++++++++++++++++++++++------------ port/segment.c | 6 ++---- port/systab.h | 9 +++------ power/mmu.c | 40 ---------------------------------------- power/segment.h | 21 +++++++++------------ 10 files changed, 75 insertions(+), 123 deletions(-) diff --git a/pc/fns.h b/pc/fns.h index 0282f1d2913c4e44c5eccccab1ca67c26672473d..a510d4276ad8241419408345fdbc8a906197d03f 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -9,10 +9,8 @@ void clockinit(void); void config(int); int cpuspeed(int); void delay(int); -void dsegfree(Page*); void dmaend(int); long dmasetup(int, void*, long, int); -Page* dsegalloc(Segment*, ulong); #define evenaddr(x) /* 386 doesn't care */ void fault386(Ureg*); void faultinit(void); diff --git a/pc/mmu.c b/pc/mmu.c index 90b27d27689b96909a3aa66e7a0231beff949c0f..9f21f9cc16f7fd09ba0ef00ddf5e7d407585a41f 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -351,31 +351,3 @@ isamem(int len) unlock(&isamemalloc); return a; } - -/* - * mapping for user access to d segment (access to TARGA) - */ -Page* -dsegalloc(Segment *s, ulong va) -{ - Page *pg; - - pg = smalloc(sizeof(Page)); - memset(pg, 0, sizeof(Page)); - pg->va = va; - pg->pa = 0xd0000 + (va - s->base); - pg->ref = 1; - return pg; -} - -void -dsegfree(Page *pg) -{ - int x; - - lock(pg); - x = --pg->ref; - unlock(pg); - if(x <= 0) - free(pg); -} diff --git a/pc/segment.h b/pc/segment.h index 28b3e935d02a60058e888028e0e26a6b94c76df1..cfedf03a14688592a4758ddabc4002679021207c 100644 --- a/pc/segment.h +++ b/pc/segment.h @@ -2,19 +2,11 @@ * Attach segment types */ -typedef struct Physseg Physseg; -struct Physseg +Physseg physseg[] = { - ulong attr; /* Segment attributes */ - char *name; /* Attach name */ - ulong pa; /* Physical address */ - ulong size; /* Maximum segment size in pages */ - Page *(*pgalloc)(Segment*, ulong); /* Allocation if we need it */ - void (*pgfree)(Page*); -}physseg[] = { { SG_SHARED, "lock", 0, SEGMAXSIZE, 0, 0 }, { SG_SHARED, "shared", 0, SEGMAXSIZE, 0, 0 }, - { SG_PHYSICAL, "dseg", 0xd0000, 64*1024, dsegalloc, dsegfree, }, + { SG_PHYSICAL, "dseg", 0xd0000, 64*1024, 0, 0 }, { SG_BSS, "memory", 0, SEGMAXSIZE, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, }; diff --git a/port/fault.c b/port/fault.c index 4138dcab67a6dd8d74a3c890d21ccd11dbc09c89..b474805d4b49a9b095340d80bf205ac0432b802d 100644 --- a/port/fault.c +++ b/port/fault.c @@ -42,10 +42,11 @@ fault(ulong addr, int read) int fixfault(Segment *s, ulong addr, int read, int doputmmu) { + int type; + Pte **p, *etp; ulong mmuphys=0, soff; Page **pg, *lkp, *new; - Pte **p, *etp; - int type; + Page *(*fn)(Segment*, ulong); addr &= ~(BY2PG-1); soff = addr-s->base; @@ -130,10 +131,20 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) break; case SG_PHYSICAL: - if(*pg == 0) - *pg = (*s->pgalloc)(s, addr); + if(*pg == 0) { + fn = s->pseg->pgalloc; + if(fn) + *pg = (*fn)(s, addr); + else { + new = smalloc(sizeof(Page)); + new->va = addr; + new->pa = s->pseg->pa+(addr-s->base); + new->ref = 1; + *pg = new; + } + } - mmuphys = PPN((*pg)->pa) | PTEWRITE|PTEUNCACHED|PTEVALID; + mmuphys = PPN((*pg)->pa) |PTEWRITE|PTEUNCACHED|PTEVALID; (*pg)->modref = PG_MOD|PG_REF; break; } diff --git a/port/page.c b/port/page.c index b8acfa6c21fcde96083caf256924f4503b710883..32e4980445fef78bcb2badabdf271b2190202b96 100644 --- a/port/page.c +++ b/port/page.c @@ -407,16 +407,33 @@ ptealloc(void) void freepte(Segment *s, Pte *p) { - Page **pg, **ptop; + int ref; + Page *pt, **pg, **ptop; + void (*fn)(Page*); switch(s->type&SG_TYPE) { case SG_PHYSICAL: + fn = s->pseg->pgfree; ptop = &p->pages[PTEPERTAB]; - for(pg = p->pages; pg < ptop; pg++) - if(*pg) { - (*s->pgfree)(*pg); + if(fn) { + for(pg = p->pages; pg < ptop; pg++) { + if(*pg == 0) + continue; + (*fn)(*pg); *pg = 0; } + break; + } + for(pg = p->pages; pg < ptop; pg++) { + pt = *pg; + if(pt == 0) + continue; + lock(pt); + ref = --pt->ref; + unlock(pt); + if(ref == 0) + free(pt); + } break; default: for(pg = p->first; pg <= p->last; pg++) diff --git a/port/portdat.h b/port/portdat.h index 750f382e499e010f6cfcfc5657657c3d81042311..d4f714f58b410f811f399eab8d5ec175a474a992 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -24,6 +24,7 @@ typedef struct Page Page; typedef struct Palloc Palloc; typedef struct Pgrps Pgrps; typedef struct Pgrp Pgrp; +typedef struct Physseg Physseg; typedef struct Proc Proc; typedef struct Pte Pte; typedef struct Qinfo Qinfo; @@ -408,22 +409,31 @@ enum #define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM) +struct Physseg +{ + ulong attr; /* Segment attributes */ + char *name; /* Attach name */ + ulong pa; /* Physical address */ + ulong size; /* Maximum segment size in pages */ + Page *(*pgalloc)(Segment*, ulong); /* Allocation if we need it */ + void (*pgfree)(Page*); +}; + struct Segment { Ref; QLock lk; - ushort steal; /* Page stealer lock */ - Segment *next; /* free list pointers */ - ushort type; /* segment type */ - ulong base; /* virtual base */ - ulong top; /* virtual top */ - ulong size; /* size in pages */ - ulong fstart; /* start address in file for demand load */ - ulong flen; /* length of segment in file */ - int flushme; /* maintain consistent icache for this segment */ - Image *image; /* text in file attached to this segment */ - Page *(*pgalloc)(Segment*, ulong);/* SG_PHYSICAL page allocator */ - void (*pgfree)(Page *); /* SG_PHYSICAL page free */ + ushort steal; /* Page stealer lock */ + Segment *next; /* free list pointers */ + ushort type; /* segment type */ + ulong base; /* virtual base */ + ulong top; /* virtual top */ + ulong size; /* size in pages */ + ulong fstart; /* start address in file for demand load */ + ulong flen; /* length of segment in file */ + int flushme; /* maintain consistent icache for this segment */ + Image *image; /* text in file attached to this segment */ + Physseg *pseg; Pte *map[SEGMAPSIZE]; /* segment pte map */ }; diff --git a/port/segment.c b/port/segment.c index e9c898167ab10b4a298cf585aec772de09e2ef31..8bb47f6e71f45654267794db618e10bb7fb80e62 100644 --- a/port/segment.c +++ b/port/segment.c @@ -10,6 +10,7 @@ void lkpgfree(Page*); void imagereclaim(void); /* System specific segattach devices */ +#include "io.h" #include "segment.h" #define IHASHSIZE 64 @@ -438,12 +439,9 @@ found: attr |= ps->attr; /* Copy in defaults */ s = newseg(attr, va, len/BY2PG); - s->pgalloc = ps->pgalloc; - s->pgfree = ps->pgfree; + s->pseg = ps; u->p->seg[sno] = s; - /* Need some code build mapped devices here */ - return 0; } diff --git a/port/systab.h b/port/systab.h index aa617daa669e3b0c40f14f08036f7b1459872586..fd9e53c1fde7ca8c20a23428b741cf7a636b646d 100644 --- a/port/systab.h +++ b/port/systab.h @@ -12,7 +12,7 @@ Syscall sysdup; Syscall sysalarm; Syscall sysexec; Syscall sysexits; -Syscall sys_x1; +Syscall sysfsession; Syscall sys_x2; Syscall sysfstat; Syscall syssegbrk; @@ -40,7 +40,6 @@ Syscall syssegflush; Syscall sysrendezvous; Syscall sysunmount; Syscall syswait; -Syscall sysfsession; Syscall sysdeath; Syscall *systab[]={ @@ -53,7 +52,7 @@ Syscall *systab[]={ [ALARM] sysalarm, [EXEC] sysexec, [EXITS] sysexits, - [_X1] sysdeath, + [FSESSION] sysfsession, [_X2] sysdeath, [FSTAT] sysfstat, [SEGBRK] syssegbrk, @@ -81,7 +80,6 @@ Syscall *systab[]={ [RENDEZVOUS] sysrendezvous, [UNMOUNT] sysunmount, [WAIT] syswait, - [FSESSION] sysfsession, }; char *sysctab[]={ @@ -94,7 +92,7 @@ char *sysctab[]={ [ALARM] "Alarm", [EXEC] "Exec", [EXITS] "Exits", - [_X1] "_x1", + [FSESSION] "Fsession", [_X2] "_x2", [FSTAT] "Fstat", [SEGBRK] "Segbrk", @@ -122,5 +120,4 @@ char *sysctab[]={ [RENDEZVOUS] "Rendez", [UNMOUNT] "Unmount", [WAIT] "Wait", - [FSESSION] "Fsession", }; diff --git a/power/mmu.c b/power/mmu.c index 202124eddc42f8969fe21c364961caee17e77862..39635632545fdd4d852f7cb51ec6885982764d43 100644 --- a/power/mmu.c +++ b/power/mmu.c @@ -180,43 +180,3 @@ putstlb(ulong tlbvirt, ulong tlbphys) if(tlbphys == 0) entry->virt = 0; } - -/* Mapping routines for td's frame buffer -Page* -a16seg(Segment *s, ulong va) -{ - Page *pg; - - pg = smalloc(sizeof(Page)); - memset(pg, 0, sizeof(Page)); - pg->va = va; - pg->pa = 0xd0000 + (va - s->base); - pg->ref = 1; - return pg; -} - -Page* -a32seg(Segment *s, ulong va) -{ - Page *pg; - - pg = smalloc(sizeof(Page)); - memset(pg, 0, sizeof(Page)); - pg->va = va; - pg->pa = VMEA32SUP(ulong, va - s->base); - pg->ref = 1; - return pg; -} - -void -vmefree(Page *pg) -{ - int x; - - lock(pg); - x = --pg->ref; - unlock(pg); - if(x <= 0) - free(pg); -} -*/ diff --git a/power/segment.h b/power/segment.h index c52324e4f068c7c3a87e93fb870dee7c24ff307e..74affd406bdf545c75f3815dd9b1a148e3ad66f9 100644 --- a/power/segment.h +++ b/power/segment.h @@ -2,18 +2,15 @@ * Attach segment types */ -typedef struct Physseg Physseg; -struct Physseg +#define VME16IO3 0x17C10000 +#define VME32TDFB (0x30000000+128*MB) + +Physseg physseg[] = { - ulong attr; /* Segment attributes */ - char *name; /* Attach name */ - ulong pa; /* Physical address */ - ulong size; /* Maximum segment size in pages */ - Page *(*pgalloc)(Segment*, ulong); /* Allocation if we need it */ - void (*pgfree)(Page*); -}physseg[] = { { SG_PHYSICAL, "lock", 0, 1024*BY2PG, lkpage, lkpgfree }, - { SG_SHARED, "shared", 0, SEGMAXSIZE, 0, 0 }, - { SG_BSS, "memory", 0, SEGMAXSIZE, 0, 0 }, - { 0, 0, 0, 0, 0, 0 }, + { SG_SHARED, "shared", 0, SEGMAXSIZE, 0, 0 }, + { SG_BSS, "memory", 0, SEGMAXSIZE, 0, 0 }, + { SG_PHYSICAL, "vme16", VME16IO3, 64*1024, 0, 0 }, + { SG_PHYSICAL, "tdsfb", VME32TDFB, 4*MB, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, };