Showing posts with label x86. Show all posts
Showing posts with label x86. Show all posts

Wednesday, September 26, 2018

[ASL] (1) How to Safely R/W I2C Device Using ASL

OperationRegion(ICM7, SystemMemory, 0xA112C000, 256)
        Field(ICM7, DWordAcc, NoLock, Preserve) //Field
        {
            ICN7, 32,                   // R_IC_CON (I2C Control)
            Offset(0x04),
            TAR7, 32,                   // R_IC_TAR (I2C Target Address)
            Offset(0x08),
            SAR7, 32,                   // R_IC_SAR (I2C Slave Address) *
            Offset(0x0C),
            HMD7, 32,                   // R_IC_HS_MADDR (I2C HS MasterMode Code Address) *
            Offset(0x10),
            DCD7, 32,                   // R_IC_DATA_CMD (I2C Rx/Tx Data Buffer and Command)
            Offset(0x14),
            SSH7, 32,                   // R_IC_SS_SCL_HCNT (Standard Speed I2C Clock SCL High Count) *
            Offset(0x18),
            SSL7, 32,                   // R_IC_SS_SCL_LCNT (Standard Speed I2C Clock SCL Low Count) *
            Offset(0x1C),
            FSH7, 32,                   // R_IC_FS_SCL_HCNT (Full Speed I2C Clock SCL High Count) *
            Offset(0x20),
            FSL7, 32,                   // R_IC_FS_SCL_LCNT (Full Speed I2C Clock SCL Low Count) *
            Offset(0x24),
            HSH7, 32,                   // R_IC_HS_SCL_HCNT (High Speed I2C Clock SCL High Count) *
            Offset(0x28),
            HSL7, 32,                   // R_IC_HS_SCL_LCNT (High Speed I2C Clock SCL Low Count) *
            Offset(0x2C),
            ITS7, 32,                   // R_IC_INTR_STAT (I2C Inetrrupt Status) *
            Offset(0x30),
            ITM7, 32,                   // R_IC_INTR_MASK (I2C Interrupt Mask)
            Offset(0x34),
            RIS7, 32,                   // R_IC_RAW_INTR_STAT (I2C Raw Interrupt Status)
            Offset(0x38),
            IRT7, 32,                   // R_IC_RX_TL (I2C Receive FIFO Threshold)
            Offset(0x3C),
            ITT7, 32,                   // R_IC_TX_TL (I2C Transmit FIFO Threshold)
            Offset(0x40),
            CIT7, 32,                   // R_IC_CLR_INTR (Clear Combined and Individual Interrupts)
            Offset(0x44),
            CRU7, 32,                   // R_IC_CLR_RX_UNDER (Clear RX_UNDER Interrupt) *
            Offset(0x48),
            CRO7, 32,                   // R_IC_CLR_RX_OVER (Clear RX_OVERinterrupt) *
            Offset(0x4C),
            CTO7, 32,                   // R_IC_CLR_TX_OVER (Clear TX_OVER interrupt) *
            Offset(0x50),
            CRR7, 32,                   // R_IC_CLR_RD_REQ (Clear RD_REQ interrupt) *
            Offset(0x54),
            CTA7, 32,                   // R_IC_CLR_TX_ABRT (Clear TX_ABRT interrupt)
            Offset(0x58),
            CRD7, 32,                   // R_IC_CLR_RX_DONE (Clear RX_DONE interrupt) *
            Offset(0x5C),
            CAT7, 32,                   // R_IC_CLR_ACTIVITY (Clear ACTIVITY interrupt) *
            Offset(0x60),
            CSD7, 32,                   // R_IC_CLR_STOP_DET (Clear STOP_DET interrupt) *
            Offset(0x64),
            SAD7, 32,                   // R_IC_CLR_START_DET (Clear START_DET interrupt) *
            Offset(0x68),
            CGC7, 32,                   // R_IC_CLR_GEN_CALL (Clear GEN_CALL interrupt) *
            Offset(0x6C),
            IEN7, 32,                   // R_IC_ENABLE (I2C Enable)
            Offset(0x70),
            IST7, 32,                   // R_IC_STATUS (I2C Status)
            Offset(0x74),
            TFL7, 32,                   // R_IC_TXFLR (Transmit FIFO Level Register)
            Offset(0x78),
            RFL7, 32,                   // R_IC_RXFLR (Receive FIFO Level Register)       
            Offset(0x80),
            TAS7, 32,                   // R_IC_TX_ABRT_SOURCE (I2C Transmit Abort Status Register)
            Offset(0x84),
            SDN7, 32,                   // R_IC_SLV_DATA_NACK_ONLY (Generate SLV_DATA_NACK Register) *
            Offset(0x88),
            DCR7, 32,                   // R_IC_DMA_CR (DMA Control Register) *
            Offset(0x8C),
            DTL7, 32,                   // R_IC_DMA_TDLR (DMA Transmit Data Level) *
            Offset(0x90),
            DRL7, 32,                   // R_IC_DMA_RDLR (DMA Receive Data Level) *
            Offset(0x94),
            SST7, 32,                   // R_IC_SDA_SETUP (I2C SDA Setup Register) *
            Offset(0x98),
            AGC7, 32,                   // R_IC_ACK_GENERAL_CALL (I2C ACK General Call Register) *
            Offset(0x9C),
            ETS7, 32,                   // R_IC_ENABLE_STATUS (I2C Enable Status Register) *
            Offset(0xC0),
            CGT7, 32,                   // R_IC_CLK_GATE (Clock Gate)
            Offset(0xF4),
            CPP7, 32,                   // R_IC_COMP_PARAM (Component Parameter Register) *
            Offset(0xF8),
            CPV7, 32,                   // R_IC_COMP_VERSION (Component Version ID) *
            Offset(0xFC),
            CPT7, 32,                   // R_IC_COMP_TYPE (Component Type) *
        }
       
