📄 cache_management.html
字号:
</p><pre class="code">CONFIG_BLKFIN_WT </pre><p>The cache is configured as <strong>Write Through</strong>.</p><p>This adds a penalty to SDRAM writes in that each write will be flushed to SDRAM.</p><p>NOTE There are chip configuration options to also bypass the caching of data on writes.</p><p>This penalty is offset by the fact that after a write to SDRAM the data may not held in cache but actually present in the memory.</p><p>This means that if you are setting up a buffer to be sent to a peripheral via DMA action then you will not have to explicitly flush the buffer before starting the DMA transfer.</p><p>Remember, however, that the CONFIG_BLKFIN_WT cache option is a configuration option. </p><p>You may have a situation where the kernel is compiled with this option turned off. Your code may then suddenly seem to stop working.</p><p>When setting up a buffer for DMA output it is always safe to flush the cache to memory. This operation is simply optioned out and has no effect when CONFIG_BLKFIN_WT is enabled.</p><p>Look in <code>linux-2.6.x/include/asm/cacheflush.h</code> for more details</p></div><!-- SECTION [9316-12413] --><h3><a name="instruction_cache" id="instruction_cache">Instruction Cache</a></h3><div class="level3"><p> In addition to the data cache the Blackfin has an instruction cache. When enabled, this is used when executing code. As instructions are read from memory they are read into cache just like the data reads. There is a 4 way Cache for instructions.</p><p>When loading executables into SDRAM memory the instruction cache should be invalidated to allow any old cached content to be removed before trying to execute the new code. </p><p>The new code maybe loaded using a data write through the data cache so the instruction cache does not register the new data.</p><p>The <code>linux-2.6.x/fs/binfmt_flat.c</code> file contains an example.</p><p>You may also need to flush the icache in the case of handling signals where the return stack to user space is modified.</p><p>Look for an example in <code>linux-2.6.x/arch/blackfin/kernel/signal.c</code>.</p><p> The cache flushing kernel functions are in the following files:</p><ul><li class="level1"><div class="li"> linux-2.6.x/arch/blackfin/mach-common/cache.S</div></li><li class="level1"><div class="li"> linux-2.6.x/include/asm/cacheflush.h</div></li></ul><p> A drastic system call that flushes all of cache is also in <code>linux-2.6.x/arch/blackfin/kernel/sys_bfin.c</code>.</p></div><!-- SECTION [12414-13518] --><h3><a name="cache_setup_and_control" id="cache_setup_and_control">Cache Setup and Control</a></h3><div class="level3"><p> The Blackfin has detailed control over the amount of SRAM that can be set up as either data or instruction caches. Some of the fast data SRAM area can be set up as data storage and also, you may want to use some of the instruction SRAM area for code. The default setup will use the maximum data ( 32K out of 64K) and instruction (16k out of 32K ) cache allocations from the on chip SRAM.</p><p>The cache allocations are set up in the file <code>linux-2.6.x/arch/blackfin/mach-common/cacheinit.S</code>.</p><p>The <strong>IMEM_CONTROL</strong> and <strong>DMEM_CONTROL</strong> registers control how much SRAM is used for cache. </p><p><strong>IMEM_CONTROL</strong> also controls which, if any, of the 4 instruction ways are locked.</p></div><h4><a name="kernel_configuration" id="kernel_configuration">Kernel Configuration</a></h4><div class="level4"><p> The Blackfin Processors have their Kernel configuration options set up in the Blackfin Specific Features section.</p><p>Select the following from the Kernel Configuration Menu</p><pre class="code">Blackfin Processor Options ---> --- Cache Support [*] Enable ICACHE [*] Enable DCACHE [ ] Enable Cache Locking Policy (Write back) ---></pre></div><h4><a name="cplbs" id="cplbs">CPLBs</a></h4><div class="level4"><p> There are a set of 16 register sets that control the cacheable of External memory.</p><p>( CPLB = Cache Protection Lookaside Buffer.) There are 16 Data and 16 Instruction CPLB’s in the system.</p><p> Each register set contains an address register and a data register The address register will provide a match for the top 22 bits [31:10] of a given address and the data register contains control information for that address.</p><p>The control information describes the following for example </p><ul><li class="level1"><div class="li"> range ( 1K, 4K , 1M, 4M ) of that address</div></li><li class="level1"><div class="li"> can that address be cached</div></li><li class="level1"><div class="li"> is the register set locked</div></li><li class="level1"><div class="li"> user / supervisor read / write access permissions</div></li></ul><p> NOTE that the Instruction and Data CPLBS have different control options.</p><p>When cache is enabled the CPLB buffers must be set up and used.</p><p>There are only 16 Instruction CPLB Register Sets and 16 Data CPLB Register Sets. There may be a need for more memory descriptors in a system configuration.</p><p>When an access to a memory location is requested that is not represented by a current Instruction or Data CPLB an exception is raised.</p><p>The exception handler is given the task of determining if the exception occurred due to a protection violation or due to an unmatched address.</p><p>The cplb manager is given the task of loading a new entry into the core register set from one of the sets defined by the system configuration.</p><p> A set of configuration register sets is set up in the file <code>linux-2.6.x/arch/blackfin/kernel/setup.c</code>.</p><p>The code in <code>linux-2.6.x/arch/blackfin/mach-common/cplbmgr.S</code> is given the job of looking through the current core registers to find an eviction victim and replacing that victim with an entry from the configuration tables.</p><p>A <strong>kernel panic</strong> is triggered if no entry is found for the address that is being accessed or if no victim can be found.</p><p>CPLB lines can also be locked into the core registers to prevent them being swapped out.</p><p>The code in <code>linux-2.6.x/arch/blackfin/mach-common/cplbhdlr.S</code> services the exception and involves either the protection violation system or the cplbmgr code to initiate a CPLB replacement.</p></div><!-- SECTION [13519-16725] --><h2><a name="using_l2_memory" id="using_l2_memory">Using L2 Memory</a></h2><div class="level2"><p> The L1 data and memory sections can be used for data and code.</p><p>If a code section is marked as residing in the L1 memory area it will be compiled and loaded into SRDAM by the system but then transferred to L1 memory during the boot processed.</p><p>In fact the only way to get data into the L1 Instruction Memory is by using a DMA process to copy the data. In an assembler file the following example shows how to identify code that needs to be transferred to L1 instruction memory. </p><pre class="code"> // extract from arch/blackfin/mach-bf533/head.S.section .text.l1ENTRY(start_dma_code)#if CONFIG_BFIN_KERNEL_CLOCK p0.h = hi(SIC_IWR); p0.l = lo(SIC_IWR); r0.l = 0x1; [p0] = r0; SSYNC;</pre><p>This is the actual relocation call from the same file </p><pre class="code"> /*Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM*/ call _bf53x_relocate_l1_mem;</pre><p>The actual memory copy to the L1 ram is done here: </p><p>The linker magic to make the L1 code and data components have an address in L1 memory but reside in the image is in the file <strong>arch/blackfin/kernel/vmlinux.lds.S</strong> This will generate the <strong>as linked</strong> absolute address in L1 cache but locate the sections inside the SDRAM kernel image.</p><p>References are made to the as loaded addresses to give the relocation code a chance to find the area to move to L1 memory.</p><pre class="code"> __l1_lma_start = .; .text_l1 L1_CODE_START : AT ( __l1_lma_start ) { . = ALIGN(4) ; __stext_l1 = . ; *(.text.l1) . = ALIGN(4) ; __etext_l1 = . ; } .data_l1 L1_DATA_A_START : AT ( __l1_lma_start + SIZEOF(.text_l1) ) { . = ALIGN(4) ; __sdata_l1 = . ; *(.data.l1) __edata_l1 = . ; . = ALIGN(4) ; __sbss_l1 = . ; *(.bss.l1) . = ALIGN(4) ; __ebss_l1 = . ; } . = __l1_lma_start + SIZEOF(.text_l1) + SIZEOF(.data_l1) ; .data (__l1_lma_start + SIZEOF(.text_l1) + SIZEOF(.data_l1)) : AT ( __l1_lma_start + SIZEOF(.text_l1) + SIZEOF(.data_l1) )</pre></div><h4><a name="more_information" id="more_information">More Information</a></h4><div class="level4"><p>Please refer to this page <a href="kernel_space_memory_allocation.html" class="wikilink1" title="kernel_space_memory_allocation.html">Kernel space memory allocation</a> for some more details on cache management.</p><p> <a href="http://example.com" class="urlextern" title="http://example.com" rel="nofollow">External Link</a> </p></div><!-- SECTION [16726-] --><div class="footnotes"><div class="fn"><a href="#fnt__1" id="fn__1" name="fn__1" class="fn_bot">1)</a> numbers are per core</div><div class="fn"><a href="#fnt__2" id="fn__2" name="fn__2" class="fn_bot">2)</a> , <a href="#fnt__3" id="fn__3" name="fn__3" class="fn_bot">3)</a> , <a href="#fnt__4" id="fn__4" name="fn__4" class="fn_bot">4)</a> , <a href="#fnt__5" id="fn__5" name="fn__5" class="fn_bot">5)</a> , <a href="#fnt__6" id="fn__6" name="fn__6" class="fn_bot">6)</a> operates at core speed</div><div class="fn"><a href="#fnt__7" id="fn__7" name="fn__7" class="fn_bot">7)</a> operates at 1/2 of core speed</div></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -