;	[]===========================================================[]
;
;	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.
;
; 	[]===========================================================[]
;

;----------------------------------------------------------------------------
;Rev	Date	 Name	Description
;----------------------------------------------------------------------------
;R12   02/26/99 BAR    Support 32bit address to update Flash.
;R11	01/28/99 BAR	Support update ESCD DMI in SMM mode.
;			define switch "Flash_IN_SMBASE"
;R10	09/29/98 KVN	Release DMI and ESCD pool in flash ROM when not define
;			"ESCD_SUPPORT" and "FLASH_SUPPORT" in BIOS.CFG
;R09	05/14/98 BAR	Added Flash1M_16K_8K_8K_Unit definition.
;R08	02/18/97 RCH	Fixed CHECKUP1.EXE failure when the P6 micro code is
;			not in flashable region.
;R07	12/24/96 AVN	Support MP Secondary Update Code For 1M/2M EEPROM
;R06	10/21/96 KVN	Fixed 16K_8K_8K flash rom update error
;R04B	07/26/96 KVN	Fixed coding mistake
;R05	07/25/96 RCH	Now, only support one 2Kb space for P6 update
;R04A	07/25/96 KVN	Fixed DMI data pool be destroy during update p6 data
;R04	07/08/96 KVN	Change P6 data pool offset and size.
;R03	07/04/96 RCH	Added error report for SECURITY_FAILURE while the
;			revision of input patch code is not match with
;			current CPU's.
;R02A	07/04/96 RCH	Fixed error coding of R02 , it cause INTEL update
;			utility can not update P6 BIOS mirco-code.
;R02	06/24/96 RCH	Return correct error code for reading & writing NVM
;			failure
;R01	06/10/96 RCH	Modified code to support P6 BIOS update for MP system

.386p
		PAGE	56,132
		TITLE	P6UPDATE.ASM - Pentium Pro Processor BIOS Update Feature
.XLIST
		INCLUDE	BIOS.CFG

		INCLUDE COMMON.MAC			;R03

.LIST
ifdef	P6_BIOS_ONLY
ifdef	FLASH_SUPPORT	;R10
		INCLUDE	P6UPDATE.EQU
		extrn	Flash_Read:near
		extrn	Flash_Write:near

ifdef	MP_SUPPORT					;R01				
		extrn	P1_SiGn:near			;R01
		extrn	P2_SiGn:near			;R01
		extrn	P1_Upd_Ver:near			;R07
		extrn	P2_Upd_Ver:near			;R07
endif;	MP_SUPPORT					;R01

DGROUP		GROUP	FCODE
FCODE		SEGMENT	USE16 DWORD PUBLIC 'CODE'
		ASSUME	CS:DGROUP,DS:DGROUP

		public	P6_BIOS_Update
P6_BIOS_Update	Proc	Near
		cmp	bl,PBU_funcion_MAX		;Is legal function?
		jb	short Function_support;		;Yes,jump
		mov	ah,NOT_IMPLEMENTED		;No,return error message
		stc
		retf	2

Function_support:
		mov	ax,bx
		xor	bh,bh
		shl	bx,1
		add	bx,offset PBU_func_table
		mov	bx,cs:[bx]			;get function address
		xchg	bx,ax
		jmp	ax				;execuate it
P6_BIOS_Update	ENDP

PBU_func_table:
		dw	offset Presence_Test		;function 0
		dw	offset Write_BIOS_Update_Data	;function 1
		dw	offset BIOS_Update_Control	;function 2
		dw	offset Read_BIOS_Update_Data	;function 3
PBU_funcion_MAX	EQU	($-offset PBU_func_table)/2

;[]========================================================================[]
;Name:   	Presence_Test
;Function:	Verify the BIOS has implemented the required BIOS update functions.
;Input:  	AX = 0D042h
;		BL = 00h
;Output: 	CF = 1 - Failure (AH contains status)
;		   = 0 - All return values are valid
;		AH = Return Code
;		AL = OEM Error - Additional OEM Information
;		EBX = Signature Part 1 - 'INTE'
;		ECX = Signature Part 2 - 'LPEP'
;		EDX = Loader Version - Version number of the BIOS update Loader.
;		SI = Update Cnt - Number of Update Blocks the system can record
;		     in NVRAM.
;[]========================================================================[]
		public	Presence_Test
		ALIGN	4
