mmm$memory_manager_helper   ident

.        ojc     1
...............................................................................
.
.           This assembly language module contains memory manager
.           procedures which for reasons of efficiency are written
.           in assembly language. This module contains the following:
.               mmp$preset_real_memory
.
...............................................................................
.
.
.  common decks used (not listed here)
.     sya$constants, sya$cybil_interface_procedures, osa$basic_register_equates,
.     sya$xp_and_sf_constants
         list,0  0,0,0
*copyc osc$keypoint_buffer_pva_offseta
*copy SYA$CONSTANTS
*copy SYA$CYBIL_INTERFACE_PROCEDURES
*copy OSA$BASIC_REGISTER_EQUATES
*copyc sya$xp_and_sf_constants
         list,0  1,2,1
.
.
...............................................................................
.  Define A and X registers. WARNING - some of the registers are loaded via
.  LMULT and SMULT instructions. Be careful if you change register numbers.
...............................................................................
.
amacscr  areg    9                     .Scratch register for macros.
a_work   areg    10                    .Pointer to working storage.
a_segtbl areg    11                    .Pointer to Monitor's segment table.
x_sva    xreg    7                     .SVA  of area to be preset.
x_rma    xreg    8                     .Rma of area to be preset.
x_pagmsk xreg    9                     .Mask for isolating page number.
.
.
. The following registers are loaded by a LMULT instruction. Make sure
. that 'regsel' agrees with the register numbers and that working storage
. data at 'regblk' are in the correct sequence.
.
a_ptbgn  areg    13                    .Pointer to the system page table.
a_pagtbl areg    14                    .Pointer to preset PTE.
a_data   areg    15                    .Pointer to area to be preset.
x_pte    xreg    12                    .Contains initial copy of PT entry.
x_length xreg    13                    .Page size in words - decremented in
.                                         SMULT loop.
.
. The following X-registers are the ONLY x-registers that can be referenced
. in the SMULT loops.
.
.  (x_length used but loaded by LMULT)
x_regsto xreg    14                    .Register for SMULT in major preset loop.
x_loop   xreg    15                    .Number of words preset per major loop.
.
         page
...............................................................................
.
.  Define constants
...............................................................................
.
regcnt   equ     13                    .Number of words of memory preset per SMULT
                                       .instruction in memory preset.  This must be
                                       .the same as the number of X-registers that
                                       .contain a copy of the preset value. For
                                       .maximum efficiency, this equate should be
                                       .equal to the number of the lowest register
                                       .used for other purposes in the SMULT loops.
.
.
...............................................................................
.  Define Binding Section..
...............................................................................
.
         use     binding
         ref     msegtbl
         ref     errstop
         def     work
msegtbl  alias   MTV$MONITOR_SEGMENT_TABLE
work     alias   MMC$MMMASM_WORKING
errstop  alias   MTP$ERROR_STOP
bs_work  address p,work
bs_segtb address p,msegtbl             .Pointer to Monitor segment table.
bs_err   address ce,errstop
.
.
...............................................................................
.  Define Working Storage.
...............................................................................
.
         use     working
work     bss     0
.
.
.  The following words are referenced only thru LMULT and SMULT instructions
.  If any changes are made, check the corresponding register equates
.  and the 'regsel' value used to load the words.
.
         align   0,8
regsel   equ     0dcfd(16)             .Register selector for LMULT.
regblk   bss     0                     .Beginning of LMULT/SMULT block.
         vfd,16,4,12,32 0,1,snptmtr,0  .Pointer to begin of Page table.
         vfd,16,4,12,32 0,1,snptmtr,0  .Pointer to preset page table entry.
         vfd,16,4,12,32 0,1,snptmtr,0  .Preset PVA.
         vfd,4,16,22,22 0c(16),0,0,0   .Template for PTE word.
         vfd,64  0                     .Page size in words. Zero
                                       . implies initialzation required.
kbpo     vfd,32  keybpo                .Page table PVA offset of keypoint collection
                                       . buffer.
err1     vfd,152 c'MM - Preset failure'

         align   0,8