// ------------------------------------------------------------------------------------
// *********************I2C R/W Registers and Definition*******************************
// ------------------------------------------------------------------------------------

        Name(RDST, 0) // RDST 是通用的 Read 回傳 Status
        Name(RDDT, 0) // RDDT 是 I2C READ Data 暫存

Name(RRRS, 0) // ByteWrite_Basic 專用 POST Code
Name(RRRT, 0) // ByteRead_Basic  專用 POST Code

// ------------------------------------------------------------------------------------
// ******************Method (IWBB) Debug POST Code Example*****************************
// ------------------------------------------------------------------------------------

// *************************
// ShiftLeft (0x01, 0, Local7)
// Or (RRRS, Local7, RRRS)
// *************************

// ------------------------------------------------------------------------------------
// ******************Method (IRBB) Debug POST Code Example*****************************
// ------------------------------------------------------------------------------------

// *************************
// ShiftLeft (0x01, 1, Local7)
// Or (RRRT, Local7, RRRT)
// *************************

// ------------------------------------------------------------------------------------
// ***************************ByteReadI2C**********************************************
// ------------------------------------------------------------------------------------

Method (IRBC, 1)
{
// 1. 呼叫一次 IWBB, 主要功能為將 Offset 寫入 I2C Command

// arg0 = "Offset"
// START = It controls whether a RESTART is issued before the byte is sent or received
// END = It controls whether a STOP is issued after the byte is sent or received.

IWBB (arg0, TRUE, FALSE)

// 2. RDST 是 IWBB 的返回值

Store(RDST, Local0)

if(LNotEqual(Local0, 0x0))
{    
Return(RDST)
}

// 3. 如果抵達此處, 則代表返回值為 0

IRBB(TRUE, TRUE)

// 以下是 I2C READ 的 Workaround-----------------------------
// 因為 Method (IRBB) 應該修好了, 所以不需要再用此 Workaround
// 但為了保險起見還是留著
//-----------------------------------------------------------

Return(RDST)
}

