From:	STAR::WCLOGHER "Bill Clogher 381-0684 ZK03-4/U06 (B11)  03-Mar-1997 1310 -0500"  3-MAR-1997 13:14:24.77
To:	STAR::EVERHART
CC:	WCLOGHER
Subj:	I need help building this special code into PKZ driver... and Tom elected you a potential candidate...

Glen,
	Here's tom's response to my mail re: help I need to build
	some special code into a driver...

bill
>>    #2           3-MAR-1997 13:06:07.14                                  NEWMAIL
>>From:   STAR::COUGHLAN     "Tom"
>>To:     STAR::WCLOGHER
>>CC:
>>Subj:   RE: I need help building this special code into PKZ driver...
>>
>>Try Glenn first. If you can't get him, try Sue or Dave.

...Any chance of your helping me with this?

bill




From:	STAR::WCLOGHER "Bill Clogher 381-0684 ZK03-4/U06 (B11)  03-Mar-1997 1049 -0500"  3-MAR-1997 10:54:20.03
To:	STAR::COUGHLAN
CC:	WCLOGHER
Subj:	I need help building this special code into PKZ driver...

Tom,
	Bob Brassard forwarded this routine to me. I'm supposed to use in
	testing the PKZdriver (XMI) with big memory on the TurboLaser tomorrow.

	The code is to be built with the driver.  I don't know how to build
	drivers, etc, etc.  I need someone to build this into the driver for
	me. I cannot tell if the code is self-explanatory, but whoever
	builds it could speak with Bob Brassard for details.  I will be
	using X6C7-SSB the SSB version of Gryphon to do my testing, so
	that's what I would need the driver built for.

	Whom should I harass to help me with this?

bill



From:	EVMS::BRASSARD "Bob B.,381-1462,CIPCA DVT  27-Feb-1997 1605 -0500" 27-FEB-1997 16:04:43.39
To:	STAR::WCLOGHER,STAR::BELLOWS
CC:	
Subj:	RESERVE_MEMORY & POOL_DRAIN TEST CODE; EMBED IN DRIVER BEFORE ALLOCATING NPAGEDYN CONTROL STRUCTURES (I.E., CTRL/UNIT-INIT ROUTINES); RUNS AT IPL-8 !!

        .SBTTL  -     SCSNP$RESERVE_MEM  - Reserve a block of PFNs

