gonzui


Format: Advanced Search

tkernel_2/kernel/extension/memory/nommu/segmgr.cbare sourcepermlink (0.04 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 T-Engine Forum at 2013/03/07.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: 
   16: /*
   17:  *      segmgr.c (T-Kernel/SM)
   18:  *      No MMU version: segment management
   19:  */
   20: 
   21: #include "sysmgr.h"
   22: #include "cache_info.h"
   23: #include <sys/segment.h>
   24: #include <sys/svc/ifsegment.h>
   25: 
   26: /*
   27:  * Conversion to physical address
   28:  *      Cache control required, but cache control by page cannot be
   29:  *      provided without MMU, so not implemented.
   30:  */
   31: LOCAL INT _CnvPhysicalAddr( CONST void *laddr, INT len, void **paddr )
   32: {
   33:         *paddr = toPhysicalAddress(laddr);
   34: 
   35:         /* Cache off not possible, so cache flash only is performed. */
   36:         FlushCache(laddr, len);
   37: 
   38:         return len;
   39: }
   40: 
   41: /*
   42:  * Get address space information
   43:  */
   44: LOCAL ER _GetSpaceInfo( CONST void *addr, INT len, T_SPINFO *pk_spinfo )
   45: {
   46:         T_RSMB rsmb;
   47:         ER     ercd = E_OK;
   48:         INT    cont, sz;
   49:         CONST void     *page, *va, *pa;
   50: 
   51:         if ( len <= 0 ) {
   52:                 ercd = E_PAR;
   53:                 goto err_ret;
   54:         }
   55:         ercd = ChkSpaceR(addr, len);
   56:         if ( ercd < E_OK ){
   57:                 goto err_ret;
   58:         }
   59: 
   60:         ercd = RefSysMemInfo(&rsmb);
   61:         if ( ercd < E_OK ) {
   62:                 goto err_ret;
   63:         }
   64: 
   65:         pk_spinfo->paddr   = toPhysicalAddress(addr);
   66:         pk_spinfo->page           = (void*)((UW)(pk_spinfo->paddr) & ~(rsmb.blksz-1));
   67:         pk_spinfo->pagesz  = rsmb.blksz;
   68:         pk_spinfo->cachesz = GetCacheLineSize();
   69: 
   70:         cont = 0;
   71:         page = pk_spinfo->page;
   72:         va = addr;
   73:         while ( cont < len ) {
   74:                 pa = toPhysicalAddress(va);
   75:                 if ( (pa < page) || (((UW)page + rsmb.blksz) <= (UW)pa) ) {
   76:                         break;
   77:                 }
   78:                 sz = rsmb.blksz - ((UW)pa - (UW)page);
   79:                 cont += sz;
   80:                 page = (void*)((UW)page + rsmb.blksz);
   81:                 va = (void*)((UW)va + sz);
   82:         }
   83:         pk_spinfo->cont = ( cont <= len )? cont: len;
   84: 
   85:         return ercd;
   86: 
   87: err_ret:
   88:         DEBUG_PRINT(("_GetSpaceInfo ercd = %d\n", ercd));
   89:         return ercd;
   90: }
   91: 
   92: /* ------------------------------------------------------------------------ */
   93: 
   94: IMPORT  INT      svc_call_limit;              /* SVC protected level (T-Kernel/OS) */
   95: 
   96: #define TA_RNGS         ( svc_call_limit << 8 )
   97: 
   98: /*
   99:  * Memory map
  100:  *      Cache control required, but cache control by page cannot be
  101:  *      provided without MMU (except for certain machines), so not implemented.
  102:  */
  103: LOCAL ER _MapMemory( CONST void *paddr, INT len, UINT attr, void **laddr )
  104: {
  105:         ER     ercd;
  106: 
  107:         if ( len <= 0 ) {
  108:                 ercd = E_PAR;
  109:                 goto err_ret;
  110:         }
  111: 
  112:         if ( paddr == NULL ) {
  113:                 UINT a = ( (attr & MM_USER) != 0 )? TA_RNG3: TA_RNGS;
  114:                 if ( (attr & MM_CDIS) != 0 ) {
  115:                         a |= TA_NOCACHE;
  116:                 }
  117: 
  118:                 /* Allocate memory automatically */
  119:                 *laddr = GetSysMemBlk((INT)smPageCount((UW)len), a);
  120:                 if ( *laddr == NULL ) {
  121:                         ercd = E_NOMEM;
  122:                         goto err_ret;
  123:                 }
  124: 
  125:         } else {
  126:                 /* Logical address conversion */
  127:                 *laddr = toLogicalAddress(paddr);
  128: 
  129:                 /* Flush cache */
  130:                 FlushCache(*laddr, len);
  131: 
  132:                 if ( (attr & MM_CDIS) != 0 ) {
  133:                         /* Allocate logical addresses for cache off area */
  134:                         *laddr = toNoCacheLogicalAddress(*laddr);
  135:                 }
  136:         }
  137: 
  138:         return E_OK;
  139: 
  140: err_ret:
  141:         DEBUG_PRINT(("_MapMemory ercd = %d\n", ercd));
  142:         return ercd;
  143: }
  144: 
  145: /*
  146:  * Memory unmap
  147:  */
  148: LOCAL ER _UnmapMemory( CONST void *laddr )
  149: {
  150:         ER     ercd;
  151: 
  152:         /* Memory release when memory is allocated automatically by MapMemory()
  153:          *     If the memory is not automatically allocated, RelSysMemBlk()
  154:          *     returns E_PAR.
  155:          */
  156:         ercd = RelSysMemBlk(laddr);
  157:         if ( ercd < E_OK && ercd != E_PAR ) {
  158:                 goto err_ret;
  159:         }
  160: 
  161:         return E_OK;
  162: 
  163: err_ret:
  164:         DEBUG_PRINT(("_UnmapMemory ercd = %d\n", ercd));
  165:         return ercd;
  166: }
  167: 
  168: /* ------------------------------------------------------------------------ */
  169: 
  170: /*
  171:  * Address space check
  172:  */
  173: LOCAL ER  _ChkSpace( CONST void *laddr, INT len, UINT mode, UINT env )
  174: {
  175:         return ( laddr == NULL )? E_MACV: E_OK;
  176: }
  177: 
  178: LOCAL INT _ChkSpaceTstr( CONST TC *str, INT max, UINT mode, UINT env )
  179: {
  180:         CONST TC       *p = str;
  181: 
  182:         if ( str == NULL ) {
  183:                 return E_MACV;
  184:         }
  185: 
  186:         while ( *p != TNULL ) {
  187:                 p++;
  188:                 if ( --max == 0 ) {
  189:                         break;
  190:                 }
  191:         }
  192:         return p - str;
  193: }
  194: 
  195: LOCAL INT _ChkSpaceBstr( CONST UB *str, INT max, UINT mode, UINT env )
  196: {
  197:         CONST UB       *p = str;
  198: 
  199:         if ( str == NULL ) {
  200:                 return E_MACV;
  201:         }
  202: 
  203:         while ( *p != '\0' ) {
  204:                 p++;
  205:                 if ( --max == 0 ) {
  206:                         break;
  207:                 }
  208:         }
  209:         return p - str;
  210: }
  211: 
  212: /* ------------------------------------------------------------------------ */
  213: 
  214: /*
  215:  * Memory Cache Control
  216:  */
  217: LOCAL ER _FlushMemCache( void *laddr, INT len, UINT mode )
  218: {
  219:         ER     ercd;
  220: 
  221:         if ( (mode & ~(TCM_ICACHE|TCM_DCACHE)) != 0 ) {
  222:                 ercd = E_PAR;
  223:                 goto err_ret;
  224:         }
  225:         ercd = ChkSpaceR(laddr, len);
  226:         if ( ercd < E_OK ){
  227:                 goto err_ret;
  228:         }
  229: 
  230:         FlushCacheM(laddr, len, mode);
  231: 
  232:         return E_OK;
  233: 
  234: err_ret:
  235:         DEBUG_PRINT(("_FlushMemCache ercd = %d\n", ercd));
  236:         return ercd;
  237: }
  238: 
  239: /*
  240:  * Memory Cache Control
  241:  */
  242: LOCAL INT _ControlCache( void *addr, INT len, UINT mode )
  243: {
  244:         ER     ercd;
  245: 
  246:         if ( len <= 0 ) {
  247:                 ercd = E_PAR;
  248:                 goto err_ret;
  249:         }
  250:         if ( mode == 0 ) {
  251:                 ercd = E_PAR;
  252:                 goto err_ret;
  253:         }
  254:         ercd = ChkSpaceR(addr, len);
  255:         if ( ercd < E_OK ){
  256:                 goto err_ret;
  257:         }
  258: 
  259:         ercd = ControlCacheM(addr, len, mode);
  260:         if( ercd != E_OK ){
  261:                 goto err_ret;
  262:         }
  263: 
  264:         return len;
  265: 
  266: err_ret:
  267:         DEBUG_PRINT(("_ControlCache ercd = %d\n", ercd));
  268:         return ercd;
  269: }
  270: 
  271: /* ------------------------------------------------------------------------ */
  272: 
  273: /*
  274:  * Extended SVC entry
  275:  */
  276: LOCAL INT SegSVCentry( void *para, W fn )
  277: {
  278:         INT    ercd;
  279: 
  280:         switch ( fn ) {
  281:                 /* Can be called from any protection levels */
  282:           case SEG_FLUSHMEMCACHE_FN:
  283:                 break;
  284: 
  285:           default:
  286:                 /* Caller protection level check */
  287:                 ercd = ChkCallPLevel();
  288:                 if ( ercd < E_OK ) {
  289:                         goto err_ret;
  290:                 }
  291:         }
  292: 
  293:         switch ( fn ) {
  294:           case SEG_LOCKSPACE_FN:
  295:           case SEG_UNLOCKSPACE_FN:
  296:                 ercd = E_OK;
  297:                 break;
  298: 
  299:           case SEG_CNVPHYSICALADDR_FN:
  300:                 { SEG_CNVPHYSICALADDR_PARA *p = para;
  301:                 ercd = _CnvPhysicalAddr(p->laddr, p->len, p->paddr); }
  302:                 break;
  303: 
  304:           case SEG_CHKSPACE_FN:
  305:                 { SEG_CHKSPACE_PARA *p = para;
  306:                 ercd = _ChkSpace(p->laddr, p->len, p->mode, p->env); }
  307:                 break;
  308:           case SEG_CHKSPACETSTR_FN:
  309:                 { SEG_CHKSPACETSTR_PARA *p = para;
  310:                 ercd = _ChkSpaceTstr(p->str, p->max, p->mode, p->env); }
  311:                 break;
  312:           case SEG_CHKSPACEBSTR_FN:
  313:                 { SEG_CHKSPACEBSTR_PARA *p = para;
  314:                 ercd = _ChkSpaceBstr(p->str, p->max, p->mode, p->env); }
  315:                 break;
  316: 
  317:           case SEG_MAPMEMORY_FN:
  318:                 { SEG_MAPMEMORY_PARA *p = para;
  319:                 ercd = _MapMemory(p->paddr, p->len, p->attr, p->laddr); }
  320:                 break;
  321:           case SEG_UNMAPMEMORY_FN:
  322:                 { SEG_UNMAPMEMORY_PARA *p = para;
  323:                 ercd = _UnmapMemory(p->laddr); }
  324:                 break;
  325: 
  326:           case SEG_FLUSHMEMCACHE_FN:
  327:                 { SEG_FLUSHMEMCACHE_PARA *p = para;
  328:                 ercd = _FlushMemCache(p->laddr, p->len, p->mode); }
  329:                 break;
  330: 
  331:           case SEG_CHKSPACELEN_FN:
  332:           case SEG_READMEMSPACE_FN:
  333:           case SEG_WRITEMEMSPACE_FN:
  334:           case SEG_SETMEMSPACEB_FN:
  335:           case SEG_MAKESPACE_FN:
  336:           case SEG_UNMAKESPACE_FN:
  337:           case SEG_CHANGESPACE_FN:
  338:                 ercd = E_NOSPT;
  339:                 break;
  340: 
  341:           /* T-Kernel 2.0 */
  342:           case SEG_CONTROLCACHE_FN:
  343:                 { SEG_CONTROLCACHE_PARA *p = para;
  344:                 ercd = _ControlCache(p->addr, p->len, p->mode); }
  345:                 break;
  346:           case SEG_GETSPACEINFO_FN:
  347:                 { SEG_GETSPACEINFO_PARA *p = para;
  348:                 ercd = _GetSpaceInfo(p->addr, p->len, p->pk_spinfo); }
  349:                 break;
  350: 
  351:           case SEG_SETCACHEMODE_FN:
  352:           case SEG_SETMEMORYACCESS_FN:
  353:                 ercd = E_NOSPT;
  354:                 break;
  355: 
  356:           default:
  357:                 ercd = E_RSFN;
  358:         }
  359: 
  360: err_ret:
  361:         return ercd;
  362: }
  363: 
  364: /*
  365:  * Initialize segment management
  366:  */
  367: EXPORT ER init_segmgr( void )
  368: {
  369:         return E_OK;
  370: }
  371: 
  372: /*
  373:  * Start segment management
  374:  */
  375: EXPORT ER start_segmgr( void )
  376: {
  377:         T_DSSY dssy;
  378:         ER     ercd;
  379: 
  380:         /* Register manager */
  381:         dssy.ssyatr    = TA_NULL;
  382:         dssy.ssypri    = SEG_PRI;
  383:         dssy.svchdr    = (FP)SegSVCentry;
  384:         dssy.breakfn   = NULL;
  385:         dssy.startupfn = NULL;
  386:         dssy.cleanupfn = NULL;
  387:         dssy.eventfn   = NULL;
  388:         dssy.resblksz  = 0;
  389:         ercd = tk_def_ssy(SEG_SVC, &dssy);
  390:         if ( ercd < E_OK ) {
  391:                 goto err_ret;
  392:         }
  393: 
  394:         return E_OK;
  395: 
  396: err_ret:
  397:         TM_DEBUG_PRINT(("start_segmgr ercd = %d\n", ercd));
  398:         return ercd;
  399: }
  400: 
  401: /*
  402:  * End segment manager
  403:  */
  404: EXPORT ER finish_segmgr( void )
  405: {
  406:         ER     ercd;
  407: 
  408:         /* Delete subsystem registration */
  409:         ercd = tk_def_ssy(SEG_SVC, NULL);
  410: 
  411: #ifdef DEBUG
  412:         if ( ercd < E_OK ) {
  413:                 DEBUG_PRINT(("finish_segmgr ercd = %d\n", ercd));
  414:         }
  415: #endif
  416: 
  417:         return ercd;
  418: }