EFI_*_PASS_THRU_PROTOCOL

Pass Thru Protocol
- Provides services that allow ATA commands to be sent to ATA Devices attached to an ATA controller.
- Packet-based commands would be sent to ATAPI devices only through
  Extended SCSI Pass Thru Protocol.
- While the ATA_PASS_THRU interface would expose an interface to the underlying ATA devices on
  an ATA controller, EXT_SCSI_PASS_THRU is resopnsible for exposing a packet-based
  command interface for the ATAPI devices on the same ATA controller.

在 UEFI 规范中 Pass Thru Protocol 有三种
 > EFI_ATA_PASS_THRU_PROTOCOL
   Provides information about an ATA controller and the ability to send
   ATA Command Blocks to any ATA device attached to that ATA Controller.

 > EFI_SCSI_PASS_THRU_PROTOCOL
   Provides information about a SCSI channel and the ability to send SCSI
   Request Packets to any SCSI device attached to that SCSI channel.

 > EFI_EXT_SCSI_PASS_THRU_PROTOCOL
   Provides information about a SCSI channel and the ability to send SCSI
   Request Packets to any SCSI device attached to that SCSI channel.


在 UEFI 规范中分别定义了它们的 GUID:
 > gEfiAtaPassThruProtocolGuid =
   { 0x1d3de7f0, 0x807, 0x424f, {0xaa, 0x69, 0x11, 0xa5, 0x4e, 0x19, 0xa4, 0x6f }}

 > gEfiScsiPassThruProtocolGuid =
   { 0xA59E8FCF, 0xBDA0, 0x43BB, { 0x90, 0xB1, 0xD3, 0x73, 0x2E, 0xCA, 0xA8, 0x77 }}

 > gEfiExtScsiPassThruProtocolGuid =
   { 0x143b7632, 0xb81b, 0x4cb7, {0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe }}

Bus Controller, Device Controller

在 UEFI 中, 对不同的Devices, 有着不一样的分类:

Bus Controller - 其下游可以接终端Device的, 如:
 NorthBridge, USB, ATA, SCSI

Device Controller - 本身就是终端Device的, 如:
 VGA, KBD, MOUSE, HDD, CD-ROM

Class Code for PCI(e) devices

Class Code
The Class Code register is read-only and is used to identify the
generic function of the device and,in some cases, a specific registerlevel programming interface.

The register is broken into three bytesize fields.
The upper byte (at offset 0Bh) is a base class code which
broadly classifies the type of function the device performs.
The middle byte (at offset 0Ah) is a sub-class code which identifies more
specifically the function of the device.
The lower byte (at offset 09h) identifies a specific register-level programming interface (if any) so that device independent software can interact with the device.


Base Class (at offset 0Bh), Sub-class (at offset 0Ah).

BaseClass = 0x01 - Mass storage controller
            0x02 - Network controller
            0x03 - Display controller
            0x06 - Bridge device
            0x0C - Serial bus controller

Intel x86 系统的中断


支持 256 种向量中断, 从 0~255 编号,可分类为: 异常(exception) 和 中断(interrupt)

1 异常可以分为: Fault, Trap, and Abort, 不使用中断控制器,又不能被屏蔽。
  Intel x86 处理器发布了大约20 种异常.
2 中断可以分为: 非可屏蔽中断 NMI 和 可屏蔽中断 INTR.
3 IRQ 与 中断向量的关系: IRQn 的缺省向量是 n+32.

中断向量表也改叫做中断描述符表IDT(Interrupt Descriptor Table)。

Modules of EDK2010.SR1.UP1

"CryptoPkg" 
Provides cryptographic-related libraries for UEFI security modules.
"EdkCompatibilityPkg"
Provides header files and libraries that enable you to build the EDK module in UEFI 2.0 + Framework 0.9x mode. Also provides Thunk modules that enable Framework 0.9x modules to work with UEFI2.3/PI1.2 EDK II Cores.
"IntelFrameworkModulePkg"
Package contains the definitions and module implementation which follows Intel EFI Framework Specification.
"IntelFrameworkPkg"
Intel Framework Package Reference Implementations
"MdeModulePkg"
Provides the modules that conform to UEFI/PI Industry standards. It also provides the defintions(including PPIs/PROTOCOLs/GUIDs and library classes) and libraries instances, which are used for those modules.
"MdePkg"
Provides all definitions(including functions, MACROs, structures and library classes) and libraries instances, which are defined in MDE Specification. It also provides the definitions(including PPIs/PROTOCOLs/GUIDs) of EFI1.10/UEFI2.3.1/PI1.2 and some Industry Standards.
"NetworkPkg"
Provides network modules that conform to UEFI 2.2 specification.
"SecurityPkg"
Includes the security drivers, defintions(including PPIs/PROTOCOLs/GUIDs and library classes) and libraries instances.

ACPI Platform Errror Interface (APEI)

APEI consists of four separate tables:
 1. Error Record Serialization Table (ERST) / Table 18-291
 2. Boot Error Record Table (BERT) / Table 18-277
 3. Hardware Error Source Table (HEST) / Table 18-279
 4. Error Injection Table (EINJ) / Table 18-298

* Refer to ACPI v5.0
http://www.ibm.com/developerworks/cn/linux/l-cn-apei/

IDE

a) In 'Compatibility' mode
use fixed addresses
  ___________________________________________
  |           | Command Block | Control Block |
  |  Channel  |   Registers   |   Registers   |
  |-----------|---------------|---------------|
  |  Primary  |  1F0h - 1F7h  |  3F6h - 3F7h  |
  |-----------|---------------|---------------|
  | Secondary |  170h - 177h  |  376h - 377h  |
  |-----------|---------------|---------------|

b) In Native-PCI mode
IDE registers are mapped into IO space using the BARs in IDE controller's PCI Configuration Space
   ___________________________________________________
  |           |   Command Block   |   Control Block   |
  |  Channel  |     Registers     |     Registers     |
  |-----------|-------------------|-------------------|
  |  Primary  | BAR at offset 0x10| BAR at offset 0x14|
  |-----------|-------------------|-------------------|
  | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
  |-----------|-------------------|-------------------|

CPU Reset 种类

Type 1: out 0xCF9, 0xE ; 非常彻底的Reset方法, HW 会先掉电再PowerOn
Type 2: out 0xCF9, 0x6 ; 同方法一,是Cold Reset.不过HW不会掉电.CPU和系统设备的Status会被Reset.
Type 3: out 0xCF9, 0x4 ; Software reset
Type 4: out 0x92, 0x1  ; Software reset
Type 5: out 0x66, 0xFE ; 是透过KBC去拉南桥的 KBC_RST#使系统Reset

Type 1 & 2, 都是将PLTRST#拉低16 Cycle, 使系统上所有的设备Reset.
Type 3, 4 & 5 都是Software Reset, 通过拉CPU的INIT#使CPU进入Reset状态.

Building the ACPI Structures for C-States

Required ACPI namespace objects for processor with C-States feature:
 1. _OSC and _PDC Method
 2. _CST Method
 3. _CSD Object

Note:
 _OSC: Operating System Detail
 _PDC: Processor Driver Capabilities
 _CST: C States
 _CSD: C-State Dependency

InstallPPI and NotifyPPI

Callback mode:
 InstallPPI 会把 PPI Interface 插入到 PPI Databse 中的 PPI List 数组中, 如 List[0],List[1]...
 NotifyPPI 会把 PPI Interface 插入到 PPI Databse 中的 PPI List 数组中, 如 List[127],List[126]...
上述两种都会检查是否有与其GUID一致的, 如有就调用Notify的Function来执行.
Dispatch mode:
 NotifyPPI 会在每个PEIM执行后去检查是否有与之GUID一致的, 如有就调用Notify的function来执行.

Memory Type Range Registers (MTRR)

Memory Type and Mnemonic:
  00h - Uncacheable(UC),
  01h - Write Combining(WC),
  04h - Write Through (WT),
  05h - Write Protected (WP),
  06h - Write Back (WB)
  02h,03h, 07h through 0FFh - Reserved
Fixed Range MTRRs:
  _FIX64K_00000 (8x 64-KByte) MSR 0x250
  _FIX16K_80000/A000 (16x 16-KByte, 8 ranges per register) MSR 0x258/9
  _FIX4K_C0000...F8000 (64x 4-KByte, 8 ranges per register) MSR 0x268~0x26F
Variable Range MTRRs: (IA32_MTRR_PHYSBASEn, IA32_MTRR_PHYSMASKn)
   MSR 0x200~0x213

总结:
1. 正常的OS可用的Memory的MTRR属性是 WB (06h),
2. 传统的 C/D/E/F 段的属性是 WP (05h),
3. 其他的如 MMIO, A/B段 的属性是 UC (00h)
4. 其他不在以上MTRR中规定范围的, 都适用默认的属性, 见 MSR 0x2FF.

宏与内联函数



宏是在预处理的地方把代码展开, 宏是由预处理器对宏进行替代. 
不需要额外的空间和时间方面的开销, 所以调用一个宏比调用一个函数更有效率. 给宏的参数都加上括号. Example: #define square(x) (x*x)


内联函数
内联函数是代码被插入到调用者代码处的函数, 内联函数是通过编译器控制来实现的. 
内联函数是真正的函数, 只是在需要用到的时候, 内联函数像宏一样的展开, 所以取消了函数的参数压栈, 减少了调用的开销.
内联函数必须是和函数体声明在一起才有效.
内联函数的函数体过大, 一般的编译器会放弃内联方式, 而采用普通的方式调用函数.
Example: inline function(int i)
inline int function(int i) {return i*i;}


可以用内联函数完全取代预处理宏.

C语言中的 常用排序

功能: 选择排序
输入: 数组名称(也就是数组首地址), 数组中元素个数
算法思想简单描述: 在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止.

功能: 直接插入排序
输入: 数组名称(也就是数组首地址), 数组中元素个数
算法思想简单描述: 在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的.如此反复循环,直到全部排好顺序.

功能: 冒泡排序
输入: 数组名称(也就是数组首地址), 数组中元素个数
算法思想简单描述: 在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换.

功能: 希尔排序
输入: 数组名称(也就是数组首地址), 数组中元素个数
算法思想简单描述: 先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序.当增量减到1时,整个要排序的数被分成一组,排序完成.

还有 堆排序 和 快速排序.

C语言中的 指针

指针是一个特殊的变量.指针有四个方面的内容:
1. 指针的类型
2. 指针所指向的类型
3. 指针的值,或者叫指针所指向的内存区
4. 指针本身所占据的内存区

如例子:      指针的类型  指针所指向的类型 指针的值               指针本身占据的内存区
int*p          int*               int                         sizeof(int*)=4         sizeof(int*)=4
char*p       char*           char                      sizeof(char*)=1      sizeof(char*)=4
int**p         int**             int*                        sizeof(int**)=4        sizeof(int**)=4
int(*p)[3]    int(*)[3]       int()[3]                   sizeof(int(*)[3])=12 sizeof(int(*)[3])=4

每遇到一个指针, 都要问问: 这个指针的类型是什么? 指针指的类型是什么? 指针指向了哪里?

C语言中的堆和栈的区别

堆 (Heap)
1) 要程序员用malloc()来申请, 用完后要手动清除. 2) 存取是随意的.
栈 (Stack)
1) 系统自动分配的.程序结束后,系统自动释放. 2) 后进先出.

Driver Model Driver 和 Non-Driver Mode Driver 的区别

在UEFI中Driver有两种 Type, Driver Model Driver 和 Non-Driver Mode Driver.
具体的区别是:
Drvier Model Driver (又称 Binding Driver):
    在被调用的时候, 只是声明它有的Function(s).
    不过这些Functions这个时候并不被RUN. 只有在其他的Driver在需要的时候,
    才真正的去run那些Function.
    必须有 Support(), Start(), Stop().
Non-Driver Mode Driver (又称 Driver):
    直接会被run它的function.

重新阅读 FAS 有感

今天重新看了 FAS 的前几章, 也明白些之前混乱的概念.

UEFI Specfication: 定义了 Firmware 与 OS 直接的接口规范.
Framework Architectural: 定义了 Firmware 要实现上面的接口规范,具体要做什么, 怎么做.
Foundation Code: 把上面的 Framework 转化为真实的源代码.

在 Blogger 开博了...

之前酝酿了很久, 一直想在 Blogger 上开博, 一直没有实施.
今天在学习 UEFI 规范, 忽然觉得应该把某些东西要记录下来, 就来这开博了.
尽量以后多多的来发博文, 也算是见证学习的过程, 并能与更多的人分享这些...