;	[]===========================================================[]
;
;	NOTICE: THIS PROGRAM BELONGS TO AWARD SOFTWARE INTERNATIONAL(R)
;	        INC. IT IS CONSIDERED A TRADE SECRET AND IS NOT TO BE 	
;	        DIVULGED OR USED BY PARTIES WHO HAVE NOT RECEIVED	
;	        WRITTEN AUTHORIZATION FROM THE OWNER.
;
; 	[]===========================================================[]
;

;R57 ifdef POWRBIOS
;R57 .MODEL  SMALL,STDCALL
;R57 .386
;R57 else
.MODEL  SMALL,BASIC                 ; no underscore, all caps
.386
 OPTION M510,OLDSTDCALL
  include bios.cfg
;R57 endif

;  []==========================================================[]
;
;      This source code is classified as confidential and
;      contains trade secrets owned by Award Software, Inc.
;
;      Copyright 1984, 1996
;      Award Software, Inc.
;      All rights reserved.
;
;  []==========================================================[]
;
;   PAGE  60,132
;   TITLE  DMIPOST  -- DMI Post support
;=============================================================================
; FILE:   DMIPOST.ASM
;
; DESC:   DMI POST support to build and maintain DMI structures
;
;
; BY:     Tim Markey
; DATE:   06/01/96
;=============================================================================
;----------------------------------------------------------------------------
;Rev  Date   Name  Description
;----------------------------------------------------------------------------
;R54A 04/23/99 RAY Fixed compiling error for Non-PnP & Non-DMI BIOS
;R51A 04/01/99 RCH Removed unused external procedures
;R60  02/04/99 KVN Fixed DMI function 54h error in POST
;R59  01/28/99 BAR Support update ESCD DMI in SMM mode.
;		   define switch "Flash_IN_SMBASE"
;R58  01/20/99 RIC Fix that 2a5lhxxx code compile error in DMI_CT.
;R57  10/31/98 RAY Support switch: MULTI_LANGUAGE_SUPPORT so that this file
;		   becomes common for 4.5 & 4.6
;R56  09/29/98 KVN Release DMI and ESCD pool in flash ROM when not define
;		   "ESCD_SUPPORT" and "FLASH_SUPPORT" in BIOS.CFG
;R55  09/18/98 STV 1.Added Type09 slot for "AGP" info.
;		   2.Fixed Type09 slot "In Use" detect error.
;R54  09/16/98 STV Added define "SMBIOS_SUPPORT_VER" EQU for SMBIOS VER.
;R53  08/25/98 KVN Added a function call for all dmipost subroutine during
;		   POST.That can support POST to call DMI function or subroutine.
;R52  08/20/98 KVN Added a external declare for OEM customer
;R51  08/18/98 KVN Removed all build and update type subroutine to DMI_MB.INC
;		   for support OEM customer issue
;R50  08/13/98 STV Added "INTEL(R) CELERON(TM)" for Type04.processor_version 
;R48C 08/10/98 STV Fixed R14 DMI_MAX_POOL_SIZE Define size
;R49  06/29/98 STV Added cpu_speed_table cpu100.
;R48B 06/18/98 STV Added PnpFunc_54h_in_post, PnpFunc_56h_in_post, PnpFunc_57h_in_post
;		   func for DMI func 54h,56h,57h.
;R48A 06/16/98 STV 1.Added DMI_GPNV_Support definition(DMI func 54h).
;		   2.Fixed DMI func 55h,56h,57h.
;R48  05/27/98 STV Added DMI func 55h,56h,57h & change DMI table checksum addr
;============================================================================-

;R54 ifdef DMI_ENABLED
.xlist
;R57 ifndef POWRBIOS
  include common.equ

ifdef DMI_ENABLED			;R54A

  include common.mac
  include cmos.equ
  include pnp.equ
  include bsetup.inc
;R57 endif

include dmi.equ
include dmipost.equ
include dmi_mb.cfg

;R54A ifdef DMI_ENABLED			;R54
ifdef	FLASH_SUPPORT	;R56

post_card macro value
  push  ax
  mov   al,value
  out   80h,al
  pop   ax
  endm

ifdef POWRBIOS

CODE SEGMENT PARA PUBLIC 'CODE'

else

option oldstdcall

g_ram		segment	use16 at 40h
		include	g_ram.inc
g_ram		ends

		include	dmi_mb.ext	;R52
;R48A start
ifdef	DMI_GPNV_support
  extrn	Write_post_mark0:near
  extrn	Write_post_mark1:near
  extrn	Write_post_mark2:near
  extrn	Read_post_mark0:near
  extrn	Clear_post_mark0:near
ifndef	flash_in_smbase		;R60
  extrn	Clear_post_mark1:near
endif	;flash_in_smbase	;R60
  extrn TEMP_MEM:ABS		;R48B
endif	;DMI_GPNV_support
;R48A end

;R57 - starts
ifdef	MULTI_LANGUAGE_SUPPORT
		DECLARE_MULTI_LANGUAGE		;macro to declare externals	
		extrn	fProc_Disp_Language:far
		extrn	X_Display_String:Near
endif	;MULTI_LANGUAGE_SUPPORT
;R57 - ends

ifdef DMI_PS2M_ENABLED				
		extrn	SYSTEM1_BYTE:near	
endif ;DMI_PS2M_ENABLED				
;R51A		extrn	Check_K6_Cpu:near	
		extrn	Read_CpuID:near		

ifndef	P6_BIOS_ONLY				
		extrn	Check_K6_Cpu:near	;R51A
		extrn	Check_IdtCpu:near	
endif;	P6_BIOS_ONLY				

ifdef	P6_BIOS_ONLY				
	extrn	Convert_P6L2_Cache:near		
endif;	P6_BIOS_ONLY				

ifdef	PIIX_ID					
 ifndef	NO_EDO_SUPPORT				
		extrn	DRAM_SPEED_ITEM:near	
 endif;	NO_EDO_SUPPORT				
endif;	PIIX_ID					
ifdef	VT597					
		extrn	Tag_Item:near
ifdef	Have_BankInterleave_Item		
		extrn	SDRAM_BK_Item:near
endif;	Have_BankInterleave_Item		
ifndef NO_PARITY_ITEM				
		extrn	Parity_Item:near
endif; NO_PARITY_ITEM				
		extrn	Bank_01_DRAM_Timing_Item:near
		extrn	Bank_23_DRAM_Timing_Item:near
		extrn	Bank_45_DRAM_Timing_Item:near
endif;	VT597					
ifdef	VT595					
		extrn	Tag_Item:near
		extrn	SDRAM_BK_Item:near
ifndef NO_PARITY_ITEM
		extrn	Parity_Item:near
endif; NO_PARITY_ITEM
		extrn	Auto_Cfg_Item:near
endif;	VT595					
ifdef	VT691					
ifdef	Have_BankInterleave_Item		
		extrn	SDRAM_BK_Item:near
endif;	Have_BankInterleave_Item		
ifndef NO_PARITY_ITEM				
		extrn	Parity_Item:near
endif; NO_PARITY_ITEM				
		extrn	Bank_01_DRAM_Timing_Item:near
		extrn	Bank_23_DRAM_Timing_Item:near
		extrn	Bank_45_DRAM_Timing_Item:near
		extrn	Bank_67_DRAM_Timing_Item:near
endif;	VT691					
ifdef	VT692					
ifdef	Have_BankInterleave_Item		
		extrn	SDRAM_BK_Item:near
endif;	Have_BankInterleave_Item		
ifndef NO_PARITY_ITEM				
		extrn	Parity_Item:near
endif; NO_PARITY_ITEM				
		extrn	Bank_01_DRAM_Timing_Item:near
		extrn	Bank_23_DRAM_Timing_Item:near
		extrn	Bank_45_DRAM_Timing_Item:near
		extrn	Bank_67_DRAM_Timing_Item:near
endif;	VT692					
ifdef	VT501				;R58 - start					
ifdef	Have_BankInterleave_Item		
		extrn	SDRAM_BK_Item:near
endif;	Have_BankInterleave_Item		
ifndef NO_PARITY_ITEM				
		extrn	Parity_Item:near
endif; NO_PARITY_ITEM				
		extrn	Bank_01_DRAM_Timing_Item:near
		extrn	Bank_23_DRAM_Timing_Item:near
		extrn	Bank_45_DRAM_Timing_Item:near
endif;	VT501				;R58 - end

		extrn	GetItem_Value:near
		extrn	post_call_proc:near	
		extrn	dmi_shadow_info:near	
		extrn	Post_Flash_Read:near	
		extrn	Post_Flash_Write:near	
		extrn	Store_DMI_to_Shadow:near
ifdef	BCPOEM_Table
		extrn	System_Ser:near
		extrn	System_Manu:near
		extrn	System_Name:near
endif	;BCPOEM_Table
Temp_DMI_Pool_SEG	EQU	1000h		
Temp_DMI_Pool_OFF	EQU	0		

XGROUP		GROUP	XCODE
XCODE		SEGMENT	USE16 PARA PUBLIC 'XCODE'
		ASSUME	CS:XGROUP,DS:G_RAM,ES:XGROUP
endif

Public  BEGIN_DMI_POST              ; Used to track overall size of
BEGIN_DMI_POST LABEL BYTE           ;  DMI Post 



include dmi_mb.inc                  ; motherboard specific dmi structures
include dmi_ct.inc                  ; chipset specific routines

;R57 build_dmi_msg   db  'Building DMI Pool ',0
;R57 one_struct_msg  db  '.',0
;R57 Verify_dmi_msg  db  'Verifying DMI Pool Data ',0	
;R57 update_dmi_msg  db  ' Update',0				
;R57 success_msg     db  ' Success',0	
;R57 new_line_msg    db  0Dh, 0Ah, 0
;R57 - starts
DEFINE_MSG	build_dmi_msg
	db	'Building DMI Pool ', 0

one_struct_msg	db  '.',0

DEFINE_MSG	Verify_dmi_msg
	db	'Verifying DMI Pool Data ', 0

DEFINE_MSG	update_dmi_msg
	db	' Update', 0

DEFINE_MSG	dmi_success_msg
	db	' Success', 0
new_line_msg    db  0Dh, 0Ah, 0
;R57 - ends
;=============================================================================
; FUNC: Post_DMI_Flash_Write
;Input    :	DS:SI = point to source buffer
;		ES:DI = point to distinct buffer (Range = FD000h-FDFFFh)
;		CX = length
;Output   :	CF = 0 successful
;		CF = 1 fail
;=============================================================================
Post_DMI_Flash_Write	proc	near
		push	si
		push	cx
;R48		mov	cx,DMI_STORAGE_SIZE-1	;get DMI pool size - 1(checksum byte)
;R48start
;R48C ifdef	DMI_GPNV_support
;R48C 		mov	cx,DMI_GPNV_MAX_POOL_SIZE-1	;get DMI pool size - 1(checksum byte)
;R48C else
		mov	cx,DMI_MAX_POOL_SIZE-1		;get DMI pool size - 1(checksum byte)
;R48C endif	;DMI_GPNV_support
;R48end

		xor	ah,ah			;clear value
@@:
		lodsb				;get data
		add	ah,al			;count
		loop	@B			;next loop
		mov	ds:[si],ah		;store to checksum byte
		pop	cx
		pop	si			;restore original SI offset
		F000_call	Post_Flash_Write	;reflash it
		ret
