00001
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include <avr32/io.h>
00051 #include <string.h>
00052 #include <malloc.h>
00053 #include <sys/exceptions.h>
00054 #include "settings.h"
00055 #include "macro.h"
00056 #include "usart.h"
00057 #include "mmu.h"
00058
00060 static int free_page_nr = 16;
00062 static volatile avr32_pio_t *pioa = &AVR32_PIOA;
00064 static volatile avr32_pio_t *piob = &AVR32_PIOB;
00066 static volatile avr32_pio_t *pioc = &AVR32_PIOC;
00068 static volatile avr32_usart_t *usart = &USART_MODULE;
00070 static unsigned long handler_table[0x104];
00071
00078 unsigned int mmu_exception(int evba_offset, int return_address)
00079 {
00080 int retval;
00081 long bear;
00082 long vpn;
00083 long pfn;
00084 struct mmu_tlb_t tlbOptions;
00085 tlbOptions.valid = MMU_ENABLE;
00086 tlbOptions.type = MMU_TLB_TYPE_DATA;
00087 tlbOptions.asid = 0;
00088 tlbOptions.cachable = MMU_DISABLE;
00089 tlbOptions.global = MMU_DISABLE;
00090 tlbOptions.bufferable = MMU_DISABLE;
00091 tlbOptions.access = 0x03;
00092 tlbOptions.page_size = MMU_PAGE_SIZE_64KB;
00093 tlbOptions.dirty = MMU_ENABLE;
00094 tlbOptions.write_through = MMU_DISABLE;
00095 tlbOptions.position = -1;
00096
00097 printf("\r\n* Handling exception: ");
00098
00099 switch (evba_offset) {
00100 case EVBA_ITLB_MISS:
00101 case EVBA_DTLB_MISS_W:
00102 case EVBA_DTLB_MISS_R:
00103 mmu_read_bear_and_tlbehi(&bear, &vpn);
00104 printf("TLB miss at virtual address 0x%08lx\r\n", bear);
00105 printf(" Bear is 0x%08lx\r\n", bear);
00106 printf(" Vpn is 0x%08lx\r\n", vpn);
00107
00108
00109 if (free_page_nr > MMU_DTLB_ENTRIES) {
00110 free_page_nr = 16;
00111 }
00112 tlbOptions.position = free_page_nr++;
00113 printf(" Adding page to TLB[%02d]... ", tlbOptions.position);
00114
00115 if (((bear ^ 0x24000000) >> 24) == 0) {
00116 pfn = 0x24000000;
00117 } else {
00118 pfn = 0;
00119 }
00120 retval = mmu_add_tlb_entry(pfn, bear, &tlbOptions);
00121 if (retval != MMU_OK) {
00122 printf("[ FAILED ]\r\n");
00123 goto out;
00124 }
00125 printf("[ OK ]\r\n");
00126 break;
00127 default:
00128 printf("unhandled exception 0x%08x!\r\n", evba_offset);
00129 }
00130
00131 out:
00132 printf("\n");
00133 return return_address;
00134 }
00135
00136
00142 int mmuex_exceptions()
00143 {
00144 int retval = MMU_OK;
00145 char * string_p = "this test string is used to generate exceptions";
00146 char * string_p61 = (char *)((long) string_p | 0x61800000);
00147
00148 printf("\r\nDemonstrate MMU mode...\r\n");
00149 printf(" Segmentation: ON\r\n");
00150 printf(" Paging : ON\r\n");
00151 printf(" Exceptions : ON\r\n\n");
00152
00153
00154 printf(" Reset MMU... ");
00155 retval = mmu_reset();
00156 if (retval != MMU_OK) {
00157 printf("[ FAILED ]\r\n");
00158 goto error;
00159 }
00160 printf("[ OK ]\r\n");
00161
00162
00163 printf(" Set MMU in shared mode... ");
00164 retval = mmu_init(MMU_DISABLE,
00165 MMU_SHARED_VIRTUAL_MODE,
00166 MMU_SEGMENTATION_ON);
00167 if (retval != MMU_OK) {
00168 printf("[ FAILED ]\r\n");
00169 goto error;
00170 }
00171 printf("[ OK ]\r\n");
00172
00173 struct mmu_tlb_t tlbOptions;
00174 tlbOptions.valid = MMU_ENABLE;
00175 tlbOptions.type = MMU_TLB_TYPE_DATA;
00176 tlbOptions.asid = 0;
00177 tlbOptions.cachable = MMU_DISABLE;
00178 tlbOptions.global = MMU_DISABLE;
00179 tlbOptions.bufferable = MMU_DISABLE;
00180 tlbOptions.access = 0x03;
00181 tlbOptions.page_size = MMU_PAGE_SIZE_64KB;
00182 tlbOptions.dirty = MMU_ENABLE;
00183 tlbOptions.write_through = MMU_DISABLE;
00184 tlbOptions.position = -1;
00185
00186
00187
00188
00189 printf(" Adding segments to TLB... ");
00190 tlbOptions.position = 12;
00191 retval = mmu_add_tlb_entry(0, 0, &tlbOptions);
00192 if (retval != MMU_OK) {
00193 printf("[ FAILED ]\r\n");
00194 goto error;
00195 }
00196
00197 tlbOptions.position = 14;
00198 retval = mmu_add_tlb_entry(0x24000000, 0x24000000, &tlbOptions);
00199 if (retval != MMU_OK) {
00200 printf("[ FAILED ]\r\n");
00201 goto error;
00202 }
00203 printf("[ OK ]\r\n");
00204
00205
00206 printf(" Changing mode... ");
00207 retval = mmu_init(MMU_ENABLE,
00208 MMU_SHARED_VIRTUAL_MODE,
00209 MMU_SEGMENTATION_ON);
00210 if (retval != MMU_OK) {
00211 printf("[ FAILED ]\r\n");
00212 goto error;
00213 }
00214 printf("[ OK ]\r\n");
00215
00216 printf("\r\n");
00217 printf(" String (0x%08lx): %s\r\n", (long)string_p, string_p);
00218
00219
00220 strcpy(string_p61, string_p);
00221
00222
00223 printf(" String61 (0x%08lx): %s\r\n", (long)string_p61, string_p61);
00224
00225 printf("\r\n");
00226 printf(" Test result... ");
00227
00228 if (strcmp(string_p, string_p61) == 0) {
00229 printf("[ OK ]\r\n\n");
00230 } else {
00231 printf("[ FAILED ]\r\n\n");
00232 }
00233
00234 return retval;
00235 error:
00236 printf("\r\n");
00237 printf(" Test result... (jumped) [ FAILED ]\r\n\n");
00238 return retval;
00239 }
00240
00241
00247 int mmuex_segon_pageon()
00248 {
00249 int retval = MMU_OK;
00250 char * string_p = "MMU test segmentation on, paging on";
00251 long string_p64 = (long) string_p | 0x64080000;
00252 long string_pPA = 0;
00253 long string_pVA = 0;
00254
00255 printf("\r\nDemonstrate MMU mode...\r\n");
00256 printf(" Segmentation: ON\r\n");
00257 printf(" Paging : ON\r\n\n");
00258
00259
00260 printf(" Reset MMU... ");
00261 retval = mmu_reset();
00262 if (retval != MMU_OK) {
00263 printf("[ FAILED ]\r\n");
00264 goto error;
00265 }
00266 printf("[ OK ]\r\n");
00267
00268
00269 printf(" Set MMU in shared mode... ");
00270 retval = mmu_init(MMU_DISABLE,
00271 MMU_SHARED_VIRTUAL_MODE,
00272 MMU_SEGMENTATION_ON);
00273 if (retval != MMU_OK) {
00274 printf("[ FAILED ]\r\n");
00275 goto error;
00276 }
00277 printf("[ OK ]\r\n");
00278
00279 struct mmu_tlb_t tlbOptions;
00280 tlbOptions.valid = MMU_ENABLE;
00281 tlbOptions.type = MMU_TLB_TYPE_DATA;
00282 tlbOptions.asid = 0;
00283 tlbOptions.cachable = MMU_DISABLE;
00284 tlbOptions.global = MMU_DISABLE;
00285 tlbOptions.bufferable = MMU_DISABLE;
00286 tlbOptions.access = 0x03;
00287 tlbOptions.page_size = MMU_PAGE_SIZE_64KB;
00288 tlbOptions.dirty = MMU_ENABLE;
00289 tlbOptions.write_through = MMU_DISABLE;
00290 tlbOptions.position = -1;
00291
00292
00293 printf(" Adding segments to TLB... ");
00294 tlbOptions.position = 12;
00295 retval = mmu_add_tlb_entry(0, 0, &tlbOptions);
00296 if (retval != MMU_OK) {
00297 printf("[ FAILED ]\r\n");
00298 goto error;
00299 }
00300 tlbOptions.position = 14;
00301 retval = mmu_add_tlb_entry(0x24000000, 0x24000000, &tlbOptions);
00302 if (retval != MMU_OK) {
00303 printf("[ FAILED ]\r\n");
00304 goto error;
00305 }
00306
00307
00308 tlbOptions.position = 11;
00309 retval = mmu_add_tlb_entry((long)string_p, 0x64080000, &tlbOptions);
00310 if (retval != MMU_OK) {
00311 printf("[ FAILED ]\r\n");
00312 goto error;
00313 }
00314 printf("[ OK ]\r\n");
00315
00316
00317 printf(" Changing mode... ");
00318 retval = mmu_init(MMU_ENABLE,
00319 MMU_SHARED_VIRTUAL_MODE,
00320 MMU_SEGMENTATION_ON);
00321 if (retval != MMU_OK) {
00322 printf("[ FAILED ]\r\n");
00323 goto error;
00324 }
00325 printf("[ OK ]\r\n");
00326
00327
00328
00329
00330 printf(" Lookup physical address... ");
00331 retval = mmu_search_virtual_ptr((void *)string_p64, &string_pPA);
00332 if (retval != MMU_OK) {
00333 printf("[ FAILED ]\r\n");
00334 goto error;
00335 }
00336 printf("[ OK ]\r\n");
00337
00338
00339
00340
00341 printf(" Lookup virtual address... ");
00342 retval = mmu_search_physical_ptr((void *)string_pPA, &string_pVA);
00343 if (retval != MMU_OK) {
00344 printf("[ FAILED ]\r\n");
00345 goto error;
00346 }
00347 printf("[ OK ]\r\n");
00348
00349
00350 long tlbIndex;
00351 printf(" Get TLB index... ");
00352 retval = mmu_find_index_to_entry(string_pPA, string_pVA, &tlbIndex);
00353 if (retval != MMU_OK) {
00354 printf(" [ FAILED ]\r\n");
00355 goto error;
00356 }
00357 printf("[%02ld] [ OK ]\r\n", tlbIndex);
00358
00359 printf("\r\n");
00360 printf(" String (0x%08lx): %s\r\n", (long)string_p, string_p);
00361 printf(" String64 (0x%08lx): %s\r\n", (long)string_p64, (char *)string_p64);
00362 printf(" StringPA (0x%08lx): %s\r\n", (long)string_pPA, (char *)string_pPA);
00363 printf(" StringVA (0x%08lx): %s\r\n", (long)string_pVA, (char *)string_pVA);
00364 printf("\r\n");
00365 printf(" Test result... ");
00366
00367 if (strcmp(string_p, (char *)string_pPA) == 0 &&
00368 strcmp(string_p, (char *)string_pVA) == 0) {
00369 printf("[ OK ]\r\n\n");
00370 } else {
00371 printf("[ FAILED ]\r\n\n");
00372 }
00373
00374 return retval;
00375 error:
00376 printf("\r\n");
00377 printf(" Test result... (jumped) [ FAILED ]\r\n\n");
00378 return retval;
00379 }
00380
00381
00387 int mmuex_segon_pageoff()
00388 {
00389 int retval = MMU_OK;
00390 char * string_p80 = 0;
00391 char * string_pA0 = 0;
00392 char * string_pC0 = 0;
00393 char * string_p = "MMU test segmentation off, paging on";
00394
00395 printf("\r\nDemonstrate MMU mode...\r\n");
00396 printf(" Segmentation: ON\r\n");
00397 printf(" Paging : OFF\r\n\n");
00398
00399
00400 printf(" Reset MMU... ");
00401 retval = mmu_reset();
00402 if (retval != MMU_OK) {
00403 printf("[ FAILED ]\r\n");
00404 goto error;
00405 }
00406 printf("[ OK ]\r\n");
00407
00408
00409 printf(" Changing mode... ");
00410 retval = mmu_init(MMU_DISABLE,
00411 MMU_SHARED_VIRTUAL_MODE,
00412 MMU_SEGMENTATION_ON);
00413 if (retval != MMU_OK) {
00414 printf("[ FAILED ]\r\n");
00415 goto error;
00416 }
00417 printf("[ OK ]\r\n");
00418
00419 string_p80 = (void*)(0x80000000|(long)string_p);
00420 string_pA0 = (void*)(0xA0000000|(long)string_p);
00421 string_pC0 = (void*)(0xC0000000|(long)string_p);
00422
00423 printf("\r\n");
00424 printf(" String (%08x): %s\r\n", (int)string_p, string_p);
00425 printf(" String80 (%08x): %s\r\n", (int)string_p80, string_p80);
00426 printf(" StringA0 (%08x): %s\r\n", (int)string_pA0, string_pA0);
00427 printf(" StringC0 (%08x): %s\r\n", (int)string_pC0, string_pC0);
00428 printf("\r\n");
00429 printf(" Test result... ");
00430
00431 if (strcmp(string_p, string_p80) == 0 &&
00432 strcmp(string_p, string_pA0) == 0 &&
00433 strcmp(string_p, string_pC0) == 0) {
00434 printf("[ OK ]\r\n\n");
00435 } else {
00436 printf("[ FAILED ]\r\n\n");
00437 }
00438
00439 return retval;
00440 error:
00441 printf("\r\n");
00442 printf(" Test result... (jumped) [ FAILED ]\r\n\n");
00443 return retval;
00444 }
00445
00449 extern char _evba[];
00450
00456 int main(int argc, char * argv[])
00457 {
00458 int error = 0;
00459
00460
00461 init_exceptions((void *)_evba, handler_table);
00462 _register_exception_handler(&mmu_exception, EVBA_ITLB_MISS);
00463 _register_exception_handler(&mmu_exception, EVBA_DTLB_MISS_R);
00464 _register_exception_handler(&mmu_exception, EVBA_DTLB_MISS_W);
00465 _register_exception_handler(&mmu_exception, EVBA_DTLB_MODIFIED);
00466
00467
00468 pioa->idr = 0xFFFFffff;
00469 piob->idr = 0xFFFFffff;
00470 pioc->idr = 0xFFFFffff;
00471
00472
00473 pioa->pdr = AVR32_PIO_P17_MASK|AVR32_PIO_P18_MASK;
00474 pioa->asr = AVR32_PIO_P17_MASK|AVR32_PIO_P18_MASK;
00475
00476
00477
00478
00479
00480 piob->per = 0x000000FF;
00481 piob->odr = 0x000000FF;
00482 piob->ifer = 0x000000FF;
00483 piob->odsr = 0x00000000;
00484 piob->puer = 0x000000FF;
00485
00486 pioc->per = 0x0000FFFF;
00487 pioc->oer = 0x0000FFFF;
00488 pioc->ower = 0x0000FFFF;
00489 pioc->odsr = 0x00000000;
00490
00491
00492 struct usart_options_t usartOptions;
00493 usartOptions.baudrate = USART_BAUD;
00494 usartOptions.charlength = USART_BITS;
00495 usartOptions.paritytype = USART_NO_PARITY;
00496 usartOptions.stopbits = USART_1_STOPBIT;
00497 usartOptions.channelmode = USART_NORMAL_CHMODE;
00498
00499
00500 error = usart_linit(usart, &usartOptions, CPUHZ);
00501
00502 if (error != USART_OK) {
00503 pioc->odsr = AVR32_PIO_P8_MASK|AVR32_PIO_P9_MASK;
00504 for (;;);
00505 }
00506
00507 printf("AVR32113: available demos:\r\n");
00508 printf(" SW2 - segmentation on\r\n");
00509 printf(" paging on\r\n");
00510 printf(" exception example\r\n\n");
00511 printf(" SW1 - segmentation on\r\n");
00512 printf(" paging on\r\n\n");
00513 printf(" SW0 - segmentation on\r\n");
00514 printf(" paging off\r\n\n");
00515
00516 unsigned int buttontimer = 0;
00517
00518 for (;;) {
00519
00520
00521
00522
00523 if ((piob->pdsr & AVR32_PIO_P2_MASK) == 0 &&
00524 buttontimer == 0) {
00525 pioc->odsr = AVR32_PIO_P2_MASK;
00526 buttontimer = DELAY_TIMEOUT;
00527
00528 int retval = MMU_OK;
00529
00530 retval = mmuex_exceptions();
00531
00532 if (retval == MMU_OK) {
00533 pioc->odsr = AVR32_PIO_P10_MASK|AVR32_PIO_P11_MASK;
00534 } else {
00535 pioc->odsr = AVR32_PIO_P8_MASK|AVR32_PIO_P9_MASK;
00536 }
00537 }
00538 else if ((piob->pdsr & AVR32_PIO_P1_MASK) == 0 &&
00539 buttontimer == 0) {
00540 pioc->odsr = AVR32_PIO_P1_MASK;
00541 buttontimer = DELAY_TIMEOUT;
00542
00543 int retval = MMU_OK;
00544
00545 retval = mmuex_segon_pageon();
00546
00547 if (retval == MMU_OK) {
00548 pioc->odsr = AVR32_PIO_P10_MASK|AVR32_PIO_P11_MASK;
00549 } else {
00550 pioc->odsr = AVR32_PIO_P8_MASK|AVR32_PIO_P9_MASK;
00551 }
00552 }
00553 else if ((piob->pdsr & AVR32_PIO_P0_MASK) == 0 &&
00554 buttontimer == 0) {
00555 pioc->odsr = AVR32_PIO_P0_MASK;
00556 buttontimer = DELAY_TIMEOUT;
00557
00558 int retval = MMU_OK;
00559
00560 retval = mmuex_segon_pageoff();
00561
00562 if (retval == MMU_OK) {
00563 pioc->odsr = AVR32_PIO_P10_MASK|AVR32_PIO_P11_MASK;
00564 } else {
00565 pioc->odsr = AVR32_PIO_P8_MASK|AVR32_PIO_P9_MASK;
00566 }
00567 }
00568
00569 if (buttontimer > 0) {
00570 --buttontimer;
00571 }
00572 }
00573
00574 return 0;
00575 }
00576