;	.TITLE	RESERVE_MEMORY - Routine to reserve a block of memory
;  	.IDENT	'XX-1'
;
;*******************************************************************************
;
; Digital Equipment Corporation and VMS Engineering assumes no responsibilty 
; for the use of this software. USE AT YOUR OWN AND YOUR SYSTEM'S RISK.
; This software is being supplied without support, be forwarned that it uses 
; internal interfaces to the VMS memory management sub-system.  These 
; interfaces may change without warning and this software may result in an 
; unbootable system.  This software will most likely need to be rebuilt
; for new versions of the OpenVMS AXP Operating System.
;
; If this software does render the system unbootable, you can disable loading
; of non-VMS execlets by clearing the low bit of the system parameter
; LOAD_SYS_IMAGES. This will allow the system to boot.
;
;*******************************************************************************
;
; ABSTRACT: Modified RESERVE_MEMORY (midnight tool from KERNEL Group) to
; remove PFNs from specified physical address ranges in 2 waves: 1st from 
; SYSGEN>VMSD3 (specified in bytes) to SYSGEN> USER3 (specified in 
; Megabytes, and shifted 13-bits for PFN #); and 2nd from SYSGEN> USER3 
; to USER4.  Removal is 
; accomplished by calling MMG$REM_PFN to mark PFN in use.  There is no
; record of PFNs for reclaiminig reserved PFNs: they are simply gone !!
;
; Controlling the memory allocation:
;
; Two system parameters control the allocation of physical memory:
; 
; USER3	- The ending physical address in Mbytes of 1st wave.
; 	  If you set this to 12, the allocation will end 
;         at the 12 Mbyte mark
;	  
; USER4 - the ending physical address in Mbytes of 2nd wave.
;
;	  If either parameter is 0, nothing is allocated. If the allocation
;	  fails because, either the memory doesn't exist or it's
;	  in use,  an error is returned; and the caller can simply
;	  continue although pool won't be forced into high memory.
;	  No attempt is made to return reserved memory to VMS.
;	  An error return simply means invalid input parameters,
;	  in which case no PFNs will be reserved for that wave.
;
;  Revision History:
;
;	XX-1	Bob Brassard			13-FEB-1997
;		Modify RESERVE_MEMORY to function as global routine
;		for inclusion around [DRIVER]SCSNPINIT Adapter-block
;		(ABLK) allocation function.  PFN removal is now broken
;		up into 2 waves, as signalled by R0 value. The 2 wave
;		reserve ranges are defined as SGN$GL_NPAGEDYN-to-USER3;
;		and SGN$GL_USER3-to-SGN$GL_USER4.
;
;	X-2	Doug Gordon			10-Oct-1996
;		Check for memory holes and skip them.  This version doesn't
;		care about pages in the requested range being in use.  All we
;		is to attempt to force the drivers to use high memory.
;
; 
;*******************************************************************************

	$PFNDEF				; get pfn database symbols
	$SSDEF				; status definitions

;	DECLARE_PSECT EXEC$INIT_CODE
;       DRIVER_CODE     $$$115_DRIVER

;	INITIALIZATION_ROUTINE RESERVE_MEM
       .enable lsb


	INPUTS:
		R1	- Indicator of 1st or 2nd wave of RESERVE_MEMORY
				  0 = 1ST WAVE
				><0 = 2ND WAVE  (Exa.: 1,-1)

		SGN$GL_VMSD3	- Starting phys. addrs (PA) in bytes for wave-1
		SGN$GL_USER3	- Ending PA (Mbs) of wave-1; Starting PA (Mbs) 
				  of wave-2; disables wave-1 or -2 if USER3=0
		SGN$GL_USER4	- Ending PA (Mbs) of wave-2; disables wave-2 
				  if USER4=0

	IMPLICIT INPUTS:

		SGN$GL_NPAGEDYN  - Default starting PA (bytes) if VMSD3=0
		MMG$GL_VA_TO_VPN - Shift count for PA (bytes) to PFN (8k page).
		MMG$GL_MAXPFN    - Max PFN # of physical memory.

	OUTPUTS:

		R0		- ss$_normal: Free-pages reserved.
				- ss$_insfrpgs: Range > MMG$GL_MAXPFN

        UNIVERSAL_JSB -
                NAME    =  SCSNP$RESERVE_MEM,-
                INPUT    = <R1               >,-
                OUTPUT   = <R0               >,-
                SCRATCH  = <R0,R1            >,-
                PRESERVE = <      R2,R3,R4,R5,R6,R7>

;scsnp$reserve_mem::
;	.call_entry output=<r0>

;	tstl	G^SCS$GL_BDLT		; Has another SCA port already
					; started and reserved memory ?
					; Note: RES_MEM called before 
					; SCS$INIT_BDLT ([CLUSTER]SCSXPORT)
;	bneq	45$			; Exit w/success if BDLT setup...
	addl3	#20,mmg$gl_va_to_vpn,r5 ; Get shift value, MBytes to PFN count

	tstl	R1			; 1st or 2nd wave ?
	BNEQ	10$			; Branch if 2nd wave

	; FIRST WAVE:  RESERVE FROM "END-O-POOL" to "USER3" (SYSGEN)

	movl	mmg$gl_va_to_vpn,r4	; convert to PFN #, since npagedyn
					; is in byte units
	movl	sgn$gl_vmsd3,R3		; Start PFN for 1st wave will now
					; be SYSGEN VMSD3.  Leftover INIT
					; PFNs prevent use of NPAGEDYN+BAP 
					; byte count to ensure himem 
					; expansion.
	bneq	8$			; No need to test value: always <>0
	movl	sgn$gl_npagedyn,R3	; Use NPAGEDYN byte count as start
					; PFN if VMSD3 not set, just to 
					; ensure we are not reserving from 
					; PFN # 0.
8$:
	ashl	r4,r3,r6		; Convert to starting PFN

	movl	sgn$gl_user3,r4		; Ending physical address in MBytes
					; of 1st wave.
	beql	45$			; no value, exit
	ashl	r5,r4,r4		; Convert to ending PFN
	brb	15$			; Go to common loop setup
	
	; SECOND WAVE:  RESERVE FROM "USER3" to "USER4" (SYSGEN)
10$:
	movl	sgn$gl_user3,r3		; Start PFN of 2nd wave = end of 1st
	beql	45$			; No value = invalid, exit
	ashl	r5,r3,r6		; Convert to starting PFN

	movl	sgn$gl_user4,r4		; Ending physical address in MBytes
					; of 2nd wave.
	beql	45$			; no value, exit
	ashl	r5,r4,r4		; Convert to ending PFN


; Now we go about marking the pages 'unavailable' so that VMS can't use 
; them. We don't care about bad pages, in-use pages or memory holes.

	ASSUME  PFN$C_FREPAGLST EQ 0

	; Common setup to RESERVE_MEM PFN "REMOVAL" LOOP......
15$:
	movl	r6,r0			; start pfn
;	addl3	r6,r4,r7		; get max pfn + 1
	movl	r4,r7			; Copy end PFN

	cmpl	r7,mmg$gl_maxpfn  	; greater than the maximum
	bgtr	50$			; exit with error	

	clrl    r2			; free list, list identifier

        LOCK    LOCKNAME=MMG,-          ; Lock MMG
                PRESERVE=YES,-          ;
                SAVIPL=-(SP)

	movl	r6,r0			; start pfn

20$:	DECL	G^PFN$GL_PHYPGCNT	; Count fluid pages
	PUSHL	R0			; Save R0

	JSB	G^EXE$CHKFLUPAGES	; Check for suff. fluid pages

	;NOTE   R0= 1:  all is fine - you may continue
	;       R0= 2:  the system has insufficient fluid pages; you must 
	;		restore PFN$GL_PHYPGCNT and you are not allowed to 
	;		lock another page

	CMPL	R0, #1			; Enough fluid pages ?
	BEQL	22$			; Branch if enough
	INCL	G^PFN$GL_PHYPGCNT	; Restore fluid page count
	POPL	R0			; Restore R0
	BRB	55$			; Take INSFMEM exit

22$:	POPL	R0			; Restore R0

	valid_pfn	pfn=r0, -	; check for a memory hole
			valid=r15
	blbc	r15, 40$		; it's a hole - skip it...

	pfn_to_entry	pfn=r0,- 	; PFN database address for PFN
			entry=r15
	tstw	pfn$w_refcnt(r15)	; is it in use?
	bneq    40$			; yes, don't grab it.

	movl	pfn$l_page_state(r15),- ; get page state
		r22 			
	extv    #pfn$v_loc,#3,r22,r22	; get page location

	cmpl	r22,#pfn$c_badpaglst 	; is it on the bad list?
	beql 	40$                     ; if yes, skip it

	cmpl	r22,#pfn$c_frepaglst 	; is it on the free list?
	beql    25$                     ; if so, go get it !

	cmpl	r22,#pfn$c_zero_list	; is it on zero'd free-page list ?
	bneq    40$                     ; if no, something is wrong, get out

	; To synchronize with SCH$IDLE, which is taking pages off of 
	; free-page-list, and zero'ing in background for zero_page_list,
	; check if page is in transition (within SCH$IDLE).
25$:
	tstl	pfn$l_flink(r15)	; Avoid pages not on "a free list"
	beql	40$			; Not on list: SCH$IDLE probably
					; has it
	tstl	pfn$l_blink(r15)	; Avoid pages not on "a free list"
	beql	40$			; Not on list: SCH$IDLE probably
					; has it

; If we got here the page is on the free list, so, remove it from the list
;
; R0  = PFN
; R2  = list identifier (free list)
; R15 = PFN database entry address
;
; R1 and R3 are destroyed by MMG$REM_PFN

	jsb	mmg$rem_pfn		; allocate the pfn

; Mark the PFN as active, unavailable and unknown.

	addw	#^X33,pfn$w_refcnt(r15)	; incremement the reference count

	movl	#<pfn$m_unavailable!<pfn$c_active@pfn$v_loc>!-
		<pfn$c_unknown@pfn$v_pagtyp>>,-
		pfn$l_page_state(r15)	
	  
40$:	aoblss  r7,r0,20$ 		; if more, check next pfn

        UNLOCK  LOCKNAME=MMG,-          ; Release MMG
                NEWIPL=(SP)+,-
                PRESERVE=YES,-
                CONDITION=RESTORE

45$:	movl	#ss$_normal,r0		; happy status
	rsb

50$:	movl	#ss$_insfrpgs,r0	; not happy status
	rsb

55$:	
        UNLOCK  LOCKNAME=MMG,-          ; Release MMG
                NEWIPL=(SP)+,-
                PRESERVE=YES,-
                CONDITION=RESTORE
	
	movl	#ss$_insfrpgs,r0	; not happy status
	rsb

	.disable lsb
;==========================================================================
;=======================================================================
;        .IF DEFINED FT$BAP_POOL
;       .TITLE  FT$BAP_WAVE	- Creates Bus Addressable Pool Exhaustion Waves
;        .IFF
;        .TITLE   FT$POOL_WAVE	- Creates Non-Paged Pool Exhaustion Waves
;        .ENDC;
;	.IDENT	'XX3.0'
;	.IDENT	'V2.0-2'
;
;****************************************************************************
;*									    *
;*  COPYRIGHT (c) 1992,1996 BY				   		    *
;*  DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS.		    *
;*  ALL RIGHTS RESERVED.						    *
;* 									    *
;*  THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED   *
;*  ONLY IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE   *
;*  INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR  ANY  OTHER   *
;*  COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY   *
;*  OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE IS  HEREBY   *
;*  TRANSFERRED.							    *
;* 									    *
;*  THE INFORMATION IN THIS SOFTWARE IS  SUBJECT TO CHANGE WITHOUT NOTICE   *
;*  AND  SHOULD  NOT  BE  CONSTRUED AS  A COMMITMENT BY DIGITAL EQUIPMENT   *
;*  CORPORATION.							    *
;* 									    *
;*  DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE  OR  RELIABILITY OF ITS   *
;*  SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.		    *
;* 									    *
;*									    *
;****************************************************************************

;++
; SOURCE LIBRARY:	VMSTEST
; FACILITY:	FAULTY_TOWERS
;
; FUNCTIONAL DESCRIPTION:
;
; Routine to create Pool Exhaustion Waves. The major function steps
; of this routine are listed below. The main routine after waiting for the
; standard fault interval calls this routine. This routine generates a random
; number on each interval and assures only that much free resource exists.
; Thus the exact pattern of free resource available is random, however the
; random resource for the last ten intervals is recorded in an array. Note that
; the random resource varies between 0 and a Throttle value entered by the 
; user starting up the fault program. Note also if there is very little
; fluctuation in resource usage then this routine drives free resource to
; zero until some waiters show up. If the process is stopped or deleted then
; the cleanup routine is called to return any privately cached Pool.
;
;	- Do one time setup
;	- Get POOL lock, Goto IPL 8 
;
;	- Get a random number which is new number of free bytes of Pool
;	- Allocate all available Pool
;	- Return new number of free bytes to Pool
;	
;	- Release POOL lock, Restore IPL 0
;
;	Two different executables are conditionally built from this source:
;		FT$BAP_WAVE.EXE	 - Creates Bus Addressable Pool Exhaustion Waves
;		FT$POOL_WAVE.EXE - Creates Non-Paged Pool Exhaustion Waves
;
; A cleanup routine exists to return any resource that may have been grabbed.
;
;++

; ENVIRONMENT:  Alpha VMS
;
; AUTHOR:  Paul  J.  Houlihan
;
; MODIFIED BY:
;
;	XX3.0	RRB	Bob Brassard			16-FEB-1997
;		Modify FT$BAP_WAVE to perform one-time pool drain, to
;		ensure allocation of ADAPTER_BLOCK (ABLK) is from
;		RESERVE_MEM controlled region.  All logic for
;		THROTTLE, FREE/TARGET limits (& associated logical
;		name translation), and pool-release has been removed !
;		This will simply make 1 pass to empty variable pool and
;		and the lookaside lists down to the size of ABLK (2804.).
;
;	V2.0-2	DAG	Doug Gordon	23-Sep-1996
;		Use 64k-64 as the starting size to avoid overflowing
;		the size word. (oops!)
;
;	V2.0-1	DAG	Doug Gordon	17-Sep-1996
;		Use a logical for the minimum value to which pool can be
;		reduced.  FAULTY_TOWERS$POOL_WAVE_MIN and 
;		FAULTY_TOWERS$BAP_WAVE_MIN now influence those.  Any error
;		translating the logical substitutes 0.  
;
;	V2.0	VDB	Verell Boaen	30-AUG-1996
;	- Generalize to handle _POOL code, eg: Bus Addressable Pool (BAP)
;	- [TBD]Optimize pool allocation routine to minimize number of allocation
;	  calls needed to exhaust a pool. This will speed up testing with
;	  multi hundred MB and GB sized pools.
;                         
;--

	.SBTTL	DECLARATIONS
;
;	Symbol definitions
;
 	$CDRPDEF			; CDRP definitions
	$DYNDEF				; Structure type definitions
	$EMBDEF				; Error log buffer offsets
        $IOCDEF                         ; I/O Database
 	$IPLDEF				; Definitions for IPL constants
	$IRPDEF				; IRP definitions
	$LCKDEF				; Lock definition 
	$LNMDEF				; Logical Name definitions
        $MMGDEF                         ; Memory ManaGement definitions
	$PBDEF				; Path Block definitions
	$PDTDEF				; Port Descriptor Table definitions
	$PFREEDEF			; Pool Header structure definitions.
	$SBDEF				; System Block definitions
	$SPLDEF				; Spinlock definitions
	$SSDEF				; Status codes
	$NPOOL_DATADEF			; NPPool definitions


;	.PSECT	DATA,PAGE,WRT,NOEXE
;
; Data Cells
;
;SCSNP$ALLOC_SIZE::
;	.LONG	0		; Current alloc size for variable allocation
;SCSNP$NPAGNEXT::
;	.LONG	0		; Saved pool size
;SCSNP$VAR_FREE_LIST::
;	.LONG	0		; Singlely linked list of privately cached

MAX_LOOKASIDE = 64*IOC_C_NUMLISTS	; Largest lookaside packet size in bytes
MAX_ALOC_SIZ  = 64*1024-64		; Max pool alloc. attempt size; size
					; value must fit within mem. hdr size
					; word. 
; Force BAP variant since all NPORT structures are from BAP for
; CIPCA sharing
	FT$BAP_POOL = 1
.IF defined EVAX
.IF defined FT$BAP_POOL
	POOL_TYPE = MMG$K_POOLTYPE_BAP ; Bus Addressable Pool
.IFF	; Then non-paged pool
	POOL_TYPE = MMG$K_POOLTYPE_NPP ; Default to non-paged pool PoolType.
.ENDC	;IF defined FT$BAP_POOL
.ENDC	;IF defined EVAX
;

	.SBTTL	SCSNP$POOL_DRAIN Fork-IPL FAULT_ROUTINE - Drain BAP npagdyn
;+
; Functional Description:
;
; This routine is called via JSB from SCSNP$INIT_CTLR init to perform
; one-time pool drain.  It should only be called once by 1st SCA device.
;
;	- Get POOL lock, Goto IPL 8 
;
;	- Run free  Pool to 0
;	
;	- Release POOL lock, Restore IPL 0
;
; Inputs:
;	NONE.  Implicit = pool type, during compile time.
;
; Outputs:
;	R2-R7 Preserved
;	R0 = SS$_NORMAL on all exits

SCSNP$POOL_DRAIN::
    .IF defined EVAX
	.JSB_ENTRY -
		INPUT    = <                 >,-
		OUTPUT   = <                 >,-
	     	SCRATCH  = <                 >,-
		PRESERVE = <      R2,R3,R4,R5,R6,R7>
    .IFF ; for VAX
	.WORD	^M<R2,R3,R4,R5> 	
    .ENDC  

;
;
; Disable of expansion of  pool
;
	MOVL	G^MMG$GL_NPAGNEXT,-	; Save current size of NPP dynamic pool
		SCSNP$NPAGNEXT 
	ADDL3   G^SGN$GL_NPAGEVIR,-     ; Compute Upper bound possible
		G^MMG$GL_NPAGEDYN,R1    ;  for dynamic pool expansion
  	MOVL	R1,G^MMG$GL_NPAGNEXT	; Set upper bound into next page to
					;  prevent expansion of NPP dynamic pool
;
; Normal fault processing, init return status
;
;
; Acquire POOL lock, Goto IPL 8 
;
     .IF defined EVAX
	LOCK     LOCKNAME=POOL,-	; Acquire the POOL spinlock
		 SAVIPL=-(SP)
    .IFF ; for VAX
	LOCK     LOCKNAME=POOL,-	; Acquire the POOL spinlock
		 LOCKIPL=#IPL$_POOL,-
		 SAVIPL=-(SP)
    .ENDC  
;
; Run free Pool to 0
;
;
	MOVL	#MAX_ALOC_SIZ, -	; Initial alloc size
		SCSNP$ALLOC_SIZE
	MOVL	SCSNP$ALLOC_SIZE, -	; Request current size
		R1
	BRW	30$
;
;  We're here 'cause allocation failed of the larger chunk - calculate
;  the next smaller chunk to get and try again.
;
25$:	MOVL	SCSNP$ALLOC_SIZE, R1	; Get current (failing) size
	CMPL	R1, #MAX_LOOKASIDE	; Are we below lookaside size?
	BLEQ	27$			; nope, not yet - use big hunks
	DIVL2	#2, R1			; halve the size
	CMPL	R1, #MAX_LOOKASIDE	; Are we below lookaside size?
	BGTR	30$			; nope, use it
	MOVL	#MAX_LOOKASIDE, R1	; Force to largest list size
	BRB	30$
;
;	We're draining the lookaside lists now...
;
27$:	SUBL2	#64, R1			; Next list
        BEQL    40$                     ; Not zero

30$:	MOVL	R1, SCSNP$ALLOC_SIZE	; save for next round

    .IF defined EVAX
	ALOPOOL POOL_TYPE		; Get some PoolType pool.
    .IFF
	JSB	G^EXE$ALONONPAGED	; Get some pool
    .ENDC	;IF defined EVAX
 
	BLBC	R0, 25$			; BR if none left of this size

    .IF defined EVAX
	MOVW	#POOL_TYPE,PFREE$L_BLINK(R2); Save pooltype in unused BLINK field.
    .ENDC	;IF defined EVAX

	MOVW	R1,PFREE$W_SIZE(R2)	; Save actual returned size for deallocation
	MOVB	#DYN$C_SPECIAL,PFREE$B_TYPE(R2) ; Setup type for deallocation
	MOVL	SCSNP$VAR_FREE_LIST,-	; Point memory to first free entry
		(R2) 			; on private list
	MOVL	R2,SCSNP$VAR_FREE_LIST	; Place memory on private free list
	BRW	30$ 			; Go try for more memory

;
;	Enable pool to expand again.
40$: 	
	MOVL	SCSNP$NPAGNEXT,-	; Restore current size of NPP 
		G^MMG$GL_NPAGNEXT 	; dynamic pool
;
; Release POOL lock, Restore IPL 0
;
	UNLOCK LOCKNAME=POOL,-		; Release the POOL spinlock
		  NEWIPL=(SP)+
	MOVZWL	#SS$_NORMAL,R0		; Return success for standard-
					; ization, but not checked by
					; caller here
	RSB
 
	.END