Presence_Test	PROC	near
		mov	ah,SUCCESS			;function is goot
		xor	al,al				;OEM Error
		mov	ebx,'INTE'
		mov	ecx,'LPEP'
		mov	edx,BIOS_Loader_revision
		mov	si,UPDATE_NUM
		clc
		retf 2
Presence_Test	ENDP

;[]========================================================================[]
;Name:   	Write_BIOS_Update_Data
;Function:	Integrates a new BIOS update into the BIOS storage device.
;Input:  	AX = 0D042h
;		BL = 01h
;		ES:DI = Update Address - Real mode pointer to the Intel Update
;				structure.This buffer is 2048 bytes in length
;		CX = Scratch Pad1 - Real mode Segment address of 64 kilobytes
;				of RAM block.
;		DX = Scratch Pad2 - Real mode Segment address of 64 kilobytes
;				of RAM block.
;		SI = Scratch Pad3 - Real mode Segment address of 64 kilobytes
;				of RAM block.
;		SS:SP = Stack pointer - 32 kilobytes of Stack Minimum.
;Output: 	CF = 1 - Failure (AH contains status)
;		   = 0 - All return values are valid
;		AH = Return Code.
;		AL = OEM Error
;[]========================================================================[]
		public	Write_BIOS_Update_Data
		ALIGN	4
Write_BIOS_Update_Data	PROC	near
ifndef	MP_SUPPORT					;R07
		push	ds
		push	es
		push	bp
		sub	sp,Total_reserve_byte		;reserve temp buffer
		mov	bp,sp
		pusha
		cmp	es:[di].Update_Data_Block.Header_Version,BIOS_Header_version
		je	short Header_Ver_OK
Invaild_Header_Exit:
		mov	Return_Code,INVALID_HEADER
		jmp	WBUD_Exit
Header_Ver_OK:
		cmp	es:[di].Update_Data_Block.Loader_Revision,BIOS_Loader_revision
		jne	short Invaild_Header_Exit
	;----- calculate checksum correct? -----
		push	di
		mov	cx,size Update_Data_Block/4	;unit is DWORD
		xor	eax,eax
Checksum_Loop:
		add	eax,es:[di]
		add	di,4
		loop	Checksum_Loop
		pop	di
		or	eax,eax
		jz	short CheckSum_OK
		mov	Return_Code,INVALID_HEADER_CS
		jmp	WBUD_Exit
	;---------------------------------------
CheckSum_OK:
		push	es
		push	di
		mov	es,si
		xor	di,di
ifndef		Flash_IN_SMBASE				;R11
		mov	si,P6_BLOCK_STORAGE_BASE	;storage base segment
		mov	ds,si
endif;		Flash_IN_SMBASE				;R11
		mov	si,P6_BLOCK_OFFSET		;storage base offset
		mov	cx,P6_Block_Storage_Size	;storage size
		call	Read_P6_Block_Data		;R12
;R12		call	Flash_Read			;read it
		pop	si
		pop	ds
		jnc	short NVRAM_Read_OK				;R02A
;R02		jc	short Security_Fail_Exit
		mov	Return_Code,READ_FAILURE	;read failure	;R02
		jmp	WBUD_Exit					;R02

NVRAM_Read_OK:
		cmp	es:[di].Update_Data_Block.Header_Version,0ffffffffh
		je	short Update_Block_Data
		mov	eax,es:[di].Update_Data_Block.Processor_Version
		mov	ebx,ds:[si].Update_Data_Block.Processor_Version
		cmp	ax,bx
		jne	short Next_Block
		mov	eax,ds:[si].Update_Data_Block.Update_Revision
		cmp	eax,es:[di].Update_Data_Block.Update_Revision
		ja	short Update_Block_Data
Return_InvalidRev:					;R08
		mov	Return_Code,INVALID_REVISION
		jmp	WBUD_Exit
Next_Block:
		add	di,P6_Block_Size		;get next block address
		cmp	di,P6_Block_Storage_Size	;overflow storage buffer?
		jb	short NVRAM_Read_OK		;No,read next block