Post_DMI_Flash_Write	endp
;=============================================================================
; FUNC: BUILD_DMI_POOL
;
; DESC: Build and maintain DMI pool.  This function will check to see if there
;       are any structures present, if there are no structures present, then
;       it will build default structures.  If there are structures already
;       present, then it will update the information in these structures to
;       reflect the current state of the system.
;
; IN:   NONE
; OUT:  NONE
;=============================================================================
build_dmi_pool proc uses es

  pusha                             ; save all general registers

;R59 - start
ifdef		Flash_IN_SMBASE
		mov	ax,DMI_STORAGE_BASE
elseifdef      	ESCD_M2	
;R59 - end
;R59 ifdef	ESCD_M2		
		mov	ax,DMI_STORAGE_BASE
else	;ESCD_M2
		mov	ax,DMI_STORAGE_BASE_16
endif	;ESCD_M2
		mov	ds,ax
		mov	si,PARAM_BLOCK_BASE+DMI_TBL_OFFSET
		mov	ax,Temp_DMI_Pool_SEG
		mov	es,ax
		mov	di,Temp_DMI_Pool_OFF
		mov	cx,DMI_STORAGE_SIZE		
		F000_call	Post_Flash_Read		
;R48		mov	cx,DMI_STORAGE_SIZE-1		;get dmi pool size - 1(checksum byte)
;R48start
;R48C ifdef	DMI_GPNV_support
;R48C 		mov	cx,DMI_GPNV_MAX_POOL_SIZE-1	;get dmi pool size - 1(checksum byte)
;R48C else
		mov	cx,DMI_MAX_POOL_SIZE-1		;get dmi pool size - 1(checksum byte)
;R48C endif	;DMI_GPNV_support
;R48end
		xor	ah,ah				;clear counter value
@@:
		mov	al,es:[di]			;get data
		inc	di				;next point
		add	ah,al				;count
		loop	@B				;next loop
		cmp	ah,es:[di]			;checksum value equal?
		je	short @F			;Yes,dont rebuild
		mov	di,Temp_DMI_Pool_OFF		;clear temp DMI pool
		mov	ax,0ffffh			;default value
;R48		mov	cx,DMI_STORAGE_SIZE/2		;size / 2 (for word)
;R48start
;R48C ifdef	DMI_GPNV_support
;R48C 		mov	cx,DMI_GPNV_MAX_POOL_SIZE/2	;size / 2 (for word)
;R48C else
		mov	cx,DMI_MAX_POOL_SIZE/2		;size / 2 (for word)
;R48C endif	;DMI_GPNV_support
;R48end
		rep	stosw				;clear it
		jmp	short Force_Build_DMI		;go to rebuild routine
@@:
  ; Do not rely on GET_DMI_INFORMATION for number of structures
  ; mov   ax,TMP_DMI_SEG1
  ; mov   es,ax
  ; call  get_dmi_information_call    ; get the DMI information
  ; 
  ; xor   di,di                       ; offset from zero
  ; assm  di:ptr get_dmi_info
  ; mov   ax,es:[di].num_struc        ; get number of structures
  ; Do not rely on GET_DMI_INFORMATION for number of structures
  mov   al,NO_SET                   ; or  value - signal to read from flash 
  call  set_dmi_state               ; set state variable for updates  

  call  check_for_structures        ; check if any structures exist

  .if   ax  == DMI_INVALID_HANDLE   ; structure not found
Force_Build_DMI:			
    call  build_dmi_info            ; build the structures
  .endif

  call  update_dmi_info             ; update DMI information

	cli
	F000_call	F000_Shadow_W		; Enable F000 shadow writeable
	mov	ax,Temp_DMI_Pool_SEG
	mov	ds,ax
	mov	si,Temp_DMI_Pool_OFF
	mov	di,0f000h
	mov	es,di
;R48A start
ifdef	DMI_GPNV_support
	push	si
;R48C	mov	si,Temp_DMI_Pool_OFF+DMI_GPNV_MAX_POOL_SIZE
	mov	si,Temp_DMI_Pool_OFF+DMI_MAX_POOL_SIZE		;R48C
;;;;;	mov	di,Shadow_DMI_Address + DMI_GPNV_MAX_POOL_SIZE
	mov	di,Shadow_DMI_Len_Address - GPNV_MIN_BUF_SIZE	; 0ffset 0E00h
	mov	cx,GPNV_MIN_BUF_SIZE
	rep	movsb

	mov	si,offset Write_post_mark0
	mov	word ptr es:[si],9090h
	mov	si,offset Write_post_mark1
	mov	word ptr es:[si],9090h
	mov	si,offset Write_post_mark2
	mov	word ptr es:[si],9090h

	mov	si,offset Read_post_mark0
	mov	word ptr es:[si],9090h

	mov	si,offset Clear_post_mark0
	mov	word ptr es:[si],9090h
ifndef	flash_in_smbase			;R60
	mov	si,offset Clear_post_mark1
	mov	word ptr es:[si],9090h
endif	;flash_in_smbase		;R60

	pop	si
endif	;DMI_GPNV_support
;R48A end
	mov	di,offset dmi_shadow_info	; point to reserved shadow area
	mov	cx,8				; size of signature+max size+num structs
	rep	movsb				; move signature, max size and num structs to shadow
	mov	ax,ds:[si-4]			; get number of structure
	cmp	ax,0ffffh			; check is invalid?
	je	short @F			; Yes,skip store to shadow
	F000_call	Store_DMI_to_Shadow
@@:
	F000_call	F000_Shadow_R		; Enable F000 shadow readonly
	sti

  popa                              ; restore all general registers

  ret

build_dmi_pool endp


;=============================================================================
; FUNC: CHECK_FOR_STRUCTURES
;
; DESC: Attempt to get first DMI structure from DMI Pool
;
; IN:   NONE
; OUT:  AX    - Return value from get dmi structure
;=============================================================================
check_for_structures proc uses es di ds si dx bx
  local dmi_struct_handle:word

  ;  Check to see if one structure already exists
  mov   dmi_struct_handle,0         ; set struct handle to zero, (find first entry)

  push  ss                          ; set ES:DI to point to struct handle
  pop   es                          ; 
  lea   di,dmi_struct_handle            ; 

  mov   dx,TMP_DMI_SEG1             ; set DS:SI to point to dmiStructBuffer
  mov   ds,dx                       ; 
  mov   si,TMP_DMI_OFS1             ; 
  
  mov   dl,al                       ; 
  mov   dh,bh                       ;
  xor   bh,bh                       ;

  call  get_dmi_structure_call      ; get the dmi structure (AX modified)

  ret

check_for_structures endp

;=============================================================================
; FUNC: BUILD_DMI_INFO
;
; DESC: Add DMI structures if not already present.  No optimizations are
;       necessary for this code as it is only performed on first boot.
;       It is safer to update the flash on every change.
;          
; IN:   NONE
; OUT:  NONE
;=============================================================================
; build_dmi_info proc uses ds es fs
build_dmi_info proc uses ds es	
  local last_structure:byte

  pusha

  mov   last_structure,0

ifndef No_show_Updata_DMI_Msg	
  mov   ax, cs
  mov   ds, ax
  mov   si, offset XGROUP:build_dmi_msg
;R57  POST_func_call  Disp_String
;R57 - starts
ifdef	MULTI_LANGUAGE_SUPPORT
  call  fProc_Disp_Language
else	;MULTI_LANGUAGE_SUPPORT
  POST_func_call  Disp_String
endif	;MULTI_LANGUAGE_SUPPORT
;R57 - ends
endif ;No_show_Updata_DMI_Msg	

  push  cs
  pop   ds                          ; code segment contains table
  lea   bx,dmi_tbl                  ; DS:[BX] points to dmi_tbl
  xor   dx,dx                       ; DX = node number

  call  get_set_dmi_buffers         ; get data buffer in ES:DI, work buffer in FS:SI

  .repeat

    call  show_one_dot              ; put a dot one the screen

    assm  di:ptr dmi_set_struct       ; assume DI points to dmi_set_struct struct
    mov   es:[di].command,DMI_ADD_STRUCT ; set command for adding a structure
    assm  bx:ptr dmi_entry          ; 

    push  bx                        ; save index
    add   bx,sizeof dmi_entry       ; point BX to next entry
    .if [bx].info == 0FFFFh         ; 
      mov   last_structure,1        ; signal that this is the last structure
    .endif
    pop   bx                        ; restore index

    movzx cx,[bx].num_entrys        ; get number of structures to include

    .if   cx != 0                   ; if more than zero entrys

      push  cx                      ; save number of entrys
      push  si                      ; save work buffer offset


      mov   si,[bx].info            ; load pointer (DS already set)
      mov   cx,[bx].tsize           ; load size of table
      mov   es:[di].data_length,cx  ; 

      push  di                      ; save dmi buffer offset
      add   di,ofs dmi_set_struct.struc_type
      rep   movsb                   ; copy structure to add onto end of data buffer
      pop   di                      ; restore dmi buffer offset
      pop   si                      ; restore work buffer offset
      pop   cx                      ; restore number of entrys

      assm  di:ptr dmi_set_struct

      .repeat

        .if  last_structure && cx == 1
          push  bx
          mov   bh,SET_INFO_MASK        ; and                        
          mov   bl,LAST_SET             ; or  - signal to flash      
          call  update_dmi_state        ; set state variable for updates  
          pop   bx
        .endif

        .repeat

          mov   es:[di].struc_handle,dx ; update handle
          call  set_dmi_structure_call  ; add the DMI structure
	  jc	short build_dmi_info_exit	
          inc   dx                      ; increment handle number in DX
        .until				

      .untilcxz                     ; loop for number of entrys in CX

    .endif                          ; end if cx != 0

    ;  removed code to change state to MIDDLE_SET

    .if  [bx].build_func != 0       ; get number of structures to include
      push	ds	
      call  [bx].build_func         ; build function (needs only to be called once)
      pop	ds	
    .endif

    add   bx,sizeof dmi_entry       ; point BX to next entry

  .until [bx].info == 0FFFFh        ; until terminator found

;R59 - start
ifdef		Flash_IN_SMBASE
		mov	ax,DMI_STORAGE_BASE
elseifdef      	ESCD_M2	
;R59 - end
;R59 ifdef	ESCD_M2	
		mov	ax,DMI_STORAGE_BASE
else	;ESCD_M2
		mov	ax,DMI_STORAGE_BASE_16
endif	;ESCD_M2
		mov	es,ax
		mov	di,PARAM_BLOCK_BASE+DMI_TBL_OFFSET
		mov	ax,Temp_DMI_Pool_SEG
		mov	ds,ax
		mov	si,Temp_DMI_Pool_OFF
		mov	cx,DMI_STORAGE_SIZE		
		call	Post_DMI_Flash_Write		
		jc	short build_dmi_info_exit
  call  show_success_msg            ; show success message
build_dmi_info_exit:			
	call	clear_line		

  popa                              ; restore all registers

  ret

build_dmi_info endp


