Search This Blog

Thursday, April 28, 2011

Disable XHCI pme when enter sleep mode on AMD chipset

We can use the SciSleepDisable (SMI_REG : 20h) register to disable sleep SCI.
If XHCI pme use L Event 24, it should be set the SciSleepDisable bit 24 to 1.
The system enter sleep mode will not resume when L Event 24 be triggered.

======================================================================

最近遇到一個USB 3.0 port上接USB hub1.1後面再接Keyboard或Mouse進S3後會自動被喚醒的問題。為了解決這問題,當系統不支援USB喚醒的時候就去設定SciSleepDisable暫存器(SMI_REG : 20h)去禁止有任何event被觸發而讓系統自動喚醒。
當XHCI pme是使用L Event24時,就去設定SciSleepDisable的第24位元為1。
如此一來,當系統進入S3的時候,它就會自動擋掉來自於L Event 24的任何Evnet了。

Wednesday, April 20, 2011

Retrieve the index of the CPU to trigger SMI

We can know which CPU core (index) to trigger SMI as below.

EFI_STATUS
GetCpuCoreIndex (
  OUT UINTN *CpuIndex
  )
{
  UINT8 Index;
  EFI_STATUS Status;
  EFI_SMM_SAVE_STATE_IO_INFO *IoInfomation;
  Status = EFI_SUCCESS;
  Status = mSmst->SmmAllocatePool (EfiRuntimeServicesData,
                    sizeof (EFI_SMM_SAVE_STATE_IO_INFO),
                    (VOID **) &IoInfomation);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Find the CPU that triggered the software SMI.
  //
  for (Index = 0; Index < mSmst->NumberOfCpus; Index++) {
    Status = mSmmCpuSaveState->ReadSaveState (
                                 mSmmCpuSaveState,
                                 sizeof (IoInfo),
                                 EFI_SMM_SAVE_STATE_REGISTER_IO,
                                 Index,
                                 IoInfomation);
    if (Status == EFI_SUCCESS &&
        (IoInfo->IoPort  == (UINT16) mSwSmiCommandPort) &&
        * (UINT8*) IoInfo->IoData == (UINT8) mSmbiosPnpSwSmiValue) {
      *CpuIndex = Index;
      break;
    }
  }
  mSmst->SmmFreePool (IoInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  if (i == mSmst->NumberOfCpus) {
    return EFI_NOT_FOUND;
  } else {
    return EFI_SUCCESS;
  }
} // GetCpuCoreIndex

Monday, April 18, 2011

SVID and SSID

What is the SVID and SSID?
SVID - Subsystem Vendor ID
SSID - Subsystem ID

Where is the SVID and SSID?
The SVID will be filled in PCI device register offset 0x2C to 0x2D (2 Bytes) by BIOS.
The SSID will be filled in PCI device register offset 0x2E to 0x2F (2 Bytes) by BIOS.

What can the SVID and SSID do?
The SVID and SSID can provide device driver to recongize in order to determine what driver function needs to be supported.

=========================================================================

什麼是SVID和SSID?
SVID - Subsystem Vendor ID
SSID - Subsystem ID

BIOS要在哪裡去填SVID和SSID?
BIOS應該在PCI裝置上的0x2C到0x2D (2 Bytes)去填SVID
BIOS應該在PCI裝置上的0x2E到0x2F (2 Bytes)去填SSID

SVID和SSID的功用?
SVID和SSID可以提供裝置的驅動程式去辦別什麼功能是需要被支援(使用)的,如此一來裝置製造商也可以為很多裝置提供共用的驅動程式。

Friday, April 15, 2011

Disable EC SMI (GPI) on AMD Chipset

How to disable EC SMI on AMD Chipset?
We can set the SMI registers to turn off EC SMI in FCH specification.
SMI registers are accessed by memory-mapped IO or IO-mapped, the range from "AcpiMMioAddr" + 0x200 to "AcpiMMioAddr" + 0x2FF offset 0x14 that register name is SmiSciEn. Every bit presents every GEvent. If Gevent 23 is EC SMI pin, we need to clear the value of SmiSciEn bit 23 that can disable EC SMI. When SmiSciStatus bit 23 is set and SmiSciEn bit 23 is set, it will trigger a SMI to call the BIOS to do SMI function.

=========================================================================

如何禁能AMD chipset的EC SMI?
透過設定FCH的SMI暫存器去關掉EC SMI。
SMI暫存器可以使用記憶體映對IO或IO映對的方式存取,其範圍從"AcpiMMioAddr" + 0x200 to "AcpiMMioAddr" + 0x2FF offset 0x14的SmiSciEn暫存器名稱,每一個位元都代表一個GEevent。
如果EC SMI腳位是使用GEvent 23,我們可以透過清掉SmiSciEn的位元23去禁能EC SMI。當SmiSciStatus bit23被設成1且SmiSciEn bit23被設定成1,將會觸發一個SMI去呼叫BIOS的SMI function。

Thursday, April 14, 2011

What is the BIOS?

What is the BIOS?
BIOS - Basic Input/Output System
When user pressed the power button, the main job of BIOS is let platform to enter operating system.

Where is the BIOS?
The BIOS is stored in flash ROM on the mother board. The ROM size is depended on BIOS binary size.

What is the legacy BIOS? What is the EFI BIOS?
The legacy BIOS is written by assembly code.
The EFI(Extensible Firmware Interface) BIOS is written by C code.
The legacy BIOS is replaced by EFI BIOS little by little.
The EFI BIOS is more easy to write for progarmmer.

How to boot to operating system by the EFI BIOS?
The EFI BIOS has four phases to boot to OS.
1. SEC phase: Check security and cache as RAM in order to build the PEI foundation to provide interface
2. PEI phase: CPU/chipset early initial and most important thing is memory sizing then enter DXE IPL.
3. DXE phase: Execute all the driver in order to let system has full function.
4. BDS phase: Connent all boot device and let system boot to be selected boot device.
System Power On -> SEC -> PEI -> DXE -> BDS -> OS

=======================================================================

何謂BIOS?
BIOS - 基本輸入輸出系統
當使用者按下電源鈕之後,讓系統能順利進到OS,並且達到客製化的需求,這就是BIOS的主要職責。

BIOS放在那裡?
BIOS被存放在主機板上的快閃記憶體內。快閃記憶體的容量大小是取決於BIOS的執行檔大小。
何謂legacy BIOS? 何謂EFI BIOS?
Lgacy BIOS的原始碼是使用組合語言來撰寫。
EFI(Extensible Firmware Interface) BIOS的原始碼是使用C語言來撰寫。
現今,legacy BIOS已漸漸地被EFI BIOS所取代。
EFI BIOS對於程式設計師來說,比較容易看懂,不需要碰到太多硬體底層的程式。

EFI BIOS是如何開機至作業系統的?
EFI BIOS需要經過四個階段的開機流程到作業系統。
1. SEC階段: 檢查系統安全性並將快取記憶體當作記憶體來使用以利建構PEI 環境並轉移至PEI 階段。
2. PEI 階段: CPU/chipset初始化及記憶體初始化讓系統進入到DXE IPL。
3. DXE階段: 執行所有driver為了讓系統能有完整的功能。
4. BDS階段: 連接所有可開機的裝置且讓系統開機到被選中的可開機裝置。
系統Power on -> SEC -> PEI -> DXE -> BDS -> 作業系統

Wednesday, April 13, 2011

AMD GPIO Setting Guide

Setting multi-function pin register in AMD FCH IoMux register(AcpiMMioAddr + 0xD00 ~ 0xDFF).
According to hardware setting to set what kind of function that BIOS should set to FCH IoMux register.

For example





    

    

     Function 0: CLK_REQ1#
     Function 1: FANOUT4
     Function 2: GPIO61
     That means IoMux<61> register should set to 0x00(CLK_REQ1#)

     If this pin isn't for GPIO use, we don't care the GPIO register setting.

According to hardware design some pins to GPI or GPO,
we should set GPIO<0 ~ 228> register to GPI or GPO, pull-up or pull down and sticky or not.

The GPIO registers also control the GEvent pins. The GEvent<X> pins,
where the X is in the range of 0 ~ 23, map to the offset range 60h ~ 77h (or 96 ~119 in decimal).


Between BIOS and EC

When system enter POST phase, the BIOS should send EC command to notify EC now is in POST.
Before system enter Windows, the BIOS should send EC command to notify EC now is in ACPI mode.

EC is in ACPI mode:
For example
In Windows --> Unplug AC Adaptor --> Trigger EC SCI Pin --> Notify OS Acpi Driver --> Do Q Event (AC unplug ASL code)

EC is not in ACPI mode:
For example
In DOS --> Unplug AC Adaptor --> Trigger EC SMI Pin --> Enter SMM Mode --> Do SMI Handler (AC unplug SMI code)




 








======================================================================

當系統在POST階段,BIOS需要送EC command告訴EC現在在POST階段。
在系統進入到Windows之前,BIOS需要送EC command告訴EC現在要進入ACPI mode, 去服務SCI。

EC在ACPI mode:
例如:
在Windows環境裡 --> 移除AC電源 --> 觸發EC SCI Pin --> 告訴OS Acpi 的驅動程式 --> 執行Q Event (AC unplug ASL code)

EC不在ACPI mode:
例如:
在DOS環境裡 --> --> 移除AC電源 --> 觸發EC SMI Pin --> 進入SMM Mode --> 執行SMI Handler (AC unplug SMI code)

Tuesday, April 12, 2011

Keyboard Buffer Concept and Tool

Location
Description
Size
40:1Ah
Keyboard, Head of Buffer Pointer
word
40:1Ch
Keyboard, End of Buffer Pointer
word
40:1Eh
Keyboard, Buffer
16 words

If the value of location 40:1Ah points to the same address as in location 40:1Ch, there are no keys in the buffer.

40:1Ah as a key is removed from the buffer, that pointer is incremented by 2, until the last word of the buffer is reached. At the point it is reset to the start of the keyboard buffer area.

40:1Ch as a key is added from the buffer, that pointer is incremented by 2, until the last word of the buffer is reached. At the point it is reset to the start of the keyboard buffer area.

40:1Eh is 16 words FIFO buffer holds up to 15 keys.
The scan code is in the upper byte of the word.
The ASCII conversion of the scan code is in the lower byte of the word.

In the BIOS code, the keyboard buffer should be cleared before end of INT19h.


Keyboard Buffer Tool (for DOS)














>> Click Here to Download <<

Monday, April 11, 2011

KBC Command

KBC Command
Function Description
0xAD
Disable keyboard interface
0xAE
Enable keyboard interface
0xED
Update keyboard LED status(Caps Lock/Scroll Lock/Num Lock)
0xAA
8042 controller self test
0xAB
Keyboard interface test

Thursday, April 7, 2011

ATI PowerXpress 4.0

ATI PX 4.0 supports two mode as below.

Dynamic Mode :
ATI driver will depend on loading to automatic to enhance performance.

Fixed Mode:
1.  High performance mode: Always turn on dGPU and iGPU to enhance performance.
2.  Power saving mode: turn off dGPU in order to saving more power.

Wednesday, April 6, 2011

ASL Code Method _BCL and _BCM

1. OS will get brightness level from _BCL

Method(_BCL, 0, NotSerialized)
{
    Return(Package(){100,    // AC Default Level 16
                                  33,    // DC Default Level 5
                                  13,    // Level 1
                                  18,    // Level 2
                                  23,    // Level 3
                                  28,    // Level 4
                                  33,    // Level 5
                                  38,    // Level 6
                                  43,    // Level 7
                                  48,    // Level 8
                                  54,    // Level 9
                                  60,    // Level 10
                                  66,    // Level 11
                                  72,    // Level 12
                                  78,    // Level 13
                                  84,    // Level 14
                                  90,    // Level 15
                                 100    // Level 16
                                })
}



2. OS will set brightness from _BCM

Method(_BCM, 1, NotSerialized)
{
    if (LEqual(\_SB.PCI0.VGA.AF7E, 0x80000001)) // Brightness control by driver
    {                                        
        // Using the equation (Arg0*3+19)/20 to convert the "0 to 100%" BCL levels
        // to "0 to 15" based.
        Divide(Add(Multiply(Arg0, 3), 19), 20, Local1, Local0)
        Store (DeRefOf(Index(BLVL, Local0)), Local3) // Get 0-255 range level from buffer
         \_SB.PCI0.AFN7(Local3)
    }
}


=======================================================================

1. OS會從ACPI的Method _BCL去得到需要所訂定的明亮度

Method(_BCL, 0, NotSerialized)
{
    Return(Package(){100,    // AC 預設 Level 16 (預設一插上AC電源就將明亮度調至100%)
                                  33,    // DC 預設  Level 5 (預設DC電源就將明亮度調至33%)
                                  13,    // Level 1
                                  18,    // Level 2
                                  23,    // Level 3
                                  28,    // Level 4
                                  33,    // Level 5
                                  38,    // Level 6
                                  43,    // Level 7
                                  48,    // Level 8
                                  54,    // Level 9
                                  60,    // Level 10
                                  66,    // Level 11
                                  72,    // Level 12
                                  78,    // Level 13
                                  84,    // Level 14
                                  90,    // Level 15
                                 100    // Level 16
                                })
}



2. OS從ACPI的Method_BCM去設定明亮度

Method(_BCM, 1, NotSerialized)
{
    if (LEqual(\_SB.PCI0.VGA.AF7E, 0x80000001)) // Brightness control by driver
    {                                        
        // Using the equation (Arg0*3+19)/20 轉換 "0 to 100%" BCL levels至 to "0 to 15" 階.
        Divide(Add(Multiply(Arg0, 3), 19), 20, Local1, Local0)
        Store (DeRefOf(Index(BLVL, Local0)), Local3) // 從buffer抓0-255的範圍
         \_SB.PCI0.AFN7(Local3)
    }
}

_BCL和_BCM僅使用在筆記型電腦,桌上型電腦不需支援

Monday, April 4, 2011

IRQ Resource Assign

IRQ Resource Assign @ PCI Register in 0x3C(Interrupt Line) and 0x3D(Interrupt Pin)















IRQ Routing (For Example)





$PIR is located in memory address from F0000h to FFFFFh.
This table is filled by system BIOS and OS will use this table to assign PCI IRQ resource.

Bit Translator Widget














>> Click here to download <<

[Interrupt Vector] INT 10h and INT 15h

The different bewteen INT10h and INT15h.



Thursday, March 17, 2011

How to Access Byte Data on SMBus (Simple)

#define SMBusStatus         0x00
#define SMBusSlaveStatus 0x01
#define SMBusControl       0x02
#define SMBusHostCmd    0x03
#define SMBusAddress      0x04
#define SMBusData0          0x05
#define DeviceAddress       0xA0  // It depends on H/W design.
#define RWDataByte          0x48
#define SMBusInterrupt      1 << 1
#define BIT0                      1

UINT8
SMBusReadByte (
  IN UINT8 RegisterIndex
)
{
  UINT8 Data8;
 
  do {
     IoWrite8 (SMBusBaseAddress + SMBusStatus, 0xFF);
     IoRead8 (SMBusBaseAddress + SMBusStatus, Data8);
  } while (Data8 != 0);                                                                  // Waiting for all status be cleared

  IoWrite8 (SMBusBaseAddress + SMBusAddress, (DeviceAddress << 1) | BIT0);  //Read
  IoWrite8 (SMBusBaseAddress + SMBusHostCmd, RegisterIndex);
  IoWrite8 (SMBusBaseAddress + SMBusControl, RWDataByte);
  do {
     IoRead8 (SMBusBaseAddress + SMBusStatus, Data8);
  } while (Data8 != SMBusInterrupt);                                                     // Check SMBus read ready
  IoRead8 (SMBusBaseAddress + SMBusData0, Data8);
  Return Data8;
}

VOID
SMBusWriteByte (
  IN UINT8 RegisterIndex,
  IN UINT8 WriteData
)
{
  UINT8 Data8;
 
  do {
     IoWrite8 (SMBusBaseAddress + SMBusStatus, 0xFF);
     IoRead8 (SMBusBaseAddress + SMBusStatus, Data8);
  } while (Data8 != 0);                                                                     // Waiting for all status be cleared

  IoWrite8 (SMBusBaseAddress + SMBusAddress, (DeviceAddress << 1));  // Write
  IoWrite8 (SMBusBaseAddress + SMBusData0, WriteData);
  IoWrite8 (SMBusBaseAddress + SMBusHostCmd, RegisterIndex);
  IoWrite8 (SMBusBaseAddress + SMBusControl, RWDataByte);
  do {
     IoRead8 (SMBusBaseAddress + SMBusStatus, Data8);
  } while (Data8 != SMBusInterrupt);                                            // Check SMBus write ready
}

Wednesday, March 9, 2011

SLP - System Locked Preinstallation

Version Windows
SLP       Windows XP,    Windows Server 2003
SLP 2.0 Windows Vista, Windows Server 2008
SLP 2.1 Windows 7,       Windows Server 2008 R2

Implement SLP that requirement as below.
1. OEMID and table ID should be provided by ODM.
2. OEMID and table ID should be the same in RSDT and SLIC table.
3. Need to install SLP public binary key into system BIOS.

Saturday, March 5, 2011

gEfiPciEnumerationCompleteGuid

The PCI deivce will complete enumeration when gEfiPciEnumerationCompleteGuid be installed.
So we can access PCI device behind PCI bridge when gEfiPciEnumerationCompleteGuid  be installed.

Thursday, February 24, 2011

Event Log

What is event log?
A: The event log is a message to inform end-user that system has error occur.

Why do we need event log?
A: When system POST has error, it should be recorded by system BIOS in order to notify end-user system has error occur.

Where can I find the event log?
A: The event log will be saved in SMBIOS type 15h by system BIOS.


Wednesday, February 23, 2011

How to call interrupt vector by SMM thunk?

...
if (InSmm) {
  Status = SmmRt->LocateProtocol (
                                  &gModulesSmmThunkProtocolGuid,
                                  NULL,
                                  &smmthunk
                                  );

  //
  // Before we execute smmthunk, we should clean the regs. In order to aviod strange issue.
  //
  EfiZeroMem (&Regs, sizeof (Regs)); 

  Status = smmthunk->SctIsr86 (
                                      smmthunk,
                                      0x10,           // Interrupt vector
                                      &Regs);
} else {
  ...
}
...

Monday, February 21, 2011

AMD Switchable Graphics

1. Implement PEI phase power sequence.
2. If the step one is right, the dGPU PCI device should be regconized under OS.
3. Need add a VBIOS for dGPU.
4. Load VBIOS to memory in DXE phase and create ACPI SSDT table for OS to active SG function.
5. Fill SVID/SSID to dGPU PCI register.
6. Save dGPU PCI register 0x00 ~ 0x3F for restore when system resume from S3.
7. If nothing is wrong, the SG should be worked very well.

ACPI Wake Up Event

How to implement ACPI wake up event?


1. Add a wake up device and namespace for _PRW

Scope(\_SB.PCI0)                                       // General-Purpose Event
{
  Device(XHC0)                 // USB 3.0 Devices
  {
      Name(_ADR,0x100000) // Device 16 Fun0
      Name(_PRW,Package(2)
      {
          0x18,                // Wake from USB PME#
          0x04                // Lowest sleep state to wake from
      })
  }
}



2. Add a GPE event for notify device

Scope(\_GPE)                                       // General-Purpose Event
{
  Method(_L18,0x0,Notserialized)        // USB PME# wake event
  {
    Notify(\_SB.PCI0.XHC0, 2)           // It will notify XHC0 driver
    ...
  } 

  ...



3. The SciMap of Xhc0 device need to change to 0x18 for AMD chipset (SB900).


The GPE event number should be the same with _PRW.
L event number need to refer chipset setting.
Q event number need to refer EC setting.

Tuesday, February 15, 2011

CMOS Access

CMOS是透過IO的方式去存取,Intel Chipset和AMD Chipset有兩個Bank(128 Bytes * 2)可以存取,但是設計上有些許差異,在使用上必須注意。

Intel
  存取Bank 0 是透過 IO port 0x70 去設定索引值(Index port),Index 值可以為0x00 ~ 0xFF,  但是0x00~0x7F會對映到0x80~0xFF為同一位置。
從IO port 0x71去取得資料(Data port)。
  存取Bank 1 是透過 IO port 0x72 去設定索引值(Index port),Index 值可以為0x00 ~ 0xFF,  但是0x00~0x7F會對映到0x80~0xFF為同一位置。
從IO port 0x73去取得資料(Data port)。

AMD
  存取Bank 0 是透過 IO port 0x70 去設定索引值(Index port),Index 值可以為0x00 ~ 0xFF,  但是0x00~0x7F會對映到0x80~0xFF為同一位置。
從IO port 0x71去取得資料(Data port)。
  存取Bank 1 是透過 IO port 0x72 去設定索引值(Index port),Index 值可以為0x00 ~ 0xFF,  但是0x00~0x7F會對映到Bank 0 0x00~0x7F的位置,而0x80~0xFF則是Bank 1 0x80~0xFF的位置。
從IO port 0x73去取得資料(Data port)。

Friday, February 4, 2011

LPC Bus

LPC - Low Pin Count

    LPC Bus用來取代傳統多腳位的的ISA Bus,最高時脈可達33MHz,像是parallel port device / serial port device / PS2 keyboard / PS2 mouse / floppy disk / EC / BIOS 比較低速的週邊裝置都使用LPC Bus來傳輸資料,避免猶如機車(慢速)騎上高速公路(BUS)去佔汽車(快速)的車道而造成塞車現象,關於LPC的詳細資料可到Intel網站去下載Low Pin Count specification。不過現在SPI Bus也開始漸漸取代LPC Bus的地位。下一篇文章會有SPI的介紹。