momo zone

调核人的blog

PAT 页面属性表

PAT(页面属性表Page Attribute Table)

X86的页面属性表(PAT)能够在页面级的粒度上设置内存属性。PAT是对MTRR的补充,通过MTRR可以为物理地址区域设置内存类型。但是PAT比MTRR更灵活,因为它可以在页面级别设置属性,而且硬件上也不限制属性设置的数量。PAT相当灵活,即使多个虚拟内存地址映射到同一个物理内存地址,也不会引起内存类型的冲突。
通过PAT能够设置多种类型的内存属性,其中最常用的有4种:写回(Write-back),不缓存(Uncached),写联合(Write-combined)以及Uncached Minus。

PAT APIs
内核中提供了很多能够在页面级设置内存属性的API。为了避免混淆,需要小心地使用这些接口。下表中列出了这些接口、它们的功能以及它们与内存属性的关系。这些API都使用reserve_memtype()/free_memtype()接口来操作物理地址区域,以避免冲突。

-------------------------------------------------------------------
API                    |    RAM   |  ACPI,...  |  Reserved/Holes  |
-----------------------|----------|------------|------------------|
                       |          |            |                  |
ioremap                |    --    |    UC-     |       UC-        |
                       |          |            |                  |
ioremap_cache          |    --    |    WB      |       WB         |
                       |          |            |                  |
ioremap_nocache        |    --    |    UC-     |       UC-        |
                       |          |            |                  |
ioremap_wc             |    --    |    --      |       WC         |
                       |          |            |                  |
set_memory_uc          |    UC-   |    --      |       --         |
 set_memory_wb         |          |            |                  |
                       |          |            |                  |
set_memory_wc          |    WC    |    --      |       --         |
 set_memory_wb         |          |            |                  |
                       |          |            |                  |
pci sysfs resource     |    --    |    --      |       UC-        |
                       |          |            |                  |
pci sysfs resource_wc  |    --    |    --      |       WC         |
 is IORESOURCE_PREFETCH|          |            |                  |
                       |          |            |                  |
pci proc               |    --    |    --      |       UC-        |
 !PCIIOC_WRITE_COMBINE |          |            |                  |
                       |          |            |                  |
pci proc               |    --    |    --      |       WC         |
 PCIIOC_WRITE_COMBINE  |          |            |                  |
                       |          |            |                  |
/dev/mem               |    --    |  WB/WC/UC- |    WB/WC/UC-     |
 read-write            |          |            |                  |
                       |          |            |                  |
/dev/mem               |    --    |    UC-     |       UC-        |
 mmap SYNC flag        |          |            |                  |
                       |          |            |                  |
/dev/mem               |    --    |  WB/WC/UC- |    WB/WC/UC-     |
 mmap !SYNC flag       |          |(from exist-|  (from exist-    |
 and                   |          |  ing alias)|    ing alias)    |
 any alias to this area|          |            |                  |
                       |          |            |                  |
/dev/mem               |    --    |    WB      |       WB         |
 mmap !SYNC flag       |          |            |                  |
 no alias to this area |          |            |                  |
 and                   |          |            |                  |
 MTRR says WB          |          |            |                  |
                       |          |            |                  |
/dev/mem               |    --    |    --      |       UC-        |
 mmap !SYNC flag       |          |            |                  |
 no alias to this area |          |            |                  |
 and                   |          |            |                  |
 MTRR says !WB         |          |            |                  |
                       |          |            |                  |
-------------------------------------------------------------------

针对设备驱动的高级APIs
A. 如果要将页面导出到用户空间,可以使用接口remap_pfn_range, io_remap_pfn_range,,vm_insert_pfn
在驱动程序中,有时会希望将一些页面导出到用户空间。此时可以使用mmap接口与下列函数的组合。
1) pgprot_noncached()
2) io_remap_pfn_range() 或 remap_pfn_range() 或 vm_insert_pfn()
在PAT的支持下,Linux引入了一个新的API,pgprot_writecombine。因此,驱动能够持续地使用上述操作序列。首先,在步骤1调用pgprot_noncached()或pgprot_writecombine()。然后在采取步骤二。
步骤二为了确保不会产生映射冲突,将跟踪内存类型列表中那些标记为UC或WC的区域。
需要指出的是,这组API仅仅对IO地址空间有效,对RAM则无效。如果驱动程序希望导出一个RAM区域,则需在步骤1之前再执行一个步骤0,即调用set_memory_uc()或set_memory_wc(),同时也需要跟踪那些页面的使用情况,在页面被释放到空闲池之前调用函数set_memory_wb()。

注意:
上面表格中的“–”符号表示“不推荐使用此API”。其中一些是内核严格规定不能使用的。其它一些,虽然目前没有这么严格的限制,但是将来有可能会出现这样的情况。
对于通过/sys或/proc进行的ioremap与pci访问,如果在被访问的地址上存在冲突,将返回一个较为严格的内存类型。比如:如果已经存在了uncached映射,那么操作ioremap_wc()会返回uncached映射而不是申请的write-combine。
set_memory_[uc|wc]和set_memory_wb需要成对的使用,此时,驱动将首先申请一个uc或wc区域,在使用之后,再将该区域切换为wb。
对/proc/mtrr的操作已经不再被推荐了,取而代之,可以使用基于PAT的接口。
驱动程序可以使用ioremap_[uc|wc]访问PCI BARs,相应的访问类型为[uc|wc]。
驱动程序可以使用set_memory_[uc|wc]为RAM区域设置访存类型。

PAT调试
如果使能了CONFIG_DEBUG_FS选项,仅能够通过下面的方式检查PAT的内存类型列表。
# mount -t debugfs debugfs /sys/kernel/debug
# cat /sys/kernel/debug/x86/pat_memtype_list
PAT memtype list:
uncached-minus @ 0x7fadf000-0x7fae0000
uncached-minus @ 0x7fb19000-0x7fb1a000
uncached-minus @ 0x7fb1a000-0x7fb1b000
uncached-minus @ 0x7fb1b000-0x7fb1c000
uncached-minus @ 0x7fb1c000-0x7fb1d000
uncached-minus @ 0x7fb1d000-0x7fb1e000
uncached-minus @ 0x7fb1e000-0x7fb25000
uncached-minus @ 0x7fb25000-0x7fb26000
uncached-minus @ 0x7fb26000-0x7fb27000
uncached-minus @ 0x7fb27000-0x7fb28000
uncached-minus @ 0x7fb28000-0x7fb2e000
uncached-minus @ 0x7fb2e000-0x7fb2f000
uncached-minus @ 0x7fb2f000-0x7fb30000
uncached-minus @ 0x7fb31000-0x7fb32000
uncached-minus @ 0x80000000-0x90000000
这个列表说明了物理地址区域以及访问这些区域的PAT设置。
另外,通过内核启动选项“debugpat”可以获取更加详细的PAT调试信息。设置此参数后,各种调试信息将打印在dmesg日志中。

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: