;       SCCSID = @(#)fsinit.asm 6.5 91/10/11
SCCSID  equ     "@(#)fsinit.asm 6.5 91/10/11"
        page    78,132
        title   Fsinit, File System Initialization
;/********************** START OF SPECIFICATIONS **********************/
;/*                                                                   */
;/* SOURCE FILE NAME: Fsinit.asm                                   @@ */
;/*                                                                   */
;/* DESCRIPTIVE NAME: File System Initialization                      */
;/*                                                                   */
;/* STATUS: CP/DOS version 1.1                                        */
;/*                                                                   */
;/* FUNCTION: To initialize the File System data areas                */
;/*                                                                   */
;/* NOTES:                                                            */
;/*   DEPENDENCIES: None                                              */
;/*   RESTRICTIONS: None                                              */
;/*                                                                   */
;/* ENTRY POINTS: InitFileSystem                                      */
;/*                                                                   */
;/* EXTERNAL REFERENCES:                                              */
;/*              Rmp_Alloc        - Allocate a CDS segment            */
;/*              VPBInit          - Initialize VPB segment            */
;/*              NmpInit          - Initialize named pipe data        */
;/*                                                                   */
;/*  CHANGE ACTIVITY:                                                 */
;/*  12/03/86    Change selector of end of buffer chain to 0          */
;/*  19-Oct-95 - scott garfinkle defect 140726                        */
;/*              Serialize access to VPBs.                            */
;/*                                                                   */
;/*********************** END OF SPECIFICATIONS ***********************/

        .sall
        .xlist
        .xcref
        include fnofs.inc
        include osconst.inc
        include dosseg.inc            ; Kernel segments
        include basemaca.inc          ; Kernel macros
        include osmaca.inc            ; Kernel macros
        include oldmaca.inc           ; Old macros
        include buffer.inc            ; File System Buffer
        include devsym.inc
        include fsc.inc
        include pgexport.inc
        include vmexport.inc
        include tkexport.inc
        include ptree.inc             ; PTree
        include mft.inc               ; Master File Table
        include vmowner.inc           ; Memory ownership list
        include sas.inc               ; System Anchor Segment
        include sft.inc               ; System File Table
        include struc.inc             ; Structured assembler macros
        include mi.inc
        include protmode.inc          ; To get GSEL macro
        include kmode.inc
        include strat2.inc
        .cref
        .list

        CpuMode 386
        ModName , FNO_FSINIT_ASM

;       Referenced fields within the Kernel Data Segment

        ReferGlobal     CDSAddr,WORD
        ReferGlobal     MaxSec,WORD
        ReferGlobal     MFT_hPTree,DWORD        ; handle to MFT PTree
        ReferGlobal     pVPBBuf,DWORD   ; pointer to VPB buffer for I/O
        ReferGlobal     SAS_file_area,BYTE
        ReferGlobal     FATCache,BYTE
        ReferGlobal     Defaultcache,BYTE

        ReferGlobal pbufWPT,DWORD       ; pointer to Write Protect Test buffer

        ReferFlat       CADHookHandle,DWORD
        ReferFlat       CADHandler,BYTE
        ReferFlat       ksemMFT,BYTE
        ReferFlat       ksemVPB,BYTE                            ;140726
        ReferFlat       _S2_RW_RQPKT_SIZE,WORD
        ReferFlat       _fLWDaemon,BYTE
        ReferFlat       _DiskThresh,DWORD

        ReferInitGlobal CFG_DiskCache,DWORD
        ReferInitGlobal CFG_LazyWrite,BYTE
        ReferInitGlobal CFG_DiskThresh,WORD
        ReferInitGlobal CFG_Defaultcache,BYTE

;       External Routines Called or Referenced

        EXTRN32         _KSEMInit
        EXTRN32         _PTCreate
        EXTRN32         MFT_KeyAlloc
        EXTRN32         MFT_KeyFree
        EXTRN32         MFT_GetKey
        EXTRN32         KMALLOCHOOK

        EXTRNF32        InitCodeLocks
        EXTRN32         _BufInit

        EXTRNFAR        Rmp_Alloc
        EXTRNFAR        SegAlloc
        EXTRNFAR        SFFromSFN

        extrn           _SELAllocKHB:near
        extrn           RLRInit:near
        extrn           SFTInit:near
        extrn           VPBInit:near
        extrn           BufInit:near
        extrn           fscInit:near
        extrn           NmpInit:near
        extrn           CharDevTabInit:near

        ReferGDT        GDT_SFT,WORD
        ReferGDT        GDT_Buffers,WORD


        page

;       Structure of a double word

doubleword struc
lsw        dw   ?                     ; least significant word
msw        dw   ?                     ; most significant word
doubleword ends

;       Equates used to modify the contents of the registers pushed
;       by a PUSHA instruction

restore_ax equ  word ptr [bp+14]
restore_bx equ  word ptr [bp+8]
restore_cx equ  word ptr [bp+12]
restore_di equ  word ptr [bp+0]

DATA segment
PBUF2K    dw     0800H         ;### P1 Fix
DATA ends

        FARCODE INIT
INITCODE segment

BREAK   <InitFileSystem>
;/********************** START OF SPECIFICATIONS **********************/
;/*                                                                   */
;/* SUBROUTINE NAME: InitFileSystem                                   */
;/*                                                                   */
;/* DESCRIPTIVE NAME: Initialize File System data structures          */
;/*                                                                   */
;/* FUNCTION:    To initialize the major data structures used by      */
;/*              the CP/DOS File System                               */
;/*                                                                   */
;/* NOTES:       InitFileSystem runs in protected mode.               */
;/*              This subroutine must be called after the base device */
;/*                 drivers are installed since it uses data          */
;/*                 provided by the Disk Device Driver                */
;/*                                                                   */
;/* ENTRY POINT: InitFileSystem                                       */
;/*                                                                   */
;/* INPUT:       AX     = number of application buffers               */
;/*              MaxSec = maximum size of sector buffer               */
;/*                                                                   */
;/* EXIT-NORMAL: Return to caller (no values returned)                */
;/*                                                                   */
;/* EXIT-ERROR:  None                                                 */
;/*                                                                   */
;/* EFFECTS:     All registers are preserved                          */
;/*                                                                   */
;/* INTERNAL REFERENCES:                                              */
;/*    ROUTINES: None                                                 */
;/*                                                                   */
;/* EXTERNAL REFERENCES:                                              */
;/*    ROUTINES:                                                      */
;/*              Rmp_Alloc        - Allocate a CDS segment            */
;/*              VPBInit          - Initialize VPB segment            */
;/*              CharDevTabInit   - Initialize Char device table seg  */
;/*              NmpInit          - Initialize named pipe data        */
;/*              _SELAllocKHB     - alloc from kernel resident heap   */
;/*                         and create GDT selector mapping the block */
;/*              InitCodeLocks    - initialize tables for swappable   */
;/*                                 code                              */
;/*                                                                   */
;/*********************** END OF SPECIFICATIONS ***********************/
;
; Procedure InitFileSystem(number of application buffers)
;
;     (SFT) segment
; initialize the System File Table segment
;
; initialize the MFT PTree
;
; Call SELAllocKHB (Max sector size) to allocate a buffer
;     for volume determination
;
; chain all the buffers together
; mark the last n buffers as owned by the Swapper
;
; Call SELAllocKHB (Max sector size) to allocate a buffer
;     for write protect test
;
; Call VPBInit to initialize the VPB segment
; Call NmpInit to initialize the named pipe segments
; Call CharDevTabInit to initailize the character device table segment
; Call Rmp_Alloc to allocate the Current Directory Structure (CDS segment)
; Call InitCodeLocks to initialize tables for swappable code
;
; Return
;
; End InitFileSystem

Procedure InitFileSystem,near
        assume  ds:nothing,es:nothing,ss:TASKAREA

        LocalVar buffers,WORD
        LocalVar hPTree,DWORD
        LocalVar vmacHeapBlockInfo,<size vmac_s>

        EnterProc <ax>                ; buffers=ax, number of application buffers
        SaveReg <ds,es>
        pushad

;       Allocate SFT segment and initialize it

        call    SFTInit

        DosContext DS,AX
        mov     SAS_file_area.SAS_file_SFT,GSEL GDT_SFT

;       Allocate MFT PTree and initialize it

        FlatContext <ds,es>,ax

        CCALL32 _KSEMInit,<<offset FLAT:ksemMFT>,KRNL_SHARESEM,KSEM_NOINTERRUPT>
                                        ; init ksem
        or      eax,eax
        jnz     infs8                   ; failure, go panic
        CCALL32 _KSEMInit,<<offset FLAT:ksemVPB>,KRNL_MUTEXSEM,0>       ;140726
                                        ; init vpb ksem                 ;140726
        or      eax,eax                                                 ;140726
        jnz     infs8                   ; failure, go panic             ;140726

        lea     eax,hPTree              ; (ss:eax)   -> hPTree
        SSToDS  eax                     ; (FLAT:eax) -> hPTree

;BUGBUG set PTF_NODESWAP only after BMP32 is used for allocation
;BUGBUG CCALL32 _PTCreate <PTF_NODESWAP OR PTF_PANICDELETE,FSMFTOWNER,MFT_MAX_NODES,OFFSET FLAT:MFT_KeyAlloc,OFFSET FLAT:MFT_KeyFree,OFFSET FLAT:MFT_GetKey,eax>
        CCALL32 _PTCreate <PTF_PANICDELETE,FSMFTOWNER,MFT_MAX_NODES,OFFSET FLAT:MFT_KeyAlloc,OFFSET FLAT:MFT_KeyFree,OFFSET FLAT:MFT_GetKey,eax>
        or      eax,eax
        jnz     infs1                   ; failure, go panic

        mov     eax,hPTree              ; (eax) = hPTree

        DosContext ds
        mov     MFT_hPTree,eax          ; update global handle
        mov     SAS_file_area.SAS_file_MFT,eax

;       Allocate RLR segment

        call    RLRInit
        jc      infs4                   ; failure, go panic

;       Allocate VPB buffer
        ; _SELAllocKHB(VM_HKH_PUB_RESRW,MaxSec,0,0,FSVPBOWNER,&vmacHeapBlockInfo)
        DosContext <ds>,ax
;       movzx   ebx,MaxSec
        movzx   ebx,PBUF2K           ; Make sure contiguous for 2K  ;P1 fix
        FlatContext <ds,es>,ax
        SSToDS  eax,vmacHeapBlockInfo
        CCALL32 _SELAllocKHB <VM_HKH_PUB_RESRW, ebx, PG_CONTIG or PG_16M, 0, FSVPBOWNER, eax>
        or      eax,eax
        jnz     infs3                          ; allocation failed
        DosContext <ds>,ax
        mov     ax,vmacHeapBlockInfo.ac_sel
        mov     pVPBBuf.msw,ax                 ; save address of VPB buffer
        mov     pVPBBuf.lsw,0
        mov     SAS_file_area.SAS_file_VPB,ax

;       Allocate File System buffer segment

        DosInitContext es
        mov     cx,buffers            ; (cx) = # of user buffers
        call    BufInit               ; Allocate and init buffer pool
        jc      infs2
        mov     ax,GSEL GDT_Buffers   ; (ax) = buffer selector
        DosContext ds
        mov     SAS_file_area.SAS_file_buffers,ax


;BUGBUG 16-Oct-1987 bens Consider putting pVPBBuf and pbufWPT in one segment

;       Allocate Write Protect Test buffer
        ; _SELAllocKHB(VM_HKH_PUB_RESRW,MaxSec,0,0,FSBUFOWNER,&vmacHeapBlockInfo)
        DosContext <ds>,ax
;       movzx   ebx,MaxSec
        movzx   ebx,PBUF2K           ; Make sure contiguous for 2K  ;P1 fix
        FlatContext <ds,es>,ax
        SSToDS  eax,vmacHeapBlockInfo
        CCALL32 _SELAllocKHB <VM_HKH_PUB_RESRW, ebx, PG_CONTIG or PG_16M, 0, FSBUFOWNER, eax>
        or      eax,eax
        jnz     infs6                  ; allocation failed
        mov     ax,vmacHeapBlockInfo.ac_sel
        DosContext <ds>
        mov     pbufWPT.msw,ax          ; save address of WPT buffer
        mov     pbufWPT.lsw,0

;       Initialize the VPB selector and segment

        call    VPBInit

;       Initialize named pipe BMP and RMP segments

        call    NmpInit

;       Initialize the character device table selector and segment

        call    CharDevTabInit

;       Initialize the FSC selector and segment

        call    fscInit
        assume ds:nothing,es:nothing

        DosInitContext ds
        xor     cx,cx
        mov     cl,CFG_Defaultcache
        cmp     cx,1
        jne     infs01

        DosContext DS
        mov     ds:[Defaultcache],1
        DosInitContext ds
infs01:
        mov     ecx,CFG_DiskCache
        movzx   edx,CFG_DiskThresh
        mov     bl,CFG_LazyWrite
        DosContext DS
        or      ecx,ecx
        jz      infs0
        mov     ds:[FATCache],1
        FlatContext <ds,es>,ax
        mov     _fLWDaemon,bl
        mov     _DiskThresh,edx
        mov     ax,S2_RW_RQPKT_SIZE
        mov     _S2_RW_RQPKT_SIZE,ax
        CCALL32 _BufInit <ecx>
        or      eax,eax
        jz      infs0
        mov     _fLWDaemon,0
        DosContext DS
        mov     ds:[FATCache],0
        DosInitContext ds
        mov     CFG_DiskCache.LowWord,0
        mov     CFG_DiskCache.HighWord,0
infs0:
        assume ds:nothing,es:nothing

;       Allocate RMP segment for CDS
;       Rmp_Alloc(ax=hobowner,bx=hobmte,esi=PG flags,es:di->rmpdata)

        mov     ax,CDSRMPOWNER
        xor     bx,bx
        mov     esi,PG_RESIDENT
        DosContext es
        mov     di,offset CDSAddr
        CALLFAR Rmp_Alloc
        jc      infs5                 ; Internal Error if Rmp_Alloc failed

        mov     ax,[CDSAddr].msw      ; save GDT selector for CDS segment
        mov     SAS_file_area.SAS_file_CDS,ax

;       Initialize swappable code lock information

        FlatContext <ds,es>,ax,noassume
        CALLF32 InitCodeLocks

;       Arm the context hook used for control-alt-delete handling
;       KMAllocHook(&CADHandler,0,0,0,KM_GLOBAL_HOOK,&CADHookHandle)

        mov     eax,offset FLAT:CADHookHandle ; pointer to hook handle
        mov     ebx,offset FLAT:CADHandler    ; routine to handle CAD
        xor     ecx,ecx
        PCALL32 KMALLOCHOOK,<ebx,ecx,ecx,ecx,KM_GLOBAL_HOOK,eax>
        or      eax,eax
        jnz     infs7

;       Return to caller

        popad
        RestoreReg <es,ds>
        LeaveProc

        ret

infs1:  InternalError <InitFileSystem: PTCreate(MFT) failed>
infs2:  InternalError <InitFileSystem: BufInit failed>
infs3:  InternalError <InitFileSystem: Unable to allocate VPB buffer>
infs4:  InternalError <InitFileSystem: RLRInit failed>
infs5:  InternalError <InitFileSystem: Rmp_Alloc>
infs6:  InternalError <InitFileSystem: Unable to allocate write protect buffer>
infs7:  InternalError <InitFileSystem: unable to create CAD context hook>
infs8:  InternalError <InitFileSystem: failed to init MFT ksem>
EndProc InitFileSystem

;**     FSD_SetSwap - notification of swap file ownership
;
;       Perform whatever actions are necessary to support the swapper
;
;       ENTRY   bx = SFN of swap file
;
;       EXIT    if 'CY' - error
;                 eax = error code
;               if 'NC' - success
;                 eax = 0
;
;       USES    eax,ecx,edx,flags

Procedure FSD_SetSwap,far16
    assume ds:nothing,es:nothing,ss:TASKAREA

        CALLFAR SFFromSFN               ; es:di -> sft
        jc      SHORT sswx              ; error, go exit

; dispatch to file system worker

        lds     si,es:[di].sf_FSC       ; ds:si -> FSC
        xor     ax,ax                   ; default = no error
        cmp     si,FSC_LOCAL            ; what file system?
        je      SHORT sswx              ; fat, do nothing (carry cleared)

; FSD, call FSD worker

        lea     ax,[di].sf_fsi          ; es:ax -> sf_fsi
        push    es
        push    ax
        lea     ax,[di].sf_fsd          ; es:ax -> sf_fsd
        push    es
        push    ax
        call    ds:[si].FS_SETSWAP      ; ax = error code
        xor     bx,bx
        cmp     bx,ax                   ; set carry if ax != 0

sswx:   RETP

EndProc FSD_SetSwap

INITCODE ends

CpuMode 386

FARCODE HIGH32
CINIT_TEXT segment

Procedure _FSD_SetSwap
        assume  ds:FLAT,es:FLAT,ss:TASKAREA,fs:nothing,gs:nothing
        ArgVar  uSFN,DWORD
        EnterProc
        push    edi
        push    esi
        push    ebx

        mov     ebx,[uSFN]
        CALL16  FSD_SetSwap
        movzx   eax,ax

        pop     ebx
        pop     esi
        FlatContext <ds,es>,edi
        LeaveProc
        RETP
EndProc _FSD_SetSwap

CINIT_TEXT ends
        end
