  TITLE 'fix-page.asm: Test the Fix Page E502 Assist'
***********************************************************************
*
*Testcase fix-page
*  A test case for "Simplified Execution Path" of the Fix
*  Page E502 Assist instruction.
*
***********************************************************************
*
*                        fix-page.asm
*
* Created and placed into public domain 09 OCT 2020 by Bob Polmanter.
* Remove runtest *Compare dependency on 2022-03-08 by Fish
*
* The Fix Page E502 Assist instruction is tested against the definition
* of the Simplified Execution Path as described in the System/370
* Assists for MVS, publication GA22-7079-1.  The tests for the E502
* execution in the problem state are tested against the definition
* in GA22-7072-0 System/370 Extended Facility within the section titled
* Virtual-Machine Extended Facility Assist.
*
* Test data is assembled into this program, and some test data is
* generated by this program. The program itself verifies the resulting
* status of registers and condition codes via simple CLC comparison.
*
*
* Tests performed with Fix Page E502:
*
* TEST #1
* 1.  That GR14 contains the address of the next sequential instruction
*       following the E502 instruction.
* 2.  That GR15 contains the contents of the fullword field MPLPFAL.
* 3.  That the PSW next instruction address is loaded with the fullword
*     field MPLPFAL and that execution resumed at that location.
*
* TEST #2
* 4.  Repeating the essence of Test #1, except that the PSW is in the
*     problem state, and CR6 is set to indicate that a virtual machine
*     is in the virtual supervisor state (CR6 bit 1=0) and the VM
*     Extended Assist feature ("370E") is enabled (CR6 bit 29=1). When
*     CR6 is set with these bits, this is the only case where E502 (and
*     the other E5xx assists) are allowed to execute in real problem
*     state. The conditions 1, 2, and 3 of Test #1 above are reverified
*     for test #2.
*
* TEST #3
* 5.  Validates that when the PSW is in the problem state and CR6 bit
*     1=1 (Virtual problem state) while the 370E feature is enabled
*     (CR6 bit 29=1) that E502 execution results in a privileged
*     operation exception.
*
* TEST #4
* 6.  Validates that when the PSW is in the problem state and CR6 bit
*     29=0 (370E feature disabled) while CR6 also indicates bit 1=0
*     (virtual supervisor state) that E502 execution results in a
*     privileged operation exception.
*
*
* NOTE: The other bits in CR6 are used by ECPS:VM and whether or not
*       the other VM assists are enabled, bits 1 and 29 of CR6 still
*       control the virtualization of the E5xx assists regardless of
*       the values of other other bits in CR6.
*
* NOTE: the MPLP is a control block normally maintained by some
*       versions of the S/370 MVS operating system in support of the
*       various Assists. The base address of the MPLP is defined by
*       the second operand of the E502 instruction.  The word MPLPFAL
*       is at offset 0x34 into the MPLP, as described in GA22-7079-1.
*
***********************************************************************
         EJECT
FPA001   START 0
STRTLABL EQU   *
R0       EQU   0
R1       EQU   1
R2       EQU   2
R3       EQU   3
R4       EQU   4
R5       EQU   5
R6       EQU   6
R7       EQU   7
R8       EQU   8
R9       EQU   9
R10      EQU   10
R11      EQU   11
R12      EQU   12
R13      EQU   13
R14      EQU   14
R15      EQU   15
*
*
         USING *,R0
*
* Selected S/370 low core layout
*
*
         ORG   STRTLABL+X'00'      Restart PSW
         DC    X'000C0000',A(START)
*
         ORG   STRTLABL+X'20'      SVC old PSW
SVCOPSW  DC    X'00000000',A(0)
*
         ORG   STRTLABL+X'28'      Program check old PSW
PGMOPSW  DC    X'00000000',A(0)
*
         ORG   STRTLABL+X'60'      SVC new PSW
SVCNPSW  DC    X'000C0000',A(SVCFLIH) SVC handler
*
         ORG   STRTLABL+X'68'      Program check new PSW
PGMNPSW  DC    X'000C0000',A(PGMFLIH) PGM Check handler
*
         ORG   STRTLABL+X'88'      interrupt code area EC mode
SVCINTC  DC    X'00000000'         SVC interrupt code area
PGMINTC  DC    X'00000000'         Prog check interrupt code area
*
         ORG   STRTLABL+X'A4'      Address of MPLP assist control block
AMPLP    DC    A(MPLP)
         EJECT
***********************************************************************
*
*  Main program.
*
         ORG   STRTLABL+X'200'