// ------------------------------------------------------------------------------------
// ***************************ByteReadI2C_Basic****************************************
// ------------------------------------------------------------------------------------

Method (IRBB, 2, NotSerialized)
{
// Return Status = SUCCESS

Store(0, RDST)

// 0. 因為 I2CBaseAddress 固定, 所以不需要維護

// 1. I2CInit 應該也不需要做事

// 2. arg0 = START (TRUE/FALSE), arg1 = END (TRUE/FALSE), RDDT 內含 Read Data

//    ReceiveDataEnd = 1 (固定值)
//    ReceiveRequest = Local0 = 初始值為 0, 區間應為 0~1
//    ReadBuffer     = Local1 = 初始值為 0, 區間應為 0~1
//    Counter        = Local2 = 初始值為 0, 區間應為 0~1024
//    檢查 Reg 專用  = Local3 = 初始值為 0
//    檢查 Reg 專用  = Local4 = 初始值為 0

//    while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadBuffer))

Store (0x0, Local0)
Store (0x0, Local1)
Store (0x0, Local2)
Store (0x0, Local3)
Store (0x0, Local4)

While(LOr(LGreater(0x01, Local0), LGreater(0x01, Local1)))
{

// 1. 讀取 R_IC_RAW_INTR_STAT (Local3), RIS7 = R_IC_RAW_INTR_STAT (I2C Raw Interrupt Status)

//    如果 Local1 = R_IC_RAW_INTR_STAT == ERROR, Return with ERROR

//    0x40 = BIT06 = I2C_INTR_TX_ABRT = NACK Set

Store (RIS7, Local3)

If (LNotEqual(And(Local1, 0x40), 0))
{
// Before EXIT, READ R_IC_CLR_TX_ABRT
// CTA7 = R_IC_CLR_TX_ABRT (Clear TX_ABRT interrupt)

Store (CTA7, Local3)

Store(0xFE, RDST)     // 0xFE = R_IC_RAW_INTR_STAT and I2C_INTR_TX_ABRT, ERROR
Return(RDST)
}

// 2. 讀取 R_IC_STATUS, IST7 = R_IC_STATUS (I2C Status) = Local3

//    If R_IC_STATUS == Not Empty, we will READ DATA
//    STAT_RFNE = BIT03 (0x08) = RX FIFO is not empty
//    if FIFO is not empty, 代表可讀資料了
//    DCD7 = R_IC_DATA_CMD (I2C Rx/Tx Data Buffer and Command)

Store (IST7, Local3)

If (LNotEqual(And(Local3, 0x08, Local3), 0))
{

// RDDT = READ DATA

Store (DCD7, Local3)
Store (Local3, RDDT)

// ReadBuffer  = Local1, ReadBuffer ++

Increment(Local1)
}

//  3. ReceiveDataEnd = 1, ReceiveRequest = Local0
// 首次進入, 不會跑入此條件, 因為ReceiveRequest 此時指向 Data
// 第二次進入, 代表 ReceiveRequest 已經加過一次 1, 已經指向 EOF, 我們會到此的唯一可能就是首次進入時 FIFO is empty, 所以 ReadBuffer ++ 沒發生
// 此處之所以需要等待 2028 毫秒, 是因為 FIFO empty 的情況情實很少見    

If (LEqual(0x01, Local0))
{
Stall (2)
Increment(Local2)
If (LLess(Local2, 1024))
{
Continue
}
else
{
Break
}
}

//  4.  If FIFO is full, Wait until a read request will fit
//      STAT_TFNF = BIT1 = TX FIFO = 0x02 is not full, 0 = FULL

Store (IST7, Local3)

If (LEqual(And(Local3, 0x02), 0))
{
Stall (10)
Continue
}

//  5. 這裡是重要的指令分歧點
//     START = TRUE,  END = TRUE,  第一個 if, 在 R_IC_DATA_CMD 直接寫入 READ + RESTART + STOP
//     START = TRUE,  END = FALSE, 第二個 if, 在 R_IC_DATA_CMD 直接寫入 READ + RESTART
//     START = FALSE, END = TRUE,  第一個 if, 在 R_IC_DATA_CMD 直接寫入 READ + STOP
//     START = FALSE, END = FALSE,  第一個 if, 在 R_IC_DATA_CMD 直接寫入 READ (通常沒人用這個)

// (Read Command = B_READ_CMD = BIT08 = 0x0100) 寫入 Local3
 
Store (0x0100, Local3)
 
// arg0 = START, arg1 = END
 
If (LEqual(arg0, TRUE))
{
If (LEqual(arg1, TRUE)) 
{
// Local0|B_CMD_RESTART|B_CMD_STOP, BIT09+BIT10

Or (Local3, 0x0600, Local3)
}
else
{
// Local0|B_CMD_RESTART, BIT10
Or (Local3, 0x0400, Local3)
}
}
else
{
If (LEqual(arg1, TRUE))
{
// Local0|B_CMD_STOP, BIT09
Or (Local3, 0x0200, Local3)
}
else
{
// Local3, Do nothing
}
}
 
// 將 (Read Command + 各種 MASK) 寫入 Command
 
Store(Local3 ,DCD7)

// 6. Wait after send cmd

Stall (2)

// 7. 累加 ReceiveRequest

Increment(Local0)

}

Return(RDST)
}

