精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

CPU CACHE策略的初始化

冬至子 ? 來源:Linux與SoC ? 作者:linux-soc ? 2023-06-05 15:03 ? 次閱讀

linux booting過程中會(huì)打印CACHE的寫機(jī)制,打印信息如下:

OF: fdt: Machine model: V2P-CA9
Memory policy: Data cache writealloc

以上打印信息來自于函數(shù)

build_mem_type_table(void)

它的調(diào)用棧如下:

setup_arch
  |
  #ifdef CONFIG_MMU
    early_mm_init(mdesc);
  #endif
    |
    early_mm_init()
      |
      build_mem_type_table();

build_mem_type_table()函數(shù)的功能是獲取當(dāng)前CPU的CACHE類型,據(jù)此初始化mem_type。kernel根據(jù)mem_types數(shù)據(jù)結(jié)構(gòu)的值,做后續(xù)的其他處理。

由于build_mem_type_table()屬于early_mm_init()的一部分,因此,從early_mm_init()入手,逐步解析CACHE的寫機(jī)制。

early_mm_init(mdesc)

early_mm_init()能否得到執(zhí)行,取決于當(dāng)前kernel是否使能了MMU。

圖片

該函數(shù)的定義位于setup.c中

void __init early_mm_init(const struct machine_desc *mdesc)
{
 build_mem_type_table();
 early_paging_init(mdesc);
}

函數(shù)參數(shù)是struct machine_desc指針。數(shù)據(jù)結(jié)構(gòu)machine_desc描述了CPU的硬件信息及一些初始化函數(shù)。

struct machine_desc {
 unsigned int  nr;
 const char  *name;
 unsigned long  atag_offset;
 const char *const  *dt_compat;
 unsigned int  nr_irqs;

#ifdef CONFIG_ZONE_DMA
 phys_addr_t  dma_zone_size;
#endif
 unsigned int  video_start;
 unsigned int  video_end;
 unsigned char  reserve_lp0 :1;
 unsigned char  reserve_lp1 :1;
 unsigned char  reserve_lp2 :1;
 enum reboot_mode reboot_mode;
 unsigned  l2c_aux_val;
 unsigned  l2c_aux_mask;
 void   (*l2c_write_sec)(unsigned long, unsigned);
 const struct smp_operations *smp;
 bool   (*smp_init)(void);
 void   (*fixup)(struct tag *, char **);
 void   (*dt_fixup)(void);
 long long  (*pv_fixup)(void);
 void   (*reserve)(void);
 void   (*map_io)(void);
 void   (*init_early)(void);
 void   (*init_irq)(void);
 void   (*init_time)(void);
 void   (*init_machine)(void);
 void   (*init_late)(void);
#ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
 void   (*handle_irq)(struct pt_regs *);
#endif
 void   (*restart)(enum reboot_mode, const char *);
};

通過解析設(shè)備樹鏡像得到mdesc成員的具體值是什么。

if (atags_vaddr) {
 mdesc = setup_machine_fdt(atags_vaddr);
 if (mdesc)
  memblock_reserve(__atags_pointer,
     fdt_totalsize(atags_vaddr));
}

build_mem_type_table()

這個(gè)函數(shù)的核心作用是初始化struct mem_type數(shù)據(jù)結(jié)構(gòu),定義如下:

struct mem_type {
 pteval_t prot_pte;
 pteval_t prot_pte_s2;
 pmdval_t prot_l1;
 pmdval_t prot_sect;
 unsigned int domain;
};

該數(shù)據(jù)結(jié)構(gòu)的歷史:

author Russell King < rmk@dyn-67.arm.linux.org.uk > 2007-04-21 10:47:29 +0100
committer Russell King < rmk+kernel@arm.linux.org.uk > 2007-04-21 20:36:00 +0100
[ARM] mm 5: Use mem_types table in ioremap
We really want to be using the memory type table in ioremap, so we
only have to do the CPU type fixups in one place.

Signed-off-by: Russell King < rmk+kernel@arm.linux.org.uk >

