Mercurial > flash_v2
comparison packages/hal/powerpc/mpc8260/current/include/var_cache.h @ 461:aae52574f8c5
Add support for PowerPC/8260 based platforms. Contributed by Patrick Doyle <wpd@delcomsys.com>
| author | gthomas |
|---|---|
| date | Thu, 12 Dec 2002 21:15:24 +0000 |
| parents | |
| children | 2568adc4834e |
comparison
equal
deleted
inserted
replaced
| 460:a65a4055f146 | 461:aae52574f8c5 |
|---|---|
| 1 #ifndef CYGONCE_VAR_CACHE_H | |
| 2 #define CYGONCE_VAR_CACHE_H | |
| 3 //============================================================================= | |
| 4 // | |
| 5 // var_cache.h | |
| 6 // | |
| 7 // Variant HAL cache control API | |
| 8 // | |
| 9 //============================================================================= | |
| 10 //####ECOSGPLCOPYRIGHTBEGIN#### | |
| 11 // ------------------------------------------- | |
| 12 // This file is part of eCos, the Embedded Configurable Operating System. | |
| 13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. | |
| 14 // Copyright (C) 2002 Gary Thomas | |
| 15 // | |
| 16 // eCos is free software; you can redistribute it and/or modify it under | |
| 17 // the terms of the GNU General Public License as published by the Free | |
| 18 // Software Foundation; either version 2 or (at your option) any later version. | |
| 19 // | |
| 20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 22 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 23 // for more details. | |
| 24 // | |
| 25 // You should have received a copy of the GNU General Public License along | |
| 26 // with eCos; if not, write to the Free Software Foundation, Inc., | |
| 27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
| 28 // | |
| 29 // As a special exception, if other files instantiate templates or use macros | |
| 30 // or inline functions from this file, or you compile this file and link it | |
| 31 // with other works to produce a work based on this file, this file does not | |
| 32 // by itself cause the resulting work to be covered by the GNU General Public | |
| 33 // License. However the source code for this file must still be made available | |
| 34 // in accordance with section (3) of the GNU General Public License. | |
| 35 // | |
| 36 // This exception does not invalidate any other reasons why a work based on | |
| 37 // this file might be covered by the GNU General Public License. | |
| 38 // | |
| 39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. | |
| 40 // at http://sources.redhat.com/ecos/ecos-license/ | |
| 41 // ------------------------------------------- | |
| 42 //####ECOSGPLCOPYRIGHTEND#### | |
| 43 //============================================================================= | |
| 44 //#####DESCRIPTIONBEGIN#### | |
| 45 // | |
| 46 // Author(s): pfine | |
| 47 // Contributors:nickg, jskov | |
| 48 // Date: 2001-12-12 | |
| 49 // Purpose: Variant cache control API | |
| 50 // Description: The macros defined here provide the HAL APIs for handling | |
| 51 // cache control operations on the MPC8260 variant CPU. | |
| 52 // Usage: Is included via the architecture cache header: | |
| 53 // #include <cyg/hal/hal_cache.h> | |
| 54 // ... | |
| 55 // | |
| 56 //####DESCRIPTIONEND#### | |
| 57 // | |
| 58 //============================================================================= | |
| 59 | |
| 60 #include <pkgconf/hal.h> | |
| 61 #include <cyg/infra/cyg_type.h> | |
| 62 | |
| 63 #include <cyg/hal/ppc_regs.h> | |
| 64 #include <cyg/hal/var_regs.h> | |
| 65 | |
| 66 #include <cyg/hal/plf_cache.h> | |
| 67 | |
| 68 //----------------------------------------------------------------------------- | |
| 69 // Cache dimensions | |
| 70 | |
| 71 // Data cache | |
| 72 #define HAL_DCACHE_SIZE 16384 // Size of data cache in bytes | |
| 73 #define HAL_DCACHE_LINE_SIZE 32 // Size of a data cache line | |
| 74 #define HAL_DCACHE_WAYS 4 // Associativity of the cache | |
| 75 | |
| 76 // Instruction cache | |
| 77 #define HAL_ICACHE_SIZE 16384 // Size of cache in bytes | |
| 78 #define HAL_ICACHE_LINE_SIZE 32 // Size of a cache line | |
| 79 #define HAL_ICACHE_WAYS 4 // Associativity of the cache | |
| 80 | |
| 81 #define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS)) | |
| 82 #define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS)) | |
| 83 | |
| 84 //----------------------------------------------------------------------------- | |
| 85 // Global control of data cache | |
| 86 | |
| 87 // Enable the data cache | |
| 88 #define HAL_DCACHE_ENABLE() \ | |
| 89 CYG_MACRO_START \ | |
| 90 cyg_uint32 tmp1, tmp2; \ | |
| 91 asm volatile ( \ | |
| 92 "mfspr %1, %2;" \ | |
| 93 "li %0, 0x4000;" \ | |
| 94 "rlwimi %1,%0,0,17,17;" \ | |
| 95 "sync;" \ | |
| 96 "mtspr %2,%1;" \ | |
| 97 "isync;" \ | |
| 98 "sync;" \ | |
| 99 : "=r" (tmp1), "=r" (tmp2) \ | |
| 100 : "I" (CYGARC_REG_HID0) /* %2 ==> HID0 */); \ | |
| 101 CYG_MACRO_END | |
| 102 | |
| 103 // Disable the data cache | |
| 104 #define HAL_DCACHE_DISABLE() \ | |
| 105 CYG_MACRO_START \ | |
| 106 register cyg_uint32 tmp1; \ | |
| 107 register cyg_uint32 tmp2; \ | |
| 108 for (tmp1 = 0; tmp1 < HAL_DCACHE_SIZE; tmp1 += HAL_DCACHE_LINE_SIZE) \ | |
| 109 tmp2 = *((cyg_uint32 *) tmp1); \ | |
| 110 asm volatile ( \ | |
| 111 "mfspr %1, %2;" \ | |
| 112 "li %0, 0x0;" \ | |
| 113 "rlwimi %1,%0,0,17,17;" \ | |
| 114 "sync;" \ | |
| 115 "mtspr %2,%1;" \ | |
| 116 "isync;" \ | |
| 117 "sync;" \ | |
| 118 : "=r" (tmp1), "=r" (tmp2) \ | |
| 119 : "I" (CYGARC_REG_HID0) /* %2 ==> HID0 */); \ | |
| 120 CYG_MACRO_END | |
| 121 | |
| 122 // Invalidate the entire cache | |
| 123 #define HAL_DCACHE_INVALIDATE_ALL() \ | |
| 124 CYG_MACRO_START \ | |
| 125 cyg_uint32 tmp1, tmp2; \ | |
| 126 asm volatile ("sync;" \ | |
| 127 "mfspr %0, %2;" \ | |
| 128 "ori %0, %0, 0x0400;" \ | |
| 129 "mtspr %2, %0;" \ | |
| 130 "li %1, 0;" \ | |
| 131 "rlwimi %0,%1,0,21,21;" \ | |
| 132 "mtspr %2, %0;" \ | |
| 133 "sync;" \ | |
| 134 : "=r" (tmp1), "=r" (tmp2) \ | |
| 135 : "I" (CYGARC_REG_HID0) /* %3 ==> HID0 */);\ | |
| 136 CYG_MACRO_END | |
| 137 | |
| 138 | |
| 139 // Synchronize the contents of the cache with memory. | |
| 140 // Use a brute force method until something better appears in my head | |
| 141 // By loading memory from 0x0 to HAL_DCACHE_SIZE, incremented by | |
| 142 // HAL_DCACHE_LINE_SIZE, it will ensure that the contents of the data | |
| 143 // cache is known. Then, I will traverse the loop again, this time | |
| 144 // flushing the address, not loading it. | |
| 145 #if 1 | |
| 146 #define HAL_DCACHE_SYNC() \ | |
| 147 CYG_MACRO_START \ | |
| 148 volatile cyg_uint32 tmp1,tmp2; \ | |
| 149 for (tmp1 = 0; tmp1 < HAL_DCACHE_SIZE; tmp1 += HAL_DCACHE_LINE_SIZE) \ | |
| 150 tmp2 = *((cyg_uint32 *) tmp1); \ | |
| 151 HAL_DCACHE_FLUSH(0x0, HAL_DCACHE_SIZE); \ | |
| 152 CYG_MACRO_END | |
| 153 #else | |
| 154 #define HAL_DCACHE_SYNC() \ | |
| 155 CYG_MACRO_START \ | |
| 156 cyg_uint32 __base = 0x0, _tmp; \ | |
| 157 cyg_int32 __size = HAL_DCACHE_SIZE; \ | |
| 158 while (__size > 0) { \ | |
| 159 asm volatile ( \ | |
| 160 "lwz %0,0(%1);" \ | |
| 161 :"=r" (_tmp) : "r" (__base) \ | |
| 162 ); \ | |
| 163 __base += HAL_DCACHE_LINE_SIZE; \ | |
| 164 __size -= HAL_DCACHE_LINE_SIZE; \ | |
| 165 } \ | |
| 166 HAL_DCACHE_FLUSH( 0x0 , HAL_DCACHE_SIZE ); \ | |
| 167 CYG_MACRO_END | |
| 168 #endif | |
| 169 | |
| 170 // Query the state of the data cache | |
| 171 #define HAL_DCACHE_IS_ENABLED(_state_) \ | |
| 172 asm volatile ("mfspr %0, %1;" \ | |
| 173 "rlwinm %0,%0,18,31,31;" \ | |
| 174 : "=r" (_state_) : "I" (CYGARC_REG_HID0)) | |
| 175 | |
| 176 // Set the data cache refill burst size | |
| 177 //#define HAL_DCACHE_BURST_SIZE(_size_) | |
| 178 | |
| 179 // Set the data cache write mode | |
| 180 //#define HAL_DCACHE_WRITE_MODE( _mode_ ) | |
| 181 | |
| 182 //#define HAL_DCACHE_WRITETHRU_MODE 0 | |
| 183 //#define HAL_DCACHE_WRITEBACK_MODE 1 | |
| 184 | |
| 185 // Load the contents of the given address range into the data cache | |
| 186 // and then lock the cache so that it stays there. | |
| 187 //#define HAL_DCACHE_LOCK(_base_, _size_) | |
| 188 | |
| 189 // Undo a previous lock operation | |
| 190 //#define HAL_DCACHE_UNLOCK(_base_, _size_) | |
| 191 | |
| 192 // Unlock entire cache | |
| 193 #define HAL_DCACHE_UNLOCK_ALL() \ | |
| 194 asm volatile ("isync;" \ | |
| 195 "mfspr %0, %2;" \ | |
| 196 "oris %1, 0,0xFFFF;" \ | |
| 197 "ori %1,%1,0xEFFF;" \ | |
| 198 "and %0,%0,%1;" \ | |
| 199 "mtspr %2,%0;" \ | |
| 200 "isync;" \ | |
| 201 "sync;" \ | |
| 202 : /* No output */ \ | |
| 203 : "I" (5) /* %0 ==> r5 */, \ | |
| 204 "I" (6) /* %1 ==> r6 */, \ | |
| 205 "I" (CYGARC_REG_HID0) /* %2 ==> HID0 */); | |
| 206 | |
| 207 //----------------------------------------------------------------------------- | |
| 208 // Data cache line control | |
| 209 | |
| 210 // Allocate cache lines for the given address range without reading its | |
| 211 // contents from memory. | |
| 212 //#define HAL_DCACHE_ALLOCATE( _base_ , _size_ ) | |
| 213 | |
| 214 // Write dirty cache lines to memory and invalidate the cache entries | |
| 215 // for the given address range. | |
| 216 #define HAL_DCACHE_FLUSH( _base_ , _size_ ) \ | |
| 217 CYG_MACRO_START \ | |
| 218 cyg_uint32 __base = (cyg_uint32) (_base_); \ | |
| 219 cyg_int32 __size = (cyg_int32) (_size_); \ | |
| 220 while (__size > 0) { \ | |
| 221 asm volatile ("dcbf 0,%0;sync;" : : "r" (__base)); \ | |
| 222 __base += HAL_DCACHE_LINE_SIZE; \ | |
| 223 __size -= HAL_DCACHE_LINE_SIZE; \ | |
| 224 } \ | |
| 225 CYG_MACRO_END | |
| 226 | |
| 227 | |
| 228 // Invalidate cache lines in the given range without writing to memory. | |
| 229 // NOTE: The errata for the 603e processor indicates use of the dcbf | |
| 230 // command as the dcbi command will only invalidate modified blocks. | |
| 231 #define HAL_DCACHE_INVALIDATE( _base_ , _size_ ) \ | |
| 232 CYG_MACRO_START \ | |
| 233 cyg_uint32 __base = (cyg_uint32) (_base_); \ | |
| 234 cyg_int32 __size = (cyg_int32) (_size_); \ | |
| 235 while (__size > 0) { \ | |
| 236 asm volatile ("dcbf 0,%0;sync;" : : "r" (__base)); \ | |
| 237 __base += HAL_DCACHE_LINE_SIZE; \ | |
| 238 __size -= HAL_DCACHE_LINE_SIZE; \ | |
| 239 } \ | |
| 240 CYG_MACRO_END | |
| 241 | |
| 242 // Write dirty cache lines to memory for the given address range. | |
| 243 #define HAL_DCACHE_STORE( _base_ , _size_ ) \ | |
| 244 CYG_MACRO_START \ | |
| 245 cyg_uint32 __base = (cyg_uint32) (_base_); \ | |
| 246 cyg_int32 __size = (cyg_int32) (_size_); \ | |
| 247 while (__size > 0) { \ | |
| 248 asm volatile ("dcbst 0,%0;sync;" : : "r" (__base)); \ | |
| 249 __base += HAL_DCACHE_LINE_SIZE; \ | |
| 250 __size -= HAL_DCACHE_LINE_SIZE; \ | |
| 251 } \ | |
| 252 CYG_MACRO_END | |
| 253 | |
| 254 // Preread the given range into the cache with the intention of reading | |
| 255 // from it later. | |
| 256 //#define HAL_DCACHE_READ_HINT( _base_ , _size_ ) | |
| 257 | |
| 258 // Preread the given range into the cache with the intention of writing | |
| 259 // to it later. | |
| 260 //#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ ) | |
| 261 | |
| 262 // Allocate and zero the cache lines associated with the given range. | |
| 263 //#define HAL_DCACHE_ZERO( _base_ , _size_ ) | |
| 264 | |
| 265 //----------------------------------------------------------------------------- | |
| 266 // Global control of Instruction cache | |
| 267 | |
| 268 // Enable the instruction cache | |
| 269 #define HAL_ICACHE_ENABLE() \ | |
| 270 CYG_MACRO_START \ | |
| 271 cyg_uint32 tmp1, tmp2; \ | |
| 272 asm volatile ( \ | |
| 273 "mfspr %1, %2;" \ | |
| 274 "li %0, 0x4000;" \ | |
| 275 "rlwimi %1,%0,1,16,16;" \ | |
| 276 "sync;" \ | |
| 277 "isync;" \ | |
| 278 "mtspr %2,%1;" \ | |
| 279 "isync;" \ | |
| 280 "sync;" \ | |
| 281 : "=r" (tmp1), "=r" (tmp2) \ | |
| 282 : "I" (CYGARC_REG_HID0) /* %2 ==> HID0 */); \ | |
| 283 CYG_MACRO_END | |
| 284 | |
| 285 // Disable the instruction cache | |
| 286 #define HAL_ICACHE_DISABLE() \ | |
| 287 CYG_MACRO_START \ | |
| 288 cyg_uint32 tmp1, tmp2; \ | |
| 289 asm volatile ( \ | |
| 290 "mfspr %1, %2;" \ | |
| 291 "li %0, 0x0;" \ | |
| 292 "rlwimi %1,%0,0,16,16;" \ | |
| 293 "sync;" \ | |
| 294 "isync;" \ | |
| 295 "mtspr %2,%1;" \ | |
| 296 "isync;" \ | |
| 297 "sync;" \ | |
| 298 : "=r" (tmp1), "=r" (tmp2) \ | |
| 299 : "I" (CYGARC_REG_HID0) /* %2 ==> HID0 */); \ | |
| 300 CYG_MACRO_END | |
| 301 | |
| 302 // Invalidate the entire cache | |
| 303 #if 1 | |
| 304 #define HAL_ICACHE_INVALIDATE_ALL() \ | |
| 305 CYG_MACRO_START \ | |
| 306 cyg_uint32 tmp1, tmp2; \ | |
| 307 asm volatile ("sync;" \ | |
| 308 "mfspr %0, %2;" \ | |
| 309 "ori %1, %0, 0x8000;" \ | |
| 310 "isync;" \ | |
| 311 "mtspr %2, %1;" \ | |
| 312 "ori %1, %0, 0x0800;" \ | |
| 313 "mtspr %2, %1;" \ | |
| 314 "mtspr %2, %0;" \ | |
| 315 "isync;" \ | |
| 316 "sync;" \ | |
| 317 : "=r" (tmp1), "=r" (tmp2) \ | |
| 318 : "I" (CYGARC_REG_HID0) /* %3 ==> HID0 */);\ | |
| 319 CYG_MACRO_END | |
| 320 #else | |
| 321 #define HAL_ICACHE_INVALIDATE_ALL() \ | |
| 322 CYG_MACRO_START \ | |
| 323 cyg_uint32 tmp1, tmp2; \ | |
| 324 asm volatile ("sync;" \ | |
| 325 "mfspr %0, %2;" \ | |
| 326 "ori %0, %0, 0x0800;" \ | |
| 327 "isync;" \ | |
| 328 "mtspr %2, %0;" \ | |
| 329 "li %1, 0;" \ | |
| 330 "rlwimi %0,%1,0,20,20;" \ | |
| 331 "isync;" \ | |
| 332 "mtspr %2, %0;" \ | |
| 333 "isync;" \ | |
| 334 "sync;" \ | |
| 335 : "=r" (tmp1), "=r" (tmp2) \ | |
| 336 : "I" (CYGARC_REG_HID0) /* %3 ==> HID0 */);\ | |
| 337 CYG_MACRO_END | |
| 338 #endif | |
| 339 // Synchronize the contents of the cache with memory. | |
| 340 #define HAL_ICACHE_SYNC() \ | |
| 341 HAL_ICACHE_INVALIDATE_ALL() | |
| 342 | |
| 343 | |
| 344 // Query the state of the instruction cache | |
| 345 #define HAL_ICACHE_IS_ENABLED(_state_) \ | |
| 346 asm volatile ("mfspr %0, %1;" \ | |
| 347 "rlwinm %0,%0,17,31,31;" \ | |
| 348 : "=r" (_state_) : "I" (CYGARC_REG_HID0)) | |
| 349 | |
| 350 | |
| 351 // Set the instruction cache refill burst size | |
| 352 //#define HAL_ICACHE_BURST_SIZE(_size_) | |
| 353 | |
| 354 // Load the contents of the given address range into the instruction cache | |
| 355 // and then lock the cache so that it stays there. | |
| 356 //#define HAL_ICACHE_LOCK(_base_, _size_) | |
| 357 | |
| 358 // Undo a previous lock operation | |
| 359 //#define HAL_ICACHE_UNLOCK(_base_, _size_) | |
| 360 | |
| 361 // Unlock entire cache | |
| 362 #define HAL_ICACHE_UNLOCK_ALL() \ | |
| 363 asm volatile ("isync;" \ | |
| 364 "mfspr %0, %2;" \ | |
| 365 "oris %1, 0,0xFFFF;" \ | |
| 366 "ori %1,%1,0xDFFF;" \ | |
| 367 "and %0,%0,%1;" \ | |
| 368 "isync;" \ | |
| 369 "mtspr %2,%0;" \ | |
| 370 "isync;" \ | |
| 371 "sync;" \ | |
| 372 : /* No output */ \ | |
| 373 : "I" (5) /* %0 ==> r5 */, \ | |
| 374 "I" (6) /* %1 ==> r6 */, \ | |
| 375 "I" (CYGARC_REG_HID0) /* %2 ==> HID0 */); | |
| 376 | |
| 377 //----------------------------------------------------------------------------- | |
| 378 // Instruction cache line control | |
| 379 | |
| 380 // Invalidate cache lines in the given range without writing to memory. | |
| 381 //#define HAL_ICACHE_INVALIDATE( _base_ , _size_ ) | |
| 382 | |
| 383 //----------------------------------------------------------------------------- | |
| 384 #endif // ifndef CYGONCE_VAR_CACHE_H | |
| 385 // End of var_cache.h |