;R51;=============================================================================
;R51; FUNC: BUILD_TYPE00 - (BIOS Information)
;R51;
;R51; DESC: Update the structure with current information from POST
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51build_type00 proc uses ds 
;R51
;R51  pusha                             ; save all general registers
;R51
;R51  mov   cx,0                        ; instance of information
;R51  mov   bh,BIOS_INFORMATION         ; BIOS information
;R51  mov   bl,0                        ; no other match required
;R51  call  get_struct_hdr              ; get DMI structure in EDX
;R51  jc    build_type00_exit           ; quit if structure not found
;R51
;R51  mov   si,0f000h			
;R51  mov   ds,si
;R51  mov   si,DATE_STRING_OFFSET       ; add date string
;R51  mov   bl,ofs type00.bios_date     ; date string index
;R51
;R51  call  update_dmi_string           ; change word in structure
;R51
;R51build_type00_exit:
;R51
;R51  popa                              ; restore all general registers
;R51
;R51  ret                               ; 
;R51
;R51build_type00 endp
;R51
;R51
;R51;=============================================================================
;R51; FUNC: BUILD_TYPE05 - (Memory Controller Information)
;R51;
;R51; DESC: Update the structure with current information from POST
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51;       DX    - handle of current structure + 1
;R51; OUT:  NONE
;R51;=============================================================================
;R51build_type05 proc uses ds 
;R51
;R51  pusha                             ; save all general registers
;R51
;R51  mov   ax,dx                       ; save handle in AX
;R51
;R51  mov   cx,0                        ; instance of information
;R51  mov   bh,MEM_CTLR_INFORMATION     ; Memory Controller information
;R51  mov   bl,0                        ; no other match required
;R51  call  get_struct_hdr              ; get DMI structure in EDX
;R51  jc    build_type05_exit           ; quit if structure not found
;R51
;R51  mov   cx,NUM_MEM_SLOTS            ; number of memory slots
;R51
;R51  mov   bl,ofs type05.mem_mod_hndl_list  ; offset
;R51
;R51  .repeat
;R51    mov   bh,DMI_CHANGE_WORD          ; Change single WORD
;R51    call  update_dmi_component        ; change word in structure
;R51    inc   ax                          ; AX = next handle
;R51    add   bl,2                        ; set BL to next handle location
;R51  .untilcxz
;R51
;R51build_type05_exit:
;R51
;R51  popa                              ; restore all general registers
;R51
;R51  ret                               ; 
;R51
;R51build_type05 endp
;R51
;R51
;R51;=============================================================================
;R51; FUNC: BUILD_TYPE06 - (Memory Module Information)
;R51;
;R51; DESC: Update the structure with current information from POST
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51;       DX    - handle of current structure + 1
;R51; OUT:  NONE
;R51;=============================================================================
;R51build_type06 proc uses ds es
;R51
;R51  pusha                             ; save all general registers
;R51
;R51  mov   ax,dx                       ; save handle in AX
;R51  push  cs                          ; set DS to CS
;R51  pop   ds
;R51  xor   cx,cx                       ; clear memory module count in CX
;R51
;R51
;R51  lea   si,mem_bank_connection_table
;R51
;R51  .repeat
;R51
;R51    mov   bh,MEM_MOD_INFORMATION    ; Memory Module information
;R51    mov   bl,0                      ; no other match required
;R51    call  get_struct_hdr            ; get DMI structure in EDX
;R51    jc    build_type06_exit         ; quit if structure not found
;R51
;R51    push  edx
;R51    mov   al,[si]
;R51    mov   bh,DMI_CHANGE_BYTE        ; Change single BYTE
;R51    mov   bl,ofs type06.bank_connection ; offset
;R51    call  update_dmi_component      ; change word in structure
;R51    inc   si                        ; point SI to next bank connection
;R51
;R51    push  si
;R51    movzx bx,cl
;R51    shl   bx,1                      ; word table
;R51    lea   si,mem_string_table       ; get start of mem string table
;R51    mov   si,wptr [si+bx]           ; get pointer to string
;R51    mov   bl,ofs type06.socket_designation ; date string index
;R51    call  update_dmi_string         ; change word in structure
;R51    pop   si
;R51    pop   edx
;R51
;R51    inc   cl                        ; get next instance
;R51
;R51  .until cl >= NUM_MEM_SLOTS
;R51
;R51build_type06_exit:
;R51
;R51
;R51  popa                              ; restore all general registers
;R51
;R51  ret                               ; 
;R51
;R51build_type06 endp

;=============================================================================
; FUNC: UPDATE_DMI_INFO
;
; DESC: Update DMI structures with information which changes and needs to
;       be detected by the BIOS during POST.
;          
;       List of items which need to be updated every POST:
;
;       Processor Information:
;          External Clock             (Done)
;          Current Speed              (Done)
;          Status                     (Done)
;       Memory Module Information:
;          Bank Connections 
;          Current Speed
;          Current Memory Type
;          Installed Size 
;          Enabled Size
;          Error Status
;       Cache Information:
;          Cache Configuration        (Done)
;          Installed Size             (Done)
;          Current SRAM Type          (Done)
;       System Slots (PCI):
;          Current Usage
;          Slot ID 
;       On Board Device Information:
;          Device Status
;       System Event Logging
;
; IN:   NONE
; OUT:  NONE
;=============================================================================
update_dmi_info proc uses ds

  pusha                             ; save all registers

;R59 - start
ifdef		Flash_IN_SMBASE
		mov	ax,DMI_STORAGE_BASE
elseifdef      	ESCD_M2	
;R59 - end
;R59 ifdef	ESCD_M2	
		mov	ax,DMI_STORAGE_BASE
else	;ESCD_M2
		mov	ax,DMI_STORAGE_BASE_16
endif	;ESCD_M2
		mov	ds,ax
		mov	si,PARAM_BLOCK_BASE+DMI_TBL_OFFSET
		mov	ax,Temp_DMI_Pool_SEG
		mov	es,ax
		mov	di,Temp_DMI_Pool_OFF
		mov	cx,DMI_STORAGE_SIZE		
		F000_call	Post_Flash_Read		
ifndef No_show_Updata_DMI_Msg  
  mov   ax, cs
  mov   ds, ax
  mov   si, offset XGROUP:Verify_dmi_msg		
;R57  POST_func_call  Disp_String
;R57 - starts
ifdef	MULTI_LANGUAGE_SUPPORT
  call  fProc_Disp_Language
else	;MULTI_LANGUAGE_SUPPORT
  POST_func_call  Disp_String
endif	;MULTI_LANGUAGE_SUPPORT
;R57 - ends
endif ;No_show_Updata_DMI_Msg	
  and	byte ptr Post_Temp_Byte[bp],not DMI_UPDATE	

  mov   bh,00h
  mov   bl,FIRST_SET
  call  update_dmi_state          ; Set DMI POST State variable     

  push  cs                          ; point DS:BX to dmi_entry table
  pop   ds                          ; 
  lea   bx,dmi_tbl                  ; 

  .repeat

    assm  bx:ptr dmi_entry          ; assume BX points to dmi_entry table

    .if  [bx].update_func != 0      ; get number of structures to include
      call  show_one_dot            ; put a dot one the screen
      push	ds	
      call  [bx].update_func        ; update function
      pop	ds	
    .endif

    add   bx,sizeof dmi_entry       ; point to next entry

  .until [bx].info == 0FFFFh        ; repeat until terminator reached

  test	byte ptr Post_Temp_Byte[bp],DMI_UPDATE
  jz	short update_dmi_info_exit
;R59 - start
ifdef		Flash_IN_SMBASE
		mov	ax,DMI_STORAGE_BASE
elseifdef      	ESCD_M2	
;R59 - end
;R59 ifdef	ESCD_M2	
		mov	ax,DMI_STORAGE_BASE
else	;ESCD_M2
		mov	ax,DMI_STORAGE_BASE_16
endif	;ESCD_M2
		mov	es,ax
		mov	di,PARAM_BLOCK_BASE+DMI_TBL_OFFSET
		mov	ax,Temp_DMI_Pool_SEG
		mov	ds,ax
		mov	si,Temp_DMI_Pool_OFF
		mov	cx,DMI_STORAGE_SIZE		
		call	Post_DMI_Flash_Write		
		jc	short update_dmi_info_exit
ifndef No_show_Updata_DMI_Msg	
  mov   ax,cs
  mov   ds,ax
  mov   si, offset XGROUP:update_dmi_msg
;R57  POST_func_call  Disp_String
;R57 - starts
ifdef	MULTI_LANGUAGE_SUPPORT
  call  fProc_Disp_Language
else	;MULTI_LANGUAGE_SUPPORT
  POST_func_call  Disp_String
endif	;MULTI_LANGUAGE_SUPPORT
;R57 - ends
  call  show_success_msg            ; show success message
endif ;No_show_Updata_DMI_Msg	
update_dmi_info_exit:		
  call	clear_line		

  popa                              ; restore all general registers

  ret

update_dmi_info endp

