From d5899f1dd5eb4fc7cc474e90b7220499ac5d1d61 Mon Sep 17 00:00:00 2001 From: "James C. Bevier" Date: Wed, 17 Jul 2019 21:39:18 -0400 Subject: [PATCH] SEL32: Correct mapping code to fix sysgen error. Fix BU *1,1 condition code error Fix EXM to correct l/r h/w detection code --- SEL32/sel32_cpu.c | 163 +++++++++++++++++++++++++++++++--------------- 1 file changed, 112 insertions(+), 51 deletions(-) diff --git a/SEL32/sel32_cpu.c b/SEL32/sel32_cpu.c index c995b8d..d217dc7 100644 --- a/SEL32/sel32_cpu.c +++ b/SEL32/sel32_cpu.c @@ -161,7 +161,7 @@ /* CPU registers, map cache, spad, and other variables */ int traceme = 0; /* dynamic trace function */ -int trstart = 9981910; /* count of when to start tracing */ +int trstart = 8000000; /* count of when to start tracing */ //int trstart = 37; /* count of when to start tracing */ int cpu_index; /* Current CPU running */ uint32 PSD[2]; /* the PC for the instruction */ @@ -722,16 +722,19 @@ t_stat load_maps(uint32 thepsd[2]) } /* num should be even at this point, so zero 32 bit word for remaining maps */ if ((num/2) > HIWM) /* largerst number of maps loaded so far* */ - HIWM = num/2; /* yes, set new high watter mark */ + HIWM = num/2; /* yes, set new high water mark */ // for (i = num/2; i < 32/2; i++) /* zero any remaining entries */ for (i = num/2; i < HIWM; i++) /* zero any remaining entries */ MAPC[i] = 0; /* clear the map entry to make not valid */ + HIWM = num/2; /* set new high water mark */ return ALLOK; /* all cache is loaded, return OK */ } else { +#if 0 /* set to 1 for traceme to work */ char n[9]; uint32 dqe; +#endif /* 32/27, 32/67, 32/87, 32/97 2KW maps */ /* Concept/32 machine, 2KW maps */ if ((modes & MAPMODE) == 0) { /* mapped mode? */ @@ -744,7 +747,11 @@ t_stat load_maps(uint32 thepsd[2]) /* master process list is in 0xf3 of spad for concept */ mpl = SPAD[0xf3] >> 2; /* get mpl from spad address */ midl = M[mpl+cpix]; /* get mpl entry wd 0 for given cpix */ - msdl = M[mpl+cpix+1]; /* get mpl entry wd 0 for given cpix */ + msdl = M[mpl+cpix+1]; /* get mpl entry wd 1 for given cpix */ + +#if 0 /* set to 1 for traceme to work */ +//traceme = trstart; +if (traceme >= trstart) { dqe = M[0x8e8>>2]; for (j=0; j<8; j++) { n[j] = (M[((dqe+0x18)>>2)+(j/4)] >> ((3-(j&7))*8)) & 0xff; @@ -752,16 +759,27 @@ t_stat load_maps(uint32 thepsd[2]) n[j] = 0x20; } n[8] = 0; -// fprintf(stderr, "mapping SPAD PSD2 %.8x PSD2 %x mpl %x osmidl %x umidl %x C.CURR %x LMN %s\r\n", -// SPAD[0xf5], PSD2, mpl, M[mpl], midl, dqe, n); - /* if bit zero of mpl entry is set, use msd entry 0 first to load maps */ - if (midl & BIT0) - { -/* TODO do not load O/S if already loaded. Bit zero of O/S midl will be set by swapper */ + fprintf(stderr, "\r\nmapping SPAD[0xf3] %x mpl %x mpl0 %x mpl1 %x midl %x msdl %x cpix %x\r\n", + SPAD[0xf3], mpl<<2, M[mpl], M[mpl+1], midl, msdl, cpix<<2); + fprintf(stderr, "mapping SPAD PSD2 %.8x PSD2 %x mpl %x osmidl %x osmidl2 %x umidl %x C.CURR %x LMN %s\r\n", + SPAD[0xf5], PSD2, mpl<<2, M[mpl], M[mpl+1], midl, dqe, n); +} +#endif + /* load msd 0 maps first (O/S) */ + osmidl = M[mpl]; /* get midl 0 word address */ + /* if bit zero of cpix mpl entry is set, use msd entry 0 first to load maps */ +// if (((osmidl & BIT0) == 0) || (midl & BIT0)) { + /* This test must be made (cpix == bpix) to allow sysgen to run without using a valid cpix */ + /* the cpix is zero indicating only load MSD 0 for the target system */ + /* bit 0 of msd 0 will be zero saying load the maps */ + if ((osmidl == midl) || (midl & BIT0)) { + /* Do not load O/S if already loaded. Bit zero of O/S midl will be set by swapper on startup */ /* load msd 0 maps first (O/S) */ - osmidl = M[mpl]; /* get midl 0 word address */ spc = osmidl & MASK16; /* get 16 bit segment description count */ - if (osmidl & BIT0) { /* see f O/S already loaded */ +#if 0 /* set to 1 for traceme to work */ + fprintf(stderr, "mapping osmidl %x spc %x osmsdl %x usermidl %x\r\n", osmidl, spc, M[mpl+1], midl); +#endif + if (osmidl & BIT0) { /* see if O/S already loaded */ num = spc; /* set the number of o/s maps loaded */ goto skipos; /* skip load */ } @@ -781,8 +799,12 @@ t_stat load_maps(uint32 thepsd[2]) if (num & 1) { /* entry going to rt hw, clean it first */ map = (MAPC[num/2] & LMASK) | map; /* map is in rt hw */ -// fprintf(stderr, "mapping 0x%x O/S num 0x%x midl %x MAPC[%d] %x\r\n", -// spc, num-1, (midl+(j/2))<<2, num/2, map); +#if 0 /* set to 1 for traceme to work */ +if (traceme >= trstart) { + fprintf(stderr, "mapping 0x%x O/S num 0x%x midl %x MAPC[%d] %x\r\n", + spc, num-1, (midl+(j/2))<<2, num/2, map); +} +#endif } else { /* entry going to left hw, clean it first */ @@ -792,17 +814,28 @@ t_stat load_maps(uint32 thepsd[2]) if (++num >= 2048) return MAPFLT; /* map loading overflow, map fault error */ } -#if 0 +#if 0 /* set to 1 for traceme to work */ +if (traceme >= trstart) { if (num & 1) fprintf(stderr, "mapping 0x%x O/S num 0x%x midl %x MAPC[%d] %x\r\n", spc, num-1, (midl+((spc-1)/2))<<2, num/2, map); +} #endif } skipos: + /* sysgen in mpx does not have a valid cpix MPL entry, only a bpix entry */ + /* that entry uses 64 map entries to map between target/host systems */ + /* When cpix in instruction is zero, just load the O/S specified by MSD 0 */ + if (cpix == 0) + goto skipcpix; /* only load maps specified by msd 0 */ + /* now load cpix maps */ midl = M[mpl+cpix]; /* get cpix midl word address */ msdl = M[mpl+cpix+1]; /* get 24 bit real word address of midl */ spc = midl & RMASK; /* get segment page count from msdl */ +#if 0 /* set to 1 for traceme to work */ + fprintf(stderr, "mapping usmidl %x spc %x msdl %x\r\n", midl, spc, msdl); +#endif midl = M[mpl+cpix+1] & MASK24; /* get 24 bit real word address of midl */ midl = midl>>2; /* get word address of midl */ for (j = 0; j < spc; j++) @@ -819,8 +852,12 @@ skipos: if (num & 1) { /* entry going to rt hw, clean it first */ map = (MAPC[num/2] & LMASK) | map; /* map is in rt hw */ -// fprintf(stderr, "mapping 0x%x USER num 0x%x midl %x MAPC[%d] %x\r\n", -// spc, num-1, (midl+(j/2))<<2, num/2, map); +#if 0 /* set to 1 for traceme to work */ +if (traceme >= trstart) { + fprintf(stderr, "mapping 0x%x USER num 0x%x midl %x MAPC[%d] %x\r\n", + spc, num-1, (midl+(j/2))<<2, num/2, map); +} +#endif } else { /* entry going to left hw, clean it first */ @@ -834,20 +871,26 @@ skipos: /* we got here without map block found, return map fault error */ if (num == 0) return MAPFLT; /* map fault error */ +skipcpix: if (num & 1) { /* left hw of map is good, zero right */ map = (MAPC[num/2] & LMASK); /* clean rt hw */ -// if (spc != 0) -// fprintf(stderr, "mapping 0x%x USER num 0x%x midl %x MAPC[%d] %x\r\n", -// spc, num-1, (midl+((spc-1)/2))<<2, num/2, map); +#if 0 /* set to 1 for traceme to work */ +if (traceme >= trstart) { + if (spc != 0) + fprintf(stderr, "mapping 0x%x USER num 0x%x midl %x MAPC[%d] %x\r\n", + spc, num-1, (midl+((spc-1)/2))<<2, num/2, map); +} +#endif MAPC[num++/2] = map; /* store the map reg contents into cache */ } /* num should be even at this point, so zero 32 bit words for remaining maps */ - if ((num/2) > HIWM) /* largerst number of maps loaded so far* */ - HIWM = num/2; /* yes, set new high watter mark */ + if ((num/2) > HIWM) /* largest number of maps loaded so far* */ + HIWM = num/2; /* yes, set new high water mark */ // for (i = num/2; i < 2048/2; i++) /* zero any remaining entries */ for (i = num/2; i < HIWM; i++) /* zero any remaining entries */ MAPC[i] = 0; /* clear the map entry to make not valid */ + HIWM = num/2; /* set new high water mark */ return ALLOK; /* all cache is loaded, retun OK */ } } @@ -1331,7 +1374,7 @@ exec: t &= ~IND; /* turn off IND bit to stop while loop */ } else { /* non-extended mode, process new X, I, ADDR fields */ -// fprintf(stderr, "Indirect NE before addr %x contents %x\n", addr, temp); +// fprintf(stderr, "Indirect NE before addr %x contents %x\n", addr, temp); addr = temp & MASK19; /* get just the addr */ ix = (temp >> 21) & 3; /* get the index reg from indirect word */ if (ix != 0) @@ -1339,7 +1382,7 @@ exec: /* if no F or C bits set, use original, else new */ if ((temp & F_BIT) || (addr & 3)) FC = ((temp & F_BIT) ? 0x4 : 0) | (addr & 3); -// fprintf(stderr, "Indirect NE after addr %x temp %x\n", addr, temp); + // fprintf(stderr, "Indirect NE after addr %x temp %x\n", addr, temp); t = temp; /* go process next indirect location */ } } @@ -1465,7 +1508,9 @@ exec: TRAPME = PRIVHALT_TRAP; /* set the trap to take */ goto newpsd; /* Privlege mode halt trap */ } -/*FIXME*/ reason = STOP_HALT; /* do halt for now */ + /*FIXME*/ + reason = STOP_HALT; /* do halt for now */ + return STOP_HALT; /* exit to simh for halt */ break; case 0x1: /* WAIT */ if (modes & PRIVBIT == 0) { /* must be privileged to wait */ @@ -2629,7 +2674,8 @@ src: goto newpsd; /* memory read error or map fault */ IR = temp; /* get instruction from memory */ - if (FC == 2) /* see if right halfword specified */ +// if (FC == 2) /* see if right halfword specified */ + if (FC == 3) /* see if right halfword specified */ IR <<= 16; /* move over the HW instruction */ if ((IR & 0xFC7F0000) == 0xC8070000 || (IR & 0xFF800000) == 0xA8000000 || @@ -2865,8 +2911,8 @@ doovr2: /* |-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| */ /* */ case 0x6: /* SVC none - none */ /* Supervisor Call Trap */ - { -#if 0 + { +#if 0 /* set to 1 for traceme to work */ int j; char n[9]; uint32 dqe = M[0x8e8>>2]; @@ -2904,7 +2950,7 @@ doovr2: PSD1 = M[(t>>2)+2]; /* get new PSD 1 */ PSD2 = (M[(t>>2)+3] & ~0x3ffc) | bc; /* get new PSD 2 w/old cpix */ M[(t>>2)+4] = IR&0xFFF; /* store call number */ -#if 0 +#if 0 /* set to 1 for traceme to work */ fprintf(stderr, "SVC @ %.8x SVC %x,%x PSD1 %.8x PSD2 %.8x SPAD PSD@ %x C.CURR %x LMN %s\r\n", OPSD1, temp2>>2, IR&0xFFF, PSD1, PSD2, SPAD[0xf5], dqe, n); fprintf(stderr, " R0=%x R1=%x R2=%x R3=%x", GPR[0], GPR[1], GPR[2], GPR[3]); fprintf(stderr, " R4=%x R5=%x R6=%x R7=%x", GPR[4], GPR[5], GPR[6], GPR[7]); @@ -2937,7 +2983,7 @@ fprintf(stderr, "SVC %x,%x GPR[6] %x GPR[6] %x\r\n", temp2>>2, IR&0xfff, GPR[6], PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ SPAD[0xf5] = PSD2; /* save the current PSD2 */ goto newpsd; /* new psd loaded */ - } + } break; case 0x7: /* EXR */ @@ -3082,6 +3128,7 @@ fprintf(stderr, "SVC %x,%x GPR[6] %x GPR[6] %x\r\n", temp2>>2, IR&0xfff, GPR[6], TRAPME = ADDRSPEC_TRAP; /* bad address, error */ goto newpsd; /* go execute the trap now */ } + temp2 = CC; /* save the old CC's */ CC = PSD1 & 0x78000000; /* get CC's if any */ switch(reg) { case 0: t = 1; break; @@ -3097,7 +3144,8 @@ fprintf(stderr, "SVC %x,%x GPR[6] %x GPR[6] %x\r\n", temp2>>2, IR&0xfff, GPR[6], if (t) { /* see if we are going to branch */ /* we are taking the branch, set CC's if indirect, else leave'm */ if (IR & IND) /* see if CCs from last indirect location are wanted */ - PSD1 = (PSD1 & 0x87fffffe) | CC; /* insert last CCs */ +// PSD1 = (PSD1 & 0x87fffffe) | CC; /* insert last CCs */ + PSD1 = (PSD1 & 0x87fffffe) | temp2; /* insert last CCs */ /* update the PSD with new address */ PSD1 = (PSD1 & 0xff000000) | (addr & 0xfffffe); /* set new PC */ i_flags |= BT; /* we branched, so no PC update */ @@ -3114,6 +3162,7 @@ fprintf(stderr, "SVC %x,%x GPR[6] %x GPR[6] %x\r\n", temp2>>2, IR&0xfff, GPR[6], TRAPME = ADDRSPEC_TRAP; /* bad address, error */ goto newpsd; /* go execute the trap now */ } + temp2 = CC; /* save the old CC's */ CC = PSD1 & 0x78000000; /* get CC's if any */ switch(reg) { case 0: t = (GPR[4] & (0x8000 >> ((CC >> 27) & 0xf))) != 0; break; @@ -3132,7 +3181,8 @@ fprintf(stderr, "SVC %x,%x GPR[6] %x GPR[6] %x\r\n", temp2>>2, IR&0xfff, GPR[6], PSD1 = (PSD1 & 0xff000000) | (addr & 0xfffffe); /* set new PC */ i_flags |= BT; /* we branched, so no PC update */ if (IR & IND) /* see if CCs from last indirect location are wanted */ - PSD1 = (PSD1 & 0x87fffffe) | CC; /* insert last CCs */ +// PSD1 = (PSD1 & 0x87fffffe) | CC; /* insert last CCs */ + PSD1 = (PSD1 & 0x87fffffe) | temp2; /* insert last CCs */ //fprintf(stderr, "BR t %.8x addr %.8x PSD1 %.8x\r\n", t, addr, PSD1); } break; @@ -3142,7 +3192,7 @@ fprintf(stderr, "SVC %x,%x GPR[6] %x GPR[6] %x\r\n", temp2>>2, IR&0xfff, GPR[6], if (dest != 0) { /* if reg is not 0, take the branch */ /* we are taking the branch, set CC's if indirect, else leave'm */ /* update the PSD with new address */ -#if 1 +#if 1 /* set to 1 to stop branch to self, for now */ /* FIXME */ if (PC == (addr & 0x7FFFC)) { /* BIB to current PC, bump branch addr */ addr += 4; // fprintf(stderr, "BI? stopping BIB $ addr %x PC %x\r\n", addr, PC); @@ -3164,8 +3214,8 @@ fprintf(stderr, "SVC %x,%x GPR[6] %x GPR[6] %x\r\n", temp2>>2, IR&0xfff, GPR[6], case 0x1: /* BL F880 */ /* copy CC's from instruction and PC incremented by 4 */ GPR[0] = ((PSD1 & 0x78000000) | (PSD1 & 0x7fffe)) + 4; - if (IR & IND) /* see if CC from last indirect loacation are wanted */ - GPR[0] = (CC | (PSD1 & 0x7fffe)) + 4; /* set CC's and incremented PC */ + if (IR & IND) /* see if CC from last indirect loacation are wanted */ + GPR[0] = (GPR[0] & 0x87fffffe) | CC; /* insert last CCs */ /* update the PSD with new address */ PSD1 = (PSD1 & 0xff000000) | (addr & 0xfffffe); i_flags |= BT; /* we branched, so no PC update */ @@ -3174,11 +3224,12 @@ fprintf(stderr, "SVC %x,%x GPR[6] %x GPR[6] %x\r\n", temp2>>2, IR&0xfff, GPR[6], case 0x3: /* LPSD F980 */ /* fall through */; case 0x5: /* LPSDCM FA80 */ - { -#if 0 + { +#if 0 /* set to 1 for traceme to work */ int j; char n[9]; uint32 dqe = M[0x8e8>>2]; +/* get task name blank filled */ for (j=0; j<8; j++) { n[j] = (M[((dqe+0x18)>>2)+(j/4)] >> ((3-(j&7))*8)) & 0xff; if (n[j] == 0) @@ -3217,16 +3268,14 @@ n[8] = 0; if (CPUSTATUS & 0x80) /* see if old mode is blocked */ PSD2 |= 0x00004000; /* set to blocked state */ - /* TRY if cpix is zero, copy cpix from PSD2 in SPAD[0xf5] */ - if ((PSD2 & 0x3fff) == 0) - PSD2 |= (SPAD[0xf5] & 0x3fff); /* use new cpix */ - if (opr & 0x0200) { /* Was it LPSDCM? */ /* map bit must be on to load maps */ if (PSD2 & MAPBIT) { -#if 0 +#if 0 /* set to 1 for traceme to work */ // FIXME DEBUG EDIT // if (n[0] == 'E' && n[1] == 'D' && n[2] == 'I' && n[3] == 'T') + // FIXME DEBUG SYSGEN +//if (n[0] == 'S' && n[1] == 'Y' && n[2] == 'S' && n[3] == 'G') // traceme = trstart; /* start tracing */ traceme++; /* start trace */ //if (traceme >= trstart) { @@ -3250,17 +3299,23 @@ fprintf(stderr, "\r\n"); PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ } else { /* LPSD */ -//traceme++; /* start trace */ -#if 0 + /* if cpix is zero, copy cpix from PSD2 in SPAD[0xf5] */ + if ((PSD2 & 0x3fff) == 0) { +// fprintf(stderr, "LPSD using SPAD PSD2 %x instead of user PSD2 %x\r\n", SPAD[0xf5], PSD2); + PSD2 |= (SPAD[0xf5] & 0x3fff); /* use new cpix */ + } +#if 0 /* set to 1 for traceme to work */ sim_debug(DEBUG_EXP, &cpu_dev, "LPSD PSD1 %x PSD2 %x CPUSTATUS %x\n", PSD1, PSD2, CPUSTATUS); +if (traceme >= trstart) { fprintf(stderr, "LPSD PSD1 %x PSD2 %x SPAD PSD2 %x CPUSTATUS %x C.CURR %x LMN %s\r\n", PSD1, PSD2, SPAD[0xf5], CPUSTATUS, dqe, n); fprintf(stderr, " R0=%x R1=%x R2=%x R3=%x", GPR[0], GPR[1], GPR[2], GPR[3]); fprintf(stderr, " R4=%x R5=%x R6=%x R7=%x", GPR[4], GPR[5], GPR[6], GPR[7]); fprintf(stderr, "\r\n"); +} #endif } -} + } /* TRAPME can be error from LPSDCM or OK here */ skipinstr = 1; /* skip next interrupt test only once */ goto newpsd; /* load the new psd */ @@ -3753,11 +3808,8 @@ sim_debug(DEBUG_EXP, &cpu_dev, "XIO DACI chan %x sa %x spad %.8x\n", chan, suba, TRAPME = AEXPCEPT_TRAP; /* trap the system now */ goto newpsd; /* process the trap */ } -#if 0 +#if 0 /* set to 1 for traceme to work */ /* no trap, so continue with next instruction */ -//PC = PSD1 & 0xfffffe; /* get 24 bit addr from PSD1 */ -// Get CCs from PSD1 and PC from original instruction */ -//if (traceme >= 4) { if (traceme >= trstart) { OPSD1 &= 0x87FFFFFE; /* clear the old CC's */ OPSD1 |= PSD1 & 0x78000000; /* update the CC's in the PSD */ @@ -3856,8 +3908,9 @@ fprintf(stderr, "[][][][][][][][][][][] HALT TRAP [][][][][][][][][][][][]\r\n") PSD2 &= ~RETMBIT; /* turn off retain bit in PSD2 */ SPAD[0xf5] = PSD2; /* save the current PSD2 */ -#if 0 -if (TRAPME == UNDEFINSTR_TRAP) { +#if 0 /* set to 1 for traceme to work */ +//if (TRAPME == UNDEFINSTR_TRAP || TRAPME == MAPFAULT_TRAP) { +if (TRAPME == MAPFAULT_TRAP) { sim_debug(DEBUG_EXP, &cpu_dev, "TRAP PSD1 %x PSD2 %x CPUSTATUS %x\n", PSD1, PSD2, CPUSTATUS); fprintf(stderr, "TRAPS %x LOAD MAPS PSD1 %x PSD2 %x CPUSTATUS %x\r\n", TRAPME, PSD1, PSD2, CPUSTATUS); goto dumpi; @@ -3872,7 +3925,7 @@ goto dumpi; /* we have a new PSD loaded via a LPSD or LPSDCM */ /* TODO finish instruction history, then continue */ /* update cpu status word too */ -#if 0 +#if 0 /* set to 1 for traceme to work */ if (traceme >= trstart) { dumpi: OPSD1 &= 0x87FFFFFE; /* clear the old CC's */ @@ -3885,6 +3938,14 @@ fprint_inst(stderr, OIR, 0); /* display instruction */ fprintf(stderr, " R0=%x R1=%x R2=%x R3=%x", GPR[0], GPR[1], GPR[2], GPR[3]); fprintf(stderr, " R4=%x R5=%x R6=%x R7=%x", GPR[4], GPR[5], GPR[6], GPR[7]); fprintf(stderr, "\r\n"); +fprintf(stderr, "Current MAPC\r\n"); +for (ix=0; ix<16; ix++) { + fprintf(stderr, "MAP %x MPC %x\r\n", ix/2, MAPC[ix]); +} +fflush(stderr); +//if (TRAPME == UNDEFINSTR_TRAP || TRAPME == MAPFAULT_TRAP) +if (TRAPME == MAPFAULT_TRAP) +return STOP_HALT; /* exit to simh for halt */ } #endif sim_debug(DEBUG_DATA, &cpu_dev, "R0=%08x R1=%08x R2=%08x R3=%08x\n", GPR[0], GPR[1], GPR[2], GPR[3]);