.TITLE USER_SYS_DISP - user system service dispatcher .IDENT 'V01-000' ;++ ; Facility: ; User Written System Services ; ; Abstract: ; This module contains a dispatcher for user written system services ; based on the example in SYS$SYSROOT:[SYSHLP.EXAMPLES]. The explanatory ; comments in that example have been deleted, but the code remains ; essentially the same except for the service routines. ; ; The following routines are used to obtain timing statistics with ; greater than 10 ms resolution. ; ; The ARC$GETTIME routine reads the microsecond real-time ; clock ICR register, adds it to the software time, and returns ; microsecond resolution time stats in 64-bit system time format. ; ; The ARC$DIFFTIME routine returns the difference between ; two system times in microseconds. ; ; Author: Mark Paulk ; System Development Corporation ; 4810 Bradford Blvd NW ; Huntsville, AL 35805 ; Date: 16 September 1983 ;-- .SBTTL Declarations and Equates ; ; Include Files ; .LIBRARY "SYS$LIBRARY:LIB.MLB" ; Macro library for system structure ; definitions ; ; Macro Definitions ; ; DEFINE_SERVICE - A macro to make the appropriate entries in several ; different PSECTs required to define an EXEC or KERNEL ; mode service. These include the transfer vector, ; the case table for dispatching, and a table containing ; the number of required arguments. ; ; DEFINE_SERVICE Name,Number_of_Arguments,Mode ; .MACRO DEFINE_SERVICE,NAME,NARG=0,MODE=KERNEL .PSECT $$$TRANSFER_VECTOR,PAGE,NOWRT,EXE,PIC .ALIGN QUAD ; Align entry points for speed and style .TRANSFER NAME ; Define name as universal symbol for entry .MASK NAME .IF IDN MODE,KERNEL CHMK # ; Change to kernel mode and execute RET ; Return KERNEL_COUNTER=KERNEL_COUNTER+1 ; Advance counter .PSECT KERNEL_NARG,BYTE,NOWRT,EXE,PIC .BYTE NARG ; Define number of required arguments .PSECT USER_KERNEL_DISP1,BYTE,NOWRT,EXE,PIC .WORD 2+NAME-KCASE_BASE ; Make entry in kernel mode CASE table .IFF CHME # ; Change to executive mode and execute RET ; Return EXEC_COUNTER=EXEC_COUNTER+1 ; Advance counter .PSECT EXEC_NARG,BYTE,NOWRT,EXE,PIC .BYTE NARG ; Define number of required arguments .PSECT USER_EXEC_DISP1,BYTE,NOWRT,EXE,PIC .WORD 2+NAME-ECASE_BASE ; Make entry in exec mode CASE table .ENDC ; .ENDM DEFINE_SERVICE ; ; ; Equated Symbols ; $PHDDEF ; Define process header offsets $PLVDEF ; Define PLV offsets and values $PRDEF ; Define processor register numbers ; ; Initialize counters for change mode dispatching codes ; KERNEL_COUNTER=0 ; Kernel code counter EXEC_COUNTER=0 ; Exec code counter ; ; Own Storage ; .PSECT KERNEL_NARG,BYTE,NOWRT,EXE,PIC KERNEL_NARG: ; Base of byte table containing the ; number of required arguments. .PSECT EXEC_NARG,BYTE,NOWRT,EXE,PIC EXEC_NARG: ; Base of byte table containing the ; number of required arguments. ; .PAGE .SBTTL Transfer Vector and Service Definitions define_service ARC$DIFFTIME,3,EXEC ; Service to get system time difference in us define_service ARC$GETTIME,2,KERNEL ; Service to get system time + microtime KCODE_BASE=-1024 ; Base CHMK code value for these services ECODE_BASE=-1024 ; Base CHME code value for these services .PSECT USER_SERVICES,PAGE,VEC,PIC,NOWRT,EXE .LONG PLV$C_TYP_CMOD ; Set type of vector to change mode dispatcher .LONG SYS$K_VERSION ; Identify system version .LONG KERNEL_DISPATCH-. ; Offset to kernel mode dispatcher .LONG EXEC_DISPATCH-. ; Offset to executive mode dispatcher .LONG 0 ; No user rundown service .LONG 0 ; Reserved. .LONG 0 ; No RMS dispatcher .LONG 0 ; Address check - PIC image ; .PAGE .SBTTL Kernel Mode Dispatcher ;++ ; Input Parameters: ; (SP) - Return address if bad change mode value ; R0 - Change mode argument value. ; R4 - Current PCB Address. (Therefore R4 must be specified in all ; register save masks for kernel routines.) ; AP - Argument pointer existing when the change ; mode instruction was executed. ; FP - Address of minimal call frame to exit ; the change mode dispatcher and return to ; the original mode. ;-- .PSECT USER_KERNEL_DISP0,BYTE,NOWRT,EXE,PIC KACCVIO: ; Kernel access violation MOVZWL #SS$_ACCVIO,R0 ; Set access violation status code RET ; and return KINSFARG: ; Kernel insufficient arguments. MOVZWL #SS$_INSFARG,R0 ; Set status code and RET ; return KNOTME: RSB ; RSB to forward request KERNEL_DISPATCH:: ; Entry to dispatcher MOVAB W^-KCODE_BASE(R0),R1 ; Normalize dispatch code value BLSS KNOTME ; Branch if code value too low CMPW R1,#KERNEL_COUNTER ; Check high limit BGEQU KNOTME ; Branch if out of range ; ; The dispatch code has now been verified as being handled by this dispatcher, ; now the argument list will be probed and the required number of arguments ; verified. ; MOVZBL W^KERNEL_NARG[R1],R1 ; Get required argument count MOVAL @#4[R1],R1 ; Compute byte count including arg count IFNORD R1,(AP),KACCVIO ; Branch if arglist not readable CMPB (AP),W^[R0] ; Check for required number BLSSU KINSFARG ; of arguments CASEW R0,- ; Case on change mode - ; argument value #KCODE_BASE,- ; Base value # ; Limit value (number of entries) KCASE_BASE: ; Case table base address for DEFINE_SERVICE ; ; Case table entries are made in the PSECT USER_KERNEL_DISP1 by ; invocations of the DEFINE_SERVICE macro. The three PSECTS, ; USER_KERNEL_DISP0,1,2 will be abutted in lexical order at link-time. ; .PSECT USER_KERNEL_DISP2,BYTE,NOWRT,EXE,PIC RSB ; Return to reject out of ; range value ; .PAGE .SBTTL Executive Mode Dispatcher ;++ ; Input Parameters: ; (SP) - Return address if bad change mode value ; R0 - Change mode argument value. ; AP - Argument pointer existing when the change ; mode instruction was executed. ; FP - Address of minimal call frame to exit ; the change mode dispatcher and return to ; the original mode. ;-- .PSECT USER_EXEC_DISP0,BYTE,NOWRT,EXE,PIC EACCVIO: ; Exec access violation MOVZWL #SS$_ACCVIO,R0 ; Set access violation status code RET ; and return EINSFARG: ; Exec insufficient arguments. MOVZWL #SS$_INSFARG,R0 ; Set status code and RET ; return ENOTME: RSB ; RSB to forward request EXEC_DISPATCH:: ; Entry to dispatcher MOVAB W^-ECODE_BASE(R0),R1 ; Normalize dispatch code value BLSS ENOTME ; Branch if code value too low CMPW R1,#EXEC_COUNTER ; Check high limit BGEQU ENOTME ; Branch if out of range ; ; The dispatch code has now been verified as being handled by this dispatcher, ; now the argument list will be probed and the required number of arguments ; verified. ; MOVZBL W^EXEC_NARG[R1],R1 ; Get required argument count MOVAL @#4[R1],R1 ; Compute byte count including arg count IFNORD R1,(AP),EACCVIO ; Branch if arglist not readable CMPB (AP),W^[R0] ; Check for required number BLSSU EINSFARG ; of arguments CASEW R0,- ; Case on change mode - ; argument value #ECODE_BASE,- ; Base value # ; Limit value (number of entries) ECASE_BASE: ; Case table base address for DEFINE_SERVICE ; ; Case table entries are made in the PSECT USER_EXEC_DISP1 by ; invocations of the DEFINE_SERVICE macro. The three PSECTS, ; USER_EXEC_DISP0,1,2 will be abutted in lexical order at link-time. ; .PSECT USER_EXEC_DISP2,BYTE,NOWRT,EXE,PIC RSB ; Return to reject out of ; range value ; .PAGE .SBTTL Difference System Times ;++ ; Functional Description: ; This routine calculates the difference between two quadword ; system times and returns the difference in microseconds. ; ; Input Parameters: ; 04(AP) - Address of high time ; 08(AP) - Address of low time ; 12(AP) - Address to return time difference ; R4 - PCB address of current process ; ; Output Parameters: ; R0 - Completion Status code ;-- .ENTRY ARC$DIFFTIME,^M ; Entry definition ifnord #8,@4(ap),10$ ; check for access violations ifnord #8,@8(ap),10$ ifnowrt #4,@12(ap),10$ movl 12(ap),r1 ; get address of result in register movq 8(ap),r2 ; place subtrahend in r2,r3 movl @4(ap),r5 ; initialize minuend address register subl (r2),r5 ; subtract sbwc 4(r2),r6 divl3 #10,r5,(r1) ; change from 100 ns to 1 us resolution ; assume no significant bits past 32 MOVZWL #SS$_NORMAL,R0 ; Set normal completion status RET ; and return 10$: MOVZWL #SS$_ACCVIO,R0 ; Indicate access violation RET ; ; .PAGE .SBTTL Get System Time ;++ ; Input Parameters: ; 04(AP) - Address to return system time + ICR value ; R4 - Address of current PCB ; ; Output Parameters: ; R0 - Completion Status Code ;-- .ENTRY ARC$GETTIME,^M MOVL 4(AP),R1 ; Get address to store time of day register IFNOWRT #8,(R1),10$ ; Branch if not writable 5$: movq g^exe$gq_systime,(r1) ; get software clock value mfpr #pr$_icr,r2 ; get micro clock cmpl g^exe$gq_systime,(r1) ; confirm time was not on tick boundary bneq 5$ movl 8(ap),r5 ; get offset value (NICR is write only) bneq 6$ ; default to 10000 (standard value) movl #10000,r5 6$: addl2 r5,r2 ; offset for start at negative time mull2 #10,r2 ; change us to 100 ns addl2 r2,(r1) ; add hardware, software times adwc #0,4(r1) MOVZWL #SS$_NORMAL,R0 ; Set normal completion status RET ; and return 10$: MOVZWL #SS$_ACCVIO,R0 ; Indicate access violation RET ; .END