;R08 - start
	;now the processor version is different with flashable region,
	;check if the CPU already patched by non-flashable micro code.
	;if patched, and the update revision is bigger the input micro code
	;return invalid revision to prevent error message.
		call	Read_CPU_UpdateRev		;read current CPU rev.
		cmp	edx,ds:[si].Update_Data_Block.Update_Revision
		jae	short Return_InvalidRev		;no update
;R08 - end

;R01 - start
		xor	di,di
;R05 ifdef	MP_SUPPORT					
;R05 		mov	eax,ds:[si].Update_Data_Block.Processor_Version
;R05 		cmp	eax,dword ptr cs:[P1_SiGn]
;R05 		je	short Update_Block_Data
;R05 		add	di,P6_Block_Size		;get next block address
;R05 		cmp	di,P6_Block_Storage_Size	;R04 overflow storage buffer?
;R05 		jae	short @F			;R04
;R05 		cmp	eax,dword ptr cs:[P2_SiGn]
;R05 		je	short Update_Block_Data
;R05 @@:							;R04
;R05 		mov	Return_Code,STORAGE_FULL	;return storage full message
;R05 		jmp	WBUD_Exit
;R05 endif	;MP_SUPPORT					
;R01 - end

;R01		mov	Return_Code,STORAGE_FULL	;return storage full message
;R01		jmp	WBUD_Exit
Update_Block_Data:

;R03 - start
;The update revision of incoming update code should bigger than current
;CPU's revision.
		call	Read_CPU_UpdateRev		;read current CPU rev.

		cmp	edx,ds:[si].Update_Data_Block.Update_Revision
 		mov	Return_Code,SECURITY_FAILURE	;return error message
		jae	short WBUD_Exit			;no update

	;Load update code to CPU to see if revision matched 
		mov	ecx,79H
		xor	eax,eax
		xor	ebx,ebx
		mov	ax,ds			;segment of patch code
		shl	eax,4
		mov	bx,si			;offset of patch code
		add	eax,ebx
		add	eax,48			;skip header
		xor	edx,edx
		WRMSR

	;Read back revision in CPU after patch

		call	Read_CPU_UpdateRev		;read current CPU rev.

		cmp	edx,ds:[si].Update_Data_Block.Update_Revision
 		mov	Return_Code,SECURITY_FAILURE	;return error message
		jne	short WBUD_Exit			;patch failed
;R03 - end

		push	es
		mov	cx,P6_Block_Size
		rep	movsb			;update new block data to temp
						;storage buffer from input
		pop	ds
		xor	si,si
;R04A start
		push	ds
		push	si
		mov	di,ds
		mov	es,di
;R06 start
ifdef	Flash_16K_8K_8K_Unit
		mov	di,1000h
		mov	cx,1000h
elseifdef	Flash1M_16K_8K_8K_Unit		;R09
		mov	di,1000h		;R09
		mov	cx,1000h		;R09
else	;Flash_16K_8K_8K_Unit
;R06 end
		mov	di,800h
		mov	cx,800h
endif	;Flash_16K_8K_8K_Unit			;R06
		cld
		rep	movsb

		xor	di,di
ifndef		Flash_IN_SMBASE				;R11
;R04B		mov	si,P6_BLOCK_STORAGE_BASE	;storage base segment
		mov	si,ESCD_BASE			;R04B
		mov	ds,si
endif;		Flash_IN_SMBASE				;R11
;R06 start
ifdef	Flash_16K_8K_8K_Unit
		mov	si,(P6_BLOCK_OFFSET and 0e000h)
		mov	cx,1000h
elseifdef	Flash1M_16K_8K_8K_Unit			;R09
		mov	si,(P6_BLOCK_OFFSET and 0e000h)	;R09
		mov	cx,1000h			;R09
else	;Flash_16K_8K_8K_Unit
;R06 end
		mov	si,(P6_BLOCK_OFFSET and 0f000h)
		mov	cx,800h
endif	;Flash_16K_8K_8K_Unit			;R06
		call	Read_P6_Block_Data		;R12
;R12		call	Flash_Read			;read it
		pop	si
		pop	ds
;R04A end
;R04B		mov	di,P6_BLOCK_STORAGE_BASE
ifndef		Flash_IN_SMBASE				;R11
		mov	di,ESCD_BASE			;R04B
		mov	es,di