START    DS    0H
         LA    R1,1                 Init
         ST    R1,RESULTS1          Initialize results area
         ST    R1,RESULTS2          Initialize results area
         ST    R1,RESULTS3          Initialize results area
         ST    R1,RESULTS4          Initialize results area
*
********** Execute Fix Page on simplified path return.
* TEST 1 * PSW in supervisor state
*        * CR6 all bits zero
********** No program checks should occur
*
TEST1    EQU   *
         LA    R8,1                 Test 1 in progress
         LCTL  6,6,C6ZERO           Init CR6: all bits off
         LA    R1,SUCCESS1          Value to place in MPLPFAL
         ST    R1,MPLPFAL           Init the field
*
         LM    R1,R2,PGSTART        -> starting,ending page addresses
         L     R0,PGRADD            -> address within page to be fixed
         DC    X'E502',AL2(0),S(AMPLP) Fix Page; operand 1 not used
*
FAIL1    EQU   *
         MVC   RESULTS1,BADRC       Set bad result code
         B     TEST2                Go to next test
*
SUCCESS1 EQU   *
         LA    R1,FAIL1             -> instruction after E502
         CLR   R1,R14               Does R14 contain correct addr?
         BNER  R1                   No, fail the test
         CL    R15,MPLPFAL          Does R15 contain MPLPFAL?
         BNER  R1                   No, fail the test
         MVC   RESULTS1,GOODRC      Test was successful
*
*
********** Execute Fix Page on simplified path return.
* TEST 2 * Real PSW in problem state
*        * CR6 = X'00000004'  (CR6 bit 1=0 (virtual supervisor state),
*                              bit 29=1 (370E enabled))
********** No program checks should occur
*
TEST2    EQU   *
         LA    R8,2                 Test 2 in progress
         LCTL  6,6,C6ALLOW          Init CR6: allow problem state
         LA    R1,SUCCESS2          Value to place in MPLPFAL
         ST    R1,MPLPFAL           Init the field
         SVC   1                    Enter problem state
*
         LM    R1,R2,PGSTART        -> starting,ending page addresses
         L     R0,PGRADD            -> address within page to be fixed
         DC    X'E502',AL2(0),S(AMPLP) Fix Page; operand 1 not used
*
FAIL2    EQU   *
         MVC   RESULTS2,BADRC       Set bad result code
         B     TEST3                Go to next test
*
SUCCESS2 EQU   *
         LA    R1,FAIL2             -> instruction after E502
         CLR   R1,R14               Does R14 contain correct addr?
         BNER  R1                   No, fail the test
         CL    R15,MPLPFAL          Does R15 contain MPLPFAL?
         BNER  R1                   No, fail the test
         MVC   RESULTS2,GOODRC      Test was successful
*
*
********** Execute Fix Page on simplified path return.
* TEST 3 * Real PSW in problem state
*        * CR6 = X'40000004'  (CR6 bit 1=1 (virtual PROBLEM state),
*                              bit 29=1 (370E enabled))
********** Program check 02 should occur
*
TEST3    EQU   *
         SVC   0                    Back to supervisor state
         LA    R8,3                 Test 3 in progress
         LCTL  6,6,C6VPROB          Init CR6: virt prob state, 370E
         LA    R1,FAIL3             Value to place in MPLPFAL
         ST    R1,MPLPFAL           Init the field
         SVC   1                    Enter problem state
*
         LM    R1,R2,PGSTART        -> starting,ending page addresses
         L     R0,PGRADD            -> address within page to be fixed
         DC    X'E502',AL2(0),S(AMPLP) Fix Page; operand 1 not used
*
SUCCESS3 EQU   *
         MVC   RESULTS3,GOODRC      Good result (expected PIC occurred)
         B     TEST4                Go to next test
*
FAIL3    EQU   *
         MVC   RESULTS3,BADRC       FAIL (E502 ran when it should not)
*
*
*
********** Execute Fix Page on simplified path return.
* TEST 4 * Real PSW in problem state
*        * CR6 = X'00000000'  (CR6 bit 1=0 (virtual Supv state),
*                              bit 29=0 (370E disabled))
********** Program check 02 should occur
*
TEST4    EQU   *
         SVC   0                    Back to supervisor state
         LA    R8,4                 Test 4 in progress
         LCTL  6,6,C6N370E          Init CR6: virt supv state, 370E OFF
         LA    R1,FAIL4             Value to place in MPLPFAL
         ST    R1,MPLPFAL           Init the field
         SVC   1                    Enter problem state
*
         LM    R1,R2,PGSTART        -> starting,ending page addresses
         L     R0,PGRADD            -> address within page to be fixed
         DC    X'E502',AL2(0),S(AMPLP) Fix Page; operand 1 not used
