zoukankan      html  css  js  c++  java
  • build_mem_type_table

    该函数设置mem_types结构体数组,结构体定义如下:

    struct mem_type {
      unsigned int prot_pte;     //二级页表属性
      unsigned int prot_l1;       //二级映射中的一级页表属性
      unsigned int prot_sect;    //一级页表属性,只一级映射
      unsigned int domain;      //映射的页框所属的domain 
    };

    static struct mem_type mem_types[] = {
        [MT_DEVICE] = {          /* Strongly ordered / ARMv6 shared device */
            .prot_pte    = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
                      L_PTE_SHARED,
            .prot_l1    = PMD_TYPE_TABLE,
            .prot_sect    = PROT_SECT_DEVICE | PMD_SECT_S,
            .domain        = DOMAIN_IO,
        },
        [MT_DEVICE_NONSHARED] = { /* ARMv6 non-shared device */
            .prot_pte    = PROT_PTE_DEVICE | L_PTE_MT_DEV_NONSHARED,
            .prot_l1    = PMD_TYPE_TABLE,
            .prot_sect    = PROT_SECT_DEVICE,
            .domain        = DOMAIN_IO,
        },
        [MT_DEVICE_CACHED] = {      /* ioremap_cached */
            .prot_pte    = PROT_PTE_DEVICE | L_PTE_MT_DEV_CACHED,
            .prot_l1    = PMD_TYPE_TABLE,
            .prot_sect    = PROT_SECT_DEVICE | PMD_SECT_WB,
            .domain        = DOMAIN_IO,
        },    
        [MT_DEVICE_WC] = {    /* ioremap_wc */
            .prot_pte    = PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,
            .prot_l1    = PMD_TYPE_TABLE,
            .prot_sect    = PROT_SECT_DEVICE,
            .domain        = DOMAIN_IO,
        },
        [MT_UNCACHED] = {
            .prot_pte    = PROT_PTE_DEVICE,
            .prot_l1    = PMD_TYPE_TABLE,
            .prot_sect    = PMD_TYPE_SECT | PMD_SECT_XN,
            .domain        = DOMAIN_IO,
        },
        [MT_CACHECLEAN] = {
            .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
            .domain    = DOMAIN_KERNEL,
        },
        [MT_MINICLEAN] = {
            .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
            .domain    = DOMAIN_KERNEL,
        },
        [MT_LOW_VECTORS] = {
            .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                    L_PTE_EXEC,
            .prot_l1   = PMD_TYPE_TABLE,
            .domain    = DOMAIN_USER,
        },
        [MT_HIGH_VECTORS] = {
            .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                    L_PTE_USER | L_PTE_EXEC,
            .prot_l1   = PMD_TYPE_TABLE,
            .domain    = DOMAIN_USER,
        },
        [MT_MEMORY] = {
            .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
            .domain    = DOMAIN_KERNEL,
        },
        [MT_ROM] = {
            .prot_sect = PMD_TYPE_SECT,
            .domain    = DOMAIN_KERNEL,
        },
        [MT_MEMORY_NONCACHED] = {
            .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
            .domain    = DOMAIN_KERNEL,
        },
    };

    其中的一些cacheable,bufferable的属性与cache策略相关,要根据cache_policy结构体的内容判断。该结构体定义如下:

    struct cachepolicy {
        const char    policy[16];
        unsigned int    cr_mask;
        unsigned int    pmd;
        unsigned int    pte;
    };
    
    static struct cachepolicy cache_policies[] __initdata = {
        {
            .policy        = "uncached",
            .cr_mask    = CR_W|CR_C,
            .pmd        = PMD_SECT_UNCACHED,
            .pte        = L_PTE_MT_UNCACHED,
        }, {
            .policy        = "buffered",
            .cr_mask    = CR_C,
            .pmd        = PMD_SECT_BUFFERED,
            .pte        = L_PTE_MT_BUFFERABLE,
        }, {
            .policy        = "writethrough",
            .cr_mask    = 0,
            .pmd        = PMD_SECT_WT,
            .pte        = L_PTE_MT_WRITETHROUGH,
        }, {
            .policy        = "writeback",
            .cr_mask    = 0,
            .pmd        = PMD_SECT_WB,
            .pte        = L_PTE_MT_WRITEBACK,
        }, {
            .policy        = "writealloc",
            .cr_mask    = 0,
            .pmd        = PMD_SECT_WBWA,
            .pte        = L_PTE_MT_WRITEALLOC,
        }
    };

    最终会依据这些配置好的页表属性来填充页表项的内容。

      1 static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
      2 /*
      3  * Adjust the PMD section entries according to the CPU in use.
      4  */
      5 static void __init build_mem_type_table(void)
      6 {
      7     struct cachepolicy *cp;
      8     unsigned int cr = get_cr();
      9     unsigned int user_pgprot, kern_pgprot, vecs_pgprot;
     10     int cpu_arch = cpu_architecture();
     11     int i;
     12 
     13     /*
     14      * Mark the device areas according to the CPU/architecture.
     15      */
     16 
     17     /*
     18      * Mark device regions on ARMv6+ as execute-never
     19      * to prevent speculative instruction fetches.
     20      */
     21     mem_types[MT_DEVICE].prot_sect |= PMD_SECT_XN;
     22     mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN;
     23     mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN;
     24     mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN;
     25 
     26 
     27     
     28 
     29     /*
     30      * Now deal with the memory-type mappings
     31      */
     32      /*
     33      {
     34         .policy        = "writeback",
     35         .cr_mask    = 0,
     36         .pmd        = PMD_SECT_WB,
     37         .pte        = L_PTE_MT_WRITEBACK,
     38     }     
     39      */
     40     cp = &cache_policies[cachepolicy];
     41     vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
     42 
     43     /*
     44      * Only use write-through for non-SMP systems
     45      */
     46      /*
     47      {
     48         .policy        = "writethrough",
     49         .cr_mask    = 0,
     50         .pmd        = PMD_SECT_WT,
     51         .pte        = L_PTE_MT_WRITETHROUGH,
     52     }
     53      */
     54     vecs_pgprot = cache_policies[CPOLICY_WRITETHROUGH].pte;
     55 
     56     /*
     57      * ARMv6 and above have extended page tables.
     58      */
     59     if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
     60         /*
     61          * Mark cache clean areas and XIP ROM read only
     62          * from SVC mode and no access from userspace.
     63          */
     64         mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
     65         mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
     66         mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
     67 
     68     }
     69 
     70     /*
     71      * Non-cacheable Normal - intended for memory areas that must
     72      * not cause dirty cache line writebacks when used
     73      */
     74     /* For both ARMv6 and non-TEX-remapping ARMv7 */
     75     mem_types[MT_MEMORY_NONCACHED].prot_sect |=
     76     PMD_SECT_TEX(1);
     77 
     78 
     79     for (i = 0; i < 16; i++) {
     80         unsigned long v = pgprot_val(protection_map[i]);
     81         protection_map[i] = __pgprot(v | user_pgprot);
     82     }
     83 
     84     mem_types[MT_LOW_VECTORS].prot_pte |= vecs_pgprot;
     85     mem_types[MT_HIGH_VECTORS].prot_pte |= vecs_pgprot;
     86 
     87     pgprot_user   = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
     88     pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
     89                  L_PTE_DIRTY | L_PTE_WRITE |
     90                  L_PTE_EXEC | kern_pgprot);
     91 
     92     mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
     93     mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
     94     mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
     95     mem_types[MT_ROM].prot_sect |= cp->pmd;
     96 
     97     switch (cp->pmd) {
     98     case PMD_SECT_WT:
     99         mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
    100         break;
    101     case PMD_SECT_WB:
    102     case PMD_SECT_WBWA:
    103         mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
    104         break;
    105     }
    106     printk("Memory policy: ECC %sabled, Data cache %s
    ",
    107         ecc_mask ? "en" : "dis", cp->policy);
    108 
    109     for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
    110         struct mem_type *t = &mem_types[i];
    111         if (t->prot_l1)
    112             t->prot_l1 |= PMD_DOMAIN(t->domain);
    113         if (t->prot_sect)
    114             t->prot_sect |= PMD_DOMAIN(t->domain);
    115     }
    116 }
    build_mem_type_table

     以上数组中的设置最终会填入页表项中

  • 相关阅读:
    loadView和viewDidLoad的官方API的一些解释
    面向对象IOS编程中的聚合与耦合
    史上最全的iOS面试题及答案
    oc的基本数据的转换
    NSDateFormatter时间函数
    图片点击放大,再次点击返回原视图.完美封装,一个类一句代码即可调用.IOS完美实现
    同一ViewController内如果有两处AlertView要用代理Delegate怎么写法
    简单实现---下拉刷新 --使用UITableViewController中的refreshControl属性
    简单实现---上拉加载刷新---
    洛谷2863 [Usaco06JAN]牛的舞会
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/9446454.html
Copyright © 2011-2022 走看看