endif;		Flash_IN_SMBASE				;R11
;R04B		mov	di,P6_BLOCK_OFFSET
;R04A		mov	cx,P6_Block_Storage_Size
;R06 start
ifdef	Flash_16K_8K_8K_Unit
		mov	di,(P6_BLOCK_OFFSET and 0e000h)
		mov	cx,2000h
elseifdef	Flash1M_16K_8K_8K_Unit			;R09
		mov	di,(P6_BLOCK_OFFSET and 0e000h)	;R09
		mov	cx,2000h			;R09
else	;Flash_16K_8K_8K_Unit
;R06 end
		mov	di,(P6_BLOCK_OFFSET and 0f000h)	;R04B
		mov	cx,1000h			;R04A
endif	;Flash_16K_8K_8K_Unit			;R06
		call	Write_P6_Block_Data		;R12
;R12		call	Flash_Write			;flush to storage pool
		mov	Return_Code,SUCCESS		;assume success
		jnc	short WBUD_Exit			;Yes,jump

		mov	Return_Code,WRITE_FAILURE	;write failure	;R02

;R02 Security_Fail_Exit:
;R02 		mov	Return_Code,SECURITY_FAILURE	;return error message
WBUD_Exit:
		popa
		mov	ah,Return_Code			;put return code to AH
		xor	al,al				;OEM Error
		add	sp,Total_reserve_byte		;restore SP
		pop	bp
		pop	es
		pop	ds
		cmp	ah,SUCCESS			;corrected carry flag
		clc
		je	short @F
		stc
@@:
		retf 2
;R07 - start
else;	MP_SUPPORT
		push	ds
		push	es
		push	gs
		push	bp
		sub	sp,Total_reserve_byte		;reserve temp buffer
		mov	bp,sp
		pusha
		cmp	es:[di].Update_Data_Block.Header_Version,BIOS_Header_version
		je	short Header_Ver_OK
Invaild_Header_Exit:
		mov	Return_Code,INVALID_HEADER
		jmp	WBUD_Exit
Header_Ver_OK:
		cmp	es:[di].Update_Data_Block.Loader_Revision,BIOS_Loader_revision
		jne	short Invaild_Header_Exit

	;----- calculate checksum correct? -----
		push	di
		mov	cx,size Update_Data_Block/4	;unit is DWORD
		xor	eax,eax
Checksum_Loop:
		add	eax,es:[di]
		add	di,4
		loop	Checksum_Loop
		pop	di
		or	eax,eax
		jz	short CheckSum_OK
		mov	Return_Code,INVALID_HEADER_CS
		jmp	WBUD_Exit
	;---------------------------------------

CheckSum_OK:
	; Read First CPU Micro Code
		push	es
		push	di
		mov	es,si
		xor	di,di
ifndef		Flash_IN_SMBASE				;R11
		mov	si,P6_BLOCK_STORAGE_BASE	;storage base segment
		mov	ds,si
endif;		Flash_IN_SMBASE				;R11
		mov	si,P6_BLOCK_OFFSET		;storage base offset
		mov	cx,P6_Block_Storage_Size	;storage size
		call	Read_P6_Block_Data		;R12
;R12		call	Flash_Read			;read it

	; Read Secondary CPU Micro Code
		push	es
		mov	es,dx
		xor	di,di
ifndef		Flash_IN_SMBASE				;R11
		mov	si,P6_BLOCK_STORAGE_BASE	;storage base segment
		mov	ds,si
endif;		Flash_IN_SMBASE				;R11
		mov	si,P6_SEC_BLOCK_OFFSET		;storage base offset
		mov	cx,P6_Block_Storage_Size	;storage size
		call	Read_P6_Block_Data		;R12
;R12		call	Flash_Read			;read it
		push	es
		pop	gs
		pop	es

		pop	si
		pop	ds
		jnc	short NVRAM_Read_OK
		mov	Return_Code,READ_FAILURE	;read failure
		jmp	WBUD_Exit

NVRAM_Read_OK:
		xor	dx,dx

	; Check 1st ROM Adjust Which CPU
		mov	eax,es:[di].Update_Data_Block.Processor_Version
 		cmp	eax,dword ptr cs:[P1_SiGn]
		jne	short Check_1st_ROM_Adjust_CPU2
		mov	dl,1
		jmp	short Check_2nd_ROM_Adjust_CPU

Check_1st_ROM_Adjust_CPU2:
 		cmp	eax,dword ptr cs:[P2_SiGn]
		jne	short Check_2nd_ROM_Adjust_CPU
		mov	dl,2

	; Check 2nd ROM Adjust Which CPU
Check_2nd_ROM_Adjust_CPU:
		mov	eax,gs:[di].Update_Data_Block.Processor_Version
 		cmp	eax,dword ptr cs:[P1_SiGn]
		jne	short Check_2st_ROM_Adjust_CPU2
		mov	dh,1
		jmp	short ROM_Adjust_CPU_End

Check_2st_ROM_Adjust_CPU2:
 		cmp	eax,dword ptr cs:[P2_SiGn]
		jne	short ROM_Adjust_CPU_End
		mov	dh,2

ROM_Adjust_CPU_End:
		xor	bl,bl
		mov	eax,ds:[si].Update_Data_Block.Processor_Version
 		cmp	eax,dword ptr cs:[P1_SiGn]
		jne	short Check_Buffers_Adjust_CPU2

		mov	bl,1				;Set CPU1 Flag
		mov	bh,1				;Set 1st ROM
		cmp	dl,1
		je	short Check_Update_Revision

		mov	bh,2				;Set 2nd ROM
		cmp	dh,1
		jne	short Check_Any_ROM_Free_For_CPU1
		push	gs
		pop	es
		jmp	short Check_Update_Revision

Check_Any_ROM_Free_For_CPU1:
		mov	bh,1				;Set 1st ROM
		cmp	dl,2
		jne	short Check_Update_Revision

		mov	bh,2				;Set 2nd ROM
		push	gs
		pop	es
		jmp	short Check_Update_Revision

Check_Buffers_Adjust_CPU2:
 		cmp	eax,dword ptr cs:[P2_SiGn]
		jne	short Buffers_Miss_CPU

		mov	bl,2				;Set CPU2 Flag
		mov	bh,1				;Set 1st ROM
		cmp	dl,2
		je	short Check_Update_Revision

		mov	bh,2				;Set 2nd ROM
		cmp	dh,2
		jne	short Check_Any_ROM_Free_For_CPU2
		push	gs
		pop	es
		jmp	short Check_Update_Revision

Check_Any_ROM_Free_For_CPU2:
		mov	bh,1				;Set 1st ROM
		cmp	dl,1
		jne	short Check_Update_Revision

		mov	bh,2				;Set 2nd ROM
		push	gs
		pop	es

Check_Update_Revision:
		cmp	es:[di].Update_Data_Block.Header_Version,0ffffffffh
		je	short Update_Block_Data

		mov	eax,ds:[si].Update_Data_Block.Update_Revision
		cmp	eax,es:[di].Update_Data_Block.Update_Revision
		ja	short Update_Block_Data

Buffers_Miss_CPU:
		mov	Return_Code,INVALID_REVISION
		jmp	WBUD_Exit

Update_Block_Data:

;The update revision of incoming update code should bigger than current
;CPU's revision.
 		mov	Return_Code,SECURITY_FAILURE	;return error message
		cmp	bl,1				;Is CPU1?
		jne	short Check_P2_Upd_Ver		;No, Skip.
 		mov	Return_Code,SECURITY_FAILURE	;return error message
		mov	al,byte ptr cs:[P1_Upd_Ver]
		cmp	al,byte ptr ds:[si].Update_Data_Block.Update_Revision
		ja	short WBUD_Exit			;no update
		jmp	short Check_Update_Revision_Ok

Check_P2_Upd_Ver:
		cmp	bl,2				;Is CPU2?
		jne	short WBUD_Exit			;No, Skip.
 		mov	Return_Code,SECURITY_FAILURE	;return error message
		mov	al,byte ptr cs:[P2_Upd_Ver]
		cmp	al,byte ptr ds:[si].Update_Data_Block.Update_Revision
		ja	short WBUD_Exit			;no update

Check_Update_Revision_Ok:
		cld
		push	ds
		push	si
		xor	di,di
		mov	si,ESCD_BASE
		mov	ds,si
ifdef	Flash_16K_8K_8K_Unit
		mov	si,(P6_BLOCK_OFFSET and 0e000h)