mmvpct   bss     0
zero     vfd,64  0
altone   vfd,64  0aaaaaaaaaaaaaaaa(16)
indef    vfd,64  07000000000000000(16)
inf      vfd,64  05000000000000000(16)
.
         defg    mmvpct
mmvpct   alias   MMV$PRESET_CONVERSION_TABLE
         page
...............................................................................
.
.  This procedure is used in monitor to preset a range of REAL MEMORY
.  ADDRESSES to a specified value. WARNING: no checks are made on the
.  validity of the address range except to verify that the SVA
.  exists in the page table with the 'valid' bit clear. The range of words to be
.  preset must not cross a page boundary.
.
.      MMP$PRESET_REAL_MEMORY (SVA, PRESET_VALUE);
.
.    SVA: (input) This parameter specifies the SVA
.         the beginning of the area to be preset.
.    PRESET_IDENTIFIER: (input) This parameter is passed as LLT$PRESET_VALUE and
.         is used as andindex into pmv$preset_conversion_table.
.
.
.      PROCEDURE [XREF] mmp$preset_real_memory (sva: ost$system_virtual_address;
.        preset_identifier: llt$preset_value);
.
.
.
.     NOTES:
.        - routine will halt if SVA is not 0 MOD 8.
.        - routine will halt if SVA is not in the page table with the
.          'valid' bit CLEAR.
.        - length is rounded down to a multiple of eight bytes.
.
.
...............................................................................
.
         use     code
         def     preset
preset   alias   MMP$PRESET_REAL_MEMORY
preset   procedur
sva      param   val,subrange,6
value    param   val,subrange,8
.
         la      a_work,a_bindin,bs_work  .Get pointer to working storage
         ente    x0,regsel             .Load working registers from memory.
         lmult   x0,a_work,regblk*8
         brxeq   x_length,x0,init      .Jump if routine not yet initialized.
.
         ploadx  x_sva,sva             .Get SVA and verify that a
         lpage   x_rma,x_sva,x1        . PT entry for the page exists
         brrge   x1,x0,preserr         . with the 'valid' bit clear.
         lbyts,8 x_rma,a_ptbgn,x_rma,0  .Page table entry of SVA presetting
         brxgt   x0,x_rma,preserr      .If valid bit set
         insb    x_pte,x_rma,x0,5225(8) .Store page frame address into presets
         sbyts,3 x_pte,a_pagtbl,x0,5   .  PTE.
.
         ploadx  x1,value              .Get bit pattern to be stored.
         lxi     x0,a_work,x1,mmvpct
         cpyax   x1,a_data             .Purge the page file - we changed the PT.
         purge   x1,10
         cpyxx   x1,x0                 .Propagate bit pattern to rest of
                                       . X-registers.
         cpyxx   x2,x0
         cpyxx   x3,x0
         cpyxx   x4,x0
         cpyxx   x5,x0
         cpyxx   x6,x0
         cpyxx   x7,x0
         cpyxx   x8,x0
         cpyxx   x9,x0
         cpyxx   xa,x0
         cpyxx   xb,x0
         cpyxx   xc,x0
.
         ente    x_regsto,regcnt+0fff(16)  .Register descriptor for SMULT.
         ente    x_loop,regcnt*4       .Number of words stored per SMULT.
preset3  smult   x_regsto,a_data,0     .Store  'regcnt'*4 words at a time
         smult   x_regsto,a_data,regcnt*8
         smult   x_regsto,a_data,regcnt*8*2
         smult   x_regsto,a_data,regcnt*8*3
         addxq   x_length,x_length,-regcnt*4
         addaq   a_data,a_data,regcnt*8*4
         brxge   x_length,x_loop,preset3  .Jump if not done with big store loop
.
preset5  entp    x_loop,regcnt         .Update number of words stored per loop.
         brxgt   x_loop,x_length,preset8  .Jump if not much to preset.
.
preset6  smult   x_regsto,a_data,0     .Preset some more data.
         addaq   a_data,a_data,regcnt*8
         decx    x_length,regcnt
         brxge   x_length,x_loop,preset6  .Jump if more than 'regcnt' words remain.