Diffstat (limited to 'arch/arm/mm/mm.h')
-rw-r--r-- arch/arm/mm/mm.h 9 
  
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a44e309706354..66f8612c5e5b9 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
+struct mem_type {
+ unsigned int prot_pte;
+ unsigned int prot_l1;
+ unsigned int prot_sect;
+ unsigned int domain;
+};
+
+const struct mem_type *get_mem_type(unsigned int type);
+

從commit信息中可以看到,struct mem_type最初的目的是給ioremap使用的,在這個(gè)patch中,增加了struct mem_type以及get_mem_type()。

到目前為止,這個(gè)數(shù)據(jù)結(jié)構(gòu)的作用已經(jīng)不僅限上面提及的內(nèi)容。更為主要的作用是根據(jù)mem類型創(chuàng)建內(nèi)核頁表。

build_mem_type_table()函數(shù)根據(jù)ARM內(nèi)核版本號(hào)例化不同的mem類型。 包括ARM v5/6/7。

int cpu_arch = cpu_architecture();

在mmu.c的init_default_cache_policy中會(huì)對(duì)cachepolicy進(jìn)行初始化。

mmu.c (arch\\arm\\mm) line 64 : static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
init_default_cache_policy in mmu.c (arch\\arm\\mm) :    cachepolicy = i;

根據(jù)不同的CPU 架構(gòu)類型對(duì)cachepolicy變量重新賦值。

build_mem_type_table in mmu.c (arch\\arm\\mm) :   if (cachepolicy > CPOLICY_BUFFERED)
build_mem_type_table in mmu.c (arch\\arm\\mm) :    cachepolicy = CPOLICY_BUFFERED;
build_mem_type_table in mmu.c (arch\\arm\\mm) :   if (cachepolicy > CPOLICY_WRITETHROUGH)
build_mem_type_table in mmu.c (arch\\arm\\mm) :    cachepolicy = CPOLICY_WRITETHROUGH;
build_mem_type_table in mmu.c (arch\\arm\\mm) :   if (cachepolicy >= CPOLICY_WRITEALLOC)
build_mem_type_table in mmu.c (arch\\arm\\mm) :    cachepolicy = CPOLICY_WRITEBACK;
build_mem_type_table in mmu.c (arch\\arm\\mm) :   if (cachepolicy != CPOLICY_WRITEALLOC) {
build_mem_type_table in mmu.c (arch\\arm\\mm) :    cachepolicy = CPOLICY_WRITEALLOC;

內(nèi)核中定義了4中CACHE 寫策略,分別是:

#define CPOLICY_BUFFERED 1
#define CPOLICY_WRITETHROUGH 2
#define CPOLICY_WRITEBACK 3
#define CPOLICY_WRITEALLOC 4

最后,根據(jù)cachepolicy的值例化數(shù)據(jù)結(jié)構(gòu)struct cachepolicy *cp,

cp = &cache_policies[cachepolicy];

在我的環(huán)境中,cachepolicy的值為4,其對(duì)應(yīng)的CACHE屬性為writealloc。

static struct cachepolicy cache_policies[] __initdata = {
 {
  .policy  = "uncached",
  .cr_mask = CR_W|CR_C,
  .pmd  = PMD_SECT_UNCACHED,
  .pte  = L_PTE_MT_UNCACHED,
  .pte_s2  = s2_policy(L_PTE_S2_MT_UNCACHED),
 }, {
  .policy  = "buffered",
  .cr_mask = CR_C,
  .pmd  = PMD_SECT_BUFFERED,
  .pte  = L_PTE_MT_BUFFERABLE,
  .pte_s2  = s2_policy(L_PTE_S2_MT_UNCACHED),
 }, {
  .policy  = "writethrough",
  .cr_mask = 0,
  .pmd  = PMD_SECT_WT,
  .pte  = L_PTE_MT_WRITETHROUGH,
  .pte_s2  = s2_policy(L_PTE_S2_MT_WRITETHROUGH),
 }, {
  .policy  = "writeback",
  .cr_mask = 0,
  .pmd  = PMD_SECT_WB,
  .pte  = L_PTE_MT_WRITEBACK,
  .pte_s2  = s2_policy(L_PTE_S2_MT_WRITEBACK),
 }, {
  .policy  = "writealloc",
  .cr_mask = 0,
  .pmd  = PMD_SECT_WBWA,
  .pte  = L_PTE_MT_WRITEALLOC,
  .pte_s2  = s2_policy(L_PTE_S2_MT_WRITEBACK),
 }
};

writealloc結(jié)合了write back的功能,而write back是在CACHE hit時(shí)所采取的策略,alloc是在CACHE miss所采取的策略,當(dāng)發(fā)生CACHE miss時(shí),會(huì)從主存中讀取數(shù)據(jù)并更新CACHE line到CACHE緩存中。對(duì)于SMP ARM而言,普遍采取的是這種CACHE 策略,結(jié)合ARM 的SCU完成緩存一致性的處理。可以查看ARM的如下寄存器確定CACHE所支持的策略類型。

圖片

CACHE寫策略

下圖是一個(gè)標(biāo)準(zhǔn)的ARM處理器芯片版圖布局,使用SRAM作為L(zhǎng)1 CACHE,它在ARM core這一區(qū)域。通過DDR SDRAM interface訪問位于芯片外部的主存DDR memory。簡(jiǎn)單而論,從二者布局布線的角度看,訪問外部DDR memory的cycle明顯高于內(nèi)部L1 CACHE。

圖片

當(dāng)CPU執(zhí)行數(shù)據(jù)寫操作時(shí),首先檢查待寫入的內(nèi)存地址是否在CACHE中,若在CACHE中則稱之為Hit,反之為Miss。在Hit命中的前提下,CACHE寫策略分為Write back和Write through。

Write through

CACHE工作于write through模式時(shí),數(shù)據(jù)同時(shí)更新到CACHE和主存當(dāng)中。這種操作模式簡(jiǎn)單可靠,適用于寫操作比較少的應(yīng)用場(chǎng)景,或者預(yù)防突然斷電的數(shù)據(jù)恢復(fù)機(jī)制中。當(dāng)然,由于同時(shí)更新CACHE和外部主存,這種寫模式的延時(shí)比較大。

圖片

Write back

CACHE工作于write through模式時(shí),數(shù)據(jù)僅更新到CACHE中而不會(huì)立即更新到主存。基于Belady’s Anomaly, LRU, FIFO, LIFO等算法,當(dāng)CACHE中的數(shù)據(jù)需要被替換時(shí),原數(shù)據(jù)會(huì)被更新到主存當(dāng)中。在CACHE的每一個(gè)block中,使用一個(gè)dirty位來標(biāo)記當(dāng)前數(shù)據(jù)是否需要被替換,若dirty位被置位1,則需要將數(shù)據(jù)更新到主存。

圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • SMP
    SMP
    +關(guān)注

    關(guān)注

    0

    文章

    72

    瀏覽量

    19635
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    592

    瀏覽量

    27360
  • ARM處理器
    +關(guān)注

    關(guān)注

    6

    文章

    360

    瀏覽量

    41668
  • MMU
    MMU
    +關(guān)注

    關(guān)注

    0

    文章

    91

    瀏覽量

    18268
  • cache技術(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    41

    瀏覽量

    1048
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    RT-Thread自動(dòng)初始化詳解

    我們知道,在寫裸機(jī)程序時(shí),當(dāng)我們完成硬件初始化后,就需要在主函數(shù)中進(jìn)行調(diào)用。當(dāng)我們使用RT-Thread后,完全不需要這樣做了,我們可以將硬件等自動(dòng)初始化。 RT-Thread?自動(dòng)初始化機(jī)制是指
    的頭像 發(fā)表于 06-25 21:38 ?1.1w次閱讀
    RT-Thread自動(dòng)<b class='flag-5'>初始化</b>詳解

    關(guān)于TMS570LS3137的cache初始化

    各位TI專家,我想問一下,TMS570LS3137這個(gè)芯片的CACHE該如何初始化啊?另外,芯片CACHE的相關(guān)文檔在哪里有下載呢?
    發(fā)表于 06-23 06:05

    ARM處理器中CACHE策略初始化簡(jiǎn)析

    1、CPU CACHE政策的初始化linux booting過程中會(huì)打印CACHE的寫入機(jī)制,打印信息如下:上面的打印信息來自于函數(shù)build_mem_type_table(void)
    發(fā)表于 06-30 16:05

    手機(jī)模塊初始化向?qū)?/a>

    手機(jī)模塊初始化向?qū)?為了剛好的對(duì)手機(jī)模塊進(jìn)行初始化,所以把最基本的向?qū)懴聛?本向?qū)нm用于本公司的西門子TC35I和華為GT9000模塊。一、在初始化手機(jī)模塊前,請(qǐng)先確定DT
    發(fā)表于 09-18 09:41 ?17次下載

    RDA1846S初始化設(shè)置

    RDA1846S初始化設(shè)置RDA1846S初始化設(shè)置RDA1846S初始化設(shè)置
    發(fā)表于 01-15 17:08 ?0次下載

    UCOS_III_配置與初始化

    UCOS_III_配置與初始化
    發(fā)表于 12-20 22:53 ?5次下載

    HX711初始化程序

    這是HX711的初始化程序
    發(fā)表于 02-08 01:51 ?89次下載

    ds1302時(shí)鐘芯片初始化,自動(dòng)決定DS1302是否需要初始化程序

    ds1302芯片時(shí)鐘芯片大家都在問到底需要不需要初始化?這篇文章將會(huì)給大家一個(gè)程序,可以自動(dòng)決定DS1302是否需要初始化
    發(fā)表于 10-19 19:19 ?8489次閱讀

    8253初始化程序分享_8253應(yīng)用案例

    本文首先介紹了8253概念及8253各通道的工作方式,其次詳細(xì)介紹了8253初始化要求及編程,最后用一個(gè)例子介紹了8253的初始化程序。
    發(fā)表于 05-23 15:52 ?2.2w次閱讀
    8253<b class='flag-5'>初始化</b>程序分享_8253應(yīng)用案例

    在51平臺(tái)下初始化文件的引入導(dǎo)致全局變量無法初始化的問題如何解決

    本文檔的主要內(nèi)容詳細(xì)介紹的是在51平臺(tái)下初始化文件的引入導(dǎo)致全局變量無法初始化的問題如何解決。
    發(fā)表于 08-20 17:31 ?0次下載
    在51平臺(tái)下<b class='flag-5'>初始化</b>文件的引入導(dǎo)致全局變量無法<b class='flag-5'>初始化</b>的問題如何解決

    神經(jīng)網(wǎng)絡(luò)如何正確初始化?

    初始化對(duì)訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)的收斂性有重要影響。
    的頭像 發(fā)表于 05-17 16:32 ?8098次閱讀
    神經(jīng)網(wǎng)絡(luò)如何正確<b class='flag-5'>初始化</b>?

    鴻蒙內(nèi)核源碼:內(nèi)核空間是怎么初始化的?

    data段 該段用于存儲(chǔ)初始化的全局變量,初始化為0的全局變量出于編譯優(yōu)化的策略還是被保存在BSS段。
    的頭像 發(fā)表于 04-26 14:43 ?1827次閱讀
    鴻蒙內(nèi)核源碼:內(nèi)核空間是怎么<b class='flag-5'>初始化</b>的?

    C++之初始化列表學(xué)習(xí)的總結(jié)

    類中可以使用初始化列表對(duì)成員進(jìn)行初始化
    的頭像 發(fā)表于 12-24 17:39 ?819次閱讀

    RT-Thread自動(dòng)初始化機(jī)制

    ??在分析之前首先查閱 RT-Thread 的官方文檔 [RT-Thread 自動(dòng)初始化機(jī)制](https://www.rt-thread.org/document/site
    的頭像 發(fā)表于 06-17 08:52 ?2566次閱讀
    RT-Thread自動(dòng)<b class='flag-5'>初始化</b>機(jī)制

    secondary cpu初始化狀態(tài)設(shè)置

    ,用于填寫secondary cpu的入口地址。 uboot負(fù)責(zé)將這塊內(nèi)存的地址寫入devicetree中,當(dāng)內(nèi)核初始化完成,需要啟動(dòng)secondary cpu時(shí),就將其內(nèi)核入口地址寫到那塊內(nèi)存中
    的頭像 發(fā)表于 12-05 15:27 ?1022次閱讀
    secondary <b class='flag-5'>cpu</b><b class='flag-5'>初始化</b>狀態(tài)設(shè)置