M pc/fns.h => pc/fns.h +0 -2
@@ 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);
M pc/mmu.c => pc/mmu.c +0 -28
@@ 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);
-}
M pc/segment.h => pc/segment.h +2 -10
@@ 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 },
};
M port/fault.c => port/fault.c +16 -5
@@ 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;
}
M port/page.c => port/page.c +21 -4
@@ 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++)
M port/portdat.h => port/portdat.h +22 -12
@@ 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 */
};
M port/segment.c => port/segment.c +2 -4
@@ 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;
}
M port/systab.h => port/systab.h +3 -6
@@ 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",
};
M power/mmu.c => power/mmu.c +0 -40
@@ 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);
-}
-*/
M power/segment.h => power/segment.h +9 -12
@@ 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 },
};