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 规范, 忽然觉得应该把某些东西要记录下来, 就来这开博了.
尽量以后多多的来发博文, 也算是见证学习的过程, 并能与更多的人分享这些...