;       SCCSID = @(#)rasstip.asm	6.2 92/01/10
;      SCCSID = @(#)rasstip.asm	6.2 92/01/10
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************
;

                PAGE    ,132;
        TITLE RASSTIP - System Trace Initialization

;**************** START OF SPECIFICATIONS ******************************
;*
;* SUBROUTINE NAME: rasstip                             (STIP)
;*
;* DESCRIPTIVE NAME: RAS System Trace Initialization
;*
;* FUNCTION: Allocate, initialize, and update System Trace Data
;*           Area and save global data for System Trace.
;*
;* NOTES:    This routine is called during System Initialization
;*
;* ENTRY POINT: rasstip
;*    LINKAGE:  CALL near
;*
;* INPUT:
;*       AX = STDA size in bytes or zero for no tracing
;*            If AX is zero, no operation is performed
;*
;*       DS:DX = address of 32 byte array of major event code data
;*               based on TRACE commands included in CONFIG.SYS file

;*
;*       REFERENCED: RASOWNER - owner
;*                  @ras_mec_table - address of Major Event Code array
;*
;* EXIT-NORMAL:
;*       Carry flag = 0
;*       If request is to allocate, System Trace Data Area is created
;*       and the Major Event Code array is initialized with passed data.
;*       Also, the pointers to the STDA and a flag indicating System
;*       Trace is available are saved in the global kernel data area.
;*
;* EXIT-ERROR:
;*       Carry flag = 1 - error occurred while doing requested function.
;*
;* EFFECTS:
;*     Uses: Flags
;*
;* INTERNAL REFERENCES:
;*    ROUTINES: NONE
;*
;* EXTERNAL REFERENCES:
;*    ROUTINES: SegAlloc - allocate fixed, low memory kernel memory
;*              SelToSeg - convert selector to physical segment
;*
;* CHANGES:
;*    96020-11/29/94-Add starting and ending time stamps to STDA structure
;*   152351-04/23/96-Add ISA Bus support for the Dekko Kernel
;*
;**************** END OF SPECIFICATIONS ********************************
;


        .XLIST
  include dosseg.inc                          ;Must be first include file
  include basemaca.inc
  include osmaca.inc
  include mhandle.inc
  include struc.inc
  include mi.inc
  include pmode.inc
  include infoseg.inc
  include systrace.inc
  include mmpha.inc
        .LIST

if RAS

      ModName rasstip
      CpuMode 386

;Externals in CONSTANTS segment

    ReferGlobal ras_mec_table,BYTE
    ReferGlobal ras_stda_addr,WORD
    ReferGlobal ras_stda_phys,WORD
    ReferGlobal ras_systr_flags,BYTE
IFDEF  MMIOPH
    ReferGDT        GDT_MMIOPH,WORD        ; MMIO GDT entry
ENDIF  ;MMIOPH


    EXTRNFAR SegAlloc
    EXTRNFAR SelToSeg
IFDEF  MMIOPH
    EXTRN32 _MMIOPhysicalToLinear
ENDIF  ;MMIOPH
    ;EXTRN    SISData:WORD


    PUBLIC RASSTIP

endif ;RAS

    PUBLIC DekkoPhysAddr                      ; Dekko card Physical Address
                                              ; DO NOT "ifdef mmioph" this out
                                              ; this is a global that should
                                              ; be available for the RAS api
                                              ; worker, _TranslateRAS

IFDEF MMIOPH
     PUBLIC MMIOSegment,MMIOSelector
ENDIF; MMIOPH

    CONSTANTS SEGMENT
      DekkoPhysAddr  dd 0                      ; Dekko card Physical Address
                                               ; DO NOT "ifdef mmioph" this out

IFDEF MMIOPH
      MMIOSegment    dw 0                      ; Memory Mapped IO Segment
      MMIOSelector   dw 0                      ; Memory Mapped IO Selector
ENDIF ;MMIOPH
    CONSTANTS ENDS


if RAS

        FARCODE INIT
INITCODE segment
  ASSUME ds:nothing,es:nothing

; The following header is "read only" as it is in the code segment; the
; reason it is here (rather than the kernel data segment) is so that it will
; be released with the rest of initialization code

  stda_header stda_s <>            ; STDA header (for front of Circ. Buffer)

Procedure RASSTIP
  LocalVar inp_size,WORD           ; Trace Buffer Size
  LocalVar inp_mecptr,DWORD        ; -> Major Code Array
  LocalVar sav_stda_sel,WORD       ; STDA selector
  EnterProc
  pusha                            ; Save Registers
  push ds
  push es


; If system tracing is requested, set up everything.

  .if <ax ne 0> near           ; Is Tracing Requested?
    .if <ax a RV_MAXBUFFSIZE>  ; YES, Is buffer size too large?
      mov ax,RV_MAXBUFFSIZE    ; YES, set to max size
    .endif

; Setup the DEKKO Card for performance tracing.  This includes querying POS
; to determine what memory between 640 and 1 meg is used by the DEKKO

IFDEF MMIOPH
;
; Micro Channel bus discovery 
;
    push  ds                  ; Init time, save everything
    push  es
    pusha
    mov   cx,MAX_SLOTS        ; Number of PS/2 slots to query
    mov   dx,START_SLOT-1     ; slot 1

NextSlot:

    inc   dx
    mov   al,dl               ; slot number
    out   PORT_SELECT,al      ; ask for slot
    push  dx                  ; save slot
    mov   dx,CARD_ID+1
    in    al,dx               ; get upper ID
    xchg  ah,al               ; save upper
    mov   dx,CARD_ID
    in    al,dx               ; Get Lower ID
    pop   dx                  ; Restore Slot
    cmp   ax,DEKKO_ID         ; Is this the dekko?
    jne   slt1                ; No, get next slot
    mov   dx,POS_BASE         ; Yes, query POS for address
    in    al,dx               ; Base address of Dekko
    and   al,DEKKO_MASK       ; Get rid of not care bits
    mov   cx,DEKKO_SLOTS      ; # of choices for dekko
    mov   dl,START_SLOT-2     ; Back up one item
    mov   bx,DEKKO_START      ; Starting segment/selector

NextAddr:

    add   dl,2                ; Get next choice
    cmp   al,dl               ; Is this the correct location?
    jne   slt2                ; No, get next location

    push  ds
    push  es
    pushad
    xor   edi,edi
    mov   di,DEKKO_LIMIT      ; Limit for DEKKO GDT entry: (1024*2)-1 = 0x800
    FlatContext <ds,es>,ax
    push  cx
    push  dx
    push  ds
    DosContext <ds>           ; setup to get the correct physical address
    movzx esi,bx
    shl   esi,4
    mov   DekkoPhysAddr,esi   ; save physical address for use by DosQueryRASInfo
    pop   ds
    CCALL32  _MMIOPhysicalToLinear  <esi, edi> ; convert physical address of DEKKO to Linear
    assume  ds:nothing, es:nothing
    pop   dx
    pop   cx
    popad
    pop   es
    pop   ds

    xor   eax,eax
    out   PORT_SELECT,al                   ; reset slot
    popa
    pop   es
    pop   ds
    jmp   short dkg1                       ; success

slt2:

    add   bx,200h                          ; next location
    loop  NextAddr
    jmp   short dkgf                       ; failure, no bit match

slt1:

    loop NextSlot                          ; Check next slot

dkgf:                                      ; failure

    xor   ax,ax
    out   PORT_SELECT,al                   ; reset slot
    popa
    pop  es
    pop  ds
;    mov  si,dx
;    and  ds:[si],NOT PERFBIT               ; Turn Off Memory Mapped
    jmp  short chk_isa                      ; d152351
dkg1:
    jmp setup_stda
;
; (E)Isa bus discovery, d152351
;  
chk_isa:
    push  ds                  ; Init time, save everything
    push  es
    pusha
    mov   dx,110h
    in    al,dx
    cmp   al,30h
    jne   short rst1
    mov   dx,111h
    in    al,dx
    cmp   al,64h
    jne   short rst1
    mov   dx,110h
    jmp   short rst5

rst1:

    mov   dx,130h
    in    al,dx
    cmp   al,30h
    jne   short rst2
    mov   dx,131h
    in    al,dx
    cmp   al,64h
    jne   short rst2
    mov   dx,130h
    jmp   short rst5

rst2:

    mov   dx,150h
    in    al,dx
    cmp   al,30h
    jne   short rst3
    mov   dx,151h
    in    al,dx
    cmp   al,64h
    jne   short rst3
    mov   dx,150h
    jmp   short rst5

rst3:

    mov   dx,170h
    in    al,dx
    cmp   al,30h
    jne   short rst4
    mov   dx,171h
    in    al,dx
    cmp   al,64h
    jne   short rst3
    mov   dx,170h
    jmp   short rst5
rst4:

    xor   dx,dx

rst5:

    or    dx,dx
    jz    rst10

rst6:                

    xor   eax,eax
    push  dx
    add   dx,2
    in    al,dx
    pop   dx
    and   al,0fh
    or    al,al
    jz    rst10
    shl   eax,13
    or    eax,0c0000h

rst7:
rst8:
rst9:

    push  ds
    push  es
    pushad
    xor   edi,edi
;
    mov di,DEKKO_LIMIT
    mov ebx,eax
    FlatContext <ds,es>,ax
    push cx
    push dx
    push ds
    DosContext <ds>
    mov  esi,ebx
    mov  DekkoPhysAddr,esi  ; save physical address for use by DosQueryRASInfo
    pop  ds
    CCALL32 _MMIOPhysicalToLinear <esi,edi>
    assume  ds:nothing, es:nothing
    pop dx
    pop cx
;
    popad
    pop   es
    pop   ds
    popa
    pop  es
    pop  ds
    jmp short setup_stda

rst10:

    popa
    pop  es
    pop  ds
    mov  si,dx
    and  ds:[si],NOT PERFBIT               ; Turn Off Memory Mapped

setup_stda:

ENDIF ;MMIOPH


    mov [inp_size],ax          ; Save Size of Buffer
    mov [inp_mecptrh],ds       ; DS:DX -> Major Code array (parameter)
    mov [inp_mecptrl],dx
    mov bx,ax                  ; Save size of buffer
    xor ax,ax                  ; Never > 63K
    add bx,SIZE stda_header    ; Add in size of STDA header
    mov ch,D_DATA0             ; ring 0 r/w data
    mov cl,SA_GDT              ; GDT selector
    mov si,HF_FIXED+HF_HIMEM+HF_ZEROINIT ;set up for allocate
    mov di,RASOWNER            ; get owner for SegAlloc

    CALLFAR SegAlloc           ; allocate STDA in fixed, High Memory
    ASSUME ds:nothing,es:nothing

    .if nc near                 ; Error?
      mov [sav_stda_sel],bx     ; NO, save protect mode selector

;set up move parameters to move STDA header ('SYSTRACE' ASCII and pointers)
      mov es,bx                 ; selector of STDA
      mov ax,cs
      mov ds,ax                 ; ds -> local, read-only data
;            ; don't change ax until restore after time stamping is done    96020
     ASSUME ds:DOSCODE
      mov si,OFFSET DOSCODE:stda_header  ; ds:si -> header
      mov cx,SIZE stda_header   ; size of header
      xor di,di                 ; es:di -> Trace Buffer
      rep movsb                 ; Move in header

; 96020- Add starting and ending time stamps to STDA structure
      DosContext ds               ;                                         96020
      ASSUME ds:DOSGROUP          ;                                         96020
      mov cx,WORD PTR ds:SISData.SIS_SecTime ;current time(low order bytes) 96020
      mov es:stda_start_sec,cx    ; save sec,hunds time in record           96020
      mov es:stda_end_sec,cx      ; save sec,hunds time in record           96020
      mov cx,WORD PTR ds:SISData.SIS_HrsTime ;current time(high order bytes)96020
      mov es:stda_start_hrs,cx    ; save hrs, min time in record            96020
      mov es:stda_end_hrs,cx      ; save hrs, min time in record            96020
      mov cx,BYTE PTR ds:SISData.SIS_DayDate ; current day and month        96020
      xchg cl,ch                  ; switch to month and day                 96020
      mov es:stda_start_mon,cx    ; save month and day in record            96020
      mov es:stda_end_mon,cx      ; save month and day in record            96020
      mov cx,WORD PTR ds:SISData.SIS_YrsDate ; current year                 96020
      mov es:stda_start_yrs,cx    ; save year in record                     96020
      mov es:stda_end_yrs,cx      ; save year in record                     96020

;update pointer to end of Circular Buffer in STDA header

      mov ds,ax                 ; restore ds -> local, read-only data       96020
      ASSUME ds:DOSCODE         ;
      mov ax,[inp_size]         ; recover size of buffer
      add ax,SIZE stda_header-1
      mov es:stda_end_buffer,ax ; last byte in circular buffer

; Set up move parameters to move 32 bytes that ds:dx points to, which is the
; major event code array - move it to normal location and also to the Global
; Infoseg for interrogation by API callers of Trace (to enhance perfomance).
;
;Caution - only set up the array after no errors can occur to prevent the
;existence of System Trace because Rasstrp and Rasmacro routines check ONLY
;the array to determine if tracing exists.

      DosContext es
      mov di,OFFSET DOSGROUP:ras_mec_table ; es:di -> Kernel Trace array
      mov cx,RV_MECSIZE                    ; size of table
      lds si,[inp_mecptr]                  ; ds:si -> Major Code Array
      ASSUME ds:nothing

; If we are doing performance tracing then allow the MMIO major code to
; be turned off/on.  If this is not a performance build, then never allow
; the user to touch major code 1

IFNDEF MMIOPH

      and ds:[si],NOT PERFBIT              ; Turn off MMIO Hook

ENDIF  ;MMIOPH

      rep movsb                            ; Move in Major Code Array
      mov di,OFFSET DOSGROUP:SISData.SIS_mec_table  ; ES:DI -> GIS
      mov cx,RV_MECSIZE                    ; size of Major code table
      lds si,[inp_mecptr]                  ; ds:si -> Major code table
      ASSUME ds:nothing
      rep movsb                            ; Move Major Code array to InfoSeg

; Save selector of STDA and indicate System Trace is now available for use in
; kernel global data area and say good completion code.

      mov ax,[sav_stda_sel]                ; save selector for STDA
      mov es:ras_stda_addr,ax
      mov es:ras_stda_phys,ax
      mov es:ras_systr_flags,RF_TRCAVAIL   ; Tracing is available

      clc                                  ; Success

    .endif                                 ; endif SegAlloc succeeded

  .else
    clc                                    ; Everything is OK
  .endif

; recover registers, recover stack, and exit

  pop es
  pop ds
  popa
  LeaveProc
  ret
EndProc RASSTIP

INITCODE ends

endif ;RAS     /* 96020*/

        END


