Files
org-hyperion-cules/ipl.c
Roger Bowler 93da32d335 PTF fixes:
PTF request vertical polarization
Add PTF (Perform Topology Function) testcase
STSI 15.1.2 Mag2 and vertical polarization
STSI 15.1.2 fix attribution
2013-11-12 00:08:07 -08:00

868 lines
27 KiB
C

/* 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 ( &regs->psw, 0, sizeof(regs->psw) );
memset ( &regs->captured_zpsw, 0, sizeof(regs->captured_zpsw) );
#ifndef NOCHECK_AEA_ARRAY_BOUNDS
memset ( &regs->cr_struct, 0, sizeof(regs->cr_struct) );
#else
memset ( &regs->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)*/