;R51;=============================================================================
;R51; FUNC: UPDATE_TYPE00 - (BIOS Information)
;R51;
;R51; DESC: Update the structure with current information from POST
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51update_type00	proc	near
;R51	jmp	build_type00
;R51update_type00 endp
;R51
;R51ifdef	BCPOEM_Table
;R51;=============================================================================
;R51; FUNC: UPDATE_TYPE01 - (System Information)
;R51;
;R51; DESC: Update the structure with current information from POST
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51update_type01	proc	near
;R51  pusha                             ; save all general registers
;R51
;R51  mov   cx,0                        ; instance of information
;R51  mov   bh,SYSTEM_INFORMATION       ; SYSTEM information
;R51  mov   bl,0                        ; no other match required
;R51  call  get_struct_hdr              ; get DMI structure in EDX
;R51  jc    build_type01_exit           ; quit if structure not found
;R51
;R51  F000_call	F000_Shadow_W		; Enable F000 shadow writeable
;R51  mov   si,0f000h
;R51  mov   ds,si
;R51  mov   si,offset System_Manu
;R51	mov	bl,20h		; string length
;R51	call	Fill_Zstring	;
;R51  mov   bl,ofs type01.Manufacturer
;R51  call  update_dmi_string           ; change word in structure
;R51	shr	esi,16		
;R51	pop	word ptr ds:[si]
;R51
;R51  mov   si,offset System_Name
;R51	mov	bl,20h		; string length
;R51	call	Fill_Zstring	;
;R51  mov   bl,ofs type01.Product_Name
;R51  call  update_dmi_string           ; change word in structure
;R51	shr	esi,16		
;R51	pop	word ptr ds:[si]
;R51
;R51  mov   si,offset System_Ser
;R51	mov	bl,10		; string length
;R51	call	Fill_Zstring	;
;R51  mov   bl,ofs type01.Serial_Number
;R51  call  update_dmi_string           ; change word in structure
;R51	shr	esi,16		
;R51	pop	word ptr ds:[si]
;R51  F000_call	F000_Shadow_R		; Enable F000 shadow readonly
;R51
;R51build_type01_exit:
;R51
;R51  popa                              ; restore all general registers
;R51
;R51  ret                               ; 
;R51update_type01 endp
;R51;Input : BL = counter
;R51;Input : SI = point offset
;R51Fill_Zstring:
;R51		push	si		;store original SI
;R51		cld
;R51@@:
;R51		lodsb			;load value of string
;R51		cmp	al,0ffh		;Is 0FFh?
;R51		je	short @F	;Yes,found it
;R51		dec	bl		;decrease counter
;R51		jnz	short @B	;Not over then continue
;R51		inc	si		;next point
;R51@@:
;R51		dec	si		;set correct point
;R51		mov	ax,ds:[si]	;store original value
;R51		mov	byte ptr ds:[si],0	;fill to zero
;R51		shl	esi,16		;store to high word of ESI
;R51		pop	si		;restore original SI
;R51		pop	bx
;R51		push	ax		;push original value to stack
;R51		jmp	bx
;R51endif	;BCPOEM_Table
;R51
;R51;=============================================================================
;R51; CPU speed conversion table used for update_type04 function
;R51;=============================================================================
;R51cpu_speed_table label byte
;R51cpu_entry {CPU100, 100}             ;R49 100Mhz
;R51cpu_entry {CPU83, 83}               ; 83 Mhz
;R51cpu_entry {CPU75, 75}               ; 75 Mhz
;R51cpu_entry {CPU66, 66}               ; 66 Mhz
;R51cpu_entry {CPU60, 60}               ; 60 Mhz
;R51cpu_entry {CPU50, 50}               ; 50 Mhz
;R51cpu_entry {CPU40, 40}               ; 40 Mhz
;R51cpu_entry {CPU33, 33}               ; 33 Mhz
;R51cpu_entry {CPU25, 25}               ; 25 Mhz
;R51cpu_entry {CPU20, 20}               ; 20 Mhz
;R51cpu_entry {CPU16, 16}               ; 16 Mhz
;R51cpu_entry {0, 0}                    ; Table Terminator
;R51
;R51null_str	db	0	
;R51Intel_str	db	'Intel',0
;R51
;R51;CPU information for P6 platform
;R51ifdef	P6_BIOS_ONLY
;R51PentiumPro_str:
;R51		db	'Pentium Pro',0	
;R51PentiumII_str:	db	'Pentium II',0			
;R51PentiumII_Celeron_str:	db	"INTEL(R) CELERON(TM)",0	;R50
;R51else;	P6_BIOS_ONLY
;R51;CPU information for P5 platform
;R51Pentium_str	db	'Pentium',0
;R51PentiumMMX_str	db	'Pentium-MMX',0		
;R51Cyrix_str	db	'Cyrix',0
;R51Cy6x86_str	db	'6x86',0
;R51Cy6x86MX_str	db	'6x86MX',0		
;R51AMD_str		db	'AMD',0
;R51AMD_K5_str	db	'AMD-K5',0
;R51AMD_K6_str	db	'AMD-K6',0		
;R51IDT_str		db	'IDT',0
;R51IDT_C6_str	db	'IDT WinChip C6',0
;R51endif;	P6_BIOS_ONLY
;R51
;R51;=============================================================================
;R51; FUNC: UPDATE_TYPE04 - (Processor Information)
;R51;
;R51; DESC: Update the structure with current information from POST
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51update_type04 proc uses ds
;R51
;R51	push	es	
;R51  pusha                             ; save all general registers
;R51
;R51ifdef	P6_BIOS_ONLY
;R51	mov	ecx,2AH			;Power on Config. Reg.
;R51	RDMSR
;R51	test	eax,080000H		;bit 19 on (100Mhz) ?
;R51					;1=100Mhz
;R51	jz	short Not_100MHZ
;R51	mov	al,100			;external clock (100MHZ)
;R51	jmp	ut04_speed_found
;R51Not_100MHZ:
;R51endif	;P6_BIOS_ONLY
;R51
;R51  mov   ax,G_RAM                    ; point DS to BIOS data area (40:)
;R51  mov   ds,ax                       ; 
;R51	xor	bx,bx	
;R51	mov	es,bx	
;R51  mov   ah,byte ptr ds:CPU_CLOCK    ; read CPU clock speed into AH
;R51  and   ah,CPU_CLOCK_MASK           ; 
;R51                                     
;R51  push  cs                          ; point DS:SI to cpu_speed_table
;R51  pop   ds                          ; 
;R51  lea   si,cpu_speed_table          ; 
;R51  assm  si:ptr cpu_entry            ; assume SI points to cpu_entry struct
;R51
;R51  .repeat
;R51    .if   ah == [si].actual_speed   ; if speed matches entry in table
;R51      mov   al,[si].display_speed   ;  then set AL to display speed
;R51      jmp   ut04_speed_found        ; jmp as we are done
;R51    .endif                          ; 
;R51    add   si,sizeof cpu_entry       ; Add size of cpu_entry to SI 
;R51  .until  [si].actual_speed == 0    ; repeat until terminator found
;R51
;R51ut04_speed_found:
;R51
;R51  mov   cx,0                        ; instance of information
;R51  .repeat	
;R51  mov   bh,CPU_INFORMATION          ; cpu information
;R51  mov   bl,0                        ; no other match required
;R51  call  get_struct_hdr              ; get DMI structure in EDX
;R51  jc    ut04_exit                   ; quit if structure not found
;R51
;R51  push	ax	
;R51  push	cx	
;R51  xor   ah,ah                       ; clear upper byte of external clock field
;R51  mov   bl,ofs type04.external_clock  ; offset
;R51  mov   bh,DMI_CHANGE_WORD          ; Change single WORD
;R51  call  update_dmi_component        ; change word in structure
;R51
;R51      mov   ax,CPU_INT_CLOCK[bp]        ; get internal clock speed from table
;R51
;R51  mov   bl,ofs type04.current_speed ; offset
;R51  mov   bh,DMI_CHANGE_WORD          ; Change single WORD
;R51  call  update_dmi_component        ; change word in structure
;R51
;R51	mov	al,41h		;assume CPU enable
;R51	cmp	byte ptr es:[500H],0AAH ;2 CPUs plugged
;R51	je	short @F
;R51	pop	cx
;R51	push	cx
;R51	or	cl,cl
;R51	jz	short @F
;R51	mov	al,42h		;CPU disable by user
;R51@@:
;R51  mov   bl,ofs type04.status		; offset
;R51  mov   bh,DMI_CHANGE_BYTE          ; Change single BYTE
;R51  call  update_dmi_component        ; change word in structure
;R51
;R51	call  ct_get_processor_id_lo      ; get CPU ID (step/model/family)
;R51	cmp	byte ptr es:[500H],0AAH ;2 CPUs plugged
;R51	je	short @F
;R51	pop	cx
;R51	push	cx
;R51	or	cl,cl
;R51	jz	short @F
;R51	xor	eax,eax
;R51@@:
;R51  mov   bl,ofs type04.lo_processor_id ; offset
;R51  mov   bh,DMI_CHANGE_DWORD         ; Change single WORD
;R51  call  update_dmi_component        ; change word in structure
;R51
;R51  push  bx
;R51  mov   bh,SET_INFO_MASK             ; and                            
;R51  mov   bl,LAST_SET                 ; or  - flash                     
;R51  call  update_dmi_state            ; set state variable for updates  
;R51  pop   bx
;R51
;R51  call  ct_get_processor_id_hi      ; get CPU id hi (feature flags)
;R51	cmp	byte ptr es:[500H],0AAH ;2 CPUs plugged
;R51	je	short @F
;R51	pop	cx
;R51	push	cx
;R51	or	cl,cl
;R51	jz	short @F
;R51	xor	eax,eax
;R51@@:
;R51  mov   bl,ofs type04.hi_processor_id ; offset
;R51  mov   bh,DMI_CHANGE_DWORD         ; Change single WORD
;R51  call  update_dmi_component        ; change word in structure
;R51
;R51	cmp	byte ptr es:[500H],0AAH ;2 CPUs plugged
;R51	je	short @F
;R51	pop	cx
;R51	push	cx
;R51	or	cl,cl
;R51	jz	short @F
;R51	mov	al,Unknown
;R51	lea	di,null_str
;R51	mov	si,di
;R51	jmp	Update_CPU_Brand	
;R51@@:
;R51ifdef	P6_BIOS_ONLY					
;R51	pushad						
;R51	post_func_call	Read_CpuID		;get CPU ID  
;R51	cmp	al,30h			;klamath ?	
;R51	popad						
;R51	mov	al,PentiumII		;yes		
;R51	lea	di,PentiumII_str			
;R51ifdef	KLAMATH_CPU_ONLY		;R50
;R51	jae	short P_II_Yes				
;R51else	;KLAMATH_CPU_ONLY		;R50
;R51	jae	short Exit_PCU_str	;R50
;R51endif	;KLAMATH_CPU_ONLY		;R50
;R51
;R51	mov	al,PentiumPro			
;R51	lea	di,PentiumPro_str		
;R51;R50 P_II_Yes:					
;R51;R50 start
;R51ifdef	KLAMATH_CPU_ONLY
;R51P_II_Yes:
;R51	pushad						
;R51	post_func_call	Read_CpuID		;get CPU ID  
;R51	and	al,11110000b		;mask stepping
;R51	cmp	al,60H			;066XH ?
;R51	popad
;R51
;R51	jne	short Exit_PCU_str
;R51	mov	al,PentiumII		;yes
;R51	lea	di,PentiumII_Celeron_str
;R51endif	;KLAMATH_CPU_ONLY
;R51Exit_PCU_str:
;R51;R50 end
;R51else	;P6_BIOS_ONLY				
;R51	mov	al,Pentium
;R51	lea	di,Pentium_str
;R51endif	;P6_BIOS_ONLY				
;R51	lea	si,Intel_str
;R51	mov	bh,CPU_BRAND[bp]
;R51	cmp	bh,CPU_BRAND_INTEL
;R51ifdef	P6_BIOS_ONLY				
;R51	je	short Update_CPU_Brand
;R51else	;P6_BIOS_ONLY
;R51	jne	short @F
;R51
;R51	Post_func_call	Check_IdtCpu		;is IDT C6 CPU ?
;R51	jne	short Not_IdtCpu
;R51	mov	al,Other
;R51	lea	si,IDT_str
;R51	lea	di,IDT_C6_str
;R51	jmp	short Update_CPU_Brand
;R51Not_IdtCpu:
;R51
;R51	pushad
;R51	post_func_call	Read_CpuID		;get CPU ID
;R51	bt	edx,23				;test MMX ?
;R51	popad
;R51	jnc	short Update_CPU_Brand
;R51	lea	di,PentiumMMX_str		;set to MMX string
;R51	jmp	short Update_CPU_Brand
;R51@@:
;R51	cmp	bh,CPU_BRAND_AMD
;R51	jne	short @F
;R51	Post_func_call	Check_K6_Cpu
;R51	mov	al,K5_CPU
;R51	lea	si,AMD_str
;R51	lea	di,AMD_K5_str
;R51	jnz	short Update_CPU_Brand
;R51	lea	di,AMD_K6_str
;R51	jmp	short Update_CPU_Brand
;R51@@:
;R51	cmp	bh,CPU_BRAND_CYRIX
;R51	jne	short @F
;R51	call	Check_M2		
;R51	mov	al,M1_CPU
;R51	lea	si,Cyrix_str
;R51	lea	di,Cy6x86_str
;R51	jnz	short Update_CPU_Brand
;R51	lea	di,Cy6x86MX_str
;R51	jmp	short Update_CPU_Brand
;R51@@:
;R51endif;	P6_BIOS_ONLY				
;R51
;R51
;R51	jmp	short Next_CPU	
;R51
;R51Update_CPU_Brand:
;R51	mov	bl,ofs type04.processor_family
;R51	mov	bh,DMI_CHANGE_BYTE          ; Change single WORD
;R51	call	update_dmi_component        ; change word in structure
;R51	mov	bl,ofs type04.processor_manufacturer
;R51	call	update_dmi_string           ; change stringin structure
;R51	mov	bl,ofs type04.processor_version
;R51	mov	si,di
;R51	call	update_dmi_string           ; change stringin structure
;R51Next_CPU:
;R51	pop	cx
;R51	pop	ax
;R51	inc	cx
;R51  
;R51	.until cx >= NUM_CPU
;R51ut04_exit:
;R51
;R51  popa                              ; restore all general registers
;R51	pop	es	
;R51  assm  si:ptr nothing              ; assume SI points to nothing
;R51
;R51  ret                               ; 
;R51
;R51update_type04 endp
;R51
;R51;Input : None
;R51;Output: ZF = M2
;R51;	 NZ = M1
;R51Check_M2:
;R51	mov	al,0feh			;DIR 0
;R51	out	22h,al
;R51	in	al,23H			;read CPU device ID
;R51	and	al,0f0h
;R51	cmp	al,50h
;R51	ret
;R51
;R51;=============================================================================
;R51; FUNC: UPDATE_TYPE05
;R51;
;R51; DESC: Update the following information:
;R51;       1.  Current Interleave
;R51;
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51update_type05 proc uses ds 
;R51
;R51  pusha                             ; save all general registers
;R51  assm  bx:ptr  dmi_entry         ; assume BX points to dmi_entry
;R51  xor   cx,cx
;R51
;R51    mov   bh,MEM_CTLR_INFORMATION     ; Memory Controller information
;R51    mov   bl,0                        ; no other match required
;R51    call  get_struct_hdr              ; get DMI structure in EDX
;R51    jc    ut05_exit		      ; quit if structure not found
;R51
;R51    ;==========================================================================
;R51    ; Set Current Interleave
;R51    ;==========================================================================
;R51    call  ct_get_dmi_mem_interleave   ; get the memory current interleave for this chipset
;R51    mov   bl,ofs type05.current_interleave ; offset
;R51    mov   bh,DMI_CHANGE_BYTE          ; Change single BYTE
;R51    call  update_dmi_component        ; change structure
;R51
;R51    ;==========================================================================
;R51    ; Set Error Detecting Method
;R51    ;==========================================================================
;R51    call  ct_get_dmi_mem_error_detecting   ; get the memory current interleave for this chipset
;R51    mov   bl,ofs type05.error_detecting ; offset
;R51    mov   bh,DMI_CHANGE_BYTE          ; Change single BYTE
;R51    call  update_dmi_component        ; change structure
;R51
;R51ut05_exit:
;R51  assm  bx:ptr nothing              ; assume BX points to nothing
;R51  popa                              ; restore all general registers
;R51
;R51  ret                               ; 
;R51
;R51update_type05 endp
;R51 
;R51;=============================================================================
;R51; FUNC: UPDATE_TYPE06
;R51;
;R51; DESC: Update the following information:
;R51;       1.  Current Memory Type
;R51;       2.  Current Installed Size
;R51;       3.  Current Enabled Size
;R51;       4.  Current Speed
;R51;
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51update_type06 proc uses ds
;R51
;R51  pusha                             ; save all general registers
;R51
;R51  assm  bx:ptr  dmi_entry         ; assume BX points to dmi_entry
;R51  xor   cx,cx
;R51
;R51  .repeat
;R51
;R51    push  cx
;R51
;R51    mov   bh,MEM_MOD_INFORMATION      ; memory module information
;R51    mov   bl,0                        ; no other match required
;R51    call  get_struct_hdr              ; get DMI structure in EDX
;R51
;R51    .if   carry?
;R51      pop   cx
;R51      jmp   ut06_exit                   ; quit if structure not found
;R51    .endif
;R51
;R51    ;==========================================================================
;R51    ; Set Memory Type
;R51    ;==========================================================================
;R51    call  ct_get_dmi_memory_type      ; get the memory type for this chipset
;R51    mov   bl,ofs type06.current_mem_type ; offset
;R51    mov   bh,DMI_CHANGE_WORD          ; Change single WORD
;R51    call  update_dmi_component        ; change structure
;R51
;R51    ;==========================================================================
;R51    ; Set Installed Size
;R51    ;==========================================================================
;R51    call  ct_get_dmi_mem_size         ; get the memory type for this chipset
;R51    mov   bl,ofs type06.installed_size ; offset
;R51    mov   bh,DMI_CHANGE_BYTE          ; Change single BYTE
;R51    call  update_dmi_component        ; change structure
;R51
;R51    ;==========================================================================
;R51    ; Set Enabled Size
;R51    ;==========================================================================
;R51    mov   bl,ofs type06.enabled_size  ; offset
;R51    mov   bh,DMI_CHANGE_BYTE          ; Change single BYTE
;R51    call  update_dmi_component        ; change structure
;R51
;R51    ;==========================================================================
;R51    ; Set Memory Speed
;R51    ;==========================================================================
;R51    call  ct_get_dmi_mem_speed        ; get the memory speed for this chipset
;R51    mov   bl,ofs type06.current_speed ; offset
;R51    mov   bh,DMI_CHANGE_BYTE          ; Change single BYTE
;R51    call  update_dmi_component        ; change structure
;R51    pop   cx
;R51
;R51    inc   cx
;R51
;R51  .until cx >= NUM_MEM_SLOTS
;R51
;R51ut06_exit:
;R51
;R51  popa                              ; restore all general registers
;R51  assm  bx:ptr nothing              ; assume BX points to nothing
;R51
;R51  ret                               ; 
;R51
;R51update_type06 endp
;R51
;R51;=============================================================================
;R51; FUNC: UPDATE_TYPE07_L1 - (Internal Cache Information)
;R51;
;R51; DESC: Update the structure with current information from POST
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51update_type07_l1 proc uses ds
;R51
;R51  pusha                             ; save all general registers
;R51
;R51  post_func_call  IntCache_Status             ; get internal cache status in AL
;R51  mov   al,80h                      ; assume that cache is on
;R51  .if   zero?
;R51    xor   al,al                     ; Cache is OFF
;R51  .endif
;R51  or    al,TYPE07_CACHE_CFG_INTERNAL ; Internal cache config
;R51  mov   ah,01				
;R51
;R51  mov   cx,0                        ; instance of information
;R51  mov   bh,CACHE_INFORMATION        ; cache information
;R51  mov   bl,0                        ; has to be an internal cache
;R51  call  get_struct_hdr              ; get DMI structure in EDX
;R51
;R51  .if  !carry?
;R51    mov   bl,ofs type07.cache_config ; offset
;R51    mov   bh,DMI_CHANGE_WORD         ; Change single WORD
;R51    call  update_dmi_component       ; change word in structure
;R51  .endif
;R51
;R51ifdef	P6_BIOS_ONLY
;R51	pushad
;R51	post_func_call	Read_CpuID		;get CPU ID
;R51	cmp	al,30h				;Pentium II?
;R51	popad
;R51	mov	ax,32				;Pentium II L1 cache size = 32K
;R51	jae	short Update_Cache_Size		;Yes,jump
;R51	mov	ax,16				;Pentium Pro L1 cache size = 16K
;R51else	;P6_BIOS_ONLY
;R51	mov	bh,CPU_BRAND[bp]
;R51	cmp	bh,CPU_BRAND_INTEL
;R51	jne	short Not_Intel_CPU
;R51	pushad
;R51	post_func_call	Read_CpuID		;get CPU ID
;R51	bt	edx,23				;test MMX ?
;R51	popad
;R51	mov	ax,32				;Pentium-MMX L1 cache size = 32K
;R51	jc	short Update_Cache_Size		;Yes,jump
;R51	mov	ax,16				;Pentium L1 cache size = 16K
;R51	jmp	short Update_Cache_Size
;R51Not_Intel_CPU:
;R51	cmp	bh,CPU_BRAND_AMD
;R51	jne	short Not_AMD_CPU
;R51	Post_func_call	Check_K6_Cpu		;Is K6?
;R51	mov	ax,16				;AMD-K5 L1 cache size = 16K
;R51	jnz	short Update_Cache_Size		;No,jump
;R51	mov	ax,64				;AMD-K6 L1 cache size = 64K
;R51	jmp	short Update_Cache_Size
;R51Not_AMD_CPU:
;R51	call	Check_M2
;R51	mov	ax,16				;Cyrix-M1 L1 cache size = 16K
;R51	jnz	short Update_Cache_Size		;No,jump
;R51	mov	ax,64				;Cyrix-M2 L1 cache size = 64K
;R51endif	;P6_BIOS_ONLY
;R51
;R51Update_Cache_Size:
;R51	push	ax
;R51	mov	bl,ofs type07.install_size	; offset
;R51	mov	bh,DMI_CHANGE_WORD		; Change single WORD
;R51	call	update_dmi_component		; change word in structure
;R51	pop	ax
;R51	mov	bl,ofs type07.max_size		; offset
;R51	mov	bh,DMI_CHANGE_WORD		; Change single WORD
;R51	call	update_dmi_component		; change word in structure
;R51
;R51  popa                              ; restore all general registers
;R51
;R51  ret
;R51
;R51update_type07_l1 endp
;R51
;R51;=============================================================================
;R51; FUNC: UPDATE_TYPE07_02 - (External Cache Information)
;R51;
;R51; DESC: Update the structure with current information from POST
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51update_type07_l2 proc uses ds
;R51
;R51  pusha                             ; save all general registers
;R51
;R51  post_func_call  ExtCache_Status             ; get external cache status in zero flag
;R51  mov   al,80h                      ; assume Cache is ON
;R51  jnz   short @F                    ; if zero than cache is ON
;R51  xor   al,al                       ; Cache is OFF
;R51@@:
;R51  or    al,TYPE07_CACHE_CFG_EXTERNAL ; External cache config
;R51  mov   ah,1                         ; Unknown operational mode
;R51
;R51  mov   cx,1                        ; instance of information
;R51  mov   bh,CACHE_INFORMATION        ; cache information
;R51  mov   bl,0                        ; no other match required
;R51  call  get_struct_hdr              ; get DMI structure in EDX
;R51  jc    ut07_l2_exit                ; quit if structure not found
;R51
;R51  call	ct_get_dmi_cache_config	    
;R51  mov   bl,ofs type07.cache_config  ; offset
;R51  mov   bh,DMI_CHANGE_WORD          ; Change single WORD
;R51  call  update_dmi_component        ; change word in structure
;R51
;R51ifdef	P6_BIOS_ONLY
;R51	mov	eax,2			;read cache isze
;R51	db	0Fh,0A2h		;OP code: CPUID
;R51	post_func_call	Convert_P6L2_Cache	;convert cache size
;R51else;	P6_BIOS_ONLY
;R51
;R51  F000_call  Get_Cache_Size         ; get cache size AL
;R51endif;	P6_BIOS_ONLY					
;R51  xor   ah,ah                       ; 
;R51  or    al,al                       ; 
;R51  .if   !zero?
;R51    mov   cl,al                     ; 
;R51    mov   al,8                      ; 
;R51    shl   ax,cl                     ; 
;R51  .endif
;R51  push  cx
;R51  push  bx
;R51  mov   cx,1                        ; instance of information
;R51  mov   bh,CACHE_INFORMATION        ; cache information
;R51  mov   bl,0                        ; no other match required
;R51  call  get_struct_hdr              ; get DMI structure in EDX
;R51  pop   bx
;R51  pop   cx
;R51  jc    ut07_l2_exit                ; quit if structure not found
;R51
;R51  mov   bl,ofs type07.install_size  ; offset
;R51  mov   bh,DMI_CHANGE_WORD          ; Change single WORD
;R51  call  update_dmi_component        ; change word in structure
;R51
;R51  mov	ax,MAX_L2_SIZE
;R51  mov   bl,ofs type07.max_size  ; offset
;R51  mov   bh,DMI_CHANGE_WORD          ; Change single WORD
;R51  call  update_dmi_component        ; change word in structure
;R51
;R51ut07_l2_exit:                       ; 
;R51
;R51  popa                              ; restore all general registers
;R51
;R51  ret
;R51
;R51update_type07_l2 endp
;R51
;R51;=============================================================================
;R51; FUNC: BUILD_TYPE08 - (Port Connector Information For PS/2 Mouse)
;R51;
;R51; DESC: Update the structure with current port connector information from POST
;R51;					  (     For PS/2 Mouse     )
;R51;          
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51		 
;R51ifdef DMI_PS2M_ENABLED
;R51mouse_no_detect_string   	db  'No '
;R51mouse_detect_string		db  'Detected',0
;R51
;R51update_type08	proc  near
;R51       pusha
;R51       xor        cx,cx
;R51       push       ds
;R51Scan_ps2_mouse_Loop:
;R51       mov        bh,PORT_CON_INFORMATION       ; BIOS information
;R51       mov        bl,0                  	; no other match required
;R51       call       get_struct			; get DMI structure in EDX
;R51     .if   !carry?
;R51       mov        edx,dptr[si]			; put structure header in EDX
;R51       cmp        byte ptr ds:[si].type08.port_type,TYPE08_FUNC_MOUSE ;compare port type == mouse
;R51       jne	short @F			
;R51       cmp        byte ptr ds:[si].type08.internal_connector,ct_ps_2  ;compare internal connector == ps2 
;R51       je	short ps2_mouse_mode
;R51@@:
;R51       inc        cx
;R51       jmp	short Scan_ps2_mouse_Loop	;Scan ps2 mouse subroutine
;R51     .else
;R51       pop      ds 
;R51       jmp      update_type08_exit 
;R51ps2_mouse_mode:
;R51     .endif
;R51       pop	ds
;R51
;R51       mov        si,ofs mouse_detect_string	;si == 'Detected'
;R51       mov        bl,type08.external_ref        ; date string index
;R51       PUSH       gs
;R51       push       0f000h			;SYSTEM1_BYTE start address 
;R51       pop	  gs
;R51       test       byte ptr gs:[SYSTEM1_BYTE],04h;PS2 mouse ?
;R51       jnz        short @F			;Yes 
;R51       mov        si,ofs mouse_no_detect_string ;si == 'No'
;R51@@:
;R51       POP        gs
;R51
;R51       call       update_dmi_string             ; change word in structure
;R51update_type08_exit: 
;R51       popa                                     ; restore all general registers
;R51        
;R51       ret                                      ; 
;R51             
;R51  update_type08 endp
;R51            
;R51endif ;DMI_PS2M_ENABLED
;R51;=============================================================================
;R51; FUNC: UPDATE_TYPE09_PCI
;R51;
;R51; DESC: Update the following information:
;R51;       1.  Current Usage
;R51;       2.  Slot ID = slot number field of PCI interupt routing option
;R51;
;R51; IN:   DS:BX - Table Entry
;R51; OUT:  NONE
;R51;=============================================================================
;R51update_type09_pci proc uses ds
;R51; local route_buffer[IRQ_BUF_SIZE]:byte
;R51
;R51  pusha                             ; save all general registers
;R51
;R51  push  cs
;R51  pop   es
;R51  lea   di,slot_id_tbl              ; load slot ID table into ES:DI
;R51
;R51  xor   cx,cx                       ; clear count in CX
;R51
;R51  .repeat
;R51
;R51    mov   bh,SYS_SLOTS_INFORMATION  ; pci slot information
;R51    mov   bl,ofs type09.slot_type   ; no other match required
;R51    mov   al,TYPE09_SLOT_TYPE_PCI   ; has to be a PCI slot
;R51    call  get_struct_hdr            ; get DMI structure in EDX
;R51    jc    ut09_pci_exit             ; quit if structure not found
;R51
;R51    push  cx
;R51    mov   al,byte ptr es:[di]                ; get device number
;R51    xor   ah,ah                     ; slot id offset 0AH set to zero
;R51    mov   bl,ofs type09.slot_id     ; offset
;R51    mov   bh,DMI_CHANGE_WORD        ; Change single WORD
;R51    call  update_dmi_component      ; change word in structure
;R51
;R51    mov   bl,al                     ; put slot usage  into BL
;R51    call  ct_get_pci_slot_usage     ; return whether slot is used or not
;R51    mov   bl,ofs type09.current_usage ; offset
;R51    mov   bh,DMI_CHANGE_BYTE        ; Change single BYTE
;R51    call  update_dmi_component      ; change word in structure
;R51
;R51
;R51    inc   di                        ; get next slot id
;R51    pop   cx
;R51    inc   cx
;R51  
;R51  .until cx >= NUM_PCI              ; instance of information
;R51
;R51ut09_pci_exit:                      ; quit
;R51
;R51  popa                              ; restore all general registers
;R51
;R51  ret
;R51
;R51update_type09_pci endp

