/* IPL.C (c) Copyright Roger Bowler, 1999-2012 */ /* ESA/390 Initial Program Loader */ /* */ /* Released under "The Q Public License Version 1" */ /* (http://www.hercules-390.org/herclic.html) as modifications to */ /* Hercules. */ /* */ /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2012 */ /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2012 */ /*-------------------------------------------------------------------*/ /* This module implements the Initial Program Load (IPL) function of */ /* the S/370, ESA/390 and z/Architectures, described in the manuals: */ /* */ /* GA22-7000 System/370 Principles of Operation */ /* SA22-7201 ESA/390 Principles of Operation */ /* SA22-7832 z/Architecture Principles of Operation. */ /* */ /*-------------------------------------------------------------------*/ #include "hstdinc.h" #define _IPL_C #define _HENGINE_DLL_ #include "hercules.h" #include "opcode.h" #include "inline.h" #ifdef FEATURE_MESSAGE_SECURITY_ASSIST_EXTENSION_3 #include "hexterns.h" #endif /*-------------------------------------------------------------------*/ /* Function to reset instruction count and CPU time */ /*-------------------------------------------------------------------*/ #if !defined(_reset_instcount_) #define _reset_instcount_ INLINE void cpu_reset_instcount_and_cputime(REGS* regs) { /* Reset instruction counts, I/O counts and real CPU time */ regs->prevcount = 0; regs->instcount = 0; regs->mipsrate = 0; regs->siocount = 0; regs->siosrate = 0; regs->siototal = 0; regs->cpupct = 0; regs->rcputime = 0; regs->bcputime = thread_cputime_us(regs); } #endif /*-------------------------------------------------------------------*/ /* Function to perform Subystem Reset */ /*-------------------------------------------------------------------*/ /* Locks held on entry/exit: */ /* sysblk.intlock */ /*-------------------------------------------------------------------*/ #if !defined(_subsystem_reset_) #define _subsystem_reset_ void subsystem_reset (void) { /* 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 */ /* Clear pending external interrupts */ OFF_IC_SERVSIG; OFF_IC_INTKEY; /* Reset the I/O subsystem */ RELEASE_INTLOCK(NULL); io_reset (); OBTAIN_INTLOCK(NULL); } #endif /*-------------------------------------------------------------------*/ /* Function to perform System Reset (either 'normal' or 'clear') */ /*-------------------------------------------------------------------*/ 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]); } } /* If IPL or system-reset-clear, clear system instruction counter, * rates, and IPLed indicator. */ if (flags & 0x03) { /* Clear system instruction counter and CPU rates */ sysblk.instcount = 0; sysblk.mipsrate = 0; sysblk.siosrate = 0; sysblk.ipled = FALSE; } #if defined(FEATURE_CONFIGURATION_TOPOLOGY_FACILITY) /* Set horizontal polarization */ sysblk.topology = TOPOLOGY_HORIZ; /* 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 */ /*-------------------------------------------------------------------*/ /* LOAD (aka IPL) functions... */ /*-------------------------------------------------------------------*/ /* Performing an Initial Program Load (aka IPL) involves three */ /* distinct phases: in phase 1 the system is reset (registers */ /* and, for load-clear, storage), and in phase two the actual */ /* Initial Program Loading from the IPL device takes place. Finally,*/ /* in phase three, the IPL PSW is loaded and the CPU is started. */ /*-------------------------------------------------------------------*/ int orig_arch_mode; /* Saved architecture mode */ PSW captured_zpsw; /* Captured z/Arch PSW */ /*-------------------------------------------------------------------*/ /* Common LOAD (IPL) begin: system-reset (register/storage clearing) */ /*-------------------------------------------------------------------*/ int ARCH_DEP(common_load_begin) (int cpu, int clear) { int capture; int rc; /* Save the original architecture mode for later */ orig_arch_mode = sysblk.dummyregs.arch_mode = sysblk.arch_mode; capture = (!clear) && IS_CPU_ONLINE(cpu) && sysblk.arch_mode == ARCH_900; /* Capture the z/Arch PSW if this is a Load-normal IPL */ if (capture) captured_zpsw = sysblk.regs[cpu]->psw; /* Perform system-reset-normal or system-reset-clear function; * architecture mode updated, if necessary. The clear indicator is * cleaned with an initial CPU reset added. * * SA22-7085-0 IBM System/370 Extended Architecture Principles of * Operation, Chapter 12, Operator Facilities, LOAD- * CLEAR KEY and LOAD-NORMAL KEY, p. 12-3. */ if ( (rc = ARCH_DEP(system_reset(cpu, ((clear & 0x01) | 0x02), sysblk.arch_mode > ARCH_390 ? ARCH_390 : sysblk.arch_mode))) ) return (rc); /* Save our captured-z/Arch-PSW if this is a Load-normal IPL since the initial_cpu_reset call cleared it to zero. */ if (capture) sysblk.regs[cpu]->captured_zpsw = captured_zpsw; /* The actual IPL (load) now begins... */ sysblk.regs[cpu]->loadstate = 1; return 0; } /* end function common_load_begin */ /*-------------------------------------------------------------------*/ /* Function to run initial CCW chain from IPL device and load IPLPSW */ /* Returns 0 if successful, -1 if error */ /* intlock MUST be held on entry */ /*-------------------------------------------------------------------*/ 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%2.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 */ /*-------------------------------------------------------------------*/ /* Common LOAD (IPL) finish: load IPL PSW and start CPU */ /*-------------------------------------------------------------------*/ 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 */ /*-------------------------------------------------------------------*/ /* Function to perform CPU Reset */ /*-------------------------------------------------------------------*/ 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; /* 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 */ /*-------------------------------------------------------------------*/ /* Function to perform Initial CPU Reset */ /*-------------------------------------------------------------------*/ int ARCH_DEP(initial_cpu_reset) (REGS *regs) { int rc1 = 0, rc; /* Clear reset pending indicators */ regs->sigpireset = regs->sigpreset = 0; /* Clear the registers */ memset ( ®s->psw, 0, sizeof(regs->psw) ); memset ( ®s->captured_zpsw, 0, sizeof(regs->captured_zpsw) ); #ifndef NOCHECK_AEA_ARRAY_BOUNDS memset ( ®s->cr_struct, 0, sizeof(regs->cr_struct) ); #else memset ( ®s->cr, 0, sizeof(regs->cr) ); #endif regs->fpc = 0; regs->PX = 0; regs->psw.AMASK_G = AMASK24; /* Ensure memory sizes are properly indicated */ regs->mainstor = sysblk.mainstor; regs->storkeys = sysblk.storkeys; regs->mainlim = sysblk.mainsize ? (sysblk.mainsize - 1) : 0; regs->psa = (PSA_3XX*)regs->mainstor; /* Perform a CPU reset (after setting PSA) */ rc1 = ARCH_DEP(cpu_reset) (regs); regs->todpr = 0; regs->clkc = 0; set_cpu_timer(regs, 0); #ifdef _FEATURE_INTERVAL_TIMER set_int_timer(regs, 0); #endif /* The breaking event address register is initialised to 1 */ regs->bear = 1; /* Initialize external interrupt masks in control register 0 */ regs->CR(0) = CR0_XM_INTKEY | CR0_XM_EXTSIG | (FACILITY_ENABLED(INTERVAL_TIMER, regs) ? CR0_XM_ITIMER : 0); #if defined(FEATURE_S370_CHANNEL) && !defined(FEATURE_ACCESS_REGISTERS) /* For S/370 initialize the channel masks in CR2 */ regs->CR(2) = 0xFFFFFFFF; #endif /* defined(FEATURE_S370_CHANNEL) && !defined(FEATURE_ACCESS_REGISTERS) */ regs->chanset = #if defined(FEATURE_CHANNEL_SWITCHING) regs->cpuad < FEATURE_LCSS_MAX ? regs->cpuad : #endif /*defined(FEATURE_CHANNEL_SWITCHING)*/ 0xFFFF; /* Initialize the machine check masks in control register 14 */ regs->CR(14) = CR14_CHKSTOP | CR14_SYNCMCEL | CR14_XDMGRPT; #ifndef FEATURE_LINKAGE_STACK /* For S/370 initialize the MCEL address in CR15 */ regs->CR(15) = 512; #endif /*!FEATURE_LINKAGE_STACK*/ if(regs->host && regs->guestregs) if( (rc = ARCH_DEP(initial_cpu_reset)(regs->guestregs)) ) rc1 = rc; #ifdef FEATURE_MESSAGE_SECURITY_ASSIST_EXTENSION_3 renew_wrapping_keys(); #endif /* FEATURE_MESSAGE_SECURITY_ASSIST_EXTENSION_3 */ return rc1; } /* end function initial_cpu_reset */ #if !defined(_GEN_ARCH) #if defined(_ARCHMODE2) #define _GEN_ARCH _ARCHMODE2 #include "ipl.c" #endif #if defined(_ARCHMODE3) #undef _GEN_ARCH #define _GEN_ARCH _ARCHMODE3 #include "ipl.c" #endif /*********************************************************************/ /* Externally Initiated Functions... */ /*********************************************************************/ /*-------------------------------------------------------------------*/ /* Load / IPL (Load Normal -or- Load Clear) */ /*-------------------------------------------------------------------*/ int load_ipl (U16 lcss, U16 devnum, int cpu, int clear) { int rc; switch (sysblk.arch_mode) { #if defined(_370) case ARCH_370: rc = s370_load_ipl (lcss, devnum, cpu, clear); break; #endif #if defined(_390) case ARCH_390: rc = s390_load_ipl (lcss, devnum, cpu, clear); break; #endif #if defined(_900) case ARCH_900: /* z/Arch always starts out in ESA390 mode */ rc = s390_load_ipl (lcss, devnum, cpu, clear); break; #endif default: rc = -1; break; } return (rc); } /*-------------------------------------------------------------------*/ /* Initial CPU Reset */ /*-------------------------------------------------------------------*/ int initial_cpu_reset (REGS *regs) { int rc; switch (regs->arch_mode) { #if defined(_370) case ARCH_370: rc = s370_initial_cpu_reset (regs); break; #endif #if defined(_390) case ARCH_390: rc = s390_initial_cpu_reset (regs); break; #endif #if defined(_900) case ARCH_900: /* z/Arch always starts out in ESA390 mode */ rc = s390_initial_cpu_reset (regs); break; #endif default: rc = -1; break; } return (rc); } /*-------------------------------------------------------------------*/ /* System Reset ( Normal reset or Clear reset ) */ /*-------------------------------------------------------------------*/ int system_reset (const int cpu, const int flags, const int target_mode) { int rc; switch (sysblk.arch_mode) { #if defined(_370) case ARCH_370: rc = s370_system_reset (cpu, flags, target_mode); break; #endif #if defined(_390) case ARCH_390: rc = s390_system_reset (cpu, flags, target_mode); break; #endif #if defined(_900) case ARCH_900: rc = z900_system_reset (cpu, flags, target_mode); break; #endif default: rc = -1; break; } return (rc); } /*-------------------------------------------------------------------*/ /* ordinary CPU Reset (no clearing takes place) */ /*-------------------------------------------------------------------*/ int cpu_reset (REGS *regs) { int rc; switch (regs->arch_mode) { #if defined(_370) case ARCH_370: rc = s370_cpu_reset (regs); break; #endif #if defined(_390) case ARCH_390: rc = s390_cpu_reset (regs); break; #endif #if defined(_900) case ARCH_900: rc = z900_cpu_reset (regs); break; #endif default: rc = -1; break; } return (rc); } /*-------------------------------------------------------------------*/ /* Function to clear main storage */ /*-------------------------------------------------------------------*/ void storage_clear() { if (!sysblk.main_clear) { if (sysblk.mainstor) memset( sysblk.mainstor, 0x00, sysblk.mainsize ); if (sysblk.storkeys) memset( sysblk.storkeys, 0x00, sysblk.mainsize / STORAGE_KEY_UNITSIZE ); sysblk.main_clear = 1; } } /*-------------------------------------------------------------------*/ /* Function to clear expanded storage */ /*-------------------------------------------------------------------*/ void xstorage_clear() { if (!sysblk.xpnd_clear) { if (sysblk.xpndstor) memset( sysblk.xpndstor, 0x00, (size_t)sysblk.xpndsize * XSTORE_PAGESIZE ); sysblk.xpnd_clear = 1; } } #endif /*!defined(_GEN_ARCH)*/