📄 cachelib.html
字号:
will get one (line 11) from <b><i><a href="./cacheLib.html#cacheDmaMalloc">cacheDmaMalloc</a></i>( )</b>. A <b>CACHE_FUNCS</b> structure(see <b>cacheLib.h</b>) is used to create a buffer that will not suffer from cachecoherency problems. If the memory allocator fails (line 13), the driverwill typically return ERROR (line 14) and quit.<p>The driver fills the output buffer with initialization information,device commands, and data (line 17), and is prepared to pass thebuffer to the device. Before doing so, the driver must flush the datacache (line 19) to ensure that the buffer is in memory, not hidden inthe cache. The routine <b><i>drvWrite</i>( )</b> lets the device know that the datais ready and where in memory it is located (line 20).<p>More driver code is executed (line 22), and the driver is then ready toreceive data that the device has placed in the buffer in memory (line24). Before the driver cache can work with the incoming data, it mustinvalidate the data cache entries (line 25) that correspond to the inputbuffer`s data in order to eliminate stale entries. That done, it is safe for the driver to handle the input data (line 27), which the driver retrieves from memory. Remember to free the buffer (line 29) acquired from the memory allocator. The driver will return OK (line 30) to distinguish a successful from an unsuccessful operation.<pre>STATUS drvExample2 (pBuf) /* simple driver - great performance */2: void * pBuf; /* buffer pointer parameter */ {5: if (pBuf != NULL) {7: /* no cache coherency problems with buffer passed to driver */ } else {11: pBuf = cacheDmaMalloc (BUF_SIZE);13: if (pBuf == NULL)14: return (ERROR); /* memory allocator failed */ }17: /* other driver initialization and buffer filling */19: CACHE_DMA_FLUSH (pBuf, BUF_SIZE);20: drvWrite (pBuf); /* output data to device */22: /* more driver code */24: drvWait (); /* wait for device data */25: CACHE_DMA_INVALIDATE (pBuf, BUF_SIZE);27: /* handle input data from device */29: cacheDmaFree (pBuf); /* return buffer to memory pool */30: return (OK); }</pre>Do not use <b>CACHE_DMA_FLUSH</b> or <b>CACHE_DMA_INVALIDATE</b> without first calling<b><i><a href="./cacheLib.html#cacheDmaMalloc">cacheDmaMalloc</a></i>( )</b>, otherwise the function pointers may not beinitialized correctly. Note that this driver scheme assumes all cachecoherency modes have been set before driver initialization, and thatthe modes do not change after driver initialization. The <b><i><a href="./cacheLib.html#cacheFlush">cacheFlush</a></i>( )</b> and<b><i><a href="./cacheLib.html#cacheInvalidate">cacheInvalidate</a></i>( )</b> functions can be used at any time throughout the systemsince they are affiliated with the hardware, not the malloc/free buffer.<p>A call to <b><i><a href="./cacheLib.html#cacheLibInit">cacheLibInit</a></i>( )</b> in write-through mode makes the flush functionpointers NULL. Setting the caches in copyback mode (if supported) shouldset the pointer to and call an architecture-specific flush routine. Theinvalidate and flush macros may be NULLified if the hardware provides bussnooping and there are no cache coherency problems.Example 3The next example shows a more complex driver that requires addresstranslations to assist in the cache coherency scheme. The previousexample had <b>a priori</b> knowledge of the system memory map and/or the deviceinteraction with the memory system. This next driver demonstrates a case in which the virtual address returned by <b><i><a href="./cacheLib.html#cacheDmaMalloc">cacheDmaMalloc</a></i>( )</b> might differ from the physical address seen by the device. It uses the <b>CACHE_DMA_VIRT_TO_PHYS</b> and <b>CACHE_DMA_PHYS_TO_VIRT</b> macros in addition to the <b>CACHE_DMA_FLUSH</b> and<b>CACHE_DMA_INVALIDATE</b> macros.<p>The <b><i><a href="./cacheLib.html#cacheDmaMalloc">cacheDmaMalloc</a></i>( )</b> routine initializes the buffer pointer (line 3). Ifthe memory allocator fails (line 5), the driver will typically returnERROR (line 6) and quit. The driver fills the output buffer withinitialization information, device commands, and data (line 8), and isprepared to pass the buffer to the device. Before doing so, the drivermust flush the data cache (line 10) to ensure that the buffer is inmemory, not hidden in the cache. The flush is based on the virtualaddress since the processor filled in the buffer. The <b><i>drvWrite</i>( )</b> routinelets the device know that the data is ready and where in memory it islocated (line 11). Note that the <b>CACHE_DMA_VIRT_TO_PHYS</b> macro convertsthe buffer's virtual address to the corresponding physical address for thedevice.<p>More driver code is executed (line 13), and the driver is then ready toreceive data that the device has placed in the buffer in memory (line15). Note the use of the <b>CACHE_DMA_PHYS_TO_VIRT</b> macro on the bufferpointer received from the device. Before the driver cache can workwith the incoming data, it must invalidate the data cache entries (line16) that correspond to the input buffer's data in order to eliminate stale entries. That done, it is safe for the driver to handle the input data (line 17), which it retrieves from memory. Remember to free (line19) the buffer acquired from the memory allocator. The driver will returnOK (line 20) to distinguish a successful from an unsuccessful operation.<pre>STATUS drvExample3 () /* complex driver - great performance */ {3: void * pBuf = cacheDmaMalloc (BUF_SIZE);5: if (pBuf == NULL)6: return (ERROR); /* memory allocator failed */8: /* other driver initialization and buffer filling */10: CACHE_DMA_FLUSH (pBuf, BUF_SIZE);11: drvWrite (CACHE_DMA_VIRT_TO_PHYS (pBuf));13: /* more driver code */15: pBuf = CACHE_DMA_PHYS_TO_VIRT (drvRead ());16: CACHE_DMA_INVALIDATE (pBuf, BUF_SIZE);17: /* handle input data from device */19: cacheDmaFree (pBuf); /* return buffer to memory pool */20: return (OK); }</pre>Driver SummaryThe virtual-to-physical and physical-to-virtual function pointersassociated with <b><i><a href="./cacheLib.html#cacheDmaMalloc">cacheDmaMalloc</a></i>( )</b> are supplements to a cache-safe buffer.Since the processor operates on virtual addresses and the devices accessphysical addresses, discrepant addresses can occur and might preventDMA-type devices from being able to access the allocated buffer.Typically, the MMU is used to return a buffer that has pages marked as non-cacheable. An MMU is used to translate virtual addresses into physicaladdresses, but it is not guaranteed that this will be a "transparent"translation.<p>When <b><i><a href="./cacheLib.html#cacheDmaMalloc">cacheDmaMalloc</a></i>( )</b> does something that makes the virtual addressdifferent from the physical address needed by the device, it provides thetranslation procedures. This is often the case when using translationlookaside buffers (TLB) or a segmented address space to inhibit caching(e.g., by creating a different virtual address for the same physicalspace.) If the virtual address returned by <b><i><a href="./cacheLib.html#cacheDmaMalloc">cacheDmaMalloc</a></i>( )</b> is the sameas the physical address, the function pointers are made NULL so that no callsare made when the macros are expanded.Board Support PackagesEach board for an architecture with more than one cache implementation hasthe potential for a different cache system. Hence the BSP for selectingthe appropriate cache library. The function pointer <b>sysCacheLibInit</b> isset to <b><i>cacheXxxLibInit</i>( )</b> ("Xxx" refers to the chip-specific name of alibrary or function) so that the function pointers for that cache systemwill be initialized and the linker will pull in only the desired cachelibrary. Below is an example of <b>cacheXxxLib</b> being linked in by <b>sysLib.c</b>.For systems without caches and for those architectures with only one cachedesign, there is no need for the <b>sysCacheLibInit</b> variable.<pre> FUNCPTR sysCacheLibInit = (FUNCPTR) cacheXxxLibInit;</pre>For cache systems with bus snooping, the flush and invalidate macrosshould be NULLified to enhance system and driver performance in <b><i><a href="./sysLib.html#sysHwInit">sysHwInit</a></i>( )</b>.<pre> void sysHwInit () { ... cacheLib.flushRtn = NULL; /* no flush necessary */ cacheLib.invalidateRtn = NULL; /* no invalidate necessary */ ... }</pre>There may be some drivers that require numerous cache calls, so many that they interfere with the code clarity. Additional checking can bedone at the initialization stage to determine if <b><i><a href="./cacheLib.html#cacheDmaMalloc">cacheDmaMalloc</a></i>( )</b> returneda buffer in non-cacheable space. Remember that it will return acache-safe buffer by virtue of the function pointers. Ideally, these areNULL, since the MMU was used to mark the pages as non-cacheable. Themacros CACHE_Xxx_IS_WRITE_COHERENT and CACHE_Xxx_IS_READ_COHERENTcan be used to check the flush and invalidate function pointers,respectively.<p>Write buffers are used to allow the processor to continue execution whilethe bus interface unit moves the data to the external device. In theory,the write buffer should be smart enough to flush itself when there is awrite to non-cacheable space or a read of an item that is in the buffer.In those cases where the hardware does not support this, the software mustflush the buffer manually. This often is accomplished by a read tonon-cacheable space or a NOP instruction that serializes the chip'spipelines and buffers. This is not really a caching issue; however, thecache library provides a <b>CACHE_PIPE_FLUSH</b> macro. External write buffersmay still need to be handled in a board-specific manner.<p></blockquote><h4>INCLUDE FILES</h4><blockquote><p><b>cacheLib.h</b><p></blockquote><h4>SEE ALSO</h4><blockquote><p><b><a href="./cacheLib.html#top">cacheLib</a></b>, Architecture-specific cache-management libraries (<b>cacheXxxLib</b>), <b><a href="./vmLib.html#top">vmLib</a></b>, <i>VxWorks Programmer's Guide: I/O System</i><hr><a name="cacheLibInit"></a><p align=right><a href="rtnIndex.html"><i>Libraries : Routines</i></a></p></blockquote><h1><i>cacheLibInit</i>( )</h1> <blockquote></a></blockquote><h4>NAME</h4><blockquote> <p><strong><i>cacheLibInit</i>( )</strong> - initialize the cache library for a processor architecture</p></blockquote><h4>SYNOPSIS</h4><blockquote><p><pre>STATUS cacheLibInit ( CACHE_MODE instMode, /* inst cache mode */ CACHE_MODE dataMode /* data cache mode */ )</pre></blockquote><h4>DESCRIPTION</h4><blockquote><p>This routine initializes the function pointers for the appropriate cache library. For architectures with more than one cache implementation, theboard support package must select the appropriate cache library with <b>sysCacheLibInit</b>. Systems without cache coherency problems (i.e., bus snooping) should NULLify the flush and invalidate function pointers in the <b><a href="./cacheLib.html#top">cacheLib</a></b> structure to enhance driver and overall system performance.This can be done in <b><i><a href="./sysLib.html#sysHwInit">sysHwInit</a></i>( )</b>.<p></blockquote><h4>RETURNS</h4><blockquote><p>OK, or ERROR if there is no cache library installed.</blockquote><h4>SEE ALSO</h4><blockquote><p><b><a href="./cacheLib.html#top">cacheLib</a></b><hr><a name="cacheEnable"></a><p align=right><a href="rtnIndex.html"><i>Libraries : Routines</i></a></p></blockquote><h1><i>cacheEnable</i>( )</h1> <blockquote></a></blockquote><h4>NAME</h4><blockquote> <p><strong><i>cacheEnable</i>( )</strong> - enable the specified cache</p></blockquote><h4>SYNOPSIS</h4><blockquote><p><pre>STATUS cacheEnable ( CACHE_TYPE cache /* cache to enable */ )</pre></blockquote><h4>DESCRIPTION</h4><blockquote><p>This routine invalidates the cache tags and enables the instruction or data cache.<p></blockquote><h4>RETURNS</h4><blockquote><p>OK, or ERROR if the cache type is invalid or the cache controlis not supported.</blockquote><h4>SEE ALSO</h4><blockquote><p><b><a href="./cacheLib.html#top">cacheLib</a></b><hr><a name="cacheDisable"></a><p align=right><a href="rtnIndex.html"><i>Libraries : Routines</i></a></p></blockquote><h1><i>cacheDisable</i>( )</h1> <blockquote></a></blockquote><h4>NAME</h4><blockquote> <p><strong><i>cacheDisable</i>( )</strong> - disable the specified cache</p></blockquote><h4>SYNOPSIS</h4><blockquote><p><pre>STATUS cacheDisable ( CACHE_TYPE cache /* cache to disable */ )</pre></blockquote><h4>DESCRIPTION</h4><blockquote><p>This routine flushes the cache and disables the instruction or data cache.<p></blockquote><h4>RETURNS</h4><blockquote><p>OK, or ERROR if the cache type is invalid or the cache controlis not supported.</blockquote><h4>SEE ALSO</h4><blockquote><p><b><a href="./cacheLib.html#top">cacheLib</a></b><hr><a name="cacheLock"></a><p align=right><a href="rtnIndex.html"><i>Libraries : Routines</i></a></p></blockquote><h1><i>cacheLock</i>( )</h1> <blockquote></a></blockquote><h4>NAME</h4><blockquote> <p><strong><i>cacheLock</i>( )</strong> - lock all or part of a specified cache</p></blockquote><h4>SYNOPSIS</h4><blockquote><p><pre>STATUS cacheLock ( CACHE_TYPE cache, /* cache to lock */ void * address, /* virtual address */ size_t bytes /* number of bytes to lock */ )</pre></blockquote><h4>DESCRIPTION</h4><blockquote><p>This routine locks all (global) or some (local) entries in the specified cache. Cache locking is useful in real-time systems. Not all caches can perform locking.<p></blockquote><h4>RETURNS</h4><blockquote><p>OK, or ERROR if the cache type is invalid or the cache controlis not supported.</blockquote><h4>SEE ALSO</h4><blockquote><p><b><a href="./cacheLib.html#top">cacheLib</a></b><hr><a name="cacheUnlock"></a><p align=right><a href="rtnIndex.html"><i>Libraries : Routines</i></a></p></blockquote><h1><i>cacheUnlock</i>( )</h1> <blockquote></a></blockquote><h4>NAME</h4><blockquote> <p><strong><i>cacheUnlock</i>( )</strong> - unlock all or part of a specified cache</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -