;       SCCSID = @(#)rasrst.asm 6.3 91/11/20
;      SCCSID = @(#)rasrst.asm  6.3 91/11/20
        PAGE    ,132                    ; (CTRL-OH)   IBM PC PRINTER CONDENSED MODE
;
;********************** START OF SPECIFICATIONS *********************
;* MAJOR COMPONENT NAME:  RASRST
;*
;*
;* DESCRIPTIVE NAME: Reset the PC hardware and initiate a Dump
;*
;* FUNCTION:
;*         This module will reset the Personal Computer Hardware
;*         and initiate a dump.  The dump is initiated when
;*         this module loads and gives control to  OS/2 Stand-alone
;*         dump via the BIOS Bootstrap Loader or to the Mini-FSD
;*         dump routine.  The Mini-FSD routine is supplied by the
;*         Mini-FSD during system initialization.  This module
;*         checks to see if an exit routine has been provided by
;*         the Mini-FSD.  If one has been provided, this module
;*         is given control by RASRST via jumping to the provided
;*         Routine.  RasRst will execute a timing loop to
;*         hopefully enable all pending disk I/O operations
;*         a chance to finish execution.  If Compatibility BIOS
;*         is installed in this machine, CBIOS will be used
;*         to reset all the PC hardware.  If this machine does
;*         not have CBIOS (Currently the Personal Computer AT and
;*         the Personal Computer XT 286), then the hardware will
;*         be reset by this module.  Once the hardware is reset,
;*         either the Mini-FSD supplied routine is given control or
;*         a message is displayed instructing the user to insert
;*         a Stand-alone dump diskette.  This module will make sure
;*         that a stand-alone dump diskette has been inserted by
;*         checking a string which resides in the dump bootstrap
;*         module.
;*
;* NOTES:
;*    Restrictions:  When any new hardware is released, this
;*                   module must be modified.  This module
;*                   must reside in low memory.
;*
;* ENTRY POINT: RASRST
;*    LINKAGE:  Keyboard device driver uses a FAR CALL
;*
;* INPUT:
;*              RAS_BIOS_data contains the saved interrupt vectors
;*              (00:7F, length 128 bytes) and the BIOS Data area (40:0,
;*              length 256 bytes)
;*              INT 70h is saved in INT 0Dh's vector pointer in the save area
;*
;* EXIT-NORMAL:
;*              Load Stand-alone dump via BIOS bootstrap (INT 19H).
;*
;*              The following physical memory locations have
;*              the following items stored in them to aid in
;*              DEBUGGING:  (All values are in HEX)
;*
;*               0000:001C : Adderss of parms                  (4 bytes)
;*
;*        Offset(in hex) into parms:
;*           0000 : Adderss of interrupt vectors at time of failure  (4 bytes)
;*           0004 : Adderss of BIOS data at time of failure          (4 bytes)
;*           0008 : Adderss of copy of 7C00-7FFF at time of failure  (4 bytes)
;*           000C : GDT REGISTER                                     (6 BYTES)
;*           0012 : IDT REGISTER                                     (6 BYTES)
;*           0018 : LDT REGISTER                                     (2 BYTES)
;*           001A : SELECTOR FOR DOSGROUP SEGMENT                    (2 BYTES)
;*           001C : SELECTOR FOR DOSHIGHDATA SEGMENT                 (2 BYTES)
;*           001E : Trace buffer seg/offset                          (4 BYTES)
;*           0022 : SELECTOR FOR SYSTEM ANCHOR                       (2 BYTES)
;*           0024 : LINEAR ADDR OF ARENA                             (4 BYTES)
;*           0028 : COUNT of MAX THREADS                             (2 BYTES)
;*           002A : _pgPhysPageDir real addr                         (4 BYTES)
;*           002E : _pobvmOne linear addr                            (4 BYTES)
;*           0032 : _StartINITDATA seg/offset                        (4 BYTES)
;*           0036 : dcm_ote_start                                    (4 BYTES)
;*           003A : CurProcPID (word pointed to by)                  (2 BYTES)
;*           003C : TaskData    seg/offset                           (4 BYTES)
;*           0040 : FirstPacket (word pointed to by)                 (2 BYTES)
;*           0042 : LastPacket (word pointed to by)                  (2 BYTES)
;*           0044 : SysSemDataTable seg/offset                       (4 BYTES)
;*           0048 : GDT_Buffers seg/offset                           (4 BYTES)
;*           004C : papTCBPtrs seg/offset                            (4 BYTES)
;*           0050 : caller ss                                        (2 bytes)
;*           0052 : caller esp                                       (4 bytes)
;*           0056 : caller PageDir                                   (4 bytes)
;*           005A : PARM SIGNATURE OF OFF(/0)                        (4 BYTES)
;*                                                       TOTAL      (94 BYTES)
;*           005E : pgphysmax max # pages -1                         (4 BYTES)
;*           0062 : cr2 page fault phys addr                         (4 BYTES)
;* EXIT-ERROR:
;*    RETURN CODE:   None
;*
;* EFFECTS:  Stand-alone dump is booted from diskette.
;*
;* EXTERNAL REFERENCES:
;*    ROUTINES:
;*              BIOS BOOTSTRAP LOADER (INT 19H)
;*              BIOS INT 10H (VIDEO)
;*              BIOS INT 13H (DISKETTE)
;*              BIOS INT 16H (KEYBOARD)
;*
;*              RealMode to perform mode switching
;*              DHInitSystemDump to get display mode
;*              DHSystemDump to pass control to bootstrap loader(INT 19h)
;*
;*    CHANGE ACTIVITY:
;*  @#00n WTE mm/dd/yy Changes made are flagged with a @#00nx
;*                     where the x is n for new code
;*                                    d for deleted code(commented out old code)
;*                                    c for changed code
;*  @#001 WTE 12/28/90 Changes made for PTR PB718829.
;*                     Changed values in parm list
;*                     Added pap_tcb_ptrs and signature to parm list
;*                     Code clean-up, not flagged
;*  @#002 WTE 01/21/91 Changes made for DCR D1085.12 and D1146.2
;*                     Deleted check for 286 processor
;*                     Added check for Aloha
;*                     Added check for Tortugas
;*
;*  @#003 MTH 11/05/91 'phy_addr_page_dir' filled from CR3
;*                     caller ss:esp is saved, inserted 'EnterProc'
;*                     caller _pgpPageDir saved
;*
;* @004SM SEM 06/22/93 dump causes trap 000d it taking during bootup
;*        #70983       Selector 400 is ring 3 during part of bootup
;*                     a Ring 0 app cant use a ring 3 stack
;*                     FIX: modify GDT for 400 to make it ring 0
;*
;*  78486 FJT 03/09/94 Changes made for F78693 shipped under defect    ;78486
;*                     Add global variables needed for AUTOIPL         ;78486
;*
;*  83230 SEM 06/22/94 Add pause to allow SCSI to finish processing its
;*                     interrupts, defect 83230
;* @005SM SEM 08/08/94 Add _pgPhysMax to parms list. This is total # pages-1
;*                     of memory. Thus memory =(_pgPhysMax+1)*4096
;*                     Add cr2 page fault address
;*                     Defect 92730.
;*                     Added comments to mark changes made for defect 77689
;*                      The "if RAS" statements need to be where they are since
;*                      an attempt was made to produce 2 different kernels,
;*                      one supporting ras, one not supporting ras.
;*                      However in the kernel not supporting ras, the parse
;*                      of the config.sys trapdump=... statement was not removed.
;*                      Thus some fields such as dumpdevice, need to be setup
;*                      otherwise there is a build break due to an unresolved
;*                      external reference.
;*********************** END OF SPECIFICATIONS **********************
PAGE
.xlist
include dosseg.inc     ; Must be first include
include basemaca.inc
include osmaca.inc
include struc.inc
; include sas.inc      ; SAS_anchor 12/04/90
include config.inc     ; Machine Types
include modesw.inc     ; for ModeSW init flag
include doshlp.inc     ; DHF DosHlp definitions
include initmac.inc    ; needed for tksetssbase
include protmode.inc   ; needed for GSEL equ offset DOSGDTDATA
include seldesc.inc    ; needed for gate.g_access (DPL on GDT entry)    @004SM
include iodelay.inc                                            ; 83230
.list
.sall

;
; Define the equates for this module
;

      ModName rasrst
      CpuMode 386

PRESENT             EQU    1     ; ABIOS Present Flag
ABIOS_PRESENT_FLAG  EQU    1     ; ABIOS Present Flag for DHSYSDMP
HYBRID_PRESENT_FLAG EQU    2     ; HYBRID Present Flag for DHSYSDMP
DCBS_PRESENT_FLAG   EQU    8     ; DCBS Present Flag for DHSYSDMP

; CONSTANTS   segment
;        extrn   DHF:dword
; CONSTANTS   ends
        ReferGlobal     DHF,dword
        ReferGDT        GDT_SAS,byte
        ReferFlat       _SELGDTLaddr,dword                             ;@004SM

DATA segment

PUBLIC      DUMP_ON
PUBLIC      REIPL_ON                    ; F78693
PUBLIC      DumpProc
PUBLIC      DumpDevice

if RAS                                  ;@005SM
vect_ptr       dw  0                    ; selector
               dw  0                    ; offset

fmtr_parms     equ vect_ptr             ; used as starting point for parms

bios_ptr          dw  0                 ; selector
                  dw  0                 ; offset
boot_ptr          dw  0                 ; selector
                  dw  0                 ; offset
gdt_reg           df  0                 ; GDT REGISTER
idt_reg           df  0                 ; IDT REGISTER
ldt_reg           dw  0                 ; LDT REGISTER
low_data_seg      dw  0                 ; SELECTOR FOR DOSGROUP SEGMENT
high_data_seg     dw  0                 ; SELECTOR FOR DOSHIGHDATA SEGMENT
trace_buf_s       dw  0                 ; Segment ADDR  OF TRACE BUFFER
trace_buf_o       dw  0                 ; Offset ADDR  OF TRACE BUFFER
anchor_sel        dw  GSEL GDT_SAS      ; SELECTOR FOR SYSTEM ANCHOR SEGMENT
lin_addr_arena    dd  0                 ; _parvmOne linear addr
max_threads       dw  0                 ; MAX THREADS value(actual count)
phy_addr_page_dir dd  0                 ; _pgPhysPageDir real addr
lin_addr_objects  dd  0                 ; _pobvmOne linear addr
startinit_s       dw  0                 ; _StartINITDATA
startinit_o       dw  0                 ; _StartINITDATA
phy_addr_dcm_ote_start   dd  0          ; dcm_ote_start
cur_proc_pid      dw  0
task_data_s       dw  0
task_data_o       dw  0
first_packet      dw  0
last_packet       dw  0
sys_sem_data_s    dw  0
sys_sem_data_o    dw  0
gdt_buffers_s     dw  0
gdt_buffers_o     dw  0
pap_tcb_ptrs_s    dw  0                 ;                       @#001n
pap_tcb_ptrs_o    dw  0                 ;                       @#001n
sav_caller_ss     dw  0                 ; caller ss             @#003n
sav_caller_esp    dd  0                 ; caller esp            @#003n
sav_caller_Pdir   dd  0                 ; caller _pgpPageDir[0] @#003n
dump_signature1   dw  0                 ; dump                  @#001n
dump_signature2   dw  0                 ;  signature            @#001n
totpages          dd  0                 ; memory size in pages (4k) @005SM _pgPhysMax+1
phy_addr_page_fault dd  0               ; CR2 contents          @005SM

ras_stack       dw  99 dup(?)
ras_stkend      dw  0

endif ;RAS                           ;@005SM

DumpProc        dd  0                ; Dump Exit Routine
DUMP_ON         db  0                ; Dump on from TRAP286
REIPL_ON        db  0                ; Dump on from PANIC              ;F78693
DumpDevice      db  'A'              ; Device to dump to (only supprted for
                                     ; now are disk drive letters). FIlled in
                                     ; by SysInit during config.sys processing
                                     ; of the TRAPDUMP=ON,D: statement. Paul.

DATA           ENDS

if RAS                               ;@005SM
ReferGlobal ras_stda_addr,DWORD           ; Refer to BIOS data
endif ;RAS                           ;@005SM

ReferGlobal ABIOS_present,BYTE            ; ABIOS machine
ReferGlobal Initialize_Flags,BYTE         ; Mode Switch Present
ReferGlobal MaxThreads,WORD               ; Maximum threads
ReferGlobal DevConfigTbl                  ; Machine Type
ReferGlobal CurProcPID,WORD
ReferGlobal TaskData,DWORD
ReferGlobal FirstPacket,WORD
ReferGlobal LastPacket,WORD
ReferGlobal SysSemDataTable,DWORD
ReferGlobal papTCBPtrs,WORD

ReferGlobal DBCS_Codepg,WORD     ;code page with DBCS activity  ;J-DB01

ReferFlat       _parvmOne,DWORD           ; arena linear address
ReferFlat       _pobvmOne,DWORD           ; object handle location
ReferFlat       _pgPhysPageDir,DWORD      ; real addr of page dir
ReferFlat       dcm_ote_start,DWORD       ; real addr of dcm_ote_start
ReferFlat       _pgpPageDir,DWORD         ; real addr of _pgpPageDir @#003n
ReferFlat       _pgPhysMax,DWORD          ; last lage of memory @005SM

ReferInitGlobal _StartINITDATA,DWORD

ReferGDT  GDT_Buffers,DWORD

if RAS                                   ;@005SM

        FARCODE LOW
CODE    SEGMENT

PUBLIC      RASRST
EXTRN       RealMode:NEAR                              ; Mode switch code
EXTRNF32    _TKSetSSBase

RASRST  PROC    FAR                                    ; ENTRY POINT FROM DOS
;@82396
;83230 must use 16 bit kiodelay, since Rasrst code segment is use16 (16 bit)
         push    bx                      ; 83230
         push    cx
;delay 500ns to allow scsi adapter to finish processing its interrupts. 83230
         mov     cx,0ffffh
 delay0: kIODelay  bx                    ; 83230
         kIODelay  bx
         loop    delay0
         pop     cx
         pop     bx                      ; 83230

        CLI                                            ; Disable interrupts

     EnterProc                                         ; there is NO stack
                                                       ; exit from this prog.

     FlatContext ds,ax


        mov     eax,[_pgpPageDir]           ; @#003n
        mov     eax,[eax]                   ; fetch page directory entry 0

; This program will use DS as the base reg for DOSGROUP

     DosContext <ds>

        mov     sav_caller_Pdir,eax         ; save page entry 0

; [While in protect mode, store away some useful information for debugging]

        SGDT     gdt_reg                         ; Store GDT Register
        SIDT     idt_reg                         ; Store IDT
        SLDT     ldt_reg                         ; Store LDT
        mov      low_data_seg,ds                 ; Store data segment

        mov      sav_caller_ss,ss                ; @#003n
        mov      sav_caller_esp,esp              ; @#003n

     DosContext es

; This program will use ES as the base reg for DOSGROUP

;if RAS                   ;@005SM removed. An if RAS is before the code segment.
        mov      high_data_seg,es                ; High data Segment
        mov      trace_buf_s,es                  ; point to System Trace
        mov      ax, OFFSET ras_stda_addr        ; get offset
        mov      trace_buf_o,ax                  ; point to System Trace
;endif ;RAS

        mov      ax,ds:MaxThreads                ; Max threads
        mov      max_threads,ax                  ; Max threads

        mov      ax,es:CurProcPID                ; from DOSGROUP  @#001c
        mov      cur_proc_pid, ax                ; data from      @#001c

        mov      task_data_s,es                  ; DOSGROUP segment address
        mov      ax, OFFSET TaskData             ; from DOSGROUP
        mov      task_data_o,ax                  ; offset

        mov      ax,es:FirstPacket               ; from DOSGROUP  @#001c
        mov      first_packet,ax                 ; data from      @#001c

        mov      ax,es:LastPacket                ; from DOSGROUP  @#001c
        mov      last_packet,ax                  ; data from      @#001c

        mov      sys_sem_data_s,es               ; DOSGROUP segment address
        mov      ax, OFFSET SysSemDataTable      ; from DOSGROUP
        mov      sys_sem_data_o,ax               ; offset

        mov      pap_tcb_ptrs_s,es               ; DOSGROUP segment addr @#001n
        mov      ax, OFFSET papTCBPtrs           ; from DOSGROUP         @#001n
        mov      pap_tcb_ptrs_o,ax               ; offset                @#001n

     GDTContext fs

; This program will use FS as the base reg for DOSGDTDATA
        mov      gdt_buffers_s,fs                ; DOSGDTDATA segment address
        mov      ax, OFFSET GDT_Buffers          ; from DOSGDTDATA
        mov      gdt_buffers_o,ax                ; offset


     FlatContext fs

; This program will use FS as the base reg for FLAT

        mov     eax,fs:[_pgPhysMax]            ;@005SM
        inc     eax                         ;@005SM
        mov     totpages,eax             ;@005SM

        lea     eax,dcm_ote_start        ;
        mov     phy_addr_dcm_ote_start,eax       ;

        mov     eax,[_parvmOne]                  ; arena linear address
        mov     lin_addr_arena,eax               ; arena linear address

;        mov     eax,[_pgPhysPageDir]             ; page dir physical address
        mov     eax,cr3                          ; get control reg page data @#003n
        mov     phy_addr_page_dir,eax            ; page dir physical address

        mov     eax,cr2                          ; get control reg page data @005SM
        mov     phy_addr_page_fault,eax          ; page dir physical address @005SM

        mov     eax,[_pobvmOne]                  ; object handle linear address
        mov     lin_addr_objects,eax             ; object handle linear address

;@004SM Get gdtr linear address, add dosgroup selector, change to dpl 0  @004SM
;@004SM Trap d if try to dump during init time, DPL for DOS group = 3    @004SM
;@004SM Later on, tries to use dosgroup (400) as stack. Must be ring 0.  @004SM
        push    eax                       ;                              @004SM
        mov     eax,fs:[_SELGDTLaddr]     ;access gdt table              @004SM
        add     ax,low_data_seg           ;ds & low_data_seg is dosgroup @004SM
;use ax since low_data_seg is a word                                     @004SM
        add     al,gate.g_access          ;update g_access byte (5)      @004SM
        and     byte ptr fs:[eax],9fh     ;set bits 5, 6 to 0 (DPL0)     @004SM
        pop     eax                       ;                              @004SM


     DosInitContext <fs>,ax                      ; get DOSINITDATA address

; This program will use FS as the base reg for DOSINITDATA

        mov     startinit_s,fs                   ; DOSGDTDATA segment address
        mov     ax, OFFSET _StartINITDATA        ; from DOSINITDATA
        mov     startinit_o,ax                   ; offest

                        ;add END_OF_PARM_SIGNATURE - OFF(/0)             @#001n
        mov      dump_signature1,464Fh         ; put OF                  @#001n
                                               ; in parm                 @#001n
                                               ; next position           @#001n
        mov      dump_signature2,0046h         ; put F(/0)               @#001n
                                               ; in parm                 @#001n
                                               ; next position           @#001n

        and      ds:Initialize_Flags,NOT(MASK Mode_Man_Present) ; Mannual
                                                                ; Mode Switch

     assume  fs:nothing

        mov     cx,ss             ; save current SS:SP in CX:DX
        mov     dx,sp
        DosContext ss             ; put DOSGROUP selector in SS
        lea     sp,ras_stkend     ; put our stack end offset in SP
        pushf
        push    eax
        push    ecx
        push    edx
        push    es
        push    ds
        FlatContext <ds,es>,,noassume
        CALLF32  _TKSetSSBase     ; Must do after every stack switch
        pop     ds
        pop     es
        pop     edx
        pop     ecx
        pop     eax
        popf

; [Now put the processor into real mode        ]

        Call     RealMode

     DosContext <ds>              ; RealMode destroys DS, ES, FS

; [Make sure Machine Status Word is clear for Post       ]
        xor  ax,ax                          ;
        lmsw ax                                        ; Clear status word

        push  ds
        pop   es                  ; RealMode destroys DS, ES, FS

;    assume es:DOSGROUP
;     assume es:DosHlpData

; [Now check to see if the Hardware is capable of reseting the hardware
;  neccessary to perform a Stand-alone dump.  If it is not available then
;  this module must reset the hardware.                                   ]

         xor  ax,ax                                    ; clear flag register

; @#002d.if <DevConfigTbl.Config_type eq Config_type_x4> and            @#002d
; @#002d.if <DevConfigTbl.Config_model eq Config_model_286>             @#002d
; @#002d    or   ax,HYBRID_PRESENT_FLAG                ; Hybrid Machine @#002d
; @#002d.endif                                                          @#002d

; model fc & type 19 is 386SX-16 Tortuga                                @#002n
        .if <DevConfigTbl.Config_type eq 019h> and                      @#002n
        .if <DevConfigTbl.Config_model eq 0F8h>                         @#002n
            or   ax,HYBRID_PRESENT_FLAG                ; Hybrid Machine @#002n
        .endif                                                          @#002n

; model fc & type 23 is 386SX-16 Aloha                                  @#002n
        .if <DevConfigTbl.Config_type eq 023h> and                      @#002n
        .if <DevConfigTbl.Config_model eq 0F8h>                         @#002n
            or   ax,HYBRID_PRESENT_FLAG                ; Hybrid Machine @#002n
        .endif

        .if <ABIOS_present eq PRESENT>                ; CBIOS reset
            or   ax,ABIOS_PRESENT_FLAG
        .endif

        .if <DBCS_Codepg ne 0FFFFh> near; DBCS consideration need  ;J-DB01
            or   ax,DCBS_PRESENT_FLAG                              ;J-DB01
        .endif                                                     ;J-DB01

        lea    si,fmtr_parms  ; 11/01/89 pass as a parm, DS too
        movzx  dx,DumpDevice                   ; DX = ASCII character to
                                               ;      identify disk drive

        call    DHF.DosHlpInitSystemDump

        mov    cx,cs                           ; pass as a parm
        lea    si,fmtr_parms                   ; DS:SI pass as a parm
        lea    ax,rasrstend                    ; pass as a parm
        les    bx, DumpProc                    ; ES:BX = addr of system dump
        movzx  dx,DumpDevice                   ; DX = ASCII character to
                                               ;      identify disk drive

        call    DHF.DosHlpSystemDump
rasrstend  equ  $
        ret                                     ; Never comes here

RASRST  ENDP
CODE    ENDS

endif ;RAS                     ;@005SM

        END
