This file gives an example of using the MMU to manage the memory on AVR32 MCUs.
$Name$
Definition in file mmu.c.
#include <avr32/io.h>
#include "mmu.h"
#include "macro.h"
#include "usart.h"

Go to the source code of this file.
Functions | |
| int | mmu_add_entry (long vpn, long pfn, int pos, int type) |
| Adds an entry to the TLB. | |
| int | mmu_add_tlb_entry (long physical_addr_base, long virtual_addr_base, struct mmu_tlb_t *options) |
| Adds an entry to the TLB. | |
| int | mmu_find_index_to_entry (long physical_addr, long virtual_addr, long *index) |
| Search the TLB for an entry matching the given physical and virtual address and return the index. | |
| int | mmu_get_addrmask_from_page_size (long tlbelo, long *address_mask) |
| Get the address mask from the page size of a TLBELO entry. | |
| int | mmu_init (int enable, int mode, int segmentation) |
| Changes mode on the MMU according to input. | |
| int | mmu_invalidate_entry (int index, int type) |
| Invalidates an entry in the TLB. | |
| int | mmu_lock_entries (int entries, int type) |
| Locks a specified number of entries. | |
| void | mmu_read_bear_and_tlbehi (long *bear, long *vpn) |
Reads the TLBEAR and TLBEHI registers and place the contents in bear and vpn. | |
| int | mmu_read_entry (long *vpn, long *pfn, int pos, int type) |
Reads an entry from the TLB and place the contents in vpn and pfn. | |
| int | mmu_reset () |
| Resets the MMU and invalidates all TLB entries. | |
| int | mmu_search_physical_ptr (void *physical_ptr, long *virtual_addr) |
| Search a physical address and get the virtual address from the TLB. The function searches the data TLBs first before searching the instruction TLBs. | |
| int | mmu_search_virtual_ptr (void *virtual_ptr, long *physical_addr) |
| Search a virtual address and get the physical address from the TLB. The function searches the data TLBs first before searching the instruction TLBs. | |
| int mmu_add_entry | ( | long | vpn, | |
| long | pfn, | |||
| int | pos, | |||
| int | type | |||
| ) |
Adds an entry to the TLB.
| vpn | the value to be written to TLBEHI | |
| pfn | the value to be written to TLBELO | |
| pos | the TLB index to add an entry to | |
| type | data or instruction entry to add
|
| MMU_OK | on success | |
| MMU_ERROR_ARGUMENT | on invalid arguments |
Definition at line 529 of file mmu.c.
References AVR32_READ_SR_REG, AVR32_SET_SR_REG, MMU_ERROR_ARGUMENT, MMU_OK, MMU_TLB_TYPE_DATA, and MMU_TLB_TYPE_INSTRUCTION.
Referenced by mmu_add_tlb_entry().
00530 { 00531 00532 if (pos < 0 || 00533 ((type == MMU_TLB_TYPE_DATA && 00534 pos >= MMU_DTLB_ENTRIES) || 00535 (type == MMU_TLB_TYPE_INSTRUCTION && 00536 pos >= MMU_ITLB_ENTRIES))) { 00537 return MMU_ERROR_ARGUMENT; 00538 } 00539 00540 long regValue = 0; 00541 00542 AVR32_READ_SR_REG(AVR32_MMUCR, regValue); 00543 00544 regValue &= 0x0000001F; 00545 00546 if (type == MMU_TLB_TYPE_INSTRUCTION) { 00547 regValue |= (pos<<AVR32_MMUCR_IRP_OFFSET); 00548 } 00549 else if (type == MMU_TLB_TYPE_DATA) { 00550 regValue |= (pos<<AVR32_MMUCR_DRP_OFFSET); 00551 } else { 00552 return MMU_ERROR_ARGUMENT; 00553 } 00554 00555 AVR32_SET_SR_REG(AVR32_MMUCR, regValue); 00556 AVR32_SET_SR_REG(AVR32_TLBEHI, vpn); 00557 AVR32_SET_SR_REG(AVR32_TLBELO, pfn); 00558 00559 #ifdef __GNUC__ 00560 __builtin_tlbw(); 00561 #elif __ICCAVR32__ 00562 __write_TLB_entry(); 00563 #else 00564 #error No known compiler used 00565 #endif 00566 00567 return MMU_OK; 00568 }
| int mmu_add_tlb_entry | ( | long | physical_addr_base, | |
| long | virtual_addr_base, | |||
| struct mmu_tlb_t * | options | |||
| ) |
Adds an entry to the TLB.
| physical_addr_base | base address of the physical placement | |
| virtual_addr_base | base address of the virtual placement | |
| options | options to the entry |
| MMU_OK | on success | |
| MMU_ERROR_ARGUMENT | on invalid arguments |
Definition at line 304 of file mmu.c.
Referenced by mmu_exception(), mmuex_exceptions(), and mmuex_segon_pageon().
00306 { 00307 if (!(options->valid == MMU_ENABLE 00308 || options->valid == MMU_DISABLE)) { 00309 return MMU_ERROR_ARGUMENT; 00310 } 00311 else if (!(options->type == MMU_TLB_TYPE_INSTRUCTION 00312 || options->type == MMU_TLB_TYPE_DATA)) { 00313 return MMU_ERROR_ARGUMENT; 00314 } 00315 else if (options->asid > 0xFF 00316 || options->asid < 0) { 00317 return MMU_ERROR_ARGUMENT; 00318 } 00319 else if (!(options->cachable == MMU_ENABLE 00320 || options->cachable == MMU_DISABLE)) { 00321 return MMU_ERROR_ARGUMENT; 00322 } 00323 else if (!(options->global == MMU_ENABLE 00324 || options->global == MMU_DISABLE)) { 00325 return MMU_ERROR_ARGUMENT; 00326 } 00327 else if (!(options->bufferable == MMU_ENABLE 00328 || options->bufferable == MMU_DISABLE)) { 00329 return MMU_ERROR_ARGUMENT; 00330 } 00331 else if (options->access > 0x0D 00332 || options->access < 0) { 00333 return MMU_ERROR_ARGUMENT; 00334 } 00335 else if (!(options->page_size == MMU_PAGE_SIZE_1KB 00336 || options->page_size == MMU_PAGE_SIZE_4KB 00337 || options->page_size == MMU_PAGE_SIZE_64KB 00338 || options->page_size == MMU_PAGE_SIZE_1MB)) { 00339 return MMU_ERROR_ARGUMENT; 00340 } 00341 else if (!(options->dirty == MMU_ENABLE 00342 || options->dirty == MMU_DISABLE)) { 00343 return MMU_ERROR_ARGUMENT; 00344 } 00345 else if (!(options->write_through == MMU_ENABLE 00346 || options->write_through == MMU_DISABLE)) { 00347 return MMU_ERROR_ARGUMENT; 00348 } 00349 else if (options->position < 0 || 00350 ((options->type == MMU_TLB_TYPE_DATA && 00351 options->position >= MMU_DTLB_ENTRIES) || 00352 (options->type == MMU_TLB_TYPE_INSTRUCTION && 00353 options->position >= MMU_ITLB_ENTRIES))) { 00354 return MMU_ERROR_ARGUMENT; 00355 } 00356 00357 unsigned long vpn; 00358 unsigned long pfn; 00359 unsigned long addr_mask; 00360 00361 if (options->page_size == MMU_PAGE_SIZE_1KB) { 00362 addr_mask = 0xFFFFFC00; 00363 } 00364 else if (options->page_size == MMU_PAGE_SIZE_4KB) { 00365 addr_mask = 0xFFFFF000; 00366 } 00367 else if (options->page_size == MMU_PAGE_SIZE_64KB) { 00368 addr_mask = 0xFFFF0000; 00369 } 00370 else if (options->page_size == MMU_PAGE_SIZE_1MB) { 00371 addr_mask = 0xFFF00000; 00372 } else { 00373 return MMU_ERROR_ARGUMENT; 00374 } 00375 00376 vpn = 00377 (virtual_addr_base & addr_mask)| 00378 (options->valid<<AVR32_TLBEHI_V_OFFSET)| 00379 (options->type<<AVR32_TLBEHI_I_OFFSET)| 00380 (options->asid<<AVR32_TLBEHI_ASID_OFFSET); 00381 00382 pfn = 00383 (physical_addr_base & addr_mask)| 00384 (options->cachable<<AVR32_TLBELO_C_OFFSET)| 00385 (options->global<<AVR32_TLBELO_G_OFFSET)| 00386 (options->bufferable<<AVR32_TLBELO_B_OFFSET)| 00387 (options->access<<AVR32_TLBELO_AP_OFFSET)| 00388 (options->page_size<<AVR32_TLBELO_SZ_OFFSET)| 00389 (options->dirty<<AVR32_TLBELO_D_OFFSET)| 00390 (options->write_through<<AVR32_TLBELO_W_OFFSET); 00391 00392 int retVal = MMU_OK; 00393 00394 retVal = mmu_add_entry(vpn, pfn, options->position, options->type); 00395 00396 return retVal; 00397 }
| int mmu_find_index_to_entry | ( | long | physical_addr, | |
| long | virtual_addr, | |||
| long * | index | |||
| ) |
Search the TLB for an entry matching the given physical and virtual address and return the index.
| physical_addr | the physical address to find | |
| virtual_addr | the virtual address to find | |
| index | the index of the entry from the search |
| MMU_OK | on success | |
| MMU_TLB_MISS | on TLB search miss |
Definition at line 424 of file mmu.c.
Referenced by mmuex_segon_pageon().
00425 { 00426 long vpn = virtual_addr & 0xFFFFfc00; 00427 long pfn = physical_addr & 0xFFFFfc00; 00428 00429 AVR32_SET_SR_REG(AVR32_TLBEHI, vpn); 00430 AVR32_SET_SR_REG(AVR32_TLBELO, pfn); 00431 00432 #ifdef __GNUC__ 00433 __builtin_tlbs(); 00434 #elif __ICCAVR32__ 00435 __search_TLB_entry(); 00436 #else 00437 #error No known compiler used 00438 #endif 00439 00440 long regValue = 0; 00441 00442 AVR32_READ_SR_REG(AVR32_MMUCR, regValue); 00443 00444 if ((regValue & AVR32_MMUCR_N_MASK) != 0) { 00445 return MMU_TLB_MISS; 00446 } 00447 00448 /* Check for instruction or data TBL */ 00449 if ((vpn & AVR32_TLBEHI_I_MASK) != 0) { 00450 *index = 0x3F & (regValue>>AVR32_MMUCR_IRP_OFFSET); 00451 } else { 00452 *index = 0x3F & (regValue>>AVR32_MMUCR_DRP_OFFSET); 00453 } 00454 00455 return MMU_OK; 00456 }
| int mmu_get_addrmask_from_page_size | ( | long | tlbelo, | |
| long * | address_mask | |||
| ) |
Get the address mask from the page size of a TLBELO entry.
| tlbelo | the tlbelo to get the page size off | |
| address_mask | pointer to a variable the address mask will be written |
| MMU_OK | on success | |
| MMU_ERROR_ARGUMENT | on invalid arguments |
Definition at line 633 of file mmu.c.
References MMU_ERROR_ARGUMENT, MMU_OK, MMU_PAGE_SIZE_1KB, MMU_PAGE_SIZE_1MB, MMU_PAGE_SIZE_4KB, and MMU_PAGE_SIZE_64KB.
Referenced by mmu_search_physical_ptr(), and mmu_search_virtual_ptr().
00634 { 00635 int page_size = (tlbelo & AVR32_TLBELO_SZ_MASK) >> AVR32_TLBELO_SZ_OFFSET; 00636 00637 if (page_size == MMU_PAGE_SIZE_1KB) { 00638 *address_mask = 0xFFFFfc00; 00639 } 00640 else if (page_size == MMU_PAGE_SIZE_4KB) { 00641 *address_mask = 0xFFFFf000; 00642 } 00643 else if (page_size == MMU_PAGE_SIZE_64KB) { 00644 *address_mask = 0xFFFF0000; 00645 } 00646 else if (page_size == MMU_PAGE_SIZE_1MB) { 00647 *address_mask = 0xFFF00000; 00648 } else { 00649 return MMU_ERROR_ARGUMENT; 00650 } 00651 00652 return MMU_OK; 00653 }
| int mmu_init | ( | int | enable, | |
| int | mode, | |||
| int | segmentation | |||
| ) |
Changes mode on the MMU according to input.
This function only changes the mode, it will not invalidate all the TLB entries. If this is needed use the mmu_reset function to reset the MMU back to default setup.
| enable | enable or disable the MMU
| |
| mode | Set the MMU in private virtual mode or 1-shared virtual mode
| |
| segmentation | Turns on or off segmentation
|
| MMU_OK | on success | |
| MMU_ERROR | if unable to initialize the MMU |
Definition at line 81 of file mmu.c.
Referenced by mmuex_exceptions(), mmuex_segon_pageoff(), and mmuex_segon_pageon().
00082 { 00083 long regval = 0; 00084 long regval_read = 0; 00085 00086 AVR32_READ_SR_REG(AVR32_MMUCR, regval); 00087 00088 regval = (enable<<AVR32_MMUCR_E_OFFSET)| 00089 (mode<<AVR32_MMUCR_M_OFFSET)| 00090 (segmentation<<AVR32_MMUCR_S_OFFSET); 00091 00092 AVR32_SET_SR_REG(AVR32_MMUCR, regval); 00093 00094 AVR32_READ_SR_REG(AVR32_MMUCR, regval_read); 00095 00096 if (regval != regval_read) { 00097 return MMU_ERROR; 00098 } 00099 00100 return MMU_OK; 00101 }
| int mmu_invalidate_entry | ( | int | index, | |
| int | type | |||
| ) |
Invalidates an entry in the TLB.
| index | the TLB index of the entry to be invalidated | |
| type | data or instruction entries to invalidate
|
| MMU_OK | on success | |
| MMU_ERROR_ARGUMENT | on invalid argument |
Definition at line 470 of file mmu.c.
00471 { 00472 if (index < 0 || 00473 ((type == MMU_TLB_TYPE_DATA && 00474 index >= MMU_DTLB_ENTRIES) || 00475 (type == MMU_TLB_TYPE_INSTRUCTION && 00476 index >= MMU_ITLB_ENTRIES))) { 00477 return MMU_ERROR_ARGUMENT; 00478 } 00479 00480 long regValue = 0; 00481 00482 AVR32_READ_SR_REG(AVR32_MMUCR, regValue); 00483 00484 if (type == MMU_TLB_TYPE_INSTRUCTION) { 00485 regValue &= ~(0x3F<<AVR32_MMUCR_IRP_OFFSET); 00486 regValue |= (index<<AVR32_MMUCR_IRP_OFFSET); 00487 } else { 00488 regValue &= ~(0x3F<<AVR32_MMUCR_DRP_OFFSET); 00489 regValue |= (index<<AVR32_MMUCR_DRP_OFFSET); 00490 } 00491 00492 AVR32_SET_SR_REG(AVR32_MMUCR, regValue); 00493 00494 #ifdef __GNUC__ 00495 __builtin_tlbr(); 00496 #elif __ICCAVR32__ 00497 __read_TLB_entry(); 00498 #else 00499 #error No known compiler used 00500 #endif 00501 00502 AVR32_CLEAR_SR_BIT(AVR32_TLBEHI, AVR32_TLBEHI_V_OFFSET); 00503 00504 #ifdef __GNUC__ 00505 __builtin_tlbw(); 00506 #elif __ICCAVR32__ 00507 __write_TLB_entry(); 00508 #else 00509 #error No known compiler used 00510 #endif 00511 00512 return MMU_OK; 00513 }
| int mmu_lock_entries | ( | int | entries, | |
| int | type | |||
| ) |
Locks a specified number of entries.
| entries | number of entries to lock | |
| type | data or instruction entries to lock
|
Definition at line 266 of file mmu.c.
00267 { 00268 if (entries < 0 || 00269 ((type == MMU_TLB_TYPE_DATA && 00270 entries >= MMU_DTLB_ENTRIES) || 00271 (type == MMU_TLB_TYPE_INSTRUCTION && 00272 entries >= MMU_ITLB_ENTRIES))) { 00273 return MMU_ERROR_ARGUMENT; 00274 } 00275 00276 long regValue = 0; 00277 00278 AVR32_READ_SR_REG(AVR32_MMUCR, regValue); 00279 00280 if (type == MMU_TLB_TYPE_INSTRUCTION) { 00281 regValue &= ~(AVR32_MMUCR_ILA_MASK); 00282 regValue |= (entries<<AVR32_MMUCR_ILA_OFFSET); 00283 } else { 00284 regValue &= ~(AVR32_MMUCR_DLA_MASK); 00285 regValue |= (entries<<AVR32_MMUCR_DLA_OFFSET); 00286 } 00287 00288 AVR32_SET_SR_REG(AVR32_MMUCR, regValue); 00289 00290 return MMU_OK; 00291 }
| void mmu_read_bear_and_tlbehi | ( | long * | bear, | |
| long * | vpn | |||
| ) |
Reads the TLBEAR and TLBEHI registers and place the contents in bear and vpn.
| bear | pointer to where to put the TLBEAR data | |
| vpn | pointer to where to put the TLBEHI data |
Definition at line 406 of file mmu.c.
Referenced by mmu_exception().
00407 { 00408 AVR32_READ_SR_REG(AVR32_TLBEAR, *bear); 00409 AVR32_READ_SR_REG(AVR32_TLBEHI, *vpn); 00410 }
| int mmu_read_entry | ( | long * | vpn, | |
| long * | pfn, | |||
| int | pos, | |||
| int | type | |||
| ) |
Reads an entry from the TLB and place the contents in vpn and pfn.
| vpn | address to the result position, MSB | |
| pfn | address to the result position, LSB | |
| pos | the TLB index to read an entry from | |
| type | data or instruction entry to read
|
| MMU_OK | on success | |
| MMU_ERROR_ARGUMENT | on invalid arguments |
Definition at line 585 of file mmu.c.
References AVR32_READ_SR_REG, AVR32_SET_SR_REG, MMU_ERROR_ARGUMENT, MMU_OK, MMU_TLB_TYPE_DATA, and MMU_TLB_TYPE_INSTRUCTION.
Referenced by mmu_search_physical_ptr(), and mmu_search_virtual_ptr().
00586 { 00587 long regValue = 0; 00588 if (pos < 0 || 00589 ((type == MMU_TLB_TYPE_DATA && 00590 pos >= MMU_DTLB_ENTRIES) || 00591 (type == MMU_TLB_TYPE_INSTRUCTION && 00592 pos >= MMU_ITLB_ENTRIES))) { 00593 return MMU_ERROR_ARGUMENT; 00594 } 00595 00596 AVR32_READ_SR_REG(AVR32_MMUCR, regValue); 00597 00598 if (type== MMU_TLB_TYPE_INSTRUCTION) { 00599 regValue &= ~(0x3F<<AVR32_MMUCR_IRP_OFFSET); 00600 regValue |= (pos<<AVR32_MMUCR_IRP_OFFSET); 00601 } else { 00602 regValue &= ~(0x3F<<AVR32_MMUCR_DRP_OFFSET); 00603 regValue |= (pos<<AVR32_MMUCR_DRP_OFFSET); 00604 } 00605 00606 AVR32_SET_SR_REG(AVR32_MMUCR, regValue); 00607 00608 #ifdef __GNUC__ 00609 __builtin_tlbr(); 00610 #elif __ICCAVR32__ 00611 __read_TLB_entry(); 00612 #else 00613 #error No known compiler used 00614 #endif 00615 00616 AVR32_READ_SR_REG(AVR32_TLBEHI, *vpn); 00617 AVR32_READ_SR_REG(AVR32_TLBELO, *pfn); 00618 00619 return MMU_OK; 00620 }
| int mmu_reset | ( | ) |
Resets the MMU and invalidates all TLB entries.
| MMU_OK | on success | |
| MMU_ERROR | if unable to reset the MMU |
Definition at line 110 of file mmu.c.
Referenced by mmuex_exceptions(), mmuex_segon_pageoff(), and mmuex_segon_pageon().
00111 { 00112 long regval; 00113 int timer = 10; 00114 00115 AVR32_SET_SR_REG(AVR32_MMUCR, AVR32_MMUCR_S_MASK|AVR32_MMUCR_I_MASK); 00116 00117 /* Wait for invalidation of MMU entries */ 00118 do { 00119 AVR32_READ_SR_REG(AVR32_MMUCR, regval); 00120 --timer; 00121 } while ((regval & AVR32_MMUCR_I_MASK) != 0 && timer > 0); 00122 00123 if (regval != AVR32_MMUCR_S_MASK || timer == 0) { 00124 return MMU_ERROR; 00125 } 00126 00127 AVR32_SET_SR_REG(AVR32_TLBARHI, 0); 00128 AVR32_SET_SR_REG(AVR32_TLBARLO, 0); 00129 00130 return MMU_OK; 00131 }
| int mmu_search_physical_ptr | ( | void * | physical_ptr, | |
| long * | virtual_addr | |||
| ) |
Search a physical address and get the virtual address from the TLB. The function searches the data TLBs first before searching the instruction TLBs.
| physical_ptr | the physical address to search for | |
| virtual_addr | pointer to a variable the virtual address will be written |
| MMU_OK | on success | |
| MMU_ERROR_ARGUMENT | on invalid arguments | |
| MMU_TLB_MISS | on TLB search miss |
Definition at line 210 of file mmu.c.
Referenced by mmuex_segon_pageon().
00211 { 00212 long addr_mask; 00213 long vpn; 00214 long pfn; 00215 int retval; 00216 int i; 00217 00218 for (i = 0; i < MMU_DTLB_ENTRIES; i++) { 00219 /* Read the TLB entry */ 00220 retval = mmu_read_entry(&vpn, &pfn, i, MMU_TLB_TYPE_DATA); 00221 if (retval != MMU_OK) { 00222 return retval; 00223 } 00224 00225 retval = mmu_get_addrmask_from_page_size(pfn, &addr_mask); 00226 if (retval == MMU_OK) { 00227 if (((long)physical_ptr & addr_mask) == (pfn & addr_mask) 00228 && (vpn & AVR32_TLBEHI_V_MASK)) { 00229 *virtual_addr = (vpn & addr_mask) 00230 |((long)physical_ptr & ~addr_mask); 00231 return MMU_OK; 00232 } 00233 } 00234 } 00235 00236 for (i = 0; i < MMU_ITLB_ENTRIES; i++) { 00237 /* Read the TLB entry */ 00238 retval = mmu_read_entry(&vpn, &pfn, i, MMU_TLB_TYPE_INSTRUCTION); 00239 if (retval != MMU_OK) { 00240 return retval; 00241 } 00242 00243 retval = mmu_get_addrmask_from_page_size(pfn, &addr_mask); 00244 if (retval == MMU_OK) { 00245 if (((long)physical_ptr & addr_mask) == (pfn & addr_mask) 00246 && (vpn & AVR32_TLBEHI_V_MASK)) { 00247 *virtual_addr = (vpn & addr_mask) 00248 |((long)physical_ptr & ~addr_mask); 00249 return MMU_OK; 00250 } 00251 } 00252 } 00253 00254 00255 return MMU_TLB_MISS; 00256 }
| int mmu_search_virtual_ptr | ( | void * | virtual_ptr, | |
| long * | physical_addr | |||
| ) |
Search a virtual address and get the physical address from the TLB. The function searches the data TLBs first before searching the instruction TLBs.
| virtual_ptr | the virtual address to search for | |
| physical_addr | pointer to a variable the physical address will be written |
| MMU_OK | on success | |
| MMU_ERROR_ARGUMENT | on invalid arguments | |
| MMU_TLB_MISS | on TLB search miss |
Definition at line 147 of file mmu.c.
Referenced by mmuex_segon_pageon().
00148 { 00149 long addr_mask; 00150 long vpn; 00151 long pfn; 00152 int retval; 00153 int i; 00154 00155 for (i = 0; i < MMU_DTLB_ENTRIES; i++) { 00156 /* Read the TLB entry */ 00157 retval = mmu_read_entry(&vpn, &pfn, i, MMU_TLB_TYPE_DATA); 00158 if (retval != MMU_OK) { 00159 return retval; 00160 } 00161 00162 retval = mmu_get_addrmask_from_page_size(pfn, &addr_mask); 00163 if (retval == MMU_OK) { 00164 if (((long)virtual_ptr & addr_mask) == (vpn & addr_mask) 00165 && (vpn & AVR32_TLBEHI_V_MASK)) { 00166 *physical_addr = (pfn & addr_mask) 00167 |((long)virtual_ptr & ~addr_mask); 00168 return MMU_OK; 00169 } 00170 } 00171 } 00172 00173 for (i = 0; i < MMU_ITLB_ENTRIES; i++) { 00174 /* Read the TLB entry */ 00175 retval = mmu_read_entry(&vpn, &pfn, i, MMU_TLB_TYPE_INSTRUCTION); 00176 if (retval != MMU_OK) { 00177 return retval; 00178 } 00179 00180 retval = mmu_get_addrmask_from_page_size(pfn, &addr_mask); 00181 if (retval == MMU_OK) { 00182 if (((long)virtual_ptr & addr_mask) == (vpn & addr_mask) 00183 && (vpn & AVR32_TLBEHI_V_MASK)) { 00184 *physical_addr = (pfn & addr_mask) 00185 |((long)virtual_ptr & ~addr_mask); 00186 return MMU_OK; 00187 } 00188 } 00189 } 00190 00191 00192 00193 return MMU_TLB_MISS; 00194 }
1.5.3