;=============================================================================
; Utitity Functions Area
;=============================================================================

;=============================================================================
; FUNC: GET_STRUCT_HDR
;
; DESC: Get the structure header which matches the type passed in BH
;
; IN:   BH      - Type
;       CL      - Instance
;       BL      - offset for compare field
;       AL      - compare value if BL is not zero
; OUT:  EDX     - 4 byte header
;       CY      - structure not found
;=============================================================================
get_struct_hdr proc uses ds si

  call  get_struct
  .if   !carry?
    mov   edx,dptr [si]       ; put structure header in EDX
  .endif

  ret

get_struct_hdr endp

;=============================================================================
; FUNC: GET_STRUCT
;
; DESC: Get the structure header which matches the type passed in BH
;
; IN:   BH      - Type
;       CL      - Instance
;       BL      - offset for compare field
;       AL      - compare value if BL is not zero
; OUT:  DS:SI   - Structure
;       CY      - structure not found
;=============================================================================
get_struct proc uses ax bx cx dx es di 
  local dmi_struct_handle:word
  local ret_struct_hdr:dword

  mov   dmi_struct_handle,0         ; set struct handle to zero, (find first entry)

  push  ss                          ; set ES:DI to point to struct handle
  pop   es                          ; 
  lea   di,dmi_struct_handle        ; 

  mov   dx,TMP_DMI_SEG1             ; set DS:SI to point to dmiStructBuffer
  mov   ds,dx                       ; 
  mov   si,TMP_DMI_OFS1             ; 
  
  assm  si:ptr dmi_struct_hdr       ; assume si points to dmi_struct_hdr

  mov   dl,al                       ; 
  mov   dh,bh
  xor   bh,bh

  .repeat
    call  get_dmi_structure_call    ; get the dmi structure (AX modified)

    .if   [si].dmi_type == dh 

      .if bx == 0 || [si+bx] == dl  
                                    ; if dmi structure type matches type looking for
        .if cx > 0                  ; if instance counter (CX) greate than zero
          dec   cx                  ; decrement instance counter (CX)
        .else                       ; else cx == 0
          clc                       ; signal that structure found
          jmp   exit                ; exit, we found structure
        .endif                      ; endif else

      .endif

    .endif                          ; 
  .until  dmi_struct_handle == 0FFFFh   ; repeat until terminator returned