.
preset8  brxeq   x_length,x0,presetx   .Exit if all done.
         addxq   x_length,x_length,0fff(16)  .Calculate new descriptor.
         smult   x_length,a_data,0     .Finish presetting odd length at end
                                       . of area.
.
presetx  ente    x0,0                  .Reset page number of PTE to zero.
         sbyts,3 x0,a_pagtbl,x0,5
         return
.
.
preserr  addaq   a0,a0,16              .Push space for plist.
         entl    x0,19                 .Message length.
         addaq   af,a_work,err1        .Address of message.
         sa      af,a1,0
         sbyts,2 x0,a1,x0,6
         cpyaa   af,a1                 .parameter list address.
         enta    x0,100ff(16)
         callseg bs_err,a_bindin,af
         page
...............................................................................
.
.  INIT - This procedure initializes constants used by the MMP$PRESET_REAL_MEMORY
.         routine. These constants are stored in "regblk', a page table entry
.         is also created in page table to use to access memory using the PVA
.         created for this purpose.
.
.        ENTRY:
.                a_work = Pointer to working storage of this module.
.                a_bindin = Pointer to binding section of this module.
.                a_ptbgn = Pointer to the system page table.
.                x_pte   = Page table entry template.
.
.        CALLS:  preserr.
.
.        EXIT:
.                'REGBLK' in working storage is initialized for presetting memory.
.                Exit is to 'preset'.
.
.        USES:   a_data, a_pagtbl, a_segtbl,  x0, x2 - x6, x_pte, x_pagmsk
...............................................................................


         align   0,2
init     bss     0
         la      a_segtbl,a_bindin,bs_segtb  .Get the ASID of the page table segment.
         entl    x0,r_ptl
         lbyts,2 x2,a_segtbl,x0,snptmtr*8+2  .Page table ASID
         cpysx   x5,x0                 .Page table length
         entl    x0,r_psm
         incx    x5,1
         cpysx   x3,x0                 .Page size mask
         ente    x4,128
         insb    x_pte,x2,x0,(4*64)+15 .Insert ASID into PTE word.
         shfx    x6,x5,x0,12+1         .Page table length in bytes * 2
         subx    x4,x3                 .Page size DIV 200(16)
         shfx    x2,x2,x0,32
         shfx    x3,x3,x0,9
         isom    x_pagmsk,x0,(48*64)+15  .Maximum page size mask
         shfx    x4,x4,x0,9            .Page size in bytes
         shfx    x_length,x4,x0,-3
         addr    x2,x6                 .Initial SVA of preset PVA
         ente    x5,32
         inhx    x_pagmsk,x3           .Mask for isolating page number and offset
                                       . from an SVA
         lbyts,4 x3,a_work,x0,kbpo     .Page table PVA offset used for keypoint
                                       . collection

.        Find an offset for preset PVA greater than the length of the page table
.        to use for presetting memory.  Use the page table PVA as the basis of
.        the preset PVA.  Start offset at twice the page table length, keypoint
.        collection uses a PVA based on the page table for buffers with a large
.        offset.  The offset used by keypoint collection will be used as the
.        upper bound.

init5    bss     0
         lpage   x6,x2,x1
         brrgt   x5,x1,init10          .If avilable slot in page table
         addr    x2,x4                 .Increment SVA offset
         brrgt   x3,x2,init5           .If maximum offset not exceeded

.  Did not find available slot in page table for memory preset, fatal error.

         brxeq   x0,x0,preserr         .Fatal error, system initialization failed

init10   bss     0
         cpyxx   x5,x2
         inhx    x2,x_pagmsk           .Page number of preset PVA
         addax   a_pagtbl,x6           .PVA of preset page table entry
         insb    x_pte,x2,x0,(20*64)+30  .Insert page number into preset PTE
         addax   a_data,x5             .Preset PVA
         sbyts,8 x_pte,a_pagtbl,x0,0   .Store preset page table entry

         ente    x0,regsel
         smult   x0,a_work,regblk*8    .Store working registers.

         brxeq   x0,x0,preset          .Initialization complete, continue preset

         end
