/*---------------------------------------------------------------------------*/ static void *stop_cpus_and_ipl(int *ipltype) { int i; char iplcmd[256]; int cpustates; CPU_BITMAP mask; sysblk.diag8cmd |= DIAG8CMD_RUNNING; panel_command("stopall"); sysblk.diag8cmd &= ~DIAG8CMD_RUNNING; WRMSG(HHC01900, "I"); sprintf(iplcmd, "%s %03X", ipltype, sysblk.ipldev); do { OBTAIN_INTLOCK(NULL); cpustates = CPUSTATE_STOPPED; mask = sysblk.started_mask; for(i = 0; mask; i++) { if(mask & 1) { WRMSG(HHC01901, "I", PTYPSTR(i), i); if(IS_CPU_ONLINE(i) && sysblk.regs[i]->cpustate != CPUSTATE_STOPPED) cpustates = sysblk.regs[i]->cpustate; } mask >>= 1; } RELEASE_INTLOCK(NULL); if(cpustates != CPUSTATE_STOPPED) { WRMSG(HHC01902, "I"); SLEEP(1); } } while(cpustates != CPUSTATE_STOPPED); sysblk.diag8cmd |= DIAG8CMD_RUNNING; panel_command(iplcmd); sysblk.diag8cmd &= ~DIAG8CMD_RUNNING; return NULL; }
/*-------------------------------------------------------------------*/ int ARCH_DEP(common_load_finish) (REGS *regs) { int rc; /* Zeroize the interrupt code in the PSW */ regs->psw.intcode = 0; /* Load IPL PSW from PSA+X'0' */ if ((rc = ARCH_DEP(load_psw) (regs, regs->psa->iplpsw)) ) { char buf[80]; MSGBUF(buf, "architecture mode %s, invalid ipl psw %2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", get_arch_mode_string((REGS *)0), regs->psa->iplpsw[0], regs->psa->iplpsw[1], regs->psa->iplpsw[2], regs->psa->iplpsw[3], regs->psa->iplpsw[4], regs->psa->iplpsw[5], regs->psa->iplpsw[6], regs->psa->iplpsw[7]); WRMSG (HHC00839, "E", PTYPSTR(sysblk.pcpu), sysblk.pcpu, buf); HDC1(debug_cpu_state, regs); return rc; } /* Set the CPU into the started state */ regs->opinterv = 0; regs->cpustate = CPUSTATE_STARTED; /* The actual IPL (load) is now completed... */ regs->loadstate = 0; /* reset sys_reset flag to indicate a active machine */ sysblk.sys_reset = FALSE; /* Signal the CPU to retest stopped indicator */ WAKEUP_CPU (regs); HDC1(debug_cpu_state, regs); return 0; } /* end function common_load_finish */
/*-------------------------------------------------------------------*/ int ARCH_DEP(load_ipl) (U16 lcss, U16 devnum, int cpu, int clear) { REGS *regs; /* -> Regs */ DEVBLK *dev; /* -> Device control block */ int i; /* Array subscript */ BYTE unitstat; /* IPL device unit status */ BYTE chanstat; /* IPL device channel status */ int rc; /* Get started */ if ((rc = ARCH_DEP(common_load_begin) (cpu, clear)) ) return rc; /* Ensure CPU is online */ if (!IS_CPU_ONLINE(cpu)) { char buf[80]; MSGBUF(buf, "CP%02.2X Offline", devnum); WRMSG (HHC00810, "E", PTYPSTR(sysblk.pcpu), sysblk.pcpu, buf); return -1; } /* The actual IPL proper starts here... */ regs = sysblk.regs[cpu]; /* Point to IPL CPU's registers */ /* Point to the device block for the IPL device */ dev = find_device_by_devnum (lcss,devnum); if (dev == NULL) { char buf[80]; MSGBUF(buf, "device %4.4X not found", devnum); WRMSG (HHC00810, "E", PTYPSTR(sysblk.pcpu), sysblk.pcpu, buf); HDC1(debug_cpu_state, regs); return -1; } if(sysblk.haveiplparm) { for(i=0;i<16;i++) { regs->GR_L(i)=fetch_fw(&sysblk.iplparmstring[i*4]); } sysblk.haveiplparm=0; } /* Set Main Storage Reference and Update bits */ STORAGE_KEY(regs->PX, regs) |= (STORKEY_REF | STORKEY_CHANGE); sysblk.main_clear = sysblk.xpnd_clear = 0; /* Build the IPL CCW at location 0 */ regs->psa->iplpsw[0] = 0x02; /* CCW command = Read */ regs->psa->iplpsw[1] = 0; /* Data address = zero */ regs->psa->iplpsw[2] = 0; regs->psa->iplpsw[3] = 0; regs->psa->iplpsw[4] = CCW_FLAGS_CC | CCW_FLAGS_SLI; /* CCW flags */ regs->psa->iplpsw[5] = 0; /* Reserved byte */ regs->psa->iplpsw[6] = 0; /* Byte count = 24 */ regs->psa->iplpsw[7] = 24; /* Enable the subchannel for the IPL device */ dev->pmcw.flag5 |= PMCW5_E; /* Build the operation request block */ /*@IWZ*/ memset (&dev->orb, 0, sizeof(ORB)); /*@IWZ*/ dev->busy = 1; RELEASE_INTLOCK(NULL); /* Execute the IPL channel program */ ARCH_DEP(execute_ccw_chain) (dev); OBTAIN_INTLOCK(NULL); /* Clear the interrupt pending and device busy conditions */ obtain_lock (&sysblk.iointqlk); DEQUEUE_IO_INTERRUPT_QLOCKED(&dev->ioint); DEQUEUE_IO_INTERRUPT_QLOCKED(&dev->pciioint); DEQUEUE_IO_INTERRUPT_QLOCKED(&dev->attnioint); release_lock(&sysblk.iointqlk); dev->busy = 0; dev->scsw.flag2 = 0; dev->scsw.flag3 = 0; /* Check that load completed normally */ unitstat = dev->scsw.unitstat; chanstat = dev->scsw.chanstat; if (unitstat != (CSW_CE | CSW_DE) || chanstat != 0) { char buf[80]; char buf2[16]; memset(buf,0,sizeof(buf)); for (i=0; i < (int)dev->numsense; i++) { MSGBUF(buf2, "%2.2X", dev->sense[i]); strlcat(buf, buf2, sizeof(buf) ); if ((i & 3) == 3) strlcat(buf, " ", sizeof(buf)); } { char buffer[256]; MSGBUF(buffer, "architecture mode %s, csw status %2.2X%2.2X, sense %s", get_arch_mode_string((REGS *)0), unitstat, chanstat, buf); WRMSG (HHC00828, "E", PTYPSTR(sysblk.pcpu), sysblk.pcpu, buffer); } HDC1(debug_cpu_state, regs); return -1; } #ifdef FEATURE_S370_CHANNEL /* Test the EC mode bit in the IPL PSW */ if (regs->psa->iplpsw[1] & 0x08) { /* In EC mode, store device address at locations 184-187 */ STORE_FW(regs->psa->ioid, dev->devnum); } else { /* In BC mode, store device address at locations 2-3 */ STORE_HW(regs->psa->iplpsw + 2, dev->devnum); } #endif /*FEATURE_S370_CHANNEL*/ #ifdef FEATURE_CHANNEL_SUBSYSTEM /* Set LPUM */ dev->pmcw.lpum = 0x80; STORE_FW(regs->psa->ioid, (dev->ssid<<16)|dev->subchan); /* Store zeroes at locations 188-191 */ memset (regs->psa->ioparm, 0, 4); #endif /*FEATURE_CHANNEL_SUBSYSTEM*/ /* Save IPL device number, cpu number and lcss */ sysblk.ipldev = devnum; sysblk.iplcpu = regs->cpuad; sysblk.ipllcss = lcss; sysblk.ipled = TRUE; /* Finish up... */ return ARCH_DEP(common_load_finish) (regs); } /* end function load_ipl */
/*-------------------------------------------------------------------*/ int locate_regs(int argc, char *argv[], char *cmdline) { int rc = 0; int cpu = sysblk.pcpu; char msgbuf[256]; int start = 0; int start_adj = 0; int length = 512; REGS *regs = sysblk.regs[cpu]; u_char *tbl = (u_char *)regs; UNREFERENCED(cmdline); if ( argc == 2 ) { int ok = TRUE; U64 loc; char hdr[32]; char tlr[32]; char blknam[32]; if(!regs) { WRMSG( HHC90000, "D", "REGS not assigned" ); return -1; } loc = swap_byte_U64(regs->blkloc); MSGBUF( blknam, "%-4.4s_%2.2s%2.2X", HDL_NAME_REGS, PTYPSTR( cpu ), cpu ); MSGBUF( hdr, "%-16.16s", blknam ); MSGBUF( tlr, "END%13.13s", blknam ); /* verify head, tail, length and address */ if ( loc != (U64)((uintptr_t)regs) ) { MSGBUF( msgbuf, "REGS[%2.2X] moved; was 0x"I64_FMTX", is 0x%p", cpu, loc, regs ); WRMSG( HHC90000, "D", msgbuf ); ok = FALSE; } if ( swap_byte_U32(regs->blksiz) != (U32)sizeof(REGS) ) { MSGBUF( msgbuf, "REGS[%2.2X] size wrong; is %u, should be %u", cpu, swap_byte_U32(regs->blksiz), (U32)sizeof(REGS)); WRMSG( HHC90000, "D", msgbuf ); ok = FALSE; } { /* verify header */ if ( memcmp( regs->blknam, hdr, sizeof(regs->blknam) ) != 0 ) { char sstr[32]; memset( sstr, 0, sizeof(sstr) ); memcpy( sstr, regs->blknam, sizeof(regs->blknam) ); MSGBUF( msgbuf, "REGS[%2.2X] header wrong; is %s, should be %s", cpu, sstr, hdr); WRMSG( HHC90000, "D", msgbuf ); ok = FALSE; } } { /* verify version */ char str[32]; memset( str, SPACE, sizeof(str) ); memcpy( str, HDL_VERS_REGS, strlen(HDL_VERS_REGS) ); if ( memcmp( regs->blkver, str, sizeof(regs->blkver) ) != 0 ) { char sstr[32]; memset( sstr, 0, sizeof(sstr) ); memcpy( sstr, regs->blkver, sizeof(regs->blkver) ); MSGBUF( msgbuf, "REGS[%2.2X] version wrong; is %s, should be %s", cpu, sstr, str); WRMSG( HHC90000, "D", msgbuf ); ok = FALSE; } } { /* verify trailer */ if ( memcmp(regs->blkend, tlr, sizeof(regs->blkend)) != 0 ) { char sstr[32]; memset( sstr, 0, sizeof(sstr) ); memcpy( sstr, regs->blkend, sizeof(regs->blkend) ); MSGBUF( msgbuf, "REGS[%2.2X] trailer wrong; is %s, should be %s", cpu, sstr, tlr); WRMSG( HHC90000, "D", msgbuf ); ok = FALSE; } } MSGBUF( msgbuf, "REGS[%2.2X] @ 0x%p - %sVerified", cpu, regs, ok ? "" : "Not " ); WRMSG( HHC90000, "D", msgbuf ); } if ( argc > 2 ) { /* start offset */ int x; BYTE c; if ( sscanf(argv[2], "%x%c", &x, &c) != 1 ) { return -1; } if ( x > (int)sizeof(REGS) ) { return -1; } start_adj = x % 16; start = x - ( x % 16 ); /* round to a 16 byte boundry */ if ( start + length + start_adj > (int)sizeof(REGS) ) length = (int)sizeof(REGS) - start; } if ( argc > 3 ) { /* length */ int x; BYTE c; if ( sscanf(argv[3], "%x%c", &x, &c) != 1 ) { return -1; } if ( x > 4096 ) { return -1; } length = x; } length += start_adj; if ( start + length > (int)sizeof(REGS) ) length = (int)sizeof(REGS) - start; fmt_line( tbl, "regs", start, length); return rc; }
int resume_cmd(int argc, char *argv[],char *cmdline) { char *fn = SR_DEFAULT_FILENAME; SR_FILE *file; U32 key = 0, len = 0; U64 mainsize = 0; U64 xpndsize = 0; CPU_BITMAP started_mask = 0; int i, rc = -1; REGS *regs = NULL; U16 devnum=0; U16 lcss=0; U16 hw; int devargc=0; char *devargv[16]; int devargx=0; DEVBLK *dev = NULL; IOINT *ioq = NULL; char buf[SR_MAX_STRING_LENGTH+1]; char zeros[16]; S64 dreg; UNREFERENCED(cmdline); if (argc > 2) { // "SR: too many arguments" WRMSG(HHC02000, "E"); return -1; } if (argc == 2) fn = argv[1]; memset (zeros, 0, sizeof(zeros)); TRACE("SR: Begin Resume Processing...\n"); /* Make sure all CPUs are deconfigured or stopped */ TRACE("SR: Waiting for CPUs to stop...\n"); OBTAIN_INTLOCK(NULL); for (i = 0; i < sysblk.maxcpu; i++) if (IS_CPU_ONLINE(i) && CPUSTATE_STOPPED != sysblk.regs[i]->cpustate) { RELEASE_INTLOCK(NULL); // "SR: all processors must be stopped to resume" WRMSG(HHC02005, "E"); return -1; } RELEASE_INTLOCK(NULL); file = SR_OPEN (fn, "rb"); if (file == NULL) { // "SR: error in function '%s': '%s'" WRMSG(HHC02001, "E", "open()",strerror(errno)); return -1; } /* First key must be SR_HDR_ID and string must match SR_ID */ TRACE("SR: Reading File Header...\n"); SR_READ_HDR(file, key, len); if (key == SR_HDR_ID) SR_READ_STRING(file, buf, len); if (key != SR_HDR_ID || strcmp(buf, SR_ID)) { // "SR: file identifier error" WRMSG(HHC02006, "E"); goto sr_error_exit; } /* Deconfigure all CPUs */ TRACE("SR: Deconfiguring all CPUs...\n"); OBTAIN_INTLOCK(NULL); for (i = 0; i < sysblk.maxcpu; i++) if (IS_CPU_ONLINE(i)) deconfigure_cpu(i); RELEASE_INTLOCK(NULL); TRACE("SR: Processing Resume File...\n"); while (key != SR_EOF) { SR_READ_HDR(file, key, len); switch (key) { case SR_HDR_DATE: SR_READ_STRING(file, buf, len); if (len >= 2) { len -= 2; while (len > 0 && isspace(buf[len])) --len; buf[len+1]=0; } // "SR: resuming suspended file created on '%s'" WRMSG(HHC02007, "I", buf); break; case SR_SYS_STARTED_MASK: SR_READ_VALUE(file, len, &started_mask, sizeof(started_mask)); break; case SR_SYS_ARCH_NAME: SR_READ_STRING(file, buf, len); i = -1; #if defined (_370) if (strcasecmp (buf, arch_name[ARCH_370]) == 0) { i = ARCH_370; } #endif #if defined (_390) if (strcasecmp (buf, arch_name[ARCH_390]) == 0) { i = ARCH_390; } #endif #if defined (_900) if (0 || strcasecmp (buf, arch_name[ARCH_900]) == 0 || strcasecmp (buf, "ESAME") == 0 ) { i = ARCH_900; } #endif if (i < 0) { // "SR: archmode '%s' not supported" WRMSG(HHC02008, "E", buf); goto sr_error_exit; } sysblk.arch_mode = i; sysblk.pcpu = 0; sysblk.dummyregs.arch_mode = sysblk.arch_mode; #if defined(OPTION_FISHIO) ios_arch_mode = sysblk.arch_mode; #endif break; case SR_SYS_MAINSIZE: SR_READ_VALUE(file, len, &mainsize, sizeof(mainsize)); if (mainsize > sysblk.mainsize) { char buf1[20]; char buf2[20]; MSGBUF(buf1, "%dM", (U32)(mainsize / (1024*1024))); MSGBUF(buf2, "%dM", (U32)(sysblk.mainsize / (1024*1024))); // "SR: mismatch in '%s': '%s' found, '%s' expected" WRMSG(HHC02009, "E", "mainsize", buf1, buf2); goto sr_error_exit; } break; case SR_SYS_MAINSTOR: TRACE("SR: Restoring MAINSTOR...\n"); SR_READ_BUF(file, sysblk.mainstor, mainsize); break; case SR_SYS_SKEYSIZE: SR_READ_VALUE(file, len, &len, sizeof(len)); if (len > (U32)(sysblk.mainsize/STORAGE_KEY_UNITSIZE)) { char buf1[20]; char buf2[20]; MSGBUF(buf1, "%d", len); MSGBUF(buf2, "%d", (U32)(sysblk.mainsize/STORAGE_KEY_UNITSIZE)); // "SR: mismatch in '%s': '%s' found, '%s' expected" WRMSG(HHC02009, "E", "storkey size", buf1, buf2); goto sr_error_exit; } break; case SR_SYS_STORKEYS: TRACE("SR: Restoring Storage Keys...\n"); SR_READ_BUF(file, sysblk.storkeys, len); break; case SR_SYS_XPNDSIZE: SR_READ_VALUE(file, len, &xpndsize, sizeof(xpndsize)); if (xpndsize > sysblk.xpndsize) { char buf1[20]; char buf2[20]; MSGBUF(buf1, "%dM", (U32)(xpndsize / (256))); MSGBUF(buf2, "%dM", sysblk.xpndsize / (256)); // "SR: mismatch in '%s': '%s' found, '%s' expected" WRMSG(HHC02009, "E", "expand size", buf1, buf2); goto sr_error_exit; } break; case SR_SYS_XPNDSTOR: TRACE("SR: Restoring Expanded Storage...\n"); SR_READ_BUF(file, sysblk.xpndstor, xpndsize * 4096); break; case SR_SYS_IPLDEV: SR_READ_VALUE(file, len, &sysblk.ipldev, sizeof(sysblk.ipldev)); break; case SR_SYS_IPLCPU: SR_READ_VALUE(file, len, &sysblk.iplcpu, sizeof(sysblk.iplcpu)); break; case SR_SYS_MBO: SR_READ_VALUE(file, len, &sysblk.mbo, sizeof(sysblk.mbo)); break; case SR_SYS_MBK: SR_READ_VALUE(file, len, &sysblk.mbk, sizeof(sysblk.mbk)); break; case SR_SYS_MBM: SR_READ_VALUE(file, len, &sysblk.mbm, sizeof(sysblk.mbm)); break; case SR_SYS_MBD: SR_READ_VALUE(file, len, &sysblk.mbd, sizeof(sysblk.mbd)); break; case SR_SYS_IOPENDING_LCSS: SR_READ_VALUE(file,len,&lcss,sizeof(lcss)); break; case SR_SYS_IOPENDING: SR_READ_VALUE(file, len, &hw, sizeof(hw)); dev = find_device_by_devnum(lcss,hw); if (dev == NULL) break; if (ioq == NULL) sysblk.iointq = &dev->ioint; else ioq->next = &dev->ioint; ioq = &dev->ioint; dev = NULL; lcss = 0; break; case SR_SYS_PCIPENDING_LCSS: SR_READ_VALUE(file,len,&lcss,sizeof(lcss)); break; case SR_SYS_PCIPENDING: SR_READ_VALUE(file, len, &hw, sizeof(hw)); dev = find_device_by_devnum(lcss,hw); if (dev == NULL) break; if (ioq == NULL) sysblk.iointq = &dev->pciioint; else ioq->next = &dev->pciioint; ioq = &dev->pciioint; dev = NULL; lcss = 0; break; case SR_SYS_ATTNPENDING_LCSS: SR_READ_VALUE(file,len,&lcss,sizeof(lcss)); break; case SR_SYS_ATTNPENDING: SR_READ_VALUE(file, len, &hw, sizeof(hw)); dev = find_device_by_devnum(lcss,hw); if (dev == NULL) break; if (ioq == NULL) sysblk.iointq = &dev->attnioint; else ioq->next = &dev->attnioint; ioq = &dev->attnioint; dev = NULL; lcss = 0; break; case SR_SYS_CHP_RESET_0: case SR_SYS_CHP_RESET_1: case SR_SYS_CHP_RESET_2: case SR_SYS_CHP_RESET_3: case SR_SYS_CHP_RESET_4: case SR_SYS_CHP_RESET_5: case SR_SYS_CHP_RESET_6: case SR_SYS_CHP_RESET_7: i = key - SR_SYS_CHP_RESET; SR_READ_VALUE(file, len, &sysblk.chp_reset[i], sizeof(sysblk.chp_reset[0])); break; case SR_SYS_SERVPARM: SR_READ_VALUE(file, len, &sysblk.servparm, sizeof(sysblk.servparm)); break; case SR_SYS_SIGINTREQ: SR_READ_VALUE(file, len, &rc, sizeof(rc)); sysblk.sigintreq = rc; break; case SR_SYS_LOADPARM: SR_READ_STRING(file, buf, len); set_loadparm ((char *)buf); break; case SR_SYS_SERVC: TRACE("SR: Restoring Service Console State...\n"); rc = servc_hresume(file); if (rc < 0) goto sr_error_exit; break; case SR_SYS_CLOCK: TRACE("SR: Restoring Clock State...\n"); rc = clock_hresume(file); if (rc < 0) goto sr_error_exit; break; case SR_CPU: SR_READ_VALUE(file, len, &i, sizeof(i)); TRACE("SR: Restoring CPU %d Data...\n", i); if (i >= sysblk.maxcpu) { // "SR: processor CP%02X exceeds max allowed CP%02X" WRMSG(HHC02010, "E", i, sysblk.maxcpu-1); goto sr_error_exit; } OBTAIN_INTLOCK(NULL); if (IS_CPU_ONLINE(i)) { RELEASE_INTLOCK(NULL); // "SR: processor %s%02X already configured" WRMSG(HHC02011, "E", PTYPSTR(i), i); goto sr_error_exit; } rc = configure_cpu(i); RELEASE_INTLOCK(NULL); if (rc < 0) { // "SR: processor %s%02X unable to configure online" WRMSG(HHC02012, "E", PTYPSTR(i), i); goto sr_error_exit; } regs = sysblk.regs[i]; break; case SR_CPU_PX: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->px, sizeof(regs->px)); break; case SR_CPU_PSW: SR_NULL_REGS_CHECK(regs); if (len != 8 && len != 16) { // "SR: processor %s%02X invalid psw length %d" WRMSG(HHC02013, "E", PTYPSTR(regs->cpuad), regs->cpuad, len); goto sr_error_exit; } memset(buf, 0, 16); SR_READ_BUF(file, buf, len); switch (regs->arch_mode) { #if defined (_370) case ARCH_370: len = 8; rc = s370_load_psw(regs, (BYTE *)&buf); break; #endif #if defined (_390) case ARCH_390: len = 8; rc = s390_load_psw(regs, (BYTE *)&buf); break; #endif #if defined (_900) case ARCH_900: len = 16; rc = z900_load_psw(regs, (BYTE *)&buf); break; #endif } /* switch (regs->arch_mode) */ if (rc != 0 && memcmp(buf, zeros, len)) { // "SR: processor %s%02X error loading psw, rc %d" WRMSG(HHC02014, "E", PTYPSTR(regs->cpuad), regs->cpuad, rc); goto sr_error_exit; } break; case SR_CPU_GR_0: case SR_CPU_GR_1: case SR_CPU_GR_2: case SR_CPU_GR_3: case SR_CPU_GR_4: case SR_CPU_GR_5: case SR_CPU_GR_6: case SR_CPU_GR_7: case SR_CPU_GR_8: case SR_CPU_GR_9: case SR_CPU_GR_10: case SR_CPU_GR_11: case SR_CPU_GR_12: case SR_CPU_GR_13: case SR_CPU_GR_14: case SR_CPU_GR_15: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_GR; SR_READ_VALUE(file, len, ®s->gr[i], sizeof(regs->gr[0])); break; case SR_CPU_CR_0: case SR_CPU_CR_1: case SR_CPU_CR_2: case SR_CPU_CR_3: case SR_CPU_CR_4: case SR_CPU_CR_5: case SR_CPU_CR_6: case SR_CPU_CR_7: case SR_CPU_CR_8: case SR_CPU_CR_9: case SR_CPU_CR_10: case SR_CPU_CR_11: case SR_CPU_CR_12: case SR_CPU_CR_13: case SR_CPU_CR_14: case SR_CPU_CR_15: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_CR; SR_READ_VALUE(file, len, ®s->CR(i), sizeof(regs->CR(0))); break; case SR_CPU_AR_0: case SR_CPU_AR_1: case SR_CPU_AR_2: case SR_CPU_AR_3: case SR_CPU_AR_4: case SR_CPU_AR_5: case SR_CPU_AR_6: case SR_CPU_AR_7: case SR_CPU_AR_8: case SR_CPU_AR_9: case SR_CPU_AR_10: case SR_CPU_AR_11: case SR_CPU_AR_12: case SR_CPU_AR_13: case SR_CPU_AR_14: case SR_CPU_AR_15: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_AR; SR_READ_VALUE(file, len, ®s->ar[i], sizeof(regs->ar[0])); break; case SR_CPU_FPR_0: case SR_CPU_FPR_1: case SR_CPU_FPR_2: case SR_CPU_FPR_3: case SR_CPU_FPR_4: case SR_CPU_FPR_5: case SR_CPU_FPR_6: case SR_CPU_FPR_7: case SR_CPU_FPR_8: case SR_CPU_FPR_9: case SR_CPU_FPR_10: case SR_CPU_FPR_11: case SR_CPU_FPR_12: case SR_CPU_FPR_13: case SR_CPU_FPR_14: case SR_CPU_FPR_15: case SR_CPU_FPR_16: case SR_CPU_FPR_17: case SR_CPU_FPR_18: case SR_CPU_FPR_19: case SR_CPU_FPR_20: case SR_CPU_FPR_21: case SR_CPU_FPR_22: case SR_CPU_FPR_23: case SR_CPU_FPR_24: case SR_CPU_FPR_25: case SR_CPU_FPR_26: case SR_CPU_FPR_27: case SR_CPU_FPR_28: case SR_CPU_FPR_29: case SR_CPU_FPR_30: case SR_CPU_FPR_31: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_FPR; SR_READ_VALUE(file, len, ®s->fpr[i], sizeof(regs->fpr[0])); break; case SR_CPU_FPC: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->fpc, sizeof(regs->fpc)); break; case SR_CPU_DXC: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->dxc, sizeof(regs->dxc)); break; case SR_CPU_MC: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->mc, sizeof(regs->mc)); break; case SR_CPU_EA: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->ea, sizeof(regs->ea)); break; case SR_CPU_PTIMER: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &dreg, sizeof(S64)); set_cpu_timer(regs, dreg); break; case SR_CPU_CLKC: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->clkc, sizeof(regs->clkc)); break; case SR_CPU_CHANSET: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->chanset, sizeof(regs->chanset)); break; case SR_CPU_TODPR: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->todpr, sizeof(regs->todpr)); break; case SR_CPU_MONCLASS: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->monclass, sizeof(regs->monclass)); break; case SR_CPU_EXCARID: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->excarid, sizeof(regs->excarid)); break; case SR_CPU_BEAR: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->bear, sizeof(regs->bear)); break; case SR_CPU_OPNDRID: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->opndrid, sizeof(regs->opndrid)); break; case SR_CPU_CHECKSTOP: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->checkstop = rc; break; case SR_CPU_HOSTINT: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->hostint = rc; break; case SR_CPU_LOADSTATE: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->loadstate = rc; break; case SR_CPU_INVALIDATE: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->invalidate = rc; break; case SR_CPU_SIGPRESET: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->sigpreset = rc; break; case SR_CPU_SIGPIRESET: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, &rc, sizeof(rc)); regs->sigpireset = rc; break; case SR_CPU_INTS_STATE: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->ints_state, sizeof(regs->ints_state)); /* Force CPU to examine the interrupt state */ ON_IC_INTERRUPT(regs); break; case SR_CPU_INTS_MASK: SR_NULL_REGS_CHECK(regs); SR_READ_VALUE(file, len, ®s->ints_mask, sizeof(regs->ints_mask)); break; case SR_CPU_MALFCPU_0: case SR_CPU_MALFCPU_1: case SR_CPU_MALFCPU_2: case SR_CPU_MALFCPU_3: case SR_CPU_MALFCPU_4: case SR_CPU_MALFCPU_5: case SR_CPU_MALFCPU_6: case SR_CPU_MALFCPU_7: case SR_CPU_MALFCPU_8: case SR_CPU_MALFCPU_9: case SR_CPU_MALFCPU_10: case SR_CPU_MALFCPU_11: case SR_CPU_MALFCPU_12: case SR_CPU_MALFCPU_13: case SR_CPU_MALFCPU_14: case SR_CPU_MALFCPU_15: case SR_CPU_MALFCPU_16: case SR_CPU_MALFCPU_17: case SR_CPU_MALFCPU_18: case SR_CPU_MALFCPU_19: case SR_CPU_MALFCPU_20: case SR_CPU_MALFCPU_21: case SR_CPU_MALFCPU_22: case SR_CPU_MALFCPU_23: case SR_CPU_MALFCPU_24: case SR_CPU_MALFCPU_25: case SR_CPU_MALFCPU_26: case SR_CPU_MALFCPU_27: case SR_CPU_MALFCPU_28: case SR_CPU_MALFCPU_29: case SR_CPU_MALFCPU_30: case SR_CPU_MALFCPU_31: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_MALFCPU; if (i < sysblk.maxcpu) SR_READ_VALUE(file, len, ®s->malfcpu[i], sizeof(regs->malfcpu[0])); break; case SR_CPU_EMERCPU_0: case SR_CPU_EMERCPU_1: case SR_CPU_EMERCPU_2: case SR_CPU_EMERCPU_3: case SR_CPU_EMERCPU_4: case SR_CPU_EMERCPU_5: case SR_CPU_EMERCPU_6: case SR_CPU_EMERCPU_7: case SR_CPU_EMERCPU_8: case SR_CPU_EMERCPU_9: case SR_CPU_EMERCPU_10: case SR_CPU_EMERCPU_11: case SR_CPU_EMERCPU_12: case SR_CPU_EMERCPU_13: case SR_CPU_EMERCPU_14: case SR_CPU_EMERCPU_15: case SR_CPU_EMERCPU_16: case SR_CPU_EMERCPU_17: case SR_CPU_EMERCPU_18: case SR_CPU_EMERCPU_19: case SR_CPU_EMERCPU_20: case SR_CPU_EMERCPU_21: case SR_CPU_EMERCPU_22: case SR_CPU_EMERCPU_23: case SR_CPU_EMERCPU_24: case SR_CPU_EMERCPU_25: case SR_CPU_EMERCPU_26: case SR_CPU_EMERCPU_27: case SR_CPU_EMERCPU_28: case SR_CPU_EMERCPU_29: case SR_CPU_EMERCPU_30: case SR_CPU_EMERCPU_31: SR_NULL_REGS_CHECK(regs); i = key - SR_CPU_EMERCPU; if (i < sysblk.maxcpu) SR_READ_VALUE(file, len, ®s->emercpu[i], sizeof(regs->emercpu[0])); break; case SR_DEV: SR_READ_VALUE(file, len, &devnum, sizeof(devnum)); TRACE("SR: Restoring Device %4.4X...\n", devnum); lcss=0; break; case SR_DEV_LCSS: SR_READ_VALUE(file, len, &lcss, sizeof(U16)); break; case SR_DEV_ARGC: SR_READ_VALUE(file, len, &devargc, sizeof(devargc)); if (devargc > 16) devargc = 16; for (i = 0; i < devargc; i++) devargv[i] = NULL; devargx = 0; break; case SR_DEV_ARGV: SR_READ_STRING(file, buf, len); if (devargx < devargc) devargv[devargx++] = strdup(buf); break; case SR_DEV_TYPNAME: SR_READ_STRING(file, buf, len); dev = find_device_by_devnum(lcss,devnum); if (dev == NULL) { if (attach_device (lcss, devnum, buf, devargc, devargv)) { // "SR: %04X: device initialization failed" WRMSG(HHC02015, "E", devnum); } } else if (strcmp(dev->typname, buf)) { // "SR: %04X: device type mismatch; '%s' found, '%s' expected" WRMSG(HHC02016, "W", devnum, buf, dev->typname); dev = NULL; } for (i = 0; i < devargx; i++) { if (devargv[i]) free(devargv[i]); devargv[i] = NULL; } devnum = devargc = devargx = 0; break; case SR_DEV_ORB: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(ORB)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ORB", len, (int)sizeof(ORB)); goto sr_error_exit; } SR_READ_BUF(file, &dev->orb, len); break; case SR_DEV_PMCW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(PMCW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "PMCW", len, (int)sizeof(PMCW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->pmcw, len); break; case SR_DEV_SCSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(SCSW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "SCSW", len, (int)sizeof(SCSW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->scsw, len); break; case SR_DEV_PCISCSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(SCSW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "PCI SCSW", len, (int)sizeof(SCSW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->pciscsw, len); break; case SR_DEV_ATTNSCSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(SCSW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ATTN SCSW", len, (int)sizeof(SCSW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->attnscsw, len); break; case SR_DEV_CSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != 8) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "CSW", len, 8); goto sr_error_exit; } SR_READ_BUF(file, &dev->csw, len); break; case SR_DEV_PCICSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != 8) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "PCI CSW", len, 8); goto sr_error_exit; } SR_READ_BUF(file, &dev->pcicsw, len); break; case SR_DEV_ATTNCSW: SR_SKIP_NULL_DEV(dev, file, len); if (len != 8) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ATTN CSW", len, 8); goto sr_error_exit; } SR_READ_BUF(file, &dev->attncsw, len); break; case SR_DEV_ESW: SR_SKIP_NULL_DEV(dev, file, len); if (len != sizeof(ESW)) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ESW", len, (int)sizeof(ESW)); goto sr_error_exit; } SR_READ_BUF(file, &dev->esw, len); break; case SR_DEV_ECW: SR_SKIP_NULL_DEV(dev, file, len); if (len != 32) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "ECW", len, 32); goto sr_error_exit; } SR_READ_BUF(file, &dev->ecw, len); break; case SR_DEV_SENSE: SR_SKIP_NULL_DEV(dev, file, len); if (len != 32) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "Sense", len, 32); goto sr_error_exit; } SR_READ_BUF(file, &dev->ecw, len); break; case SR_DEV_PGSTAT: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->pgstat, sizeof(dev->pgstat)); break; case SR_DEV_PGID: SR_SKIP_NULL_DEV(dev, file, len); if (len != 11) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "PGID", len, 11); goto sr_error_exit; } SR_READ_BUF(file, &dev->pgid, len); break; /* By Adrian - SR_DEV_DRVPWD */ case SR_DEV_DRVPWD: SR_SKIP_NULL_DEV(dev, file, len); if (len != 11) { // "SR: %04X: '%s' size mismatch: %d found, %d expected" WRMSG(HHC02017, "E", dev->devnum, "DRVPWD", len, 11); goto sr_error_exit; } SR_READ_BUF(file, &dev->drvpwd, len); break; case SR_DEV_BUSY: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->busy = rc; break; case SR_DEV_RESERVED: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->reserved = rc; break; case SR_DEV_SUSPENDED: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->suspended = rc; break; case SR_DEV_PENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->pending = rc; QUEUE_IO_INTERRUPT(&dev->ioint); break; case SR_DEV_PCIPENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->pcipending = rc; QUEUE_IO_INTERRUPT(&dev->pciioint); break; case SR_DEV_ATTNPENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->attnpending = rc; QUEUE_IO_INTERRUPT(&dev->attnioint); break; case SR_DEV_STARTPENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->startpending = rc; break; case SR_DEV_CRWPENDING: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &rc, sizeof(rc)); dev->crwpending = rc; break; case SR_DEV_CCWADDR: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->ccwaddr, sizeof(dev->ccwaddr)); break; case SR_DEV_IDAPMASK: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->idapmask, sizeof(dev->idapmask)); break; case SR_DEV_IDAWFMT: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->idawfmt, sizeof(dev->idawfmt)); break; case SR_DEV_CCWFMT: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->ccwfmt, sizeof(dev->ccwfmt)); break; case SR_DEV_CCWKEY: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &dev->ccwkey, sizeof(dev->ccwkey)); break; /* This is the trigger to call the device dependent resume routine */ case SR_DEV_DEVTYPE: SR_SKIP_NULL_DEV(dev, file, len); SR_READ_VALUE(file, len, &hw, sizeof(hw)); if (hw != dev->devtype) { char buf1[20]; char buf2[20]; MSGBUF(buf1, "%04X", hw); MSGBUF(buf2, "%04X", dev->devtype); // "SR: %04X: device type mismatch; '%s' found, '%s' expected" WRMSG(HHC02016, "E", dev->devnum, buf1, buf2); goto sr_error_exit; } if (dev->hnd->hresume) { rc = (dev->hnd->hresume) (dev, file); if (rc < 0) goto sr_error_exit; } break; default: if ((key & SR_KEY_ID_MASK) != SR_KEY_ID) { // "SR: invalid key %8.8X" WRMSG(HHC02018, "E", key); goto sr_error_exit; } SR_READ_SKIP(file, len); break; } /* switch (key) */ } /* while (key != SR_EOF) */ TRACE("SR: Resume File Processing Complete...\n"); TRACE("SR: Resuming Devices...\n"); /* For all suspended devices, resume the `suspended' state */ for (dev = sysblk.firstdev; dev; dev = dev->nextdev) { if (dev->suspended && (dev->pmcw.flag5 & PMCW5_V)) { dev->resumesuspended=1; switch (sysblk.arch_mode) { #if defined(_370) case ARCH_370: rc = create_thread (&dev->tid, DETACHED, s370_execute_ccw_chain, dev, "device thread"); break; #endif #if defined(_390) case ARCH_390: rc = create_thread (&dev->tid, DETACHED, s390_execute_ccw_chain, dev, "device thread"); break; #endif #if defined(_900) case ARCH_900: rc = create_thread (&dev->tid, DETACHED, z900_execute_ccw_chain, dev, "device thread"); break; #endif } /* switch (sysblk.arch_mode) */ if (rc != 0) { // "Error in function create_thread(): %s" WRMSG(HHC00102, "E", strerror(rc)); goto sr_error_exit; } } /* If suspended device */ } /* For each device */ /* Indicate crw pending for any new devices */ #if defined(_370) if (sysblk.arch_mode != ARCH_370) #endif machine_check_crwpend(); /* Start the CPUs */ TRACE("SR: Resuming CPUs...\n"); OBTAIN_INTLOCK(NULL); ON_IC_IOPENDING; for (i = 0; i < sysblk.maxcpu; i++) if (IS_CPU_ONLINE(i) && (started_mask & CPU_BIT(i))) { sysblk.regs[i]->opinterv = 0; sysblk.regs[i]->cpustate = CPUSTATE_STARTED; sysblk.regs[i]->checkstop = 0; WAKEUP_CPU(sysblk.regs[i]); } RELEASE_INTLOCK(NULL); TRACE("SR: Resume Complete; System Resumed.\n"); return 0; sr_null_regs_exit: // "SR: CPU key %8.8X found but no active CPU" WRMSG(HHC02019, "E", key); goto sr_error_exit; sr_error_exit: // "SR: error processing file '%s'" WRMSG(HHC02004, "E", fn); SR_CLOSE (file); return -1; }
void sigabend_handler (int signo) { REGS *regs = NULL; TID tid; int i; tid = thread_id(); if( signo == SIGUSR2 ) { DEVBLK *dev; if (0 || equal_threads( tid, sysblk.cnsltid ) || equal_threads( tid, sysblk.socktid ) #if defined(OPTION_SHARED_DEVICES) || equal_threads( tid, sysblk.shrdtid ) #endif // defined(OPTION_SHARED_DEVICES) || equal_threads( tid, sysblk.httptid ) ) return; for (dev = sysblk.firstdev; dev != NULL; dev = dev->nextdev) if (0 || equal_threads( dev->tid, tid ) #if defined(OPTION_SHARED_DEVICES) || equal_threads( dev->shrdtid, tid ) #endif // defined(OPTION_SHARED_DEVICES) ) break; if( dev == NULL) { if (!sysblk.shutdown) WRMSG(HHC00825, "E"); } else if(dev->ccwtrace) WRMSG(HHC00826, "E", SSID_TO_LCSS(dev->ssid), dev->devnum); return; } for (i = 0; i < sysblk.maxcpu; i++) { if ( equal_threads( sysblk.cputid[i], tid ) ) { regs = sysblk.regs[i]; break; } } if (regs == NULL) { signal(signo, SIG_DFL); raise(signo); return; } if(MACHMASK(®s->psw)) { #if defined(_FEATURE_SIE) WRMSG(HHC00822, "I", regs->sie_active ? "IE" : PTYPSTR(regs->cpuad), regs->sie_active ? regs->guestregs->cpuad : regs->cpuad, strsignal(signo) ); #else /*!defined(_FEATURE_SIE)*/ WRMSG(HHC00822, "I", PTYPSTR(regs->cpuad), regs->cpuad, strsignal(signo)); #endif /*!defined(_FEATURE_SIE)*/ display_inst( #if defined(_FEATURE_SIE) regs->sie_active ? regs->guestregs : #endif /*defined(_FEATURE_SIE)*/ regs, #if defined(_FEATURE_SIE) regs->sie_active ? regs->guestregs->ip : #endif /*defined(_FEATURE_SIE)*/ regs->ip); switch(regs->arch_mode) { #if defined(_370) case ARCH_370: s370_sync_mck_interrupt(regs); break; #endif #if defined(_390) case ARCH_390: s390_sync_mck_interrupt(regs); break; #endif #if defined(_900) case ARCH_900: z900_sync_mck_interrupt(regs); break; #endif } } else { #if defined(_FEATURE_SIE) WRMSG(HHC00823, "I", regs->sie_active ? "IE" : PTYPSTR(regs->cpuad), regs->sie_active ? regs->guestregs->cpuad : regs->cpuad, strsignal(signo)); #else /*!defined(_FEATURE_SIE)*/ WRMSG(HHC00823, "I", PTYPSTR(regs->cpuad), regs->cpuad, strsignal(signo)); #endif /*!defined(_FEATURE_SIE)*/ display_inst( #if defined(_FEATURE_SIE) regs->sie_active ? regs->guestregs : #endif /*defined(_FEATURE_SIE)*/ regs, #if defined(_FEATURE_SIE) regs->sie_active ? regs->guestregs->ip : #endif /*defined(_FEATURE_SIE)*/ regs->ip); regs->cpustate = CPUSTATE_STOPPING; regs->checkstop = 1; ON_IC_INTERRUPT(regs); /* Notify other CPU's by means of a malfuction alert if possible */ if (!try_obtain_lock(&sysblk.sigplock)) { if(!try_obtain_lock(&sysblk.intlock)) { for (i = 0; i < sysblk.maxcpu; i++) if (i != regs->cpuad && IS_CPU_ONLINE(i)) { ON_IC_MALFALT(sysblk.regs[i]); sysblk.regs[i]->malfcpu[regs->cpuad] = 1; } release_lock(&sysblk.intlock); } release_lock(&sysblk.sigplock); } } longjmp (regs->progjmp, SIE_INTERCEPT_MCK); }
void ARCH_DEP(sync_mck_interrupt) (REGS *regs) { int rc; /* Return code */ PSA *psa; /* -> Prefixed storage area */ U64 mcic = MCIC_P | /* Instruction processing damage */ MCIC_WP | MCIC_MS | MCIC_PM | MCIC_IA | #ifdef FEATURE_HEXADECIMAL_FLOATING_POINT MCIC_FP | #endif /*FEATURE_HEXADECIMAL_FLOATING_POINT*/ MCIC_GR | MCIC_CR | MCIC_ST | #ifdef FEATURE_ACCESS_REGISTERS MCIC_AR | #endif /*FEATURE_ACCESS_REGISTERS*/ #if defined(FEATURE_ESAME) && defined(FEATURE_EXTENDED_TOD_CLOCK) MCIC_PR | #endif /*defined(FEATURE_ESAME) && defined(FEATURE_EXTENDED_TOD_CLOCK)*/ #if defined(FEATURE_BINARY_FLOATING_POINT) MCIC_XF | #endif /*defined(FEATURE_BINARY_FLOATING_POINT)*/ MCIC_CT | MCIC_CC ; U32 xdmg = 0; RADR fsta = 0; /* Release intlock if held */ if (regs->cpuad == sysblk.intowner) RELEASE_INTLOCK(regs); /* Release mainlock if held */ if (regs->cpuad == sysblk.mainowner) RELEASE_MAINLOCK(regs); /* Exit SIE when active */ #if defined(FEATURE_INTERPRETIVE_EXECUTION) if(regs->sie_active) ARCH_DEP(sie_exit) (regs, SIE_HOST_INTERRUPT); #endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/ /* Set the main storage reference and change bits */ STORAGE_KEY(regs->PX, regs) |= (STORKEY_REF | STORKEY_CHANGE); /* Point to the PSA in main storage */ psa = (void*)(regs->mainstor + regs->PX); /* Store registers in machine check save area */ ARCH_DEP(store_status) (regs, regs->PX); #if !defined(FEATURE_ESAME) // ZZ /* Set the extended logout area to zeros */ memset(psa->storepsw, 0, 16); #endif /* Store the machine check interrupt code at PSA+232 */ STORE_DW(psa->mckint, mcic); /* Trace the machine check interrupt */ if (CPU_STEPPING_OR_TRACING(regs, 0)) #if defined(_FEATURE_SIE) WRMSG (HHC00824, "I", regs->sie_active ? "IE" : PTYPSTR(regs->cpuad), regs->sie_active ? regs->guestregs->cpuad : regs->cpuad, mcic); #else WRMSG (HHC00824, "I", PTYPSTR(regs->cpuad), regs->cpuad, mcic); #endif /* Store the external damage code at PSA+244 */ STORE_FW(psa->xdmgcode, xdmg); #if defined(FEATURE_ESAME) /* Store the failing storage address at PSA+248 */ STORE_DW(psa->mcstorad, fsta); #else /*!defined(FEATURE_ESAME)*/ /* Store the failing storage address at PSA+248 */ STORE_FW(psa->mcstorad, fsta); #endif /*!defined(FEATURE_ESAME)*/ /* Store current PSW at PSA+X'30' */ ARCH_DEP(store_psw) ( regs, psa->mckold ); /* Load new PSW from PSA+X'70' */ rc = ARCH_DEP(load_psw) ( regs, psa->mcknew ); if ( rc ) ARCH_DEP(program_interrupt) (regs, rc); } /* end function sync_mck_interrupt */