gs_error:                           ; error 

  stc                               ; signal that structure not found

exit:

  ret

get_struct endp


;=============================================================================
; FUNC: UPDATE_DMI_STRING
;
; DESC: Update DMI string with new string
;
;  IN:  DS:SI - New String
;       BL    - String Number to change
;       EDX   - Structure header
;               
; OUT:  NONE
;=============================================================================
update_dmi_string proc uses es fs

  pusha                             ; save all general registers

  xor   cx,cx                       ; clear count in cx

  push  si                          ; save string pointer SI
  .repeat                           ;
    lodsb                           ; load character into AL
    inc   cx                        ; increment CX for each character
  .until  al  == 0                  ; repeat until terminating zero found
  pop   si                          ; restore string pointer SI

  push  TMP_DMI_SEG1                ; set ES to data buffer segment 
  pop   es                          ; 
  mov   di,TMP_DMI_OFS1             ; set DI to data buffer offset

  assm  di:ptr dmi_set_struct       ; assume DI points to dmi_set_struct

  mov   es:[di].data_length,cx      ; fill in string length
  mov   es:[di].field_ofs,bl        ; field offset to modify
  mov   es:[di].command,DMI_CHANGE_STRING ; command (either change BYTE, WORD, or DWORD)
  mov   dptr es:[di].struc_type,edx ; 4 byte structure header to modify

  push  di                          ; save pointer to change string struct
  add   di,sizeof dmi_set_struct    ; point to location to copy the string
  rep   movsb                       ; copy the string
  pop   di                          ; restore pointer to change string struct
  
  push  TMP_DMI_SEG2                ; set FS to work buffer segment 
  pop   fs                          ; 
  mov   si,TMP_DMI_OFS2             ; set SI to work buffer offset

  call  set_dmi_structure_call      ; set the DMI structure
  jc	short @F
  or	byte ptr Post_Temp_Byte[bp],DMI_UPDATE
@@:
  assm   di:ptr none                ; assume nothing
  popa                              ; restore all general registers

  ret

update_dmi_string endp


;=============================================================================
; FUNC: UPDATE_DMI_COMPONENT
;
; DESC: Update DMI structure with new information
;
;  IN:  BH    - Command Type, either:
;               DMI_CHANGE_BYTE      - Change byte
;               DMI_CHANGE_WORD      - Change word
;               DMI_CHANGE_DWORD     - Change dword
;       EAX   - New Value
;       EDX   - Structure header
;       BL    - Offset of new value
;               
; OUT:  NONE
;=============================================================================
update_dmi_component proc uses es fs

  push	ds	
  push	es	
  pusha                             ; save all general registers

  call  get_set_dmi_buffers         ; get data buffer in ES:DI, work buffer in FS:SI

  assm  di:ptr dmi_set_struct       ; assume DI points to dmi_set_struct
  mov   es:[di].field_ofs,bl        ; field offset to modify
  mov   es:[di].command,bh          ; command (either change BYTE, WORD, or DWORD)
  mov   es:[di].change_mask,00000000h ; ANDing Mask
  mov   es:[di].change_value,eax    ; New Value (ORing Mask)
  mov   dptr es:[di].struc_type,edx ; 4 byte structure header to modify
  
  call  set_dmi_structure_call      ; set the DMI structure
  jc	short udc_exit		
  or	byte ptr Post_Temp_Byte[bp],DMI_UPDATE

udc_exit:

  assm   di:ptr none                ; assume nothing
  popa                              ; restore all general registers
  pop	es	
  pop	ds	

  ret

update_dmi_component endp


;=============================================================================
; FUNC: GET_SET_DMI_BUFFERS
;
; DESC: Setup pointer to work buffer for function: SET_DMI_STRUCTURE_CALL
;       
; IN:   NONE
; OUT:  ES:DI - Data Buffer
;       FS:SI - Work Buffer
;  Do not use TMP_DMI_SEG2 for anything other than the work buffer segment
;=============================================================================
get_set_dmi_buffers proc

  push  TMP_DMI_SEG1                ; set ES to data buffer segment 
  pop   es                          ; 
  mov   di,TMP_DMI_OFS1             ; set DI to data buffer offset
  push  TMP_DMI_SEG2                ; set FS to work buffer segment 
  pop   fs                          ; 
  mov   si,TMP_DMI_OFS2             ; set SI to work buffer offset

  ret

get_set_dmi_buffers endp

;=============================================================================
; FUNC: SHOW_ONE_DOT
;
; DESC: Show one dot on the screen
;
; IN:   NONE
; OUT:  NONE
;=============================================================================
show_one_dot proc uses ax si ds

ifndef No_show_Updata_DMI_Msg	
  mov   ax, cs
  mov   ds, ax
  mov   si, offset XGROUP:one_struct_msg
  POST_func_call  Disp_String
endif ;No_show_Updata_DMI_Msg	

  ret

show_one_dot endp


;=============================================================================
; FUNC: SHOW SUCCESS MSG
;
; DESC: Show one dot on the screen
;
; IN:   NONE
; OUT:  NONE
;=============================================================================
show_success_msg proc uses ax si ds

ifndef No_show_Updata_DMI_Msg	
;R57  mov   si,offset XGROUP:success_msg
  mov   si,offset XGROUP:dmi_success_msg		;R57
  mov   ax,cs
  mov   ds,ax
;R57  POST_func_call  Disp_String
;R57 - starts
ifdef	MULTI_LANGUAGE_SUPPORT
  call  fProc_Disp_Language
else	;MULTI_LANGUAGE_SUPPORT
  POST_func_call  Disp_String
endif	;MULTI_LANGUAGE_SUPPORT
;R57 - ends

;  call  disp_str_in_post            ; display success for building
;  call  F000_Vcrlf
endif ;No_show_Updata_DMI_Msg	

  ret

show_success_msg endp

;=============================================================================
; FUNC: CLEAR_LINE
;
; DESC: Clear Line
;
; IN:   NONE
; OUT:  NONE
;=============================================================================
clear_line proc uses ax si ds

ifndef No_show_Updata_DMI_Msg	
  mov   si,offset XGROUP:new_line_msg
  mov   ax,cs
  mov   ds,ax
	POST_func_call	Disp_String
endif ;No_show_Updata_DMI_Msg	

  ret

clear_line endp


;=============================================================================
; FUNC: UPDATE_DMI_STATE
;
; DESC: Set the current DMI update state
;
; IN:   BH    - And Value
;       BL    - Or Value
; OUT:  NONE
;=============================================================================
update_dmi_state proc uses ax

  call  get_dmi_state
  and   ah,bh                     ; clear
  or    al,bl                     ; set
  call  set_dmi_state

  ret

update_dmi_state endp


;=============================================================================
; FUNC: GET_DMI_STATE
;
; DESC: Get the current DMI update state
;
; IN:   NONE
; OUT:  AL    - Current State
;=============================================================================
get_dmi_state proc uses ds bx

  mov   bx,G_RAM
  mov   ds,bx
  mov	al,ds:DMI_STATE	

  ret

get_dmi_state endp

;=============================================================================
; FUNC: SET_DMI_STATE
;
; DESC: Set the current DMI update state
;
; IN:   AL    - New State
; OUT:  NONE
;=============================================================================
set_dmi_state proc uses ds bx

  mov   bx,G_RAM
  mov   ds,bx
  mov	ds:DMI_STATE,al	

  ret

set_dmi_state endp


cpuid macro
  db  0Fh
  db  0A2h
endm

;=============================================================================
; FUNC: CT_GET_PROCESSOR_ID_LO
;
; DESC: Get the processor ID in EAX
;
; IN:   NONE
; OUT:  EAX  - Processor ID
;=============================================================================
ct_get_processor_id_lo proc uses edx

  mov   eax,1                     ; signal to return information
	;--- if not set CPU ID (e.g. CYRIX CPU) in DMI pool then LDCM can't
	;--- show processor information in Basic Hardware component
	cmp	byte ptr CPU_BRAND[bp],CPU_BRAND_CYRIX
	je	short @F
  cpuid

@@:
  ret

ct_get_processor_id_lo endp

;=============================================================================
; FUNC: CT_GET_PROCESSOR_ID_HI
;
; DESC: Get the processor ID in EAX
;
; IN:   NONE
; OUT:  EAX  - Processor ID
;=============================================================================
ct_get_processor_id_hi proc uses edx

  mov   eax,1                     ; signal to return information
	;--- if not set CPU ID (e.g. CYRIX CPU) in DMI pool then LDCM can't
	;--- show processor information in Basic Hardware component
	cmp	byte ptr CPU_BRAND[bp],CPU_BRAND_CYRIX
	je	short @F
  cpuid
  mov   eax,edx

@@:
  ret

ct_get_processor_id_hi endp


;=============================================================================
; FUNC: CT_GET_PCI_SLOT_USAGE
;
; DESC: Get whether the PCI slot is in use
;
;R55 IN:   BL      - Device / Function Number
; IN:   BX      - Bus / Device / Function Number  ;R55
;          BH   - Bus Number			  ;R55
;          BL   - Device / Function Number	  ;R55
; OUT:  AL      - slot usage
;=============================================================================
ct_get_pci_slot_usage proc uses bx cx di

  assm  di: ptr pci_routing_tbl

  mov   ah,PCI_FUNCTION_ID
;R55  mov   bh,0                        ; bus number
  mov   di,DEVICE_ID                ; register number
  mov   al,09h
  int   1ah

  .if   cx  == 0FFFFh               ; if slot is empty
    mov   al,TYPE09_USAGE_AVAILABLE ; slot is available
  .else
    mov   al,TYPE09_USAGE_INUSE     ; slot is in use
  .endif

  ret

ct_get_pci_slot_usage endp

;=============================================================================
; FUNC: SET_DMI_STRUCTURE_CALL
;
; DESC: Add new DMI structure to structure pool by calling DMI function
;       52h, Add DMI structure
;
; IN:   CX    - size of structure to add 
;       ES:DI - Data Buffer
;       FS:SI - Work Buffer
; OUT:  AX    - Return Code
;       00h   - Function Completed Successfully
;       83h   - Invalid handle
;       84h   - Invalid parameter
;       87h   - Insufficient storage space
;=============================================================================

set_dmi_structure_call proc uses bx

  xor   ah,ah
  call  get_dmi_state                                                        
  mov   bl,al                       ; save state variable                    
  and   al,SET_INFO                 ; seperate out state info                
  .if   al == FIRST_SET                                                      
                                                                             
    mov   bh,SET_INFO_MASK           ; and                           
    mov   bl,MIDDLE_SET             ; or  - dont read or flash       
    call  update_dmi_state          ; set state variable for updates 

    mov   al,0                      ; Read in pool, don't flash              
                                                                             
  .elseif al == LAST_SET                                                     
    mov   al,SET_DMI_POOL+DONT_READ_IN_POOL ; Don't Read in pool, flash      
                                                                             
    .if   bl & UPDATE_DMI_POOL                                               
      or    al,FORCE_UPDATE         ; Force update of POOL, even if no change
    .endif                                                                   
                                                                             
  .elseif al == MIDDLE_SET                                                                 
    mov   al,DONT_READ_IN_POOL      ; Don't Read in pool, don't flash        
  .else
    mov   al,SET_DMI_POOL           ; normal operation
  .endif                                                                     

	call	Set_DMI_to_Temp_Pool   

	pushf			       
    mov   bh,0FFh
    mov   bl,UPDATE_DMI_POOL        ; Update DMI pool at end of POST 
    call  update_dmi_state          ; Set DMI POST State variable    
	popf			       

  ret

set_dmi_structure_call endp

;Input	: ES:DI = data buffer address
Set_DMI_to_Temp_Pool:
		push	ds
		pusha

		mov	ax,Temp_DMI_Pool_SEG
		mov	ds,ax
		mov	si,Temp_DMI_Pool_OFF
		mov	dword ptr ds:[si],DMI_SIGNATURE
		add	si,DMI_SIGNATURE_SIZE
		mov	ax,word ptr ds:[si]		;DMI pool total number structures
		mov	bx,word ptr ds:[si+2]		;DMI pool maximum size structures
		add	si,DMI_INFO_SIZE
Check_Next_Struct:
		mov	dh,byte ptr es:[di].command
		mov	cx,word ptr ds:[si]
		add	si,2				;point to struct start
		cmp	cx,0ffffh
		je	short No_else_struct
		mov	dl,byte ptr ds:[si].dmi_handle	;get struct handle
		cmp	dl,byte ptr es:[di].struc_handle
		je	short Set_DMI_Struct
		add	si,cx
		jmp	short Check_Next_Struct
No_else_struct:
		cmp	dh,DMI_ADD_STRUCT
		jne	SDTP_Exit
		mov	cx,word ptr es:[di].data_length
		mov	word ptr ds:[si-2],cx

		cmp	ax,0ffffh			;DMI pool num_structs is invalid?
		jne	short @F			;No,jump
		xor	ax,ax				;clear DMI pool num_structs
@@:
		inc	ax
		mov	word ptr ds:[Temp_DMI_Pool_OFF+DMI_SIGNATURE_SIZE].num_structs,ax

		cmp	bx,0ffffh			;DMI pool max_struct_size is invalid?
		je	short update_max_struct_size	;Yes,jump
		cmp	bx,cx				;new struct size less than max_struct_size
		jae	short @F			;Yes,skip don't update max_struct_size
update_max_struct_size:
		mov	word ptr ds:[Temp_DMI_Pool_OFF+DMI_SIGNATURE_SIZE].max_struct_size,cx
@@:

		add	di,size dmi_set_struct-size dmi_struct_hdr
;LDCM-start
		movzx	bx,byte ptr es:[di].dmi_len
		xor	dx,dx
		push	si
		push	cx
;LDCM-end
@@:
		mov	al,byte ptr es:[di]
; LDCM-start
		cmp	cx,1				;string terminator signature
		je	short Not_Str_Start		;Yes,skip
		or	bx,bx				;string start offset
		jnz	short Not_Str_Start		;No,skip
		inc	bl
		inc	dh				;increase string counter
		or	al,al				;Is string terminator
		jnz	short Not_Str_Start		;No,skip
		cmp	dh,1				;Null string?
		mov	dh,0				;Clear string counter
		jne	short Not_Str_Start		;Not null string then skip
		mov	byte ptr ds:[si],' '		;Force store space char
		inc	si
		inc	dl
Not_Str_Start:
		dec	bx
; LDCM-end
		mov	byte ptr ds:[si],al
		inc	si
		inc	di
		loop	@B
;LDCM-start
		pop	cx
		pop	si
		xor	dh,dh
		add	cx,dx
		mov	word ptr ds:[si-2],cx
		cmp	word ptr ds:[Temp_DMI_Pool_OFF+DMI_SIGNATURE_SIZE].max_struct_size,cx
		jae	short @F
		mov	word ptr ds:[Temp_DMI_Pool_OFF+DMI_SIGNATURE_SIZE].max_struct_size,cx
@@:
;LDCM-end
		clc
		jmp	SDTP_Exit
Set_DMI_Struct:
		movzx	bx,byte ptr es:[di].field_ofs
		mov	eax,dword ptr es:[di].change_mask
		mov	ecx,dword ptr es:[di].change_value
		cmp	dh,DMI_CHANGE_BYTE
		jne	short Not_CHANGE_BYTE
		mov	ah,al
		not	ah
		and	ah,byte ptr ds:[si][bx]
		cmp	ah,cl
		stc
		je	SDTP_Exit
		and	byte ptr ds:[si][bx],al
		or	byte ptr ds:[si][bx],cl
		clc
		jmp	SDTP_Exit
Not_CHANGE_BYTE:
		cmp	dh,DMI_CHANGE_WORD
		jne	short Not_CHANGE_WORD
		mov	di,ax
		not	di
		and	di,word ptr ds:[si][bx]
		cmp	di,cx
		stc
		je	SDTP_Exit
		and	word ptr ds:[si][bx],ax
		or	word ptr ds:[si][bx],cx
		clc
		jmp	SDTP_Exit
Not_CHANGE_WORD:
		cmp	dh,DMI_CHANGE_DWORD
		jne	short Not_CHANGE_DWORD
		mov	edi,eax
		not	edi
		and	edi,dword ptr ds:[si][bx]
		cmp	edi,ecx
		stc
		je	SDTP_Exit
		and	dword ptr ds:[si][bx],eax
		or	dword ptr ds:[si][bx],ecx
		clc
		jmp	SDTP_Exit
Not_CHANGE_DWORD:
		cmp	dh,DMI_ADD_STRUCT
		jne	short Not_ADD_STRUCT

		stc
		jmp	SDTP_Exit
Not_ADD_STRUCT:
		cmp	dh,DMI_DEL_STRUCT
		jne	short Not_DEL_STRUCT

		stc
		jmp	SDTP_Exit
Not_DEL_STRUCT:
		cmp	dh,DMI_CHANGE_STRING
		jne	Not_CHANGE_STRING
;----- Temp DMI pool change string function -----
		push	si				;store struct start offset
		mov	al,byte ptr ds:[si][bx]		;get string number
		movzx	cx,byte ptr ds:[si].dmi_len	;get struct length
		add	si,cx
Search_next_match_string:
		push	si
		xor	ah,ah				;assume string same
		mov	bx,size	dmi_set_struct
@@:
		mov	dl,byte ptr ds:[si]
		cmp	dl,byte ptr es:[di][bx]
		je	short String_Char_Same
		or	ah,1
String_Char_Same:
		cmp	byte ptr ds:[si],0
		je	short @F
		inc	si
		inc	bx
		jmp	short @B
@@:
		pop	cx
		dec	al
		jz	short get_string_start_offset
		inc	si
		jmp	short Search_next_match_string
get_string_start_offset:
		pop	bx			;restore struct start offset to BX
		or	ah,ah
		jnz	short @F
		stc
		jmp	short SDTP_Exit
@@:
		push	cx			;store change string offset
		mov	ax,si
		sub	ax,cx
		inc	ax
		mov	cx,word ptr es:[di].data_length
		sub	cx,ax
		pushf				
		add	word ptr ds:[bx-2],cx	;adjust struct total length
		popf				
		jz	short override_string
		jc	short over_original_string
		mov	ax,cx
		push	es
		push	di
;R48C ifdef	DMI_GPNV_support						
;R48C 		mov	di,Temp_DMI_Pool_OFF+DMI_GPNV_MAX_POOL_SIZE-1	
;R48C else									
		mov	di,Temp_DMI_Pool_OFF+DMI_MAX_POOL_SIZE-1	
;R48C endif	;DMI_GPNV_support						
		mov	cx,di
		sub	cx,si
		sub	cx,ax
		mov	si,di
		sub	si,ax
		push	ds
		pop	es
		std
		rep	movsb
		pop	di
		pop	es
		jmp	short override_string
over_original_string:



		pop	cx
		push	cx
		add	cx,word ptr es:[di].data_length
		push	es
		push	di
		mov	di,cx
;R48C ifdef	DMI_GPNV_support						
;R48C 		mov	cx,Temp_DMI_Pool_OFF+DMI_GPNV_MAX_POOL_SIZE-1	
;R48C else									
		mov	cx,Temp_DMI_Pool_OFF+DMI_MAX_POOL_SIZE-1
;R48C endif	;DMI_GPNV_support						
		sub	cx,si
		inc	si
		push	ds
		pop	es
		rep	movsb
		pop	di
		pop	es





override_string:
		pop	si
		mov	bx,size	dmi_set_struct
		mov	cx,word ptr es:[di].data_length
@@:
		mov	al,byte ptr es:[di][bx]
		mov	byte ptr ds:[si],al
		inc	si
		inc	bx
		loop	@B
		cld
		clc
		jmp	short SDTP_Exit
Not_CHANGE_STRING:

SDTP_Exit:
		popa
		pop	ds
		ret

;=============================================================================
; FUNC: GET_DMI_STRUCTURE_CALL
;
; DESC: Get the DMI structure
;
; IN:   ES:DI - Structure
;       DS:SI - dmiStrucBuffer
; OUT:  AX    - Return Code
;       00h   - Function Completed Successfully
;       83h   - Invalid handle
; MODIFIED: Structure       - Contains handle to next available structure
;           dmiStructBuffer - Contains the Structure requested
;=============================================================================
get_dmi_structure_call proc
		push	ds
		pusha
		mov	al,DMI_INVALID_HANDLE
		push	es
		push	di
		mov	dx,word ptr es:[di]
		mov	bx,0ffffh
		mov	di,Temp_DMI_Pool_SEG
		mov	es,di
		mov	di,Temp_DMI_Pool_OFF
		cmp	dword ptr es:[di],DMI_SIGNATURE
		jne	short GDSC_exit
		add	di,DMI_SIGNATURE_SIZE+size dmi_info_struct
		xor	ah,ah
Get_Struct_Loop:
		mov	cx,word ptr es:[di]
		cmp	cx,0ffffh
		je	short Scan_Over
		add	di,2
		or	dx,dx
		jz	short Got_First_Struct
		cmp	word ptr es:[di].dmi_handle,dx
		jne	short Not_got_struct
Got_First_Struct:
		or	ah,ah			;if got it?
		jnz	short Not_got_struct	;Yes,dont duplicate got it
		push	cx
		push	si
		push	di
@@:
		mov	al,byte ptr es:[di]
		mov	byte ptr ds:[si],al
		inc	si
		inc	di
		loop	@B

		pop	di
		pop	si
		pop	cx
		or	ah,1			;got struct component
Not_got_struct:
		cmp	word ptr es:[di].dmi_handle,dx
		jbe	short Next_Struct
		cmp	word ptr es:[di].dmi_handle,bx
		jae	short Next_Struct
		mov	bx,word ptr es:[di].dmi_handle
Next_Struct:
		add	di,cx
;R48C ifdef	DMI_GPNV_support						
;R48C 		cmp	di,Temp_DMI_Pool_OFF+DMI_GPNV_MAX_POOL_SIZE	
;R48C else									
		cmp	di,Temp_DMI_Pool_OFF+DMI_MAX_POOL_SIZE
;R48C endif	;DMI_GPNV_support						
		jb	short Get_Struct_Loop
Scan_Over:
		mov	al,DMI_SUCCESS
GDSC_exit:
		pop	di
		pop	es
		mov	word ptr es:[di],bx
		xor	ah,ah
		mov	ds,ax
		popa
		mov	ax,ds
		pop	ds
  ret

get_dmi_structure_call endp
        
;  This function not currently needed                               
;=============================================================================
; FUNC: GET_DMI_INFORMATION_CALL
;
; DESC: Get the DMI information
;
; IN:   ES:0  - Structure Segment
; OUT:  AX    - Return Code
;=============================================================================
; get_dmi_information_call proc
; 
;   push  0F000h                         ; BiosSelector
;   push  es                             ; 
;   push  ofs get_dmi_info.storage_size  ; DMIStorageSize
;   push  es                             ; 
;   push  ofs get_dmi_info.storage_base  ; DMIStorageBase
;   push  es                             ; 
;   push  ofs get_dmi_info.struc_size    ; StructureSize
;   push  es                             ; 
;   push  ofs get_dmi_info.num_struc     ; NumStructures
;   push  es                             ; 
;   push  ofs get_dmi_info.bios_rev      ; DMIBIOSRevision
;   push  DFN_GET_DMI_INFO               ; Get DMI Information (50h)
;   FAR_CALL  <offset PNP_BIOS_Real>, 0F000h ; 
;   add   sp,24                          ; 
; 
;   ret
; 
; get_dmi_information_call endp

;R48B start
ifdef	DMI_GPNV_support
;=============================================================================
; FUNC: PnpFunc_54h_in_post
;
; DESC: Clear Event Log
;
; IN:   AX - Control
; OUT:  AX - Return Code
;=============================================================================
		public	PnpFunc_54h_in_post
PnpFunc_54h_in_post	proc	near

		push	eax				; BiosSelect & dmiSelect
		mov	ax,1				; control
		push	ax
		mov	ax,TEMP_MEM			
		shl	eax,16
		push	eax				; FAR *Data(data buffer)
		mov	ax,0
		push	ax				; sub func num
		mov	ax,54h				; Pnp Func num
		push	ax
		FAR_CALL  <offset PNP_BIOS_Real>, 0F000h
		add	sp,0Eh

PnpFunc_54h_in_post	endp

;=============================================================================
; FUNC: PnpFunc_56h_in_post
;
; DESC: Read GPNV Data
;
; IN:   BX    - Read Handle
; OUT:  AX    - Return Code
;=============================================================================
		public	PnpFunc_56h_in_post
PnpFunc_56h_in_post	proc	near

		xor	eax,eax
		push	eax				; BiosSelect & GPNVSelect
		mov	ax,TEMP_MEM		
		shl	eax,16
		push	eax				; FAR *GPNVLock
		push	eax				; FAR *GPNVBuffer
		push	bx				; handle
		mov	cx,56h				;;;;; Pnp Func num
		push	cx
		FAR_CALL  <offset PNP_BIOS_Real>, 0F000h
		add	sp,10h

PnpFunc_56h_in_post	endp

;=============================================================================
; FUNC: PnpFunc_57h_in_post
;
; DESC: 
;
; IN:   ES:DI - input data buffer
;	AX    - Write GPNV Handle
;
; OUT:  AX    - Return Code
;=============================================================================
		public	PnpFunc_57h_in_post
PnpFunc_57h_in_post	proc	near

		push	ebx				; BiosSelect & GPNVSelect
		mov	bx,es
		shl	ebx,16
		mov	bx,di
		push	ebx				; FAR *GPNVLock
		push	ebx				; FAR *GPNVBuffer
		mov	bx,0				; handle
		push	bx
		mov	cx,57h				; Pnp Func num
		push	word ptr 57h
		FAR_CALL  <offset PNP_BIOS_Real>, 0F000h
		add	sp,10h

PnpFunc_57h_in_post	endp
endif	;DMI_GPNV_support
;R48B end

;R53 start
		public	POST_PreGallDMI
POST_PreGallDMI:
;R59 - start
ifdef		Flash_IN_SMBASE
		mov	ax,DMI_STORAGE_BASE
elseifdef      	ESCD_M2	
;R59 - end
;R59 ifdef	ESCD_M2	
		mov	ax,DMI_STORAGE_BASE
else	;ESCD_M2
		mov	ax,DMI_STORAGE_BASE_16
endif	;ESCD_M2
		mov	ds,ax
		mov	si,PARAM_BLOCK_BASE+DMI_TBL_OFFSET
		mov	ax,Temp_DMI_Pool_SEG
		mov	es,ax
		mov	di,Temp_DMI_Pool_OFF
		mov	cx,DMI_STORAGE_SIZE		
		F000_call	Post_Flash_Read		
		ret
;R53 end

Public  END_DMI_POST              ; Used to track overall size of
END_DMI_POST LABEL BYTE           ;  DMI Post 

XCODE    ENDS
endif	;FLASH_SUPPORT	;R56
endif   ; DMI_ENABLED

END
