1
0
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:
Jim 2005-08-21 00:00:00 -04:00
parent 99337af999
commit 8c04dcdd8f
2 changed files with 62 additions and 69 deletions

68
em.c
View File

@ -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
View File

@ -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);