*
SUCCESS4 EQU   *
         MVC   RESULTS4,GOODRC      Good result (expected PIC occurred)
         B     EOJ                  All tests completed
*
FAIL4    EQU   *
         MVC   RESULTS4,BADRC       FAIL (E502 ran when it should not)
*
EOJ      EQU   *
         SVC   0                    Back to supervisor state
*
**      Verify test results...
*
         CLC   RESULTS1,=F'0'
         BNE   FAIL
         CLC   RESULTS2,=F'0'
         BNE   FAIL
         CLC   RESULTS3,=F'0'
         BNE   FAIL
         CLC   RESULTS4,=F'0'
         BNE   FAIL
*
         LPSW  GOODPSW              EOJ, load disabled wait PSW
         EJECT
*
*
* HERE FOR PROGRAM CHECKS
*
         DS    0D
PGMFLIH  EQU   *                    PGM Check Interruption Routine
         C     R8,=F'1'             Doing test 1?
         BE    FAIL                 FAIL, program check not allowed
         C     R8,=F'2'             Doing test 2?
         BE    FAIL                 FAIL, program check not allowed
*
*                                   Tests 3 & 4: PIC 02 is expected
         CLI   PGMINTC+3,X'02'      priv-op exception?
         BNE   FAIL                 No, FAIL. Test # in R8.
         LPSW  PGMOPSW              Expected; resume execution
*
FAIL     LPSW  FAILPSW              Halt on unexpected pgm check.
*                                   Failed test # is in R8
*
* HERE FOR SVCs
*
         DS    0D
SVCFLIH  EQU   *                    SVC Interruption Routine
         CLI   SVCINTC+3,X'00'      SVC 0? (switch to supervisor state)
         BE    SVC000               Yes
         CLI   SVCINTC+3,X'01'      SVC 1? (switch to problem state)
         BE    SVC001               Yes
         LPSW  XSVCPSW              Halt on bad SVC
*
SVC000   EQU   *
         NI    SVCOPSW+1,255-X'01'  Turn OFF problem bit in old PSW
         LPSW  SVCOPSW              Resume execution in supv state
*
SVC001   EQU   *
         OI    SVCOPSW+1,X'01'      Turn ON problem bit in old PSW
         LPSW  SVCOPSW              Resume execution in problem state
*
         DS    0D                   Ensure correct alignment for PSW
GOODPSW  DC    X'000A000000000000'  SUCCESS diabled wait PSW
XSVCPSW  DC    X'000A000000000BAD'  Bad SVC # disabled wait PSW
FAILPSW  DC    X'000A00000000DEAD'  TEST FAILED disabled wait PSW
*                                   (unexpected program check,
*                                    or general test failure)
         LTORG
         EJECT
         ORG   STRTLABL+X'600'
RESULTS1 DC    X'00000000'          Return code from test 1
RESULTS2 DC    X'00000000'          Return code from test 2
RESULTS3 DC    X'00000000'          Return code from test 3
RESULTS4 DC    X'00000000'          Return code from test 4
*
         ORG   STRTLABL+X'700'
*
* The MPLP area below defines only the relevant part of the MPLP assist
* control block; in this case, the location at MPLP+X'34' (MPLPFAL)
* must contain the address of where the assist should begin execution
* at the completion of the X'E502' instruction.
*
MPLP     DC    A(0)           Relevant MPLP block definition
         DC    A(0)           +4
         DC    A(0)           +8
         DC    A(0)           +C
         DC    A(0)           +10
         DC    A(0)           +14
         DC    A(0)           +18
         DC    A(0)           +1C
         DC    A(0)           +20
         DC    A(0)           +24
         DC    A(0)           +28
         DC    A(0)           +2C
         DC    A(0)           +30
MPLPFAL  DC    A(0)           +34
         DC    A(0)           +38
*
PGSTART  DC    X'00002000'    -> begin page to fix
PGEND    DC    X'00002000'    -> end page to fix
PGRADD   DC    X'00002044'    -> address within the page to be fixed
BADRC    DC    F'8'           Bad result code (test failed)
GOODRC   DC    F'0'           Good result code (test success)
C6ZERO   DC    X'00000000'    CR6 init
C6ALLOW  DC    X'00000004'    CR6 Virtual Suprv state + 370E enabled
C6VPROB  DC    X'40000004'    CR6 Virtual Prob state + 370E enabled
C6N370E  DC    X'00000000'    CR6 Virtual Suprv state but 370E Disabled
*
         END
