/*-------------------------------------------------------------------*/ int ARCH_DEP(cpu_reset) (REGS *regs) { int i, rc = 0; /* Array subscript */ regs->ip = regs->inst; /* Clear indicators */ regs->loadstate = 0; regs->checkstop = 0; regs->sigpreset = 0; regs->extccpu = 0; for (i = 0; i < sysblk.maxcpu; i++) regs->emercpu[i] = 0; regs->instinvalid = 1; regs->instcount = regs->prevcount = 0; /* Clear interrupts */ SET_IC_INITIAL_MASK(regs); SET_IC_INITIAL_STATE(regs); /* Clear the translation exception identification */ regs->EA_G = 0; regs->excarid = 0; /* Clear monitor code */ regs->MC_G = 0; /* Purge the lookaside buffers */ ARCH_DEP(purge_tlb) (regs); #if defined(FEATURE_ACCESS_REGISTERS) ARCH_DEP(purge_alb) (regs); #endif /*defined(FEATURE_ACCESS_REGISTERS)*/ if(regs->host) { /* Put the CPU into the stopped state */ regs->opinterv = 0; regs->cpustate = CPUSTATE_STOPPED; ON_IC_INTERRUPT(regs); } #ifdef FEATURE_INTERVAL_TIMER ARCH_DEP(store_int_timer_nolock) (regs); #endif if(regs->host && regs->guestregs) { rc = ARCH_DEP(cpu_reset)(regs->guestregs); /* CPU state of SIE copy cannot be controlled */ regs->guestregs->opinterv = 0; regs->guestregs->cpustate = CPUSTATE_STARTED; } /* Initialize Architecture Level Set */ init_als(regs); return rc; } /* end function cpu_reset */
/*-------------------------------------------------------------------*/ int ARCH_DEP(system_reset) (const int cpu, const int clear, const int target_mode) { int rc; int n; int regs_mode; int architecture_switch; REGS* regs; CPU_BITMAP mask; /* Configure the cpu if it is not online (configure implies initial * reset) */ if (!IS_CPU_ONLINE(cpu)) { sysblk.arch_mode = target_mode; if ( (rc = configure_cpu(cpu)) ) return rc; } HDC1(debug_cpu_state, sysblk.regs[cpu]); /* Define the target mode for reset */ if (target_mode > ARCH_390 && (clear || sysblk.arch_mode != target_mode)) regs_mode = ARCH_390; else regs_mode = target_mode; architecture_switch = (target_mode != sysblk.arch_mode); /* Signal all CPUs in configuration to stop and reset */ { /* Switch lock context to hold both sigplock and intlock */ RELEASE_INTLOCK(NULL); obtain_lock(&sysblk.sigplock); OBTAIN_INTLOCK(NULL); /* Ensure no external updates pending */ OFF_IC_SERVSIG; OFF_IC_INTKEY; /* Loop through CPUs and issue appropriate CPU reset function */ { mask = sysblk.config_mask; for (n = 0; mask; mask >>= 1, ++n) { if (mask & 1) { regs = sysblk.regs[n]; /* Signal CPU reset function; if requesting CPU with * CLEAR or architecture change, signal initial CPU * reset. Otherwise, signal a normal CPU reset. */ regs->arch_mode = regs_mode; if (n == cpu && (clear || architecture_switch)) regs->sigpireset = 1; else regs->sigpreset = 1; regs->opinterv = 1; regs->cpustate = CPUSTATE_STOPPING; ON_IC_INTERRUPT(regs); wakeup_cpu(regs); } } } /* Return to hold of just intlock */ RELEASE_INTLOCK(NULL); release_lock(&sysblk.sigplock); OBTAIN_INTLOCK(NULL); } /* Wait for CPUs to complete reset */ { int i; int wait; for (n = 0; ; ++n) { mask = sysblk.config_mask; for (i = wait = 0; mask; mask >>= 1, ++i) { regs = sysblk.regs[i]; if (regs->cpustate != CPUSTATE_STOPPED) { /* Release intlock, take a nap, and re-acquire */ RELEASE_INTLOCK(NULL); wait = 1; usleep(10000); OBTAIN_INTLOCK(NULL); } } if (!wait) break; if (n < 300) continue; /* FIXME: Recovery code needed to handle case where CPUs * are misbehaving. Outstanding locks should be * reported, then take-over CPUs and perform an * initial reset of each CPU. */ WRMSG(HHC90000, "E", "Could not perform reset within three seconds"); break; } } /* Perform subsystem reset */ subsystem_reset(); /* Switch modes to requested mode */ sysblk.arch_mode = regs_mode; /* Perform system-reset-clear additional functions */ if (clear) { /* Finish reset-clear of all CPUs in the configuration */ for (n = 0; n < sysblk.maxcpu; ++n) { if (IS_CPU_ONLINE(n)) { regs = sysblk.regs[n]; /* Clear all the registers (AR, GPR, FPR, VR) as part * of the CPU CLEAR RESET operation */ memset (regs->ar, 0, sizeof(regs->ar)); memset (regs->gr, 0, sizeof(regs->gr)); memset (regs->fpr, 0, sizeof(regs->fpr)); #if defined(_FEATURE_VECTOR_FACILITY) memset (regs->vf->vr, 0, sizeof(regs->vf->vr)); #endif /*defined(_FEATURE_VECTOR_FACILITY)*/ } } sysblk.ipled = FALSE; sysblk.program_parameter = 0; /* Clear storage */ sysblk.main_clear = sysblk.xpnd_clear = 0; storage_clear(); xstorage_clear(); } #if defined(FEATURE_CONFIGURATION_TOPOLOGY_FACILITY) /* Clear topology-change-report-pending condition */ sysblk.topchnge = 0; #endif /*defined(FEATURE_CONFIGURATION_TOPOLOGY_FACILITY)*/ /* set default system state to reset */ sysblk.sys_reset = TRUE; return (0); } /* end function system_reset */
/*-------------------------------------------------------------------*/ void ARCH_DEP(diagnose_call) (VADR effective_addr2, int b2, int r1, int r2, REGS *regs) { #ifdef FEATURE_HERCULES_DIAGCALLS U32 n; /* 32-bit operand value */ #endif /*FEATURE_HERCULES_DIAGCALLS*/ U32 code; code = effective_addr2; switch(code) { #if defined(FEATURE_IO_ASSIST) case 0x002: /*---------------------------------------------------------------*/ /* Diagnose 002: Update Interrupt Interlock Control Bit in PMCW */ /*---------------------------------------------------------------*/ ARCH_DEP(diagnose_002) (regs, r1, r2); break; #endif case 0x01F: /*---------------------------------------------------------------*/ /* Diagnose 01F: Power Off */ /*---------------------------------------------------------------*/ /* If diag8cmd is not enabled then we are not allowed * to manipulate the real machine i.e. hercules itself */ if(!(sysblk.diag8cmd & DIAG8CMD_ENABLE)) ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); /* The poweroff diagnose is only valid on the 9221 */ if (sysblk.cpumodel != 0x9221 /* and r1/r2 must contain C'POWEROFF' in EBCDIC */ || regs->GR_L(r1) != 0xD7D6E6C5 || regs->GR_L(r2) != 0xD9D6C6C6) ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION); regs->cpustate = CPUSTATE_STOPPING; ON_IC_INTERRUPT(regs); /* Release the configuration */ do_shutdown(); /* Power Off: exit hercules */ exit(0); #if defined(FEATURE_HYPERVISOR) || defined(FEATURE_EMULATE_VM) case 0x044: /*---------------------------------------------------------------*/ /* Diagnose 044: Voluntary Time Slice End */ /*---------------------------------------------------------------*/ ARCH_DEP(scpend_call) (); break; #endif #ifdef FEATURE_MSSF_CALL case 0x080: /*---------------------------------------------------------------*/ /* Diagnose 080: MSSF Call */ /*---------------------------------------------------------------*/ regs->psw.cc = ARCH_DEP(mssf_call) (r1, r2, regs); break; #endif /*FEATURE_MSSF_CALL*/ #if defined(FEATURE_HYPERVISOR) || defined(FEATURE_EMULATE_VM) case 0x09C: /*---------------------------------------------------------------*/ /* Diagnose 09C: Voluntary Time Slice End With Target CPU */ /*---------------------------------------------------------------*/ ARCH_DEP(scpend_call) (); // (treat same as DIAG X'44') break; #endif #if defined(FEATURE_HYPERVISOR) case 0x204: /*---------------------------------------------------------------*/ /* Diagnose 204: LPAR RMF Interface */ /*---------------------------------------------------------------*/ ARCH_DEP(diag204_call) (r1, r2, regs); regs->psw.cc = 0; break; case 0x224: /*---------------------------------------------------------------*/ /* Diagnose 224: CPU Names */ /*---------------------------------------------------------------*/ ARCH_DEP(diag224_call) (r1, r2, regs); regs->psw.cc = 0; break; #endif /*defined(FEATURE_HYPERVISOR)*/ #if 0 case 0x21C: /*---------------------------------------------------------------*/ /* Diagnose 21C: ???? */ /*---------------------------------------------------------------*/ /*INCOMPLETE*/ regs->psw.cc = 0; break; #endif #if 0 case 0x288;: /*---------------------------------------------------------------*/ /* Diagnose 288: Control Virtual Machine Time Bomb */ /*---------------------------------------------------------------*/ regs->psw.cc = ARCH_DEP(vm_timebomb) (r1, r2, regs); break; #endif #ifdef FEATURE_EMULATE_VM case 0x000: /*---------------------------------------------------------------*/ /* Diagnose 000: Store Extended Identification Code */ /*---------------------------------------------------------------*/ ARCH_DEP(extid_call) (r1, r2, regs); break; case 0x008: /*---------------------------------------------------------------*/ /* Diagnose 008: Virtual Console Function */ /*---------------------------------------------------------------*/ /* If diag8cmd is not enabled then we are not allowed * to manipulate the real machine i.e. hercules itself */ if(!(sysblk.diag8cmd & DIAG8CMD_ENABLE)) ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); /* Process CP command and set condition code */ regs->psw.cc = ARCH_DEP(cpcmd_call) (r1, r2, regs); break; case 0x00C: /*---------------------------------------------------------------*/ /* Diagnose 00C: Pseudo Timer */ /*---------------------------------------------------------------*/ ARCH_DEP(pseudo_timer) (code, r1, r2, regs); break; case 0x024: /*---------------------------------------------------------------*/ /* Diagnose 024: Device Type and Features */ /*---------------------------------------------------------------*/ regs->psw.cc = ARCH_DEP(diag_devtype) (r1, r2, regs); break; case 0x05C: /*---------------------------------------------------------------*/ /* Diagnose 05C: Error Message Editing */ /*---------------------------------------------------------------*/ /* This function is implemented as a no-operation */ regs->psw.cc = 0; break; case 0x060: /*---------------------------------------------------------------*/ /* Diagnose 060: Virtual Machine Storage Size */ /*---------------------------------------------------------------*/ /* Load main storage size in bytes into R1 register */ regs->GR_L(r1) = regs->mainlim + 1; break; case 0x064: /*---------------------------------------------------------------*/ /* Diagnose 064: Named Saved Segment Manipulation */ /*---------------------------------------------------------------*/ /* Return code 44 cond code 2 means segment does not exist */ regs->GR_L(r2) = 44; regs->psw.cc = 2; break; case 0x0A4: /*---------------------------------------------------------------*/ /* Diagnose 0A4: Synchronous I/O (Standard CMS Blocksize) */ /*---------------------------------------------------------------*/ regs->psw.cc = ARCH_DEP(syncblk_io) (r1, r2, regs); // logmsg ("Diagnose X\'0A4\': CC=%d, R15=%8.8X\n", /*debug*/ // regs->psw.cc, regs->GR_L(15)); /*debug*/ break; case 0x0A8: /*---------------------------------------------------------------*/ /* Diagnose 0A8: Synchronous General I/O */ /*---------------------------------------------------------------*/ regs->psw.cc = ARCH_DEP(syncgen_io) (r1, r2, regs); // logmsg ("Diagnose X\'0A8\': CC=%d, R15=%8.8X\n", /*debug*/ // regs->psw.cc, regs->GR_L(15)); /*debug*/ break; case 0x0B0: /*---------------------------------------------------------------*/ /* Diagnose 0B0: Access Re-IPL Data */ /*---------------------------------------------------------------*/ ARCH_DEP(access_reipl_data) (r1, r2, regs); break; case 0x0DC: /*---------------------------------------------------------------*/ /* Diagnose 0DC: Control Application Monitor Record Collection */ /*---------------------------------------------------------------*/ /* This function is implemented as a no-operation */ regs->GR_L(r2) = 0; regs->psw.cc = 0; break; case 0x210: /*---------------------------------------------------------------*/ /* Diagnose 210: Retrieve Device Information */ /*---------------------------------------------------------------*/ regs->psw.cc = ARCH_DEP(device_info) (r1, r2, regs); break; case 0x214: /*---------------------------------------------------------------*/ /* Diagnose 214: Pending Page Release */ /*---------------------------------------------------------------*/ regs->psw.cc = ARCH_DEP(diag_ppagerel) (r1, r2, regs); break; case 0x220: /*---------------------------------------------------------------*/ /* Diagnose 220: TOD Epoch */ /*---------------------------------------------------------------*/ ODD_CHECK(r2, regs); switch(regs->GR_L(r1)) { case 0: /* Obtain TOD features */ regs->GR_L(r2) =0xc0000000; regs->GR_L(r2+1)=0x00000000; break; case 1: /* Obtain TOD offset to real TOD in R2, R2+1 */ regs->GR_L(r2) = (regs->tod_epoch >> 24) & 0xFFFFFFFF; regs->GR_L(r2+1)= (regs->tod_epoch << 8) & 0xFFFFFFFF; break; default: ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); } break; case 0x23C: /*---------------------------------------------------------------*/ /* Diagnose 23C: Address Space Services */ /*---------------------------------------------------------------*/ /* This function is implemented as a no-operation */ regs->GR_L(r2) = 0; break; #if defined(FEATURE_VM_BLOCKIO) case 0x250: /*---------------------------------------------------------------*/ /* Diagnose 250: Standardized Block I/O */ /*---------------------------------------------------------------*/ regs->psw.cc = ARCH_DEP(vm_blockio) (r1, r2, regs); break; #endif /*defined(FEATURE_VM_BLOCKIO)*/ case 0x260: /*---------------------------------------------------------------*/ /* Diagnose 260: Access Certain Virtual Machine Information */ /*---------------------------------------------------------------*/ ARCH_DEP(vm_info) (r1, r2, regs); break; case 0x264: /*---------------------------------------------------------------*/ /* Diagnose 264: CP Communication */ /*---------------------------------------------------------------*/ /* This function is implemented as a no-operation */ PTT_ERR("*DIAG264",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L); regs->psw.cc = 0; break; case 0x270: /*---------------------------------------------------------------*/ /* Diagnose 270: Pseudo Timer Extended */ /*---------------------------------------------------------------*/ ARCH_DEP(pseudo_timer) (code, r1, r2, regs); break; case 0x274: /*---------------------------------------------------------------*/ /* Diagnose 274: Set Timezone Interrupt Flag */ /*---------------------------------------------------------------*/ /* This function is implemented as a no-operation */ PTT_ERR("*DIAG274",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L); regs->psw.cc = 0; break; #endif /*FEATURE_EMULATE_VM*/ #ifdef FEATURE_PROGRAM_DIRECTED_REIPL case 0x308: /*---------------------------------------------------------------*/ /* Diagnose 308: IPL functions */ /*---------------------------------------------------------------*/ switch(r2) { TID tid; /* Thread identifier */ char *ipltype; /* "ipl" or "iplc" */ int rc; case DIAG308_IPL_CLEAR: ipltype = "iplc"; goto diag308_cthread; case DIAG308_IPL_NORMAL: ipltype = "ipl"; diag308_cthread: rc = create_thread(&tid, DETACHED, stop_cpus_and_ipl, ipltype, "Stop cpus and ipl"); if(rc) WRMSG(HHC00102, "E", strerror(rc)); regs->cpustate = CPUSTATE_STOPPING; ON_IC_INTERRUPT(regs); break; case DIAG308_SET_PARAM: /* INCOMPLETE */ regs->GR(1) = DIAG308_RC_OK; break; case DIAG308_STORE_PARAM: /* INCOMPLETE */ regs->GR(1) = DIAG308_RC_OK; break; default: ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); } /* end switch(r2) */ break; #endif /*FEATURE_PROGRAM_DIRECTED_REIPL*/ #ifdef FEATURE_HERCULES_DIAGCALLS case 0xF00: /*---------------------------------------------------------------*/ /* Diagnose F00: Hercules normal mode */ /*---------------------------------------------------------------*/ /* If diag8cmd is not enabled then we are not allowed * to manipulate the real machine i.e. hercules itself */ if(!(sysblk.diag8cmd & DIAG8CMD_ENABLE)) ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); sysblk.inststep = 0; SET_IC_TRACE; break; case 0xF04: /*---------------------------------------------------------------*/ /* Diagnose F04: Hercules single step mode */ /*---------------------------------------------------------------*/ /* If diag8cmd is not enabled then we are not allowed * to manipulate the real machine i.e. hercules itself */ if(!(sysblk.diag8cmd & DIAG8CMD_ENABLE)) ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); sysblk.inststep = 1; SET_IC_TRACE; break; case 0xF08: /*---------------------------------------------------------------*/ /* Diagnose F08: Hercules get instruction counter */ /*---------------------------------------------------------------*/ regs->GR_L(r1) = (U32)INSTCOUNT(regs); break; case 0xF0C: /*---------------------------------------------------------------*/ /* Diagnose F0C: Set/reset bad frame indicator */ /*---------------------------------------------------------------*/ /* If diag8cmd is not enabled then we are not allowed * to manipulate the real machine i.e. hercules itself */ if(!(sysblk.diag8cmd & DIAG8CMD_ENABLE)) ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); /* Load 4K block address from R2 register */ n = regs->GR_L(r2) & ADDRESS_MAXWRAP(regs); /* Convert real address to absolute address */ n = APPLY_PREFIXING (n, regs->PX); /* Addressing exception if block is outside main storage */ if ( n > regs->mainlim ) { ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION); break; } /* Update the storage key from R1 register bit 31 */ STORAGE_KEY(n, regs) &= ~(STORKEY_BADFRM); STORAGE_KEY(n, regs) |= regs->GR_L(r1) & STORKEY_BADFRM; break; case 0xF10: /*---------------------------------------------------------------*/ /* Diagnose F10: Hercules CPU stop */ /*---------------------------------------------------------------*/ /* If diag8cmd is not enabled then we are not allowed * to manipulate the real machine i.e. hercules itself */ if(!(sysblk.diag8cmd & DIAG8CMD_ENABLE)) ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); regs->cpustate = CPUSTATE_STOPPING; ON_IC_INTERRUPT(regs); break; #if defined(OPTION_DYNAMIC_LOAD) case 0xF14: /*---------------------------------------------------------------*/ /* Diagnose F14: Hercules DLL interface */ /*---------------------------------------------------------------*/ ARCH_DEP(diagf14_call) (r1, r2, regs); break; #endif /*defined(OPTION_DYNAMIC_LOAD)*/ #if defined(_FEATURE_HOST_RESOURCE_ACCESS_FACILITY) case 0xF18: /*---------------------------------------------------------------*/ /* Diagnose F18: Hercules Access Host Resource */ /*---------------------------------------------------------------*/ ARCH_DEP(diagf18_call) (r1, r2, regs); break; #endif /* defined(_FEATURE_HOST_RESOURCE_ACCESS_FACILITY) */ #if !defined(NO_SIGABEND_HANDLER) /* The following diagnose calls cause a exigent (non-repressible) machine check, and are used for test purposes only *JJ */ case 0xFE8: /*---------------------------------------------------------------*/ /* Diagnose FE8: Simulate Illegal Instruction */ /*---------------------------------------------------------------*/ raise(SIGILL); break; case 0xFEC: /*---------------------------------------------------------------*/ /* Diagnose FEC: Simulate Floating Point Exception */ /*---------------------------------------------------------------*/ raise(SIGFPE); break; case 0xFF0: /*---------------------------------------------------------------*/ /* Diagnose FF0: Simulate Segment Violation */ /*---------------------------------------------------------------*/ CRASH(); break; case 0xFF4: /*---------------------------------------------------------------*/ /* Diagnose FF4: Simulate BUS Error */ /*---------------------------------------------------------------*/ raise(SIGBUS); break; case 0xFF8: /*---------------------------------------------------------------*/ /* Diagnose FF8: Simulate Loop */ /*---------------------------------------------------------------*/ while(1); /* (never reached) */ case 0xFFC: /*---------------------------------------------------------------*/ /* Diagnose FFC: Simulate Wait */ /*---------------------------------------------------------------*/ SLEEP(300); break; #endif /*!defined(NO_SIGABEND_HANDLER)*/ #endif /*FEATURE_HERCULES_DIAGCALLS*/ default: /*---------------------------------------------------------------*/ /* Diagnose xxx: Invalid function code */ /*---------------------------------------------------------------*/ if( HDC4(debug_diagnose, code, r1, r2, regs) ) return; /* Power Off diagnose on 4361, 9371, 9373, 9375, 9377, 9221: */ /* */ /* DS 0H */ /* DC X'8302',S(SHUTDATA) MUST BE R0 AND R2 */ /* ... */ /* DS 0H */ /* SHUTDATA DC X'0000FFFF' MUST BE X'0000FFFF' */ if (0 == r1 && 2 == r2 && sysblk.cpuversion != 0xFF && (sysblk.cpumodel == 0x4361 || (sysblk.cpumodel & 0xFFF9) == 0x9371 /* (937X) */ || sysblk.cpumodel == 0x9221) ) { if (0x0000FFFF == ARCH_DEP(vfetch4)(effective_addr2, b2, regs)) { /* If diag8cmd is not enabled then we are not allowed * to manipulate the real machine i.e. hercules itself */ if(!(sysblk.diag8cmd & DIAG8CMD_ENABLE)) ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); regs->cpustate = CPUSTATE_STOPPING; ON_IC_INTERRUPT(regs); /* Release the configuration */ do_shutdown(); /* Power Off: exit hercules */ exit(0); } } #if defined(FEATURE_S370_CHANNEL) && defined(OPTION_NOP_MODEL158_DIAGNOSE) if (regs->cpumodel != 0x0158) #endif ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION); return; } /* end switch(code) */ return; } /* end function diagnose_call */
/*-------------------------------------------------------------------*/ int ARCH_DEP(system_reset) ( const int cpu, /* CPU address */ const int flags, /* Flags: * 0x00 0000 0000 System reset normal * 0x01 .... ...1 System reset clear * 0x02 .... ..1. System reset normal * with initial CPU * reset on requesting * processor (used by * IPL) */ const int target_mode /* Target architecture mode */ ) { int rc; int n; int regs_mode; int architecture_switch; REGS* regs; CPU_BITMAP mask; /* Configure the cpu if it is not online (configure implies initial * reset) */ if (!IS_CPU_ONLINE(cpu)) { sysblk.arch_mode = target_mode; if ( (rc = configure_cpu(cpu)) ) return rc; } HDC1(debug_cpu_state, sysblk.regs[cpu]); /* Define the target mode for reset */ if (flags && target_mode > ARCH_390) regs_mode = ARCH_390; else regs_mode = target_mode; architecture_switch = (regs_mode != sysblk.arch_mode); /* Signal all CPUs in configuration to stop and reset */ { /* Switch lock context to hold both sigplock and intlock */ RELEASE_INTLOCK(NULL); obtain_lock(&sysblk.sigplock); OBTAIN_INTLOCK(NULL); /* Ensure no external updates pending */ OFF_IC_SERVSIG; OFF_IC_INTKEY; /* Loop through CPUs and issue appropriate CPU reset function */ { mask = sysblk.config_mask; for (n = 0; mask; mask >>= 1, ++n) { if (mask & 1) { regs = sysblk.regs[n]; /* Signal CPU reset function; if requesting CPU with * CLEAR or architecture change, signal initial CPU * reset. Otherwise, signal a normal CPU reset. */ if ((n == cpu && (flags & 0x03)) || architecture_switch) regs->sigpireset = 1; else regs->sigpreset = 1; regs->opinterv = 1; regs->cpustate = CPUSTATE_STOPPING; ON_IC_INTERRUPT(regs); wakeup_cpu(regs); } } } /* Return to hold of just intlock */ RELEASE_INTLOCK(NULL); release_lock(&sysblk.sigplock); OBTAIN_INTLOCK(NULL); } /* Wait for CPUs to complete reset */ { int i; int wait; for (n = 0; ; ++n) { mask = sysblk.config_mask; for (i = wait = 0; mask; mask >>= 1, ++i) { if (!(mask & 1)) continue; regs = sysblk.regs[i]; if (regs->cpustate != CPUSTATE_STOPPED) { /* Release intlock, take a nap, and re-acquire */ RELEASE_INTLOCK(NULL); wait = 1; usleep(10000); OBTAIN_INTLOCK(NULL); } } if (!wait) break; if (n < 300) continue; /* FIXME: Recovery code needed to handle case where CPUs * are misbehaving. Outstanding locks should be * reported, then take-over CPUs and perform an * initial reset of each CPU. */ WRMSG(HHC90000, "E", "Could not perform reset within three seconds"); break; } } /* If architecture switch, complete reset in requested mode */ if (architecture_switch) { sysblk.arch_mode = regs_mode; return ARCH_DEP(system_reset)(cpu, flags, target_mode); } /* Perform subsystem reset * * GA22-7000-10 IBM System/370 Principles of Operation, Chapter 4. * Control, Subsystem Reset, p. 4-34 * SA22-7085-00 IBM System/370 Extended Architecture Principles of * Operation, Chapter 4. Control, Subsystem Reset, * p. 4-28 * SA22-7832-09 z/Architecture Principles of Operation, Chapter 4. * Control, Subsystem Reset, p. 4-57 */ subsystem_reset(); /* Perform system-reset-clear additional functions */ if (flags & 0x01) { /* Finish reset-clear of all CPUs in the configuration */ for (n = 0; n < sysblk.maxcpu; ++n) { if (IS_CPU_ONLINE(n)) { regs = sysblk.regs[n]; /* Clear all the registers (AR, GPR, FPR, VR) as part * of the CPU CLEAR RESET operation */ memset (regs->ar, 0, sizeof(regs->ar)); memset (regs->gr, 0, sizeof(regs->gr)); memset (regs->fpr, 0, sizeof(regs->fpr)); #if defined(_FEATURE_VECTOR_FACILITY) memset (regs->vf->vr, 0, sizeof(regs->vf->vr)); #endif /*defined(_FEATURE_VECTOR_FACILITY)*/ /* Clear the instruction counter and CPU time used */ cpu_reset_instcount_and_cputime(regs); } } /* Clear storage */ sysblk.main_clear = sysblk.xpnd_clear = 0; storage_clear(); xstorage_clear(); /* Clear IPL program parameter */ sysblk.program_parameter = 0; } /* If IPL call, reset CPU instruction counts and times */ else if (flags & 0x02) { CPU_BITMAP mask = sysblk.config_mask; int i; for (i = 0; mask; mask >>= 1, ++i) { if (mask & 1) cpu_reset_instcount_and_cputime(sysblk.regs[i]); } }
int suspend_cmd(int argc, char *argv[],char *cmdline) { char *fn = SR_DEFAULT_FILENAME; SR_FILE *file; CPU_BITMAP started_mask; struct timeval tv; time_t tt; int i, j, rc; REGS *regs; DEVBLK *dev; IOINT *ioq; BYTE psw[16]; UNREFERENCED(cmdline); if (argc > 2) { // "SR: too many arguments" WRMSG(HHC02000, "E"); return -1; } if (argc == 2) fn = argv[1]; file = SR_OPEN (fn, "wb"); if (file == NULL) { // "SR: error in function '%s': '%s'" WRMSG(HHC02001, "E","open()",strerror(errno)); return -1; } TRACE("SR: Begin Suspend Processing...\n"); /* Save CPU state and stop all CPU's */ TRACE("SR: Stopping All CPUs...\n"); OBTAIN_INTLOCK(NULL); started_mask = sysblk.started_mask; while (sysblk.started_mask) { for (i = 0; i < sysblk.maxcpu; i++) { if (IS_CPU_ONLINE(i)) { sysblk.regs[i]->cpustate = CPUSTATE_STOPPING; ON_IC_INTERRUPT(sysblk.regs[i]); signal_condition(&sysblk.regs[i]->intcond); } } RELEASE_INTLOCK(NULL); usleep (1000); OBTAIN_INTLOCK(NULL); } RELEASE_INTLOCK(NULL); /* Wait for I/O queue to clear out */ TRACE("SR: Waiting for I/O Queue to clear...\n"); #ifdef OPTION_FISHIO SLEEP (2); #else obtain_lock (&sysblk.ioqlock); while (sysblk.ioq) { release_lock (&sysblk.ioqlock); usleep (1000); obtain_lock (&sysblk.ioqlock); } release_lock (&sysblk.ioqlock); #endif /* Wait for active I/Os to complete */ TRACE("SR: Waiting for Active I/Os to Complete...\n"); for (i = 1; i < 5000; i++) { dev = sr_active_devices(); if (dev == NULL) break; if (i % 500 == 0) { // "SR: waiting for device %04X" WRMSG(HHC02002, "W", dev->devnum); } usleep (10000); } if (dev != NULL) { // "SR: device %04X still busy, proceeding anyway" WRMSG(HHC02003, "W",dev->devnum); } /* Write header */ TRACE("SR: Writing File Header...\n"); SR_WRITE_STRING(file, SR_HDR_ID, SR_ID); SR_WRITE_STRING(file, SR_HDR_VERSION, VERSION); gettimeofday(&tv, NULL); tt = tv.tv_sec; SR_WRITE_STRING(file, SR_HDR_DATE, ctime(&tt)); /* Write system data */ TRACE("SR: Saving System Data...\n"); SR_WRITE_STRING(file,SR_SYS_ARCH_NAME,arch_name[sysblk.arch_mode]); SR_WRITE_VALUE (file,SR_SYS_STARTED_MASK,started_mask,sizeof(started_mask)); SR_WRITE_VALUE (file,SR_SYS_MAINSIZE,sysblk.mainsize,sizeof(sysblk.mainsize)); TRACE("SR: Saving MAINSTOR...\n"); SR_WRITE_BUF (file,SR_SYS_MAINSTOR,sysblk.mainstor,sysblk.mainsize); SR_WRITE_VALUE (file,SR_SYS_SKEYSIZE,(sysblk.mainsize/STORAGE_KEY_UNITSIZE),sizeof(U32)); TRACE("SR: Saving Storage Keys...\n"); SR_WRITE_BUF (file,SR_SYS_STORKEYS,sysblk.storkeys,sysblk.mainsize/STORAGE_KEY_UNITSIZE); SR_WRITE_VALUE (file,SR_SYS_XPNDSIZE,sysblk.xpndsize,sizeof(sysblk.xpndsize)); TRACE("SR: Saving Expanded Storage...\n"); SR_WRITE_BUF (file,SR_SYS_XPNDSTOR,sysblk.xpndstor,4096*sysblk.xpndsize); SR_WRITE_VALUE (file,SR_SYS_CPUID,sysblk.cpuid,sizeof(sysblk.cpuid)); SR_WRITE_VALUE (file,SR_SYS_IPLDEV,sysblk.ipldev,sizeof(sysblk.ipldev)); SR_WRITE_VALUE (file,SR_SYS_IPLCPU,sysblk.iplcpu,sizeof(sysblk.iplcpu)); SR_WRITE_VALUE (file,SR_SYS_MBO,sysblk.mbo,sizeof(sysblk.mbo)); SR_WRITE_VALUE (file,SR_SYS_MBK,sysblk.mbk,sizeof(sysblk.mbk)); SR_WRITE_VALUE (file,SR_SYS_MBM,sysblk.mbm,sizeof(sysblk.mbm)); SR_WRITE_VALUE (file,SR_SYS_MBD,sysblk.mbd,sizeof(sysblk.mbd)); for (ioq = sysblk.iointq; ioq; ioq = ioq->next) if (ioq->pcipending) { SR_WRITE_VALUE(file,SR_SYS_PCIPENDING_LCSS, SSID_TO_LCSS(ioq->dev->ssid),sizeof(U16)); SR_WRITE_VALUE(file,SR_SYS_PCIPENDING, ioq->dev->devnum,sizeof(ioq->dev->devnum)); } else if (ioq->attnpending) { SR_WRITE_VALUE(file,SR_SYS_ATTNPENDING_LCSS, SSID_TO_LCSS(ioq->dev->ssid),sizeof(U16)); SR_WRITE_VALUE(file,SR_SYS_ATTNPENDING, ioq->dev->devnum,sizeof(ioq->dev->devnum)); } else { SR_WRITE_VALUE(file,SR_SYS_IOPENDING_LCSS, SSID_TO_LCSS(ioq->dev->ssid),sizeof(U16)); SR_WRITE_VALUE(file,SR_SYS_IOPENDING, ioq->dev->devnum,sizeof(ioq->dev->devnum)); } for (i = 0; i < 8; i++) SR_WRITE_VALUE(file,SR_SYS_CHP_RESET+i,sysblk.chp_reset[i],sizeof(sysblk.chp_reset[0])); SR_WRITE_VALUE (file,SR_SYS_SERVPARM,sysblk.servparm,sizeof(sysblk.servparm)); SR_WRITE_VALUE (file,SR_SYS_SIGINTREQ,sysblk.sigintreq,1); SR_WRITE_STRING(file,SR_SYS_LOADPARM,str_loadparm()); SR_WRITE_VALUE (file,SR_SYS_INTS_STATE,sysblk.ints_state,sizeof(sysblk.ints_state)); SR_WRITE_HDR(file, SR_DELIMITER, 0); /* Save service console state */ TRACE("SR: Saving Service Console State...\n"); SR_WRITE_HDR(file, SR_SYS_SERVC, 0); servc_hsuspend(file); SR_WRITE_HDR(file, SR_DELIMITER, 0); /* Save clock state */ TRACE("SR: Saving Clock State...\n"); SR_WRITE_HDR(file, SR_SYS_CLOCK, 0); clock_hsuspend(file); SR_WRITE_HDR(file, SR_DELIMITER, 0); /* Write CPU data */ for (i = 0; i < sysblk.maxcpu; i++) { if (!IS_CPU_ONLINE(i)) continue; TRACE("SR: Saving CPU %d Data...\n", i); regs = sysblk.regs[i]; SR_WRITE_VALUE(file, SR_CPU, i, sizeof(i)); SR_WRITE_VALUE(file, SR_CPU_ARCHMODE, regs->arch_mode,sizeof(regs->arch_mode)); SR_WRITE_VALUE(file, SR_CPU_PX, regs->PX_G,sizeof(regs->PX_G)); copy_psw (regs, psw); SR_WRITE_BUF(file, SR_CPU_PSW, psw, 16); for (j = 0; j < 16; j++) SR_WRITE_VALUE(file, SR_CPU_GR+j, regs->GR_G(j),sizeof(regs->GR_G(0))); for (j = 0; j < 16; j++) SR_WRITE_VALUE(file, SR_CPU_CR+j, regs->CR_G(j),sizeof(regs->CR_G(0))); for (j = 0; j < 16; j++) SR_WRITE_VALUE(file, SR_CPU_AR+j, regs->ar[j],sizeof(regs->ar[0])); for (j = 0; j < 32; j++) SR_WRITE_VALUE(file, SR_CPU_FPR+j, regs->fpr[j],sizeof(regs->fpr[0])); SR_WRITE_VALUE(file, SR_CPU_FPC, regs->fpc, sizeof(regs->fpc)); SR_WRITE_VALUE(file, SR_CPU_DXC, regs->dxc, sizeof(regs->dxc)); SR_WRITE_VALUE(file, SR_CPU_MC, regs->MC_G, sizeof(regs->MC_G)); SR_WRITE_VALUE(file, SR_CPU_EA, regs->EA_G, sizeof(regs->EA_G)); SR_WRITE_VALUE(file, SR_CPU_PTIMER, cpu_timer(regs), sizeof(S64)); SR_WRITE_VALUE(file, SR_CPU_CLKC, regs->clkc, sizeof(regs->clkc)); SR_WRITE_VALUE(file, SR_CPU_CHANSET, regs->chanset, sizeof(regs->chanset)); SR_WRITE_VALUE(file, SR_CPU_TODPR, regs->todpr, sizeof(regs->todpr)); SR_WRITE_VALUE(file, SR_CPU_MONCLASS, regs->monclass, sizeof(regs->monclass)); SR_WRITE_VALUE(file, SR_CPU_EXCARID, regs->excarid, sizeof(regs->excarid)); SR_WRITE_VALUE(file, SR_CPU_BEAR, regs->bear, sizeof(regs->bear)); SR_WRITE_VALUE(file, SR_CPU_OPNDRID, regs->opndrid, sizeof(regs->opndrid)); SR_WRITE_VALUE(file, SR_CPU_CHECKSTOP, regs->checkstop, 1); SR_WRITE_VALUE(file, SR_CPU_HOSTINT, regs->hostint, 1); SR_WRITE_VALUE(file, SR_CPU_EXECFLAG, regs->execflag, 1); // SR_WRITE_VALUE(file, SR_CPU_INSTVALID, regs->instvalid, 1); SR_WRITE_VALUE(file, SR_CPU_PERMODE, regs->permode, 1); SR_WRITE_VALUE(file, SR_CPU_LOADSTATE, regs->loadstate, 1); SR_WRITE_VALUE(file, SR_CPU_INVALIDATE, regs->invalidate, 1); SR_WRITE_VALUE(file, SR_CPU_SIGPRESET, regs->sigpreset, 1); SR_WRITE_VALUE(file, SR_CPU_SIGPIRESET, regs->sigpireset, 1); SR_WRITE_VALUE(file, SR_CPU_INTS_STATE, regs->ints_state, sizeof(regs->ints_state)); SR_WRITE_VALUE(file, SR_CPU_INTS_MASK, regs->ints_mask, sizeof(regs->ints_mask)); for (j = 0; j < sysblk.maxcpu; j++) SR_WRITE_VALUE(file, SR_CPU_MALFCPU+j, regs->malfcpu[j], sizeof(regs->malfcpu[0])); for (j = 0; j < sysblk.maxcpu; j++) SR_WRITE_VALUE(file, SR_CPU_EMERCPU+j, regs->emercpu[j], sizeof(regs->emercpu[0])); SR_WRITE_VALUE(file, SR_CPU_EXTCCPU, regs->extccpu, sizeof(regs->extccpu)); SR_WRITE_HDR(file, SR_DELIMITER, 0); } /* Write Device data */ for (dev = sysblk.firstdev; dev; dev = dev->nextdev) { if (!(dev->pmcw.flag5 & PMCW5_V)) continue; TRACE("SR: Saving Device %4.4X...\n", dev->devnum); /* These fields must come first so the device could be attached */ SR_WRITE_VALUE(file, SR_DEV, dev->devnum, sizeof(dev->devnum)); SR_WRITE_VALUE(file, SR_DEV_LCSS, SSID_TO_LCSS(dev->ssid), sizeof(U16)); SR_WRITE_VALUE(file, SR_DEV_ARGC, dev->argc, sizeof(dev->argc)); for (i = 0; i < dev->argc; i++) if (dev->argv[i]) { SR_WRITE_STRING(file, SR_DEV_ARGV, dev->argv[i]); } else { SR_WRITE_STRING(file, SR_DEV_ARGV, ""); } SR_WRITE_STRING(file, SR_DEV_TYPNAME, dev->typname); /* Common device fields */ SR_WRITE_BUF (file, SR_DEV_ORB, &dev->orb, sizeof(ORB)); SR_WRITE_BUF (file, SR_DEV_PMCW, &dev->pmcw, sizeof(PMCW)); SR_WRITE_BUF (file, SR_DEV_SCSW, &dev->scsw, sizeof(SCSW)); SR_WRITE_BUF (file, SR_DEV_PCISCSW, &dev->pciscsw, sizeof(SCSW)); SR_WRITE_BUF (file, SR_DEV_ATTNSCSW, &dev->attnscsw, sizeof(SCSW)); SR_WRITE_BUF (file, SR_DEV_CSW, dev->csw, 8); SR_WRITE_BUF (file, SR_DEV_PCICSW, dev->pcicsw, 8); SR_WRITE_BUF (file, SR_DEV_ATTNCSW, dev->attncsw, 8); SR_WRITE_BUF (file, SR_DEV_ESW, &dev->esw, sizeof(ESW)); SR_WRITE_BUF (file, SR_DEV_ECW, dev->ecw, 32); SR_WRITE_BUF (file, SR_DEV_SENSE, dev->sense, 32); SR_WRITE_VALUE(file, SR_DEV_PGSTAT, dev->pgstat, sizeof(dev->pgstat)); SR_WRITE_BUF (file, SR_DEV_PGID, dev->pgid, 11); /* By Adrian - SR_DEV_DRVPWD */ SR_WRITE_BUF (file, SR_DEV_DRVPWD, dev->drvpwd, 11); SR_WRITE_VALUE(file, SR_DEV_BUSY, dev->busy, 1); SR_WRITE_VALUE(file, SR_DEV_RESERVED, dev->reserved, 1); SR_WRITE_VALUE(file, SR_DEV_SUSPENDED, dev->suspended, 1); SR_WRITE_VALUE(file, SR_DEV_PCIPENDING, dev->pcipending, 1); SR_WRITE_VALUE(file, SR_DEV_ATTNPENDING, dev->attnpending, 1); SR_WRITE_VALUE(file, SR_DEV_PENDING, dev->pending, 1); SR_WRITE_VALUE(file, SR_DEV_STARTPENDING, dev->startpending, 1); SR_WRITE_VALUE(file, SR_DEV_CRWPENDING, dev->crwpending, 1); SR_WRITE_VALUE(file, SR_DEV_CCWADDR, dev->ccwaddr, sizeof(dev->ccwaddr)); SR_WRITE_VALUE(file, SR_DEV_IDAPMASK, dev->idapmask, sizeof(dev->idapmask)); SR_WRITE_VALUE(file, SR_DEV_IDAWFMT, dev->idawfmt, sizeof(dev->idawfmt)); SR_WRITE_VALUE(file, SR_DEV_CCWFMT, dev->ccwfmt, sizeof(dev->ccwfmt)); SR_WRITE_VALUE(file, SR_DEV_CCWKEY, dev->ccwkey, sizeof(dev->ccwkey)); /* Device type specific data */ SR_WRITE_VALUE(file, SR_DEV_DEVTYPE, dev->devtype, sizeof(dev->devtype)); if (dev->hnd->hsuspend) { rc = (dev->hnd->hsuspend) (dev, file); if (rc < 0) goto sr_error_exit; } SR_WRITE_HDR(file, SR_DELIMITER, 0); } TRACE("SR: Writing EOF\n"); SR_WRITE_HDR(file, SR_EOF, 0); SR_CLOSE (file); TRACE("SR: Suspend Complete; shutting down...\n"); /* Shutdown */ do_shutdown(); return 0; sr_error_exit: // "SR: error processing file '%s'" WRMSG(HHC02004, "E", fn); SR_CLOSE (file); return -1; }
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); }