gonzui


Format: Advanced Search

tkernel_2/monitor/cmdsvc/src/armv6/chkaddr.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: 
   15: /*
   16:  *      chkaddr.c
   17:  *
   18:  *       Check address
   19:  */
   20: 
   21: #include "../cmdsvc.h"
   22: 
   23: LOCAL   UW        validLA;               // valid logical start address
   24: LOCAL   UW        validSz;               // valid logical address size
   25: LOCAL   UW        mmuStat;               // MMU state
   26: 
   27: /*
   28:         Initialize address check data (executed upon monitor entry)
   29: */
   30: EXPORT  void     initChkAddr(void)
   31: {
   32:         validLA = validSz = 0;         // clear the previous effective addresses
   33:         mmuStat = getCP15(1, 0);       // MMU state
   34: }
   35: /*
   36:         Check memory address
   37:                 return  contiguous range <= len  (0 means illegal value)
   38:                 * pa     physical address to access
   39: */
   40: EXPORT  W        chkMemAddr(UW addr, UW *pa, W len, W rw)
   41: {
   42:         const MEMSEG *mp;
   43:         UW     n;
   44: 
   45:         if (mmuStat & 0x1) {   // MMU is enabled
   46:                 // if the prevous check range doesn't include the address,
   47:                 // if the address is a valid existing address is checked by looking at page table.
   48:                 if (addr < validLA || addr >= validLA + validSz) {
   49:                         UW pte, *ppte;
   50: 
   51:                         // Depending on the valid rage of TTBR0 described in TTBCR
   52:                         // TTBR0/TTBR1(=TopPageTable) is switched
   53:                         pte  = 0xfe000000 << (7 - (getCP15(2, 2) & 0x07));
   54:                                                                 // TTBCR
   55:                         ppte = (addr & pte) ? TopPageTable :
   56:                                 (UW *)(getCP15(2, 0) & ~0x7f);      // TTBR0
   57:                         pte = ppte[addr >> 20];
   58: 
   59:                         validSz = 0;
   60:                         switch(pte & 0x3) {
   61:                         case 0x2:    // Section Entry
   62:                                 pte &= 0xFFF00000;  // Section Address
   63:                                 if (rw && AddrMatchMemArea(pte,
   64:                                                 MSA_ROM|MSA_FROM) != NULL)
   65:                                         errinfo = E_ROM;
   66:                                 else        validSz = 0x100000;    // 1 MB
   67:                                 break;
   68:                         case 0x1:    // Page Table Entry
   69:                                 pte &= 0xFFFFFC00;  // Page Table Address
   70:                                 pte = *((UW*)(pte + ((addr >>(12-2))& 0x3FC)));
   71:                                 switch(pte & 0x3) {
   72:                                 case 0x1:   // Large Page : 16 KB x 4
   73:                                         validSz = 0x10000; // 64 KB
   74:                                         break;
   75:                                 case 0x2:   // Small Page : 1 KB x 4
   76:                                 case 0x3:   // Small Page with XN
   77:                                         validSz = 0x1000;  // 4 KB
   78:                                         break;
   79:                                 }
   80:                                 break;
   81:                         case 0x3:    // Fine Page Table Entry
   82:                                 break;      // unsupported
   83:                         }
   84:                         validLA = (validSz) ? (addr & ~(validSz - 1)) : 0;
   85:                 }
   86: 
   87:                 n = (validSz) ? (validLA + validSz - addr) : 0;
   88: 
   89:         } else {       // MMU is disabled, the unmodified address is used
   90:                 mp = AddrMatchMemArea(addr, MSA_HW);
   91:                 if ( mp != NULL ) {
   92:                         if ( rw && (mp->attr & (MSA_ROM|MSA_FROM)) != 0 ) {
   93:                                 n = 0;
   94:                                 errinfo = E_ROM;
   95:                         } else {
   96:                                 n = mp->end - addr;
   97:                         }
   98:                 } else {
   99:                         n = 0;
  100:                 }
  101:         }
  102:         *pa = addr;    // access by logical address
  103:         return (len > n) ? n : len;
  104: }
  105: /*
  106:         I/O address check & conversion to physical address
  107:                 return  contiguous range <= len  (0 means illegal value)
  108:                 * pa     I/O address to access
  109: */
  110: EXPORT  W        chkIOAddr(UW addr, UW *pa, W len)
  111: {
  112:         const MEMSEG *mp;
  113:         UW     n;
  114: 
  115:         mp = AddrMatchMemArea(addr, MSA_IO);
  116:         n = ( mp != NULL )? mp->end - addr: 0;
  117: 
  118:         *pa = addr;    // access by logical address
  119:         return (len > n) ? n : len;
  120: }
  121: /*
  122:         Validate PC
  123:                 return 0: OK, -1: illegal
  124: */
  125: EXPORT  W        invalidPC(UW addr)
  126: {
  127:         // memory range check is not performed
  128:         // an odd address needs to be regarded as THUMB, and so nothing is done here.
  129:         return 0;
  130: }
  131: EXPORT  W        invalidPC2(UW addr)
  132: {
  133:         // memory range check is not performed
  134:         // PC of an ARM instruction is always on WORD-boundary
  135:         return (addr & 0x03) ? -1 : 0;
  136: }