{"id":341,"date":"2012-01-04T09:33:20","date_gmt":"2012-01-04T15:33:20","guid":{"rendered":"http:\/\/tommysprinkle.com\/txxos\/?p=341"},"modified":"2021-04-17T18:22:58","modified_gmt":"2021-04-17T23:22:58","slug":"svc-interrupt-handler","status":"publish","type":"post","link":"https:\/\/tommysprinkle.com\/txxos\/?p=341","title":{"rendered":"TXXSVCIR &#8211; SVC Interrupt Handler"},"content":{"rendered":"<p>SVC routines are defined in a SVC Table Module. \u00a0The SVC table is a two-level index to the SVC routine. \u00a0The first level is a 256 byte table. \u00a0Each byte corresponds to a SVC number. If the corresponding byte in the table is zero then the SVC routine is not defined. \u00a0If the value is non-zero it is an index into a vector table that points to the SVC routine.<\/p>\n<p>For example the first level table of x&#8217;00 02 03 01 00&#8230;&#8217; would define three SVC&#8217;s. \u00a0SVC 0 is not defined, but 1,2 and 3 are. \u00a0The values in the table are not the SVC number but they are an index. \u00a0The vector table would have A(SVC02, SVC03, SVC01). \u00a0The order of the pointers in the vector table correspond with the values in the first level table.<\/p>\n<p>The vector table entry also indicates if the SVC routine should be called enabled or disabled for interrupts. \u00a0If the high-order bit in the address is one, the routine is called with interrupts disabled.<\/p>\n<p>X&#8217;80&#8217;,VL3(SVC-Disabled) \u00a0or X&#8217;00&#8217;,VL3(SVC-Enabled)<\/p>\n<p>The first thing the SVC Interrupt Handler does is to look up the SVC in the first level table:<\/p>\n<pre>000000                                8 TXXSVCIR CSECT ,\r\n000000 18CF                           9          LR    R12,R15            ESTABLISH\r\n                            00000    10          USING TXXSVCIR,R12                BASE REGISTER\r\n                                     11 *\r\n                            00000    12          USING @TCB,R4\r\n                                     13 *\r\n000002 1FBB                          14          SLR   R11,R11\r\n000004 BFB3 401A      0001A          15          ICM   R11,B'0011',TCBPSW+2   GET INTERRUPT CODE\r\n000008 58A0 0014      00014          16          L     R10,20                 MVT\r\n00000C 58A0 A014      00014          17          L     R10,MVTSVCTB-@MVT(,R10)  POINT TO SVC TABLE\r\n000010 5AB0 A000      00000          18          A     R11,0(,R10)            SVC TABLE INDEX\r\n000014 1F11                          19          SLR   R1,R1\r\n000016 4310 B000      00000          20          IC    R1,0(,R11)             GET INDEX PTR\r\n00001A 1211                          21          LTR   R1,R1                  CHECK IF DEFINED\r\n00001C 4780 C084      00084          22          BZ    BADSVC                 NO - BAD SVC\r\n                                     23 *\r\n000020 8910 0002      00002          24          SLL   R1,2                   MULTIPLY BY 4\r\n000024 58B0 A004      00004          25          L     R11,4(,R10)            SVC VECTOR TABLE\r\n000028 1AB1                          26          AR    R11,R1                 INDEX INTO TABLE<\/pre>\n<p>The SVC interrupt number is obtained from the SVC Old PSW that was stored in the TCB. \u00a0This value is used as an index into the first level table. \u00a0If the indexed byte is zero the SVC is not defined. \u00a0The indexed byte is then\u00a0multiplied\u00a0by 4 to become an index into the vector table.<\/p>\n<pre>00002A 4110 0050      00050          28          LA    R1,RBLEN               GET LENGTH OF RB\r\n00002E BF18 C0A0      000A0          29          ICM   R1,B'1000',=AL1(128)   SP=128\r\n                                     30          @CALL GETMAIN                GETMAIN STORAGE\r\n000032 58F0 0014      00014          31+         L     R15,20             MVT ADDRESS\r\n000036 58F0 F018      00018          32+         L     R15,MVTGMAIN-@MVT(,R15) ROUTINE ADDRESS\r\n00003A 05EF                          33+         BALR  R14,R15\r\n00003C 12FF                          34          LTR   R15,R15                CHECK RC\r\n00003E 4770 C094      00094          35          BNZ   GETMFAIL                 BRANCH IF FAILED<\/pre>\n<p>A new RB is now needed to create a new execution environment for the SVC code to run under while preserving the calling environment. \u00a0A branch entry to GETMAIN is made to allocate the storage for the new RB.<\/p>\n<pre>000042 1851                          37          LR    R5,R1                  COPY ADDRESS OF NEW RB\r\n                            00000    38          USING @RB,R5\r\n                                     39 *\r\n000044 D74F 5000 5000 00000 00000    40          XC    0(RBLEN,R5),0(R5)      CLEAR STORAGE\r\n00004A D207 5008 4018 00008 00018    41          MVC   RBPSW,TCBPSW           COPY IN CURRENT PSW\r\n000050 D23F 5010 4020 00010 00020    42          MVC   RBREGS,TCBREGS         COPY IN REGISTERS<\/pre>\n<p>The storage for the new RB is cleared and the registers and PSW from the TCB are copied into the new RB.<\/p>\n<pre>000056 5810 4008      00008          44          L     R1,TCBRB               CURRENT RB PTR\r\n00005A 5010 5000      00000          45          ST    R1,RBNEXT              CHAIN ON\r\n00005E 5050 4008      00008          46          ST    R5,TCBRB                       NEW RB\r\n000062 5810 5014      00014          47          L     R1,RBREG1              RESTORE REG 1\r\n000066 5800 5010      00010          48          L     R0,RBREG0              RESTORE REG 0<\/pre>\n<p>The new RB is added to the top of the RB chain. \u00a0The RB chain is a push-down stack with the TCB pointing to the top of the stack.<\/p>\n<pre>00006A 58F0 B000      00000          50          L     R15,0(,R11)            GET SVC EP\r\n00006E 58E0 0014      00014          51          L     R14,20                 MVT ADDRESS\r\n000072 58E0 E024      00024          52          L     R14,MVTEXIT-@MVT(,R14) SET EXIT AS RETURN ADDR<\/pre>\n<p>Now the SVC routine entry point is loaded into Register 15. \u00a0The Exit Routine address is loaded into Register 14 as the return point from the SVC routine.<\/p>\n<pre>000076 9180 B000      00000          54          TM    0(R11),X'80'           DISABLED EXECUTION\r\n00007A 4710 C082      00082          55          BO    SVCHND00               YES - BRANCH\r\n                                     56 *\r\n00007E 8000 C0A1      000A1          57          SSM   =X'FF'                 ENABLE FOR INTERRUPTS\r\n                                     58 *\r\n000082                               59 SVCHND00 DS    0H\r\n000082 07FF                          60          BR    R15<\/pre>\n<p>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. \u00a0If the bit is not set, indicating interrupts enabled, the Set System Mask (SSM) instruction is used to enable interrupts.<\/p>\n<pre>000084                               63 BADSVC   DS    0F\r\n000084 4110 0FFF      00FFF          64          LA    R1,X'FFF'          ABEND CODE\r\n                                     65          @CALL ABEND              CALL ABEND\r\n000088 58F0 0014      00014          66+         L     R15,20             MVT ADDRESS\r\n00008C 58F0 F020      00020          67+         L     R15,MVTABEND-@MVT(,R15) ROUTINE ADDRESS\r\n000090 05EF                          68+         BALR  R14,R15\r\n                                     70 *\r\n000094                               71 GETMFAIL DS    0F\r\n000094 8200 C098      00098          72          LPSW  ERRPSW             ERROR - OUT OF MEMORY\r\n                                     73 *\r\n000098                               76          DS    0D\r\n000098 0002000000EE0004              77 ERRPSW   DC    AL1(0,2,0,0),A(@E@SVCM)      DISABLED WAIT PSW<\/pre>\n<p>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). \u00a0The abend code is set to x&#8217;FFF&#8217; to indicate an undefined SVC. \u00a0If the Getmain request failed a disabled wait PSW is loaded.<\/p>\n<p>[Next &#8211; <a title=\"TXXEXIT \u2013 Exit Routine\" href=\"http:\/\/tommysprinkle.com\/txxos\/?p=344\">TXXEXIT &#8211; Exit Routine<\/a>]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>SVC routines are defined in a SVC Table Module. \u00a0The SVC table is a two-level index to the SVC routine. \u00a0The first level is a 256 byte table. \u00a0Each byte corresponds to a SVC number. If the corresponding byte in &hellip; <a href=\"https:\/\/tommysprinkle.com\/txxos\/?p=341\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"template-page-builder-no-sidebar.php","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-341","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1CPQT-5v","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=341"}],"version-history":[{"count":5,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/341\/revisions"}],"predecessor-version":[{"id":481,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/341\/revisions\/481"}],"wp:attachment":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}