// ------------------------------------------------------------------------------------
// ***************************ByteWriteI2C*********************************************
// ------------------------------------------------------------------------------------

        // AKA: ByteWriteI2C

Method (IWBC, 2, NotSerialized)
{

// 1. 呼叫一次 IWBB, 主要功能為將 Offset 寫入 I2C Command

// arg0 = "Offset to be Written"
// arg1 = "Data to be Written"

// START = It controls whether a RESTART is issued before the byte is sent or received
// END   = It controls whether a STOP is issued after the byte is sent or received.

IWBB(arg0, TRUE, FALSE)

// 2. RDST 是 IWBB 的返回值

Store(RDST, Local0)

if(LNotEqual(Local0, 0x0))
{  
Return(RDST)
}

// 3. 如果抵達此處, 則代表返回值為 0

IWBB(arg1, FALSE, TRUE)
Return(RDST)
}

// ------------------------------------------------------------------------------------
// ***************************ByteWriteI2C_Basic***************************************
// ------------------------------------------------------------------------------------

// arg0 = "Offset" or "Data to be Written"
// arg1 = It controls whether a RESTART is issued before the byte is sent or received
// arg2 = It controls whether a STOP is issued after the byte is sent or received.

// 0xFE = R_IC_RAW_INTR_STAT and I2C_INTR_TX_ABRT, ERROR
// 0xFD = R_IC_STATUS and STAT_TFNF, ERROR
// 0xFC = EFI_TIMEOUT

Method (IWBB, 3, NotSerialized)
{

  // 0. 初始化 RDST, 做為回傳值-------------------------------------------------------------------------
 
  Store(0xFF, RDST) // Set the status to FAIL

  // 1. 這個是 (I2CInit) -------------------------------------------------------------------------------
 
  //    將 SlaveAddress 寫到 IC_TAR
 
  Store (0x46, TAR7)
 
  // 2. 用 While 重覆跑前段的檢查 ----------------------------------------------------------------------
 
  // Local5 = TransmitEnd
  // Local6 = WriteBuffer
 
  Store (1, Local5)
  Store (0, Local6)
 
  While(LGreater(Local5, Local6))
  {
 
// 1. 讀取 R_IC_STATUS, IST7 = R_IC_STATUS (I2C Status)

Store (IST7, Local0)
 
    // 2. 讀取 R_IC_RAW_INTR_STAT (Local1), RIS7 = R_IC_RAW_INTR_STAT (I2C Raw Interrupt Status)

Store (RIS7, Local1)

// 3. 如果 Local1 = R_IC_RAW_INTR_STAT == ERROR, Return with ERROR

//    0x40 = BIT06 = I2C_INTR_TX_ABRT = NACK Set

If (LNotEqual(And(Local1, 0x40), 0))
{
// Before EXIT, READ R_IC_CLR_TX_ABRT
// CTA7 = R_IC_CLR_TX_ABRT (Clear TX_ABRT interrupt)

Store (CTA7, Local1)

Store(0xFE, RDST)     // 0xFE = R_IC_RAW_INTR_STAT and I2C_INTR_TX_ABRT, ERROR
Return(RDST)
}

// 4. If R_IC_STATUS == ERROR, Delay and Retry
//    STAT_TFNF = BIT1 = 0x02

If (LEqual(And(Local0, 0x02), 0))
{
//FIFO_WRITE_DELAY = 0x02

Stall (0x02)

Store(0xFD, RDST)     // 0xFD = R_IC_STATUS and STAT_TFNF, ERROR
Continue
}

// 這裡是重要的指令分歧點 -------------------------------------------
 
//      前導指令 (Read/Write) START = TRUE,  END = FALSE, 第二個 if, 在 R_IC_DATA_CMD 直接寫入 RESTART
//      後續指令 (Read)       START = TRUE,  END = TRUE,  第一個 if, 在 R_IC_DATA_CMD 直接寫入 RESTART + STOP
//      後續指令 (Write)      START = FALSE, END = TRUE,  第一個 if, 在 R_IC_DATA_CMD 直接寫入 STOP
 
// (Offset or Data) 寫入 Local0
 
Store (arg0, Local0)
 
// arg1 = START, arg2 = END
 
If (LEqual(arg1, TRUE))
{
If (LEqual(arg2, TRUE)) 
{
// Local0|B_CMD_RESTART|B_CMD_STOP, BIT09+BIT10

Or (Local0, 0x0600, Local0)
Increment (Local6)
}
else
{
// Local0|B_CMD_RESTART, BIT10

Or (Local0, 0x0400, Local0)
Increment (Local6)
}
}
else
{
If (LEqual(arg2, TRUE))
{
// Local0|B_CMD_STOP, BIT09
Or (Local0, 0x0200, Local0)
Increment (Local6)
}
else
{
// Local0, Do nothing
Increment (Local6)
}
}
 
// 將 (Offset or Data) 寫入 Command
 
Store(Local0 ,DCD7)

// Delay
 
Stall (2)

// ---------------------------------------------------------

//    Local2 做為 Counter 初始化
 
Store(0,Local2)

While(TRUE)
{  
// 1. 讀取 R_IC_RAW_INTR_STAT (Local1), RIS7 = R_IC_RAW_INTR_STAT (I2C Raw Interrupt Status)

Store (RIS7, Local1)
 
// 2. 如果 Local1 = R_IC_RAW_INTR_STAT == ERROR, Return with ERROR

//    0x40 = BIT06 = I2C_INTR_TX_ABRT = NACK Set

If (LNotEqual(And(Local1, 0x40), 0))
{
// Before EXIT, READ R_IC_CLR_TX_ABRT
// CTA7 = R_IC_CLR_TX_ABRT (Clear TX_ABRT interrupt)

Store (CTA7, Local1)
Store(0xFE, RDST)     // 0xFE = R_IC_RAW_INTR_STAT and I2C_INTR_TX_ABRT, ERROR
}
 
// 3. 如果 Local1 = R_IC_TXFLR == 0, 則 Break
//    TFL7 = R_IC_TXFLR (Transmit FIFO Level Register)

Store (TFL7, Local1)

If (LEqual(Local1, 0x0))
{
Store(0x00, RDST)
Break
}

// 4. Delay

Stall (2)

// 5. Timeout Test

Increment(Local2)

If(LLess(Local2, 1024))
{
Continue
}
else
{
Store(0xFC, RDST)     // 0xFC = EFI_TIMEOUT
Break
}
}
}
 
  // Return SUCCESS
 
  Store(0x00, RDST)
  Return(RDST)
 
}