elseifdef	Flash1M_16K_8K_8K_Unit		       	;R09
		mov	si,(P6_BLOCK_OFFSET and 0e000h)	;R09
else;	Flash_16K_8K_8K_Unit
		mov	si,(P6_BLOCK_OFFSET and	3000h)
		cmp	bh,1				;Update 1st P6 ROM
		je	short Copy_P6_Block_To_Buffer	;Yes, Skip
		mov	si,(P6_SEC_BLOCK_OFFSET and 3000h)
Copy_P6_Block_To_Buffer:
endif;	Flash_16K_8K_8K_Unit
		mov	cx,P6_Block_Read_Size
		call	Read_P6_Block_Data		;R12
;R12		call	Flash_Read			;read it
		pop	si
		pop	ds

ifdef	Flash_16K_8K_8K_Unit
		mov	di,P6_BLOCK_OFFSET
		cmp	bh,1				;Update 1st P6 ROM
		je	short Copy_Source_To_Buffer	;Yes, Skip

	;Set 2nd P6 ROM
		mov	di,P6_SEC_BLOCK_OFFSET
;R09 - start
elseifdef	Flash1M_16K_8K_8K_Unit
		mov	di,P6_BLOCK_OFFSET
		cmp	bh,1				;Update 1st P6 ROM
		je	short Copy_Source_To_Buffer	;Yes, Skip

	;Set 2nd P6 ROM
		mov	di,P6_SEC_BLOCK_OFFSET
;R09 - end

else;	Flash_16K_8K_8K_Unit
		mov	di,(P6_BLOCK_OFFSET and 0f00h)
endif;	Flash_16K_8K_8K_Unit

Copy_Source_To_Buffer:
		mov	cx,P6_Block_Size
		rep	movsb			;update new block data to temp
						;storage buffer from input
		push	es
		pop	ds
		xor	si,si
		mov	di,ESCD_BASE
		mov	es,di

ifdef	Flash_16K_8K_8K_Unit
		mov	di,(P6_BLOCK_OFFSET and 0e000h)
elseifdef	Flash1M_16K_8K_8K_Unit			;R09
		mov	di,(P6_BLOCK_OFFSET and 0e000h)	;R09
else;	Flash_16K_8K_8K_Unit
		mov	di,(P6_BLOCK_OFFSET and 3000h)
		cmp	bh,1				;Update 1st P6 ROM
		je	short Write_P6_Block_To_ROM	;Yes, Skip
		mov	di,(P6_SEC_BLOCK_OFFSET and 3000h)
Write_P6_Block_To_ROM:
endif;	Flash_16K_8K_8K_Unit
		mov	cx,P6_Block_Read_Size
		call	Write_P6_Block_Data		;R12
;R12		call	Flash_Write			;flush to storage pool
		mov	Return_Code,SUCCESS		;assume success
		jnc	short WBUD_Exit			;Yes,jump

		mov	Return_Code,WRITE_FAILURE	;write failure

WBUD_Exit:
		popa
		mov	ah,Return_Code			;put return code to AH
		xor	al,al				;OEM Error
		add	sp,Total_reserve_byte		;restore SP
		pop	bp
		pop	gs
		pop	es
		pop	ds
		cmp	ah,SUCCESS			;corrected carry flag
		clc
		je	short @F
		stc
@@:
		retf 2
endif;	MP_SUPPORT
;R07 - end
Write_BIOS_Update_Data	ENDP

;R03 - start
;Function : Read CPU's update revision
;Input    : none
;Output   : EDX - update revision in CPU
Read_CPU_UpdateRev	proc	near

		mov	ecx,08BH	;MSR register
		xor	eax,eax
		xor	edx,edx
		WRMSR			;load 0 to MSR at 8BH

		mov	eax,1
		db	0fh,0A2h     	;CPU ID instruction
		
		mov	ecx,08BH	;MSR register to read
		RDMSR		     	;edx contain update revision

		ret
Read_CPU_UpdateRev	endp
;R03 - end

;[]========================================================================[]
;Name:   	BIOS_Update_Control
;Function:	
;Input:  	AX = 0D042h
;		BL = 02h
;		BH = Task
;		CX = Scratch Pad1 - Real mode Segment address of 64 kilobytes
;				of RAM block.
;		DX = Scratch Pad2 - Real mode Segment address of 64 kilobytes
;				of RAM block.
;		SI = Scratch Pad3 - Real mode Segment address of 64 kilobytes
;				of RAM block.
;		SS:SP = Stack pointer - 32 kilobytes of Stack Minimum.
;Output: 	CF = 1 - Failure (AH contains status)
;		   = 0 - All return values are valid
;		AH = Return Code.
;		AL = OEM Error
;		BL = Update Status - Either Enable or Disable indicator.
;[]========================================================================[]
		public	BIOS_Update_Control
		ALIGN	4
BIOS_Update_Control	PROC	near
		mov	ah,SUCCESS			;function is goot
		xor	al,al				;OEM Error
		mov	bl,1				;Enabled ???
		clc
		retf 2
BIOS_Update_Control	ENDP

;[]========================================================================[]
;Name:   	Read_BIOS_Update_Data
;Function:	
;Input:  	AX = 0D042h
;		BL = 03h
;		ES:DI = BufferAddress - Real mode pointer to the Intel update
;				structure that will be written with the binary
;				data.
;		ECX = Scratch Pad1 - Real mode Segment address of 64 kilobytes
;				of RAM block.(lower 16 bits)
;		ECX = Scratch Pad2 - Real mode Segment address of 64 kilobytes
;				of RAM block.(upper 16 bits)
;		DX = Scratch Pad3 - Real mode Segment address of 64 kilobytes
;				of RAM block.
;		SS:SP = Stack pointer - 32 kilobytes of Stack Minimum.
;		SI = Update Number - The index number of the update block to be
;				read.This value is zero based and must be less
;				than the Update Cnt returned from the Presence
;				Test function.
;Output: 	CF = 1 - Failure (AH contains status)
;		   = 0 - All return values are valid
;		AH = Return Code.
;		AL = OEM Error
;[]========================================================================[]
		public	Read_BIOS_Update_Data
		ALIGN	4
Read_BIOS_Update_Data	PROC	near
		push	ds
		push	bp
		sub	sp,Total_reserve_byte		;reserve temp buffer
		mov	bp,sp
		pusha
		cmp	si,UPDATE_NUM		;to be read update number
						;is overflow storage buffer
		jb	short Update_Num_Valid		;No,jump
		mov	Return_Code,UPDATE_NUM_INVALID	;return error message
		jmp	RBUD_Exit
Update_Num_Valid:
ifndef		Flash_IN_SMBASE				;R11
		mov	ax,P6_BLOCK_STORAGE_BASE
		mov	ds,ax
endif;		Flash_IN_SMBASE				;R11
		mov	ax,si				;-- calculate exact --
		mov	cx,P6_Block_Size		;block offset for read
		mul	cx				;---------------------
		mov	si,ax				;store in SI
		add	si,P6_BLOCK_OFFSET
		call	Read_P6_Block_Data		;R12
;R12		call	Flash_Read
		mov	Return_Code,SUCCESS
		jnc	short RBUD_Exit
		mov	Return_Code,READ_FAILURE
RBUD_Exit:
		popa
		mov	ah,Return_Code			;put return code to AH
		xor	al,al				;OEM Error
		add	sp,Total_reserve_byte		;restore SP
		pop	bp
		pop	ds
		cmp	ah,SUCCESS			;corrected carry flag
		clc
		je	short @F
		stc
@@:
		retf 2
Read_BIOS_Update_Data	ENDP

;R12 - start
Read_P6_Block_Data	Proc	Near
		push	esi
ifdef 	ESCD_32bits
		and	esi,0ffffh
		or	esi, P6_BLOCK_STORAGE_BASE
endif;	ESCD_32bits
		call	Flash_Read
		pop	esi
		ret
Read_P6_Block_Data	endp

Write_P6_Block_Data	Proc	Near
		push	edi
ifdef 	ESCD_32bits
		and	edi,0ffffh
		or	edi, P6_BLOCK_STORAGE_BASE
endif;	ESCD_32bits
		call	Flash_Write
		pop	edi
		ret
Write_P6_Block_Data	endp

;R12 - end

FCODE		ENDS
endif	;FLASH_SUPPORT	;R10
endif	;P6_BIOS_ONLY

		END
