SVC routines are defined in a SVC Table Module. The SVC table is a two-level index to the SVC routine. The first level is a 256 byte table. Each byte corresponds to a SVC number. If the corresponding byte in the table is zero then the SVC routine is not defined. If the value is non-zero it is an index into a vector table that points to the SVC routine.
For example the first level table of x’00 02 03 01 00…’ would define three SVC’s. SVC 0 is not defined, but 1,2 and 3 are. The values in the table are not the SVC number but they are an index. The vector table would have A(SVC02, SVC03, SVC01). The order of the pointers in the vector table correspond with the values in the first level table.
The vector table entry also indicates if the SVC routine should be called enabled or disabled for interrupts. If the high-order bit in the address is one, the routine is called with interrupts disabled.
X’80’,VL3(SVC-Disabled) or X’00’,VL3(SVC-Enabled)
The first thing the SVC Interrupt Handler does is to look up the SVC in the first level table:
000000 8 TXXSVCIR CSECT , 000000 18CF 9 LR R12,R15 ESTABLISH 00000 10 USING TXXSVCIR,R12 BASE REGISTER 11 * 00000 12 USING @TCB,R4 13 * 000002 1FBB 14 SLR R11,R11 000004 BFB3 401A 0001A 15 ICM R11,B'0011',TCBPSW+2 GET INTERRUPT CODE 000008 58A0 0014 00014 16 L R10,20 MVT 00000C 58A0 A014 00014 17 L R10,MVTSVCTB-@MVT(,R10) POINT TO SVC TABLE 000010 5AB0 A000 00000 18 A R11,0(,R10) SVC TABLE INDEX 000014 1F11 19 SLR R1,R1 000016 4310 B000 00000 20 IC R1,0(,R11) GET INDEX PTR 00001A 1211 21 LTR R1,R1 CHECK IF DEFINED 00001C 4780 C084 00084 22 BZ BADSVC NO - BAD SVC 23 * 000020 8910 0002 00002 24 SLL R1,2 MULTIPLY BY 4 000024 58B0 A004 00004 25 L R11,4(,R10) SVC VECTOR TABLE 000028 1AB1 26 AR R11,R1 INDEX INTO TABLE
The SVC interrupt number is obtained from the SVC Old PSW that was stored in the TCB. This value is used as an index into the first level table. If the indexed byte is zero the SVC is not defined. The indexed byte is then multiplied by 4 to become an index into the vector table.
00002A 4110 0050 00050 28 LA R1,RBLEN GET LENGTH OF RB 00002E BF18 C0A0 000A0 29 ICM R1,B'1000',=AL1(128) SP=128 30 @CALL GETMAIN GETMAIN STORAGE 000032 58F0 0014 00014 31+ L R15,20 MVT ADDRESS 000036 58F0 F018 00018 32+ L R15,MVTGMAIN-@MVT(,R15) ROUTINE ADDRESS 00003A 05EF 33+ BALR R14,R15 00003C 12FF 34 LTR R15,R15 CHECK RC 00003E 4770 C094 00094 35 BNZ GETMFAIL BRANCH IF FAILED
A new RB is now needed to create a new execution environment for the SVC code to run under while preserving the calling environment. A branch entry to GETMAIN is made to allocate the storage for the new RB.
000042 1851 37 LR R5,R1 COPY ADDRESS OF NEW RB 00000 38 USING @RB,R5 39 * 000044 D74F 5000 5000 00000 00000 40 XC 0(RBLEN,R5),0(R5) CLEAR STORAGE 00004A D207 5008 4018 00008 00018 41 MVC RBPSW,TCBPSW COPY IN CURRENT PSW 000050 D23F 5010 4020 00010 00020 42 MVC RBREGS,TCBREGS COPY IN REGISTERS
The storage for the new RB is cleared and the registers and PSW from the TCB are copied into the new RB.
000056 5810 4008 00008 44 L R1,TCBRB CURRENT RB PTR 00005A 5010 5000 00000 45 ST R1,RBNEXT CHAIN ON 00005E 5050 4008 00008 46 ST R5,TCBRB NEW RB 000062 5810 5014 00014 47 L R1,RBREG1 RESTORE REG 1 000066 5800 5010 00010 48 L R0,RBREG0 RESTORE REG 0
The new RB is added to the top of the RB chain. The RB chain is a push-down stack with the TCB pointing to the top of the stack.
00006A 58F0 B000 00000 50 L R15,0(,R11) GET SVC EP 00006E 58E0 0014 00014 51 L R14,20 MVT ADDRESS 000072 58E0 E024 00024 52 L R14,MVTEXIT-@MVT(,R14) SET EXIT AS RETURN ADDR
Now the SVC routine entry point is loaded into Register 15. The Exit Routine address is loaded into Register 14 as the return point from the SVC routine.
000076 9180 B000 00000 54 TM 0(R11),X'80' DISABLED EXECUTION 00007A 4710 C082 00082 55 BO SVCHND00 YES - BRANCH 56 * 00007E 8000 C0A1 000A1 57 SSM =X'FF' ENABLE FOR INTERRUPTS 58 * 000082 59 SVCHND00 DS 0H 000082 07FF 60 BR R15
Now the high-level bit in the vector entry is checked to determine if the SVC routine should be called with interrupts enabled or disabled. If the bit is not set, indicating interrupts enabled, the Set System Mask (SSM) instruction is used to enable interrupts.
000084 63 BADSVC DS 0F 000084 4110 0FFF 00FFF 64 LA R1,X'FFF' ABEND CODE 65 @CALL ABEND CALL ABEND 000088 58F0 0014 00014 66+ L R15,20 MVT ADDRESS 00008C 58F0 F020 00020 67+ L R15,MVTABEND-@MVT(,R15) ROUTINE ADDRESS 000090 05EF 68+ BALR R14,R15 70 * 000094 71 GETMFAIL DS 0F 000094 8200 C098 00098 72 LPSW ERRPSW ERROR - OUT OF MEMORY 73 * 000098 76 DS 0D 000098 0002000000EE0004 77 ERRPSW DC AL1(0,2,0,0),A(@E@SVCM) DISABLED WAIT PSW
Finally if the SVC is not defined in the SVC table the Abend routine is called (actually branched to since it does not return to the caller). The abend code is set to x’FFF’ to indicate an undefined SVC. If the Getmain request failed a disabled wait PSW is loaded.
[Next – TXXEXIT – Exit Routine]