[Clang] (1) How to Compile EDKII Based BIOS Source using Clang?

How to Compile EDKII Based BIOS Source using Clang (https://en.wikipedia.org/wiki/Clang)?

1. Files to be modified:

1.1. MSFT_DEF.txt = Microsoft Tool Chain Definition

--> This is main Tool Chain file

1.2. MSFT_DEF.txt, GCC_DEF.txt, ... 

MYTOOLS_DEF.txt --->

!include MSFT_DEF.txt
*_MYTOOLS_*_*_FAMILY = MSFT

VS2015_DEF.txt --->

!include MSFT_DEF.txt
*_VS2015_*_*_FAMILY = MSFT
DEBUG_VS2015_IA32_CC_FLAGS = DEF(DEBUG_CC_FLAGS) DEF(COMMON_CC_FLAGS) /arch:IA32
RELEASE_VS2015_IA32_CC_FLAGS = DEF(COMMON_CC_FLAGS) /arch:IA32

Since MYTOOLS_DEF.txt and VS2015_DEF.txt are sharing the usage of MSFT_DEF.txt, we need to list the difference between them. (MyTools as Default)

1.3. The usage of MYTOOLS_DEF.txt is selected in target.txt 

This file is generated in main.mak

target.txt --->

ACTIVE_PLATFORM    =  Build/Platform.dsc

TARGET = RELEASE

TOOL_CHAIN_CONF    = AmiPkg/Configuration/MYTOOLS_DEF.txt

TOOL_CHAIN_TAG = MYTOOLS

MAX_CONCURRENT_THREAD_NUMBER = 8

BUILD_RULE_CONF = AmiPkg/Configuration/build_rule.txt

The make command in main.mak as follows:

# Create Conf/target.txt, based on SDL tokens
Conf/target.txt : $(TOKEN_MAK) $(MAIN_MAK) Conf
@$(ECHO) \
"ACTIVE_PLATFORM    = $(subst \,/, $(ACTIVE_PLATFORM))\
$(EOL)\
$(EOL)TARGET = $(TARGET)\
$(EOL)\
$(EOL)TOOL_CHAIN_CONF    = $(TOOL_DEFINITION_FILE)\
$(EOL)\
$(EOL)TOOL_CHAIN_TAG = $(TOOL_CHAIN_TAG)\
$(EOL)\
$(EOL)MAX_CONCURRENT_THREAD_NUMBER = $(NUMBER_OF_BUILD_PROCESS_THREADS)\
$(EOL)\
$(EOL)BUILD_RULE_CONF = $(BUILD_RULE_FILE)" > Conf/target.txt

-----------------------------------------------------------------

TOKEN
Name  = "TOOL_DEFINITION_FILE"
Value  = "$(CONFIGURATION_DIR)$(TOOL_CHAIN_TAG)_DEF.txt"
Help  = "Name of the tool definition file.\This value goes to to auto-generated Conf/target.txt."
TokenType = Expression
TargetMAK = Yes
End

--------------------------------------------------------------

Conf/target.txt : $(TOKEN_MAK) $(MAIN_MAK) Conf
@$(ECHO) \
"ACTIVE_PLATFORM    = $(subst \,/, $(ACTIVE_PLATFORM))\
$(EOL)\
$(EOL)TARGET = $(TARGET)\
$(EOL)\
$(EOL)TOOL_CHAIN_CONF    = $(TOOL_DEFINITION_FILE)\
$(EOL)\
$(EOL)TOOL_CHAIN_TAG = $(TOOL_CHAIN_TAG)\
$(EOL)\
$(EOL)MAX_CONCURRENT_THREAD_NUMBER = $(NUMBER_OF_BUILD_PROCESS_THREADS)\
$(EOL)\
$(EOL)BUILD_RULE_CONF = $(BUILD_RULE_FILE)" > Conf/target.txt

---------------------------------------------------------------

1.4. Search "Clang Support" for building on Mac OS X (in EDK2_Build_Spec.pdf), where the full sample of Clang_DEF.txt 

1.5. Complete Flow:

1.5.1. Veb Calls Tools (make.exe) -> makefile

1.5.2. makefile gives the control to main.mak

1.5.3. main.mak in charge of including all makefiles came from module.mak

1.5.4. Based on definition of toolchain, main.mak will generate target.txt

1.5.5. main.mak calls EDK2 build.exe

1.5.6. Compile Example of a EDKII "Driver"

Control Tool:   C:\WinDDK\7600.16385.1\bin\x86\amd64\cl.exe
Generated File: v3_lib.obj
Source File:    v3_lib.c

---------------------------------------------------------------

2. target.txt

# Platform.dsc:

ACTIVE_PLATFORM    =  Build/Platform.dsc

TARGET = RELEASE

TOOL_CHAIN_CONF    = AmiPkg/Configuration/MYTOOLS_DEF.txt

TOOL_CHAIN_TAG = MYTOOLS

MAX_CONCURRENT_THREAD_NUMBER = 8

BUILD_RULE_CONF = AmiPkg/Configuration/build_rule.txt

Thursday, February 20, 2014

[x86] (9) PFAT aka. BIOS Guard and its flaw





Back to x86 again everyone, for responsible to curious feedback from 王御多, here's some little explain for PFAT aka. BIOS Guard.



Alright, I know some might feel it's too short for explaining the PFAT, however, it's really necessary to understand the basis of RSA first. If you do familiar with RSA, the only mist of PFAT to you is "Use HW solution to replace SMI method".

Using SMI method to verify and update BIOS package is okay in traditional way since in early days, people aren't so familiar with SMI. However, now days we have various software tools and spec. help us to catch and hijack the SMI.

So here's the PFAT (HW solution), the main idea is extremely simple, doing the verify and update in the hideout, block the interrupt and fetch the package data from HW-specified memory part. See, it's really simple so say so, PFAT is doing the exactly same thing except it's hiding in specified HW place.

Well, it's pretty nice, isn't?

However, someone just forgot a little thing about compatibility with BIOS recovery...what? how they get messed up since BIOS recovery is so conventional? Well, they did forget it. You may seem BIOS recovery as another kind BIOS update package only difference is the package itself is previously stored in BIOS ROM and it runs in PEI phase. Sounds fine...but PFAT module only runs in DXE phase....WTF?! BIOS recovery module could never pass the verify phase!

Anyway, I'm pretty sure it's just a little flaw had been fixed by now, just to share the experience that even the mighty one would make such funny issue.

Please leave me any comments or questions, I'd be thankful and response as soon as possible! Thanks!

Friday, November 1, 2013

[x86] (4) Security Features Diagram


End of the Friday already? Great, let's give a sneaky shot on old x86 based security features. I'll explain those stuffs later and let you guys have great weekend first.

Leave me any questions, suggestions and comments as you need, thanks!

Thursday, October 31, 2013

[x86] (3) UEFI BIOS Dynamic and Static Analyzer

Alright everyone, I believe you guys might pass out or fall into some kinds of coma for visiting old x86 museum yesterday (2) Post Mortem: ACPI/ SCI/ Q Event) since that slide is actually the compilation of few insight reports either written in English and Mandarin. Thanks to old great guys and hope my material could be as open minded as they do.

Say, let's see something new today, it's about an idea that none never support it or take it serious but me. UEFI is the BIOS standard highly promoted by Intel...and forced everyone to do so. However, BIOS is an old industry that experienced engineers tend to use traditional debug methods such as break-points. That's what I called single debug view as following diagram.

This kind of debug view is fine when you're dealing with annoying OEM customer or Project Leader urging for issue report. Yeah, just do it and attach all your records from POST code/ debug message from PCH or EC serial out/ break-point insight from IBV or Intel's online debug monitors. However, you're looking at one issue at a time. Or you're looking at two or three issues at the same time, but you're still using single debug view.


As the engineer of one project, you should be fine with single debug view. As the BIOS leader or Feature leader, you might face multiple projects ongoing in the same time and all those projects binding with second/ third source junk components (memory of worse margin, TPM initializes/ wakes up so late), and even more disasters you could possibly image.

So my idea was to create analyze view based on automatic calculation in build time and run-time. With this analyze view, you may control multiple projects at the same time without manual efforts on each project's inspection. More to that, you could create a golden template based on the vendor's reference board to control all your projects. All analyze view reports are generated automatically, no more schedule losing control.



I really love this diagram, it explains how automatic framework collecting data in build-time and run-time to create analyze view.



It's the representation example of analyze view, it's easy to gain the benefit of free and open source diagram automation generator.


See the event schedule mentioned in previously diagram? That overcomes the late initialization/ wake-up issues as well, how I love this.


How thousands of Taiwan BIOS RD still doing their jobs like this...It's not a joke, man.


How it really works and helps us from try and error.


Too shay I still have bad news about this UEFI BIOS Dynamic and Static Analyzer, which is, UEFI is not welcome to future world since x86 members (Vendors, OEM, ODM) are mainly focus on making their own money. Even UEFI is supposed to be open, people tend to doubt it and pay attention to other standards.

Finally, welcome to give me any questions, suggestions or comments, thanks!



[x86] (2) Post Mortem: ACPI/ SCI/ Q Event

Before we back to the Future world full of mobile and smart devices, let's take a look on those old bones from yesterday world...however, as the latest news I know, there are still a huge bunch of Taiwan engineers devoted their self to the x86 based, nearly dead PC and NB markets and refuse to wake up. It's really sucks that our human nature tends to follow, not to lead. Anyway, pretend you're visiting the x86 museum....with my sarcasm introduce.

 Long long time ago, there is a power saving standard called APM, the main idea is that any devices besides the CPU might notify CPU through SMI (software or hardware wired) that CPU would run the power state modify routine written in BIOS code. SMIs can't be scheduled well since it's nothing to do with OS that the system would halt while CPU's dealing with SMIs.

Well, it sucks to be so technique. Let's do it over again, CPU is a poor cook, only dealing one customer's order at one time. However, there are a bunch of crazy supervisors, they could interrupt cooker's job in the name of SMI. So the poor cook got customer complaint and supervisor take it as their huge contribution as management level.
























Boring questions you guys must know the answers.


More boring history.


ACPI's so complicated...Really? The main idea is as simple as the poor cook example in APM.



I really like this page that I draw before, however it's too detailed on ACPI events. If anyone's interested, I would append the explanation as demand.


This is my favorite page that I update it several times! Too bad it's still detailed, but I would point one thing take-away, ACPI is like the poor cook in previously example, hires one sexy waitress (that is Operating System!) to assist the order schedule including the non-sense requests from stupid supervisors. The SMI requests mentioned previously are now replaced by SCI requests.


Huh, boring power states. Can you image that all those years go by and still the general users got confused on all those damn S3/S4/S5/S0/Hibernate/Fast-Start-Up/ Connected-Stand-By things... No one really sees what are they doing and they didn't even recognize it...wow!


More Reference...


More questions... make it stop!


Good trip of old stuff, right? I had devoted a lot time and efforts on it, but now I realize that I shouldn't only learn for the job and money, or there goes the consequences that most things you know became the yesterday's ashes. At least I wake up now, ha ha.

Any questions, suggestions or comments, please show me some support, thanks!