!TITLE Calling Director Procedures ! This chapter describes how a subsystem acquires access to the Director ! procedures by forming System Call descriptors from the pairs of values ! (i,j) associated with the identifiers of the procedures forming the ! Director interface. Knowledge of the 2900 Series System Call mechanism ! (Ref. 5) is assumed. The fields SC IDENS AD, SC IDENS and SCT DATE in ! the record format UINFF are relevant. SC IDENS AD is the address of a ! record array whose elements have the following format: ! ! %recordformat SC IDF (%string(31)IDEN, %integer I, J) ! ! SC IDENS is the number of elements in the record array. ! ! In the Edinburgh standard object module format, calls to external ! routines in modules compiled separately involve a machine instruction ! CALL with a 64-bit operand which is a descriptor descriptor. If the ! operand instead is a System Call descriptor then the System Call ! mechanism is invoked, providing controlled access to higher-privilege ! procedures (such as the Director procedures). ! ! When a version of Director is created, a list of identifiers specifying ! permitted procedure entry points is referenced, a new System Call Table ! entry is created, and the identifier and (i,j) values are placed in the ! record array described above. The task of a subsystem requiring access ! to a Director procedure is thus that of selecting the correct (i,j) ! pair from the record array, creating a System Call descriptor ! containing the (i,j) values, and making that descriptor the operand of ! a CALL instruction. Subsystem writers using the Edinburgh standard ! object module format should consult Ref. 6. ! ! The field SCT DATE has been provided to remove the need for a ! subsystem to satisfy its references to Director procedures dynamically, ! and to enable them to be fixed up when the subsystem is created. ! SCT DATE is a unique identifier associated with a given version of ! Director. If the SCT DATE current at the time a subsystem is entered ! is identical to that current when the subsystem was created, then ! clearly the (i,j) values and entry identifiers obtaining when the ! subsystem was created will serve for invocations of the new subsystem. ! The new subsystem will of course have to retain code for fixing up ! Director references dynamically should it find that SCT DATE is ! different from that current when it was created. !<DNEWINWARDCALL externalintegerfn DNEW INWARD CALL(integer KEY, DR0, DR1, integername I, J) ! ! A new System call table entry is created for an inward call to the ! current ACR (ie the ACR of the program calling this procedure). ACCESS ! KEY specifies the ACR at and below which access is allowed to the ! specified procedure, and DR0, DR1 is a descriptor descriptor to the ! entry descriptor for the procedure. The i and j values specifying the ! System call table entry are returned in I and J. ! ! Entries created by this procedure are cumulative and cannot ! subsequently be removed from the System call table. !> ! ADDS A NEW ENTRY TO THE "I=2" "VERTICAL" VECOTR, FOR AN ! INWARD CALL INTEGER TOP J2 VALUE,J2 VECTOR ADDRESS RECORD (SCTIF)ARRAYFORMAT SCTIAF(0:TOP I VALUE) RECORD (SCTIF)ARRAYNAME SCTI; ! 2 WORDS PER ENTRY RECORD (SCTJF)ARRAYFORMAT SCTJAF(0:TOP J VALUE) RECORD (SCTJF)ARRAYNAME SCTJ INTEGER F ! F = IN2(48) -> DOUT UNLESS F = 0 ! SCTI==ARRAY(SCTIAD,SCTIAF) J2 VECTOR ADDRESS=(ADDR(UINF_UEND)+15) & (¬15) SCTJ==ARRAY(J2 VECTOR ADDRESS,SCTJAF) TOP J2 VALUE=SCTI(2)_DR0 & X'3FFFF' ! F = 54 -> DOUT IF TOP J2 VALUE<=1; ! NO OUTWARD CALL SET UP ! F = 55 -> DOUT IF TOP J2 VALUE>=255; ! SCT FULL ! F = 45 -> DOUT IF VAL(ADDR(I), 4, 1, D CALLERS PSR) = NO -> DOUT IF VAL(ADDR(J), 4, 1, D CALLERS PSR) = NO I = 2 ! F = 8 -> DOUT UNLESS KEY>=D CALLERS ACR ! F = 0 J=TOP J2 VALUE; ! J-VALUE BEING SUPPLIED SCTI(2)_DR0=VEC128 ! (TOP J2 VALUE+1) SCTJ(TOP J2 VALUE)_TYPE=X'80000000' ! (KEY)<<20 SCTJ(TOP J2 VALUE)_ACR=D CALLERS ACR<<20 SCTJ(TOP J2 VALUE)_DRDR0=DR0 SCTJ(TOP J2 VALUE)_DRDR1=DR1 DOUT: RESULT = OUT(F, "") END ; ! DNEW INWARD CALL ! !----------------------------------------------------------------------- ! !<DNEWOUTWARDCALL externalintegerfn DNEW OUTWARD CALL(integer NEWACR, EMAS, NEW STACK SEG, DR0, DR1, integername I, J) ! ! A System call table entry is created for an outward call, according ! to Ref. 8. In the entry created, KEY is set equal to the ACR of the ! program calling this function, E is set to 0 or 1 according to the ! value of EMAS. Target SSN is set with the value of NEW STACK SEG, which ! must be even and in the range 34 to HISEG. DR0 and DR1 should supply the ! descriptor descriptor to the required entry descriptor for the ! procedure to be outward-called. I and J are set on return to the i and ! j values to be used in making the outward call. ! ! Only one of these System call table entries will be extant at any time ! a further call of DNEW OUTWARD CALL will cause the previous outward ! call entry to be lost. ! ! The descriptor supplied is not checked. !> ! CREATE NEW (OR OVER-WRITE EXISTING) SC TABLE ENTRY (I=2, J=1) FOR ! A (SINGLE) OUTWARD CALL. LOCATION OF THE "VERTICAL VECTOR" BEING ! CREATED (OR WRITTEN INTO) IS CURRENTLY EPAGE 2 (0,1M2,..) OF LOCAL ! SEGMENT 8. ROOM FOR 256 ENTRIES IN A PAGE - PLENTY. INTEGER TOP J2 VALUE,J2 VECTOR ADDRESS,CALLERS PRIV INTEGER F RECORD (SCTIF)ARRAYFORMAT SCTIAF(0:TOP I VALUE) RECORD (SCTIF)ARRAYNAME SCTI; ! 2 WORDS PER ENTRY RECORD (SCTJF)ARRAYFORMAT SCTJAF(0:TOP J VALUE) RECORD (SCTJF)ARRAYNAME SCTJ ! F = IN2(49) -> DOUT UNLESS F = 0 ! SCTI == ARRAY(SCTIAD, SCTIAF) J2 VECTOR ADDRESS = (ADDR(UINF_UEND)+15) & (¬15) SCTJ == ARRAY(J2 VECTOR ADDRESS, SCTJAF) TOP J2 VALUE = SCTI(2)_DR0 & X'3FFFF' UNLESS 0 < TOP J2 VALUE < 256 START ; ! FIRST TIME ONLY ! SET UP ENTRY 2 IN "HORIZONTAL" VECTOR SCTI(2)_DR0 = VEC128 ! 2 SCTI(2)_DR1 = ADDR(SCTJ(0)_TYPE) SCTJ(0) = 0; ! ZERO ZEROTH ENTRY IN "VERTICAL" VECTOR FINISH ! F = 45 -> DOUT IF VAL(ADDR(I), 4, 1, D CALLERS PSR) = NO -> DOUT IF VAL(ADDR(J), 4, 1, D CALLERS PSR) = NO I = 2; ! VALUE IF SUCCESSFUL J = 1 ! F = 8 CALLERS PRIV = D CALLERS PSR & X'00040000'; ! PRIV BIT IN PSR -> DOUT UNLESS 15 >= NEWACR >= D CALLERS ACR -> DOUT UNLESS 0 <= EMAS <= 1 -> DOUT UNLESS NEW STACK SEG&1 = 0 -> DOUT UNLESS 34 <= NEW STACK SEG <= UINF_HISEG -> DOUT UNLESS SST(NEW STACK SEG+1) = ENDSST ! F = 0 ! MAKE/OVER-WRITE ENTRY 2,1 SCTJ(1)_TYPE = X'40000000' ! (D CALLERS ACR<<20) ! (EMAS<<16) ! NEW STACK SEG SCTJ(1)_ACR = NEWACR<<20 ! CALLERS PRIV SCTJ(1)_DRDR0 = DR0 SCTJ(1)_DRDR1 = DR1 DOUT: RESULT = OUT(F, "") END ; ! DNEW OUTWARD CALL ! !----------------------------------------------------------------------- ! !<DNOMINATESTACK externalintegerfn DNOMINATE STACK(integer SEG) ! ! This function is provided to satisfy requirement number 4 of Ref. 8, ! by calling the OUT12 (defined in Ref. 9) to notify the Local Controller ! to enable it to supply the locked-down SSN+1. !> INTEGER J RECORD (PARMF)NAME P ! J = IN2(52) -> DOUT UNLESS J = 0 ! P==RECORD(OUTPAD) J = 8 ->DOUT UNLESS SEG&1=0 AND SST(SEG+1)=ENDSST P=0 P_P1=3; ! STACK NUMBER P_P2=SEG IF SEG>0 START *OUT_12; ! NOMINATE STACK FINISH ELSE START ! *OUT_13 FINISH J=P_DEST; ! 0=SUCCESS, -1 = FAIL J=36 IF J<0 DOUT: RESULT = OUT(J, "I") END ; ! DNOMINATE STACK ! !----------------------------------------------------------------------- ! !<DPLUGINJVECTOR externalintegerfn DPLUGIN JVECTOR(integername IVALUE, integer ADDRESS, TOP ENTRY) ! ! ADDRESS points to the zeroth element of a record array (0:TOP ENTRY), ! format (integer TYPE, ACR, DR0, DR1), which is to be a new ("vertical") ! J-vector in the System Call table. If the call is successful, IVALUE ! is set to the I-value to be used in subsequent System Calls accessing ! the vector. The procedure allows a subsystem to cause outward calls ! and to allow users' programs to do inward calls to the subsystem. The ! address must lie in a non-write-access file, readable at Director's ! ACR. No target ACR in any of the entries may be less than the ! caller's ACR, nor may the target PRIV bit be set. After a successful ! call, the file may not be disconnected (except by calling DSTOP), nor ! may its size or access mode be changed (error result 84 is returned if ! attempt is made). The vector may contain a maximum of 512 System Call ! entries. If the vector exceeds this limit the error result 8 is ! returned. Subsequent calls of DPLUGIN JVECTOR cause the previously ! plugged-in vector to be forgotten (though the file still may not be ! disconnected). !> INTEGER J, FLAG, APF, SLAVED, NOTDRUM, SEG, CP RECORD (SCTIF)ARRAYFORMAT SCTIAF(0:TOP I VALUE) RECORD (SCTIF)ARRAYNAME SCTI; ! 2 WORDS PER ENTRY RECORD (SCTJF)ARRAYFORMAT SCTJAF(0:TOP J VALUE) RECORD (SCTJF)ARRAYNAME SCTJ FLAG = IN2(61) -> RES UNLESS FLAG = 0 ! FLAG = 8 -> RES UNLESS 1<TOP ENTRY<=TOP J VALUE SEG = ADDRESS >> 18 -> RES UNLESS LOUSEG<=SEG<=HISEG ! FLAG=45; ! area not accessible -> RES IF VAL(ADDRESS,(TOP ENTRY+1)<<4,0,0)=0 ! FLAG=8 IVALUE=4; ! (if successful) SCTI==ARRAY(SCTIAD,SCTIAF) SCTJ==ARRAY(ADDRESS,SCTJAF) ! validate all entries: TARCGET ACR>= subsys acr ! and PRIV not set. J=1 WHILE J<=TOP ENTRY CYCLE IF SCTJ(J)_ACR&PRIV BIT#0 OR C (SCTJ(J)_ACR>>20)&15<DCALLERS ACR THEN -> RES J=J+1 REPEAT ! Check also that seg is not write-able GIVE APF(APF,NOTDRUM,SLAVED,SEG) IF (APF>>4)&15#0 THEN -> RES ! Finally mark file not to be disconnected (until DSTOP ! called) nor to be changed in size nor changed in access. CP=DIROWN_CPOINT(SEG) UNLESS CP>RESERVED THEN -> RES DIROWN_CONLIST(CP)_NODISCO = 1 SCTI(IVALUE)_DR0=VEC128 ! (TOP ENTRY+1) SCTI(IVALUE)_DR1=ADDRESS FLAG=0 RES: RESULT = OUT(FLAG, "") END ; ! DPLUGIN JVECTOR ! !-------------------end-of-included-text--------------------------------- !