mirror of
https://github.com/prirun/p50em.git
synced 2026-01-18 08:52:41 +00:00
STLB changes, ITLB instruction
This commit is contained in:
parent
99337af999
commit
8c04dcdd8f
68
em.c
68
em.c
@ -239,7 +239,6 @@ typedef struct {
|
||||
char access[4]; /* ring n access rights */
|
||||
unsigned short procid; /* process id for segments >= '4000 */
|
||||
unsigned short seg; /* segment number */
|
||||
unsigned short vpage; /* virtual page address */
|
||||
unsigned int ppn; /* physical page number (128MB limit) */
|
||||
unsigned short *pmep; /* pointer to page table flag word */
|
||||
unsigned long load_ic; /* instruction where STLB was loaded */
|
||||
@ -446,7 +445,7 @@ pa_t mapva(ea_t ea, short intacc, short *access) {
|
||||
or the segment is private and the process id doesn't match,
|
||||
then the STLB has to be loaded first */
|
||||
|
||||
if (/* 1 || instcount == 20445443 || */ !stlbp->valid || stlbp->seg != seg || (seg >= 04000 && stlbp->procid != crs[OWNERL])) {
|
||||
if (!stlbp->valid || stlbp->seg != seg || (seg >= 04000 && stlbp->procid != crs[OWNERL])) {
|
||||
dtar = *(unsigned int *)(crs+DTAR0-2*DTAR(ea)); /* get dtar register */
|
||||
nsegs = 1024-(dtar>>22);
|
||||
relseg = seg & 0x3FF; /* segment within segment table */
|
||||
@ -472,19 +471,16 @@ pa_t mapva(ea_t ea, short intacc, short *access) {
|
||||
stlbp->access[3] = (sdw >> 6) & 7;
|
||||
stlbp->procid = crs[OWNERL];
|
||||
stlbp->seg = seg;
|
||||
stlbp->vpage = ea & 0xfc00;
|
||||
stlbp->ppn = (pte & 0xFFF);
|
||||
stlbp->pmep = mem+pmaddr;
|
||||
stlbp->load_ic = instcount;
|
||||
}
|
||||
if (stlbp->vpage != (ea & 0xfc00))
|
||||
fatal("STLB page number is wrong!");
|
||||
*access = stlbp->access[ring];
|
||||
if (((intacc & *access) != intacc) || (intacc == PACC && ((*access & 3) == 0)))
|
||||
fault(ACCESSFAULT, 0, ea);
|
||||
if (intacc == WACC && stlbp->unmodified) {
|
||||
stlbp->unmodified = 0;
|
||||
//*(stlbp->pmep) &= ~020000; /* reset unmodified bit in memory */
|
||||
*(stlbp->pmep) &= ~020000; /* reset unmodified bit in memory */
|
||||
}
|
||||
pa = (stlbp->ppn << 10) | (ea & 0x3FF);
|
||||
} else {
|
||||
@ -2113,14 +2109,13 @@ keys = 14200, modals=137
|
||||
put32(utempl, ea); /* update the semaphore */
|
||||
|
||||
if (inst & 4) { /* interrupt notify */
|
||||
if (inst & 2) { /* clear active interrupt */
|
||||
if (inst & 2) /* clear active interrupt */
|
||||
intvec = -1;
|
||||
crs[MODALS] |= 0100000; /* enable interrupts */
|
||||
}
|
||||
/* not sure about all this... Case 85/87 */
|
||||
RP = regs.sym.pswpb;
|
||||
crs[PBH] = RPH;
|
||||
newkeys(regs.sym.pswkeys);
|
||||
crs[MODALS] |= 0100000; /* enable interrupts */
|
||||
}
|
||||
|
||||
if (resched || (inst & 4))
|
||||
@ -2468,10 +2463,8 @@ main (int argc, char **argv) {
|
||||
traceflags = -1;
|
||||
if (0 && instcount > 18255000) /* this is rev 20 mem test requiring STLB */
|
||||
traceflags = -1;
|
||||
#if 0
|
||||
if (instcount > 20445443)
|
||||
exit(1);
|
||||
#endif
|
||||
if (crs[OWNERL] == 0100600)
|
||||
traceflags = -1;
|
||||
|
||||
#if 0
|
||||
if (trapaddr != 0 && mem[trapaddr] != trapvalue) {
|
||||
@ -2607,7 +2600,7 @@ main (int argc, char **argv) {
|
||||
#endif
|
||||
|
||||
xec:
|
||||
if (T_FLOW) fprintf(stderr,"\n%o/%o: %o A='%o/%:0d B='%o/%d X=%o/%d Y=%o/%d C=%d L=%d LT=%d EQ=%d K=%o M=%o #%d [%s %o]\n", RPH, RPL-1, inst, crs[A], *(short *)(crs+A), crs[B], *(short *)(crs+B), crs[X], *(short *)(crs+X), crs[Y], *(short *)(crs+Y), (crs[KEYS]&0100000) != 0, (crs[KEYS]&020000) != 0, (crs[KEYS]&0200) != 0, (crs[KEYS]&0100) != 0, crs[KEYS], crs[MODALS], instcount, searchloadmap(*(unsigned int *)(crs+OWNER)), crs[OWNERL]);
|
||||
if (T_FLOW) fprintf(stderr,"\n #%d [%s %o] SB: %o/%o LB: %o/%o XB: %o/%o\n%o/%o: %o A='%o/%:0d B='%o/%d X=%o/%d Y=%o/%d C=%d L=%d LT=%d EQ=%d K=%o M=%o\n", instcount, searchloadmap(*(unsigned int *)(crs+OWNER)), crs[OWNERL], crs[SBH], crs[SBL], crs[LBH], crs[LBL], crs[XBH], crs[XBL], RPH, RPL-1, inst, crs[A], *(short *)(crs+A), crs[B], *(short *)(crs+B), crs[X], *(short *)(crs+X), crs[Y], *(short *)(crs+Y), (crs[KEYS]&0100000) != 0, (crs[KEYS]&020000) != 0, (crs[KEYS]&0200) != 0, (crs[KEYS]&0100) != 0, crs[KEYS], crs[MODALS]);
|
||||
|
||||
/* begin instruction decode: generic? */
|
||||
|
||||
@ -3056,9 +3049,20 @@ stfa:
|
||||
if (T_FLOW) fprintf(stderr," ITLB\n");
|
||||
RESTRICT();
|
||||
utempl = *(int *)(crs+L);
|
||||
utempa = STLBIX(utempl);
|
||||
stlb[utempa].valid = 0;
|
||||
if (T_INST) fprintf(stderr," invalidated STLB index %d\n", utempa);
|
||||
|
||||
/* NOTE: Primos substitutes an ITLB loop for PTLB, and the ITLB
|
||||
segno is 1, ie, it looks like using segment 1 invalidates all
|
||||
pages, regardless of segment number?? */
|
||||
|
||||
if (utempl == 0x10000) {
|
||||
for (utempa = 0; utempa < STLBENTS; utempa++)
|
||||
stlb[utempa].valid = 0;
|
||||
if (T_INST) fprintf(stderr," purged entire STLB\n");
|
||||
} else {
|
||||
utempa = STLBIX(utempl);
|
||||
stlb[utempa].valid = 0;
|
||||
if (T_INST) fprintf(stderr," invalidated STLB index %d\n", utempa);
|
||||
}
|
||||
/* HACK for DIAG to suppress ITLB loop in trace */
|
||||
if (RP == 0106070)
|
||||
if (*(int *)(crs+L) == 0) {
|
||||
@ -3125,6 +3129,13 @@ irtn:
|
||||
goto irtn;
|
||||
}
|
||||
|
||||
if (inst == 000411) {
|
||||
if (T_FLOW) fprintf(stderr," CAI\n", inst);
|
||||
RESTRICT();
|
||||
intvec = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* R-mode/infrequent gen 0 instructions */
|
||||
|
||||
if (inst == 000005) { /* SGL */
|
||||
@ -5990,17 +6001,9 @@ svc() {
|
||||
printf("Class %o, func %o: %s %d args %o\n", class,func, svcinfo[class][func].name, svcinfo[class][func].numargs, svcinfo[class][func].locargs);
|
||||
#endif
|
||||
|
||||
/* if the svc fault vector is zero, interpret the svc here. This
|
||||
allows the emulator to run r-mode programs directly */
|
||||
|
||||
if ((crs[KEYS] & 010) || get16(065) != 0) {
|
||||
fault(SVCFAULT, 0, 0);
|
||||
fatal("Returned from SVC fault");
|
||||
}
|
||||
|
||||
/* get svc code word, break into class and function */
|
||||
|
||||
code = mem[RPL];
|
||||
code = get16(RPL);
|
||||
class = (code >> 6) & 077;
|
||||
if (class == 0)
|
||||
class = 1;
|
||||
@ -6009,7 +6012,7 @@ svc() {
|
||||
/* determine argument list location and create arg list vector */
|
||||
|
||||
if (code & 0100000)
|
||||
argl = mem[RPL-2];
|
||||
argl = get16(RPL-2);
|
||||
else if (code & 040000)
|
||||
argl = RPL+2;
|
||||
else
|
||||
@ -6023,11 +6026,12 @@ svc() {
|
||||
|
||||
/* if location '65 is set, do indirect JST to handle svc */
|
||||
|
||||
if (mem[065] != 0) {
|
||||
if (T_INST) fprintf(stderr," JST* '65 [%o]\n", mem[065]);
|
||||
mem[mem[065]] = RPL;
|
||||
RPL = mem[065]+1;
|
||||
return;
|
||||
/* if the svc fault vector is zero, interpret the svc here. This
|
||||
allows the emulator to run r-mode programs directly */
|
||||
|
||||
if ((crs[KEYS] & 010) || get16(065) != 0) {
|
||||
fault(SVCFAULT, 0, 0);
|
||||
fatal("Returned from SVC fault");
|
||||
}
|
||||
|
||||
if (svcinfo[class][func].numargs == 99)
|
||||
|
||||
63
emdev.h
63
emdev.h
@ -127,6 +127,9 @@ void devnull (short class, short func, short device) {
|
||||
|
||||
/* Device '4: system console
|
||||
|
||||
NOTES:
|
||||
- needs to set -icanon -icrnl on system console tty
|
||||
|
||||
OCP '0004 = initialize for input only, echoplex, 110 baud, 8-bit, no parity
|
||||
OCP '0104 = same, but for output only
|
||||
OCP '0204 = set receive interrupt mask
|
||||
@ -267,8 +270,7 @@ readasr:
|
||||
}
|
||||
if (func >= 010)
|
||||
crs[A] = 0;
|
||||
/* NOTE: probably don't need 0x80 here... */
|
||||
crs[A] = crs[A] | ch | 0x80;
|
||||
crs[A] = crs[A] | ch;
|
||||
if (T_INST) fprintf(stderr," character read=%o: %c\n", crs[A], crs[A]);
|
||||
IOSKIP;
|
||||
} else if (n != 0) {
|
||||
@ -425,7 +427,7 @@ keys = 14000, modals=137
|
||||
|
||||
case 0:
|
||||
if (T_INST) fprintf(stderr," OCP '%02o%02o\n", func, device);
|
||||
printf("OCP '%02o%02o\n", func, device);
|
||||
//printf("OCP '%02o%02o\n", func, device);
|
||||
|
||||
if (func == 0 || func == 015) {
|
||||
fprintf(stderr,"Clock process initialized!\n");
|
||||
@ -707,7 +709,7 @@ void devdisk (short class, short func, short device) {
|
||||
} else if (order == 2) {
|
||||
if (T_INST || T_DIO) fprintf(stderr," Format order\n");
|
||||
fatal("DFORMAT channel order not implemented");
|
||||
} else if (order == 5) {
|
||||
} else { /* order = 5 (read) or 6 (write) */
|
||||
|
||||
/* translate head/track/sector to drive record address */
|
||||
|
||||
@ -717,8 +719,6 @@ void devdisk (short class, short func, short device) {
|
||||
perror("Unable to seek drive file");
|
||||
fatal(NULL);
|
||||
}
|
||||
dc[device].unit[u].readnum++;
|
||||
rtnw = 0;
|
||||
while (dc[device].dmanch >= 0) {
|
||||
dmareg = ((dc[device].dmachan & 036) << 1) | (dc[device].dmachan & 1);
|
||||
dmanw = regs.sym.regdmx[dmareg];
|
||||
@ -728,46 +728,35 @@ void devdisk (short class, short func, short device) {
|
||||
|
||||
/* later, use mapva to do page-based mapped I/O in pieces */
|
||||
|
||||
if (crs[MODALS] & 020)
|
||||
iobufp = iobuf;
|
||||
else
|
||||
iobufp = mem+dmaaddr;
|
||||
if (read(dc[device].unit[u].devfd, (char *)iobufp, dmanw*2) != dmanw*2) {
|
||||
perror("Unable to read drive file");
|
||||
fatal(NULL);
|
||||
}
|
||||
if (crs[MODALS] & 020)
|
||||
for (i=0; i<dmanw; i++)
|
||||
put16(iobuf[i], dmaaddr+i);
|
||||
|
||||
#if 0
|
||||
if (T_DIO) {
|
||||
fprintf(stderr, "\nRT: Read #%d.%d, RA=%d, numwords=%d, memaddr=%o, Unix pos=%d\n", readnum, dmanch, phyra, dmanw, dmaaddr, phyra*2080+rtnw*2);
|
||||
snprintf(rtfile,sizeof(rtfile),"rt/rt%d.%d", readnum, dmanch);
|
||||
if ((rtfd = open(rtfile, O_WRONLY+O_CREAT, 0777)) == -1) {
|
||||
printf("Read trace filename: %s\n", rtfile);
|
||||
perror("Read trace file open");
|
||||
if (order == 5) {
|
||||
if (crs[MODALS] & 020)
|
||||
iobufp = iobuf;
|
||||
else
|
||||
iobufp = mem+dmaaddr;
|
||||
if (read(dc[device].unit[u].devfd, (char *)iobufp, dmanw*2) != dmanw*2) {
|
||||
perror("Unable to read drive file");
|
||||
fatal(NULL);
|
||||
}
|
||||
/* NEEDS HELP! */
|
||||
if (write(rtfd, mem+dmaaddr, dmanw*2) != dmanw*2) {
|
||||
perror("Unable to write read trace file");
|
||||
if (crs[MODALS] & 020)
|
||||
for (i=0; i<dmanw; i++)
|
||||
put16(iobuf[i], dmaaddr+i);
|
||||
} else {
|
||||
if (crs[MODALS] & 020) {
|
||||
iobufp = iobuf;
|
||||
for (i=0; i<dmanw; i++)
|
||||
iobuf[i] = get16(dmaaddr+i);
|
||||
} else
|
||||
iobufp = mem+dmaaddr;
|
||||
if (write(dc[device].unit[u].devfd, (char *)iobufp, dmanw*2) != dmanw*2) {
|
||||
perror("Unable to write drive file");
|
||||
fatal(NULL);
|
||||
}
|
||||
close(rtfd);
|
||||
rtnw += dmanw;
|
||||
if (dmanw == 16)
|
||||
fprintf(stderr, "RT: cra=%d, bra=%d, cnt=%d, type=%d, next=%d, prev=%d\n", *(int *)(mem+dmaaddr), *(int *)(mem+dmaaddr+2), mem[dmaaddr+4], mem[dmaaddr+5], *(int *)(mem+dmaaddr+6), *(int *)(mem+dmaaddr+8));
|
||||
}
|
||||
#endif
|
||||
regs.sym.regdmx[dmareg] = 0;
|
||||
regs.sym.regdmx[dmareg+1] += dmanw;
|
||||
dc[device].dmachan += 2;
|
||||
dc[device].dmanch--;
|
||||
}
|
||||
|
||||
} else if (order == 6) {
|
||||
fatal("DWRITE channel order not implemented");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -783,7 +772,7 @@ void devdisk (short class, short func, short device) {
|
||||
if (dc[device].unit[u].devfd == -1) {
|
||||
snprintf(devfile,sizeof(devfile),"dev%ou%d", device, u);
|
||||
if (T_INST || T_DIO) fprintf(stderr," filename for unit %d is %s\n", u, devfile);
|
||||
if ((dc[device].unit[u].devfd = open(devfile, O_RDONLY, 0)) == -1)
|
||||
if ((dc[device].unit[u].devfd = open(devfile, O_RDWR, 0)) == -1)
|
||||
dc[device].status = 0100001; /* not ready */
|
||||
}
|
||||
if (T_INST || T_DIO) fprintf(stderr," select unit %d\n", u);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user