static inline void set_pte(pte_t *ptep, pte_t pte)
{
WRITE_ONCE(*ptep, pte);
/*
* Only if the new pte is valid and kernel, otherwise TLB maintenance
* or update_mmu_cache() have the necessary barriers.
*/
if (pte_valid_not_user(pte)) {
dsb(ishst);
isb();
}
}
#define __WRITE_ONCE(x, val) \
do { \
*(volatile typeof(x) *)&(x) = (val); \
} while (0)
#define WRITE_ONCE(x, val) \
do { \
compiletime_assert_rwonce_type(x); \
__WRITE_ONCE(x, val); \
} while (0)
WRITE_ONCE(*ptep, pte);
就是把 pfn_pte(__phys_to_pfn(phys), prot) 赋给 *ptep
pfn_pte(__phys_to_pfn(phys), prot)
pfn_pte(__phys_to_pfn(phys), prot)
macro 只能一级一级的看
#define __phys_to_pfn(paddr) PHYS_PFN(paddr)
#define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT))
page size 4k, PAGE_SHIFT 就是12
把物理地址左移12位,就是PFN (Page Frame Number)
再看外层
#define pfn_pte(pfn,prot) \
__pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
#define __pte(x) ((pte_t) { (x) } ) //类型转换
#define __phys_to_pte_val(phys) (phys) //什么也没做
#define pgprot_val(x) ((x).pgprot)
__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)
就是 pfn右移12为 或 .pgprot