gonzui


Format: Advanced Search

t2ex/t2ex_source/kernel/extension/memory/t2ex/segmgr.cbare sourcepermlink (0.02 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T2EX Software Package
    4:  *
    5:  *    Copyright 2012 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 2012/12/12.
   10:  *    Modified by T-Engine Forum at 2013/03/08.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/04.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: /*
   16:  * This software package is available for use, modification, 
   17:  * and redistribution in accordance with the terms of the attached 
   18:  * T-License 2.x.
   19:  * If you want to redistribute the source code, you need to attach 
   20:  * the T-License 2.x document.
   21:  * There's no obligation to publish the content, and no obligation 
   22:  * to disclose it to the TRON Forum if you have modified the 
   23:  * software package.
   24:  * You can also distribute the modified source code. In this case, 
   25:  * please register the modification to T-Kernel traceability service.
   26:  * People can know the history of modifications by the service, 
   27:  * and can be sure that the version you have inherited some 
   28:  * modification of a particular version or not.
   29:  *
   30:  *    http://trace.tron.org/tk/?lang=en
   31:  *    http://trace.tron.org/tk/?lang=ja
   32:  *
   33:  * As per the provisions of the T-License 2.x, TRON Forum ensures that 
   34:  * the portion of the software that is copyrighted by Ken Sakamura or 
   35:  * the TRON Forum does not infringe the copyrights of a third party.
   36:  * However, it does not make any warranty other than this.
   37:  * DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
   38:  * responsible for any consequences or damages caused directly or
   39:  * indirectly by the use of this software package.
   40:  *
   41:  * The source codes in bsd_source.tar.gz in this software package are 
   42:  * derived from NetBSD or OpenBSD and not covered under T-License 2.x.
   43:  * They need to be changed or redistributed according to the 
   44:  * representation of each source header.
   45:  */
   46: 
   47: /*
   48:  *      segmgr.c (T2EX)
   49:  *      T2EX: segment manager
   50:  */
   51: 
   52: #include <typedef.h>
   53: #include "sysmgr.h"
   54: #include "segmgr.h"
   55: #include "excmgr.h"
   56: #include "cache_info.h"
   57: #include "pagedef.h"
   58: #include <sys/segment.h>
   59: #include <sys/svc/ifsegment.h>
   60: 
   61: /*
   62:  * Segment manager lock
   63:  *      LockSEG() is called while the operating system is being started. 
   64:  *      To prevent it from transiting to wait status, initial value is set.
   65:  */
   66: EXPORT  FastLock SegLock = { -1, -1 };
   67: 
   68: /*
   69:  * Get address space information
   70:  */
   71: LOCAL ER _GetSpaceInfo( CONST void *addr, INT len, T_SPINFO *pk_spinfo )
   72: {
   73:         T_RSMB rsmb;
   74:         ER     ercd = E_OK;
   75: 
   76:         if ( len <= 0 ) {
   77:                 ercd = E_PAR;
   78:                 goto err_ret;
   79:         }
   80:         ercd = ChkSpaceR(addr, len);
   81:         if ( ercd < E_OK ){
   82:                 goto err_ret;
   83:         }
   84: 
   85:         ercd = RefSysMemInfo(&rsmb);
   86:         if ( ercd < E_OK ) {
   87:                 goto err_ret;
   88:         }
   89: 
   90:         pk_spinfo->paddr   = toPhysicalAddress(addr);
   91:         pk_spinfo->page           = (void*)((UW)(pk_spinfo->paddr) & ~(rsmb.blksz-1));
   92:         pk_spinfo->pagesz  = rsmb.blksz;
   93:         pk_spinfo->cachesz = GetCacheLineSize();
   94: 
   95:         /* Assumes here that logical and physical addresses are mapped linear.
   96:            This assures that physical page addresses are also contiguous 
   97:            if logical page addresses are contiguous. */
   98:         pk_spinfo->cont = len;
   99: 
  100:         return ercd;
  101: 
  102: err_ret:
  103:         TM_DEBUG_PRINT(("_GetSpaceInfo ercd = %d\n", ercd));
  104:         return ercd;
  105: }
  106: 
  107: /* ------------------------------------------------------------------------ */
  108: 
  109: /*
  110:  * Memory map
  111:  *      When paddr is NULL, allocate len bytes of memory having contiguous physical address,
  112:  *      and returns the logical address to *laddr.
  113:  *      When paddr is not NULL, map len bytes of physical memory from paddr and returns 
  114:  *      the logical address to *laddr.
  115:  *
  116:  *      N.B. Access to *laddr may cause page fault.
  117:  */
  118: LOCAL ER _MapMemory( CONST void *paddr, INT len, UINT attr, void **laddr )
  119: {
  120:         ER     ercd;
  121:         UINT   a;
  122: 
  123:         if ( len <= 0 ) {
  124:                 ercd = E_PAR;
  125:                 goto err_ret;
  126:         }
  127: 
  128:         a = ( (attr & MM_USER) != 0 )? TA_RNG3: TA_RNG0;
  129:         if ( (attr & MM_CDIS) != 0 ) {
  130:                 a |= TA_NOCACHE;
  131:         }
  132: 
  133:         if ( paddr == NULL ) {
  134:                 /* Allocate memory automatically */
  135:                 *laddr = GetSysMemBlk((INT)smPageCount((UW)len), a);
  136:                 if ( *laddr == NULL ) {
  137:                         ercd = E_NOMEM;
  138:                         goto err_ret;
  139:                 }
  140: 
  141:                 /* Set memory access privilege */
  142:                 ercd = _SetMemoryAccess(*laddr, len, (attr & (MM_READ|MM_WRITE|MM_EXECUTE)));
  143:                 if ( ercd < E_OK ) {
  144:                         RelSysMemBlk(*laddr);
  145:                         *laddr = NULL;
  146:                         goto err_ret;
  147:                 }
  148: 
  149:         } else {
  150:                 /* Logical address conversion */
  151:                 *laddr = toLogicalAddress(paddr);
  152: 
  153:                 /* Flush cache */
  154:                 FlushCache(*laddr, len);
  155: 
  156:                 if ( (attr & MM_CDIS) != 0 ) {
  157:                         /* Allocate logical addresses for cache off area */
  158:                         *laddr = toNoCacheLogicalAddress(*laddr);
  159:                 }
  160:         }
  161: 
  162:         return E_OK;
  163: 
  164: err_ret:
  165:         TM_DEBUG_PRINT(("_MapMemory ercd = %d\n", ercd));
  166:         return ercd;
  167: }
  168: 
  169: /*
  170:  * Memory unmap
  171:  */
  172: LOCAL ER _UnmapMemory( CONST void *laddr )
  173: {
  174:         ER     ercd;
  175: 
  176:         /* Memory release when memory is allocated automatically by MapMemory()
  177:          *     If the memory is not automatically allocated, RelSysMemBlk()
  178:          *     returns E_PAR.
  179:          */
  180:         ercd = RelSysMemBlk(laddr);
  181:         if ( ercd < E_OK && ercd != E_PAR ) {
  182:                 goto err_ret;
  183:         }
  184: 
  185:         return E_OK;
  186: 
  187: err_ret:
  188:         TM_DEBUG_PRINT(("_UnmapMemory ercd = %d\n", ercd));
  189:         return ercd;
  190: }
  191: 
  192: /* ------------------------------------------------------------------------ */
  193: 
  194: /*
  195:  * Memory Cache Control
  196:  */
  197: LOCAL ER _FlushMemCache( void *laddr, INT len, UINT mode )
  198: {
  199:         ER     ercd;
  200: 
  201:         if ( (mode & ~(TCM_ICACHE|TCM_DCACHE)) != 0 ) {
  202:                 ercd = E_PAR;
  203:                 goto err_ret;
  204:         }
  205:         ercd = ChkSpaceR(laddr, len);
  206:         if ( ercd < E_OK ){
  207:                 goto err_ret;
  208:         }
  209: 
  210:         FlushCacheM(laddr, len, mode);
  211: 
  212:         return E_OK;
  213: 
  214: err_ret:
  215:         TM_DEBUG_PRINT(("_FlushMemCache ercd = %d\n", ercd));
  216:         return ercd;
  217: }
  218: 
  219: /*
  220:  * Memory Cache Control
  221:  */
  222: LOCAL INT _ControlCache( void *addr, INT len, UINT mode )
  223: {
  224:         ER     ercd;
  225: 
  226:         if ( len <= 0 ) {
  227:                 ercd = E_PAR;
  228:                 goto err_ret;
  229:         }
  230:         if ( mode == 0 ) {
  231:                 ercd = E_PAR;
  232:                 goto err_ret;
  233:         }
  234:         ercd = ChkSpaceR(addr, len);
  235:         if ( ercd < E_OK ){
  236:                 goto err_ret;
  237:         }
  238: 
  239:         ercd = ControlCacheM(addr, len, mode);
  240:         if( ercd != E_OK ){
  241:                 goto err_ret;
  242:         }
  243: 
  244:         return len;
  245: 
  246: err_ret:
  247:         TM_DEBUG_PRINT(("_ControlCache ercd = %d\n", ercd));
  248:         return ercd;
  249: }
  250: 
  251: /* ------------------------------------------------------------------------ */
  252: 
  253: /*
  254:  * Extended SVC entry
  255:  */
  256: LOCAL INT SegSVCentry( void *para, W fn )
  257: {
  258:         INT    ercd;
  259: 
  260:         switch ( fn ) {
  261:                 /* You can call it from all protection levels */
  262:           case SEG_FLUSHMEMCACHE_FN:
  263:                 break;
  264: 
  265:           default:
  266:                 /* Caller protection level check */
  267:                 ercd = ChkCallPLevel();
  268:                 if ( ercd < E_OK ) {
  269:                         goto err_ret;
  270:                 }
  271:         }
  272: 
  273:         switch ( fn ) {
  274:           case SEG_LOCKSPACE_FN:
  275:           case SEG_UNLOCKSPACE_FN:
  276:                 ercd = E_OK;
  277:                 break;
  278: 
  279:           case SEG_CNVPHYSICALADDR_FN:
  280:                 { SEG_CNVPHYSICALADDR_PARA *p = para;
  281:                 ercd = _CnvPhysicalAddr(p->laddr, p->len, p->paddr); }
  282:                 break;
  283: 
  284:           case SEG_CHKSPACE_FN:
  285:                 { SEG_CHKSPACE_PARA *p = para;
  286:                 ercd = _ChkSpace(p->laddr, p->len, p->mode, p->env); }
  287:                 break;
  288:           case SEG_CHKSPACETSTR_FN:
  289:                 { SEG_CHKSPACETSTR_PARA *p = para;
  290:                 ercd = _ChkSpaceTstr(p->str, p->max, p->mode, p->env); }
  291:                 break;
  292:           case SEG_CHKSPACEBSTR_FN:
  293:                 { SEG_CHKSPACEBSTR_PARA *p = para;
  294:                 ercd = _ChkSpaceBstr(p->str, p->max, p->mode, p->env); }
  295:                 break;
  296: 
  297:           case SEG_MAPMEMORY_FN:
  298:                 { SEG_MAPMEMORY_PARA *p = para;
  299:                 ercd = _MapMemory(p->paddr, p->len, p->attr, p->laddr); }
  300:                 break;
  301:           case SEG_UNMAPMEMORY_FN:
  302:                 { SEG_UNMAPMEMORY_PARA *p = para;
  303:                 ercd = _UnmapMemory(p->laddr); }
  304:                 break;
  305: 
  306:           case SEG_FLUSHMEMCACHE_FN:
  307:                 { SEG_FLUSHMEMCACHE_PARA *p = para;
  308:                 ercd = _FlushMemCache(p->laddr, p->len, p->mode); }
  309:                 break;
  310: 
  311:           case SEG_CHKSPACELEN_FN:
  312:                 { SEG_CHKSPACELEN_PARA *p = para;
  313:                 ercd = _ChkSpaceLen(p->laddr, p->len, p->mode, p->env, p->lsid); }
  314:                 break;
  315:           case SEG_READMEMSPACE_FN:
  316:           case SEG_WRITEMEMSPACE_FN:
  317:           case SEG_SETMEMSPACEB_FN:
  318:                 ercd = E_NOSPT;
  319:                 break;
  320:           case SEG_MAKESPACE_FN:
  321:                 { SEG_MAKESPACE_PARA *p = para;
  322:                 ercd = _MakeSpace(p->laddr, p->npage, p->lsid, p->pte); }
  323:                 break;
  324:           case SEG_UNMAKESPACE_FN:
  325:                 { SEG_UNMAKESPACE_PARA *p = para;
  326:                 ercd = _UnmakeSpace(p->laddr, p->npage, p->lsid); }
  327:                 break;
  328:           case SEG_CHANGESPACE_FN:
  329:                 { SEG_CHANGESPACE_PARA *p = para;
  330:                 ercd = _ChangeSpace(p->laddr, p->npage, p->lsid, p->pte); }
  331:                 break;
  332: 
  333:           /* T-Kernel 2.0 */
  334:           case SEG_CONTROLCACHE_FN:
  335:                 { SEG_CONTROLCACHE_PARA *p = para;
  336:                 ercd = _ControlCache(p->addr, p->len, p->mode); }
  337:                 break;
  338:           case SEG_GETSPACEINFO_FN:
  339:                 { SEG_GETSPACEINFO_PARA *p = para;
  340:                 ercd = _GetSpaceInfo(p->addr, p->len, p->pk_spinfo); }
  341:                 break;
  342:           case SEG_SETCACHEMODE_FN:
  343:                 ercd = E_NOSPT;
  344:                 break;
  345:           case SEG_SETMEMORYACCESS_FN:
  346:                 { SEG_SETMEMORYACCESS_PARA *p = para;
  347:                 ercd = _SetMemoryAccess(p->addr, p->len, p->mode); }
  348:                 break;
  349: 
  350:           default:
  351:                 ercd = E_RSFN;
  352:         }
  353: 
  354: err_ret:
  355:         return ercd;
  356: }
  357: 
  358: /*
  359:  * Initialize segment management
  360:  */
  361: EXPORT ER init_segmgr( void )
  362: {
  363:         ER ercd;
  364: 
  365:         /* Initialize system exception manager */
  366:         ercd = init_excmgr();
  367:         if (ercd < E_OK ) {
  368:                 goto err_ret;
  369:         }
  370: 
  371:         /* Initialize logical space */
  372:         ercd = InitLogicalSpace();
  373:         if ( ercd < E_OK ) {
  374:                 goto err_ret;
  375:         }
  376: 
  377: err_ret:
  378:         return ercd;
  379: }
  380: 
  381: /*
  382:  * Start segment management
  383:  */
  384: EXPORT ER start_segmgr( void )
  385: {
  386:         T_DSSY dssy;
  387:         ER     ercd;
  388: 
  389:         /* Create segment manager lock */
  390:         ercd = CreateLock(&SegLock, "Seg");
  391:         if ( ercd < E_OK ) {
  392:                 goto err_ret;
  393:         }
  394: 
  395:         /* Start system exception manager */
  396:         ercd = start_excmgr();
  397:         if ( ercd < E_OK ) {
  398:                 goto err_ret;
  399:         }
  400: 
  401:         /* Register manager */
  402:         dssy.ssyatr    = TA_NULL;
  403:         dssy.ssypri    = SEG_PRI;
  404:         dssy.svchdr    = (FP)SegSVCentry;
  405:         dssy.breakfn   = NULL;
  406:         dssy.startupfn = NULL;
  407:         dssy.cleanupfn = NULL;
  408:         dssy.eventfn   = NULL;
  409:         dssy.resblksz  = 0;
  410:         ercd = tk_def_ssy(SEG_SVC, &dssy);
  411:         if ( ercd < E_OK ) {
  412:                 goto err_ret;
  413:         }
  414: 
  415:         return E_OK;
  416: 
  417: err_ret:
  418:         TM_DEBUG_PRINT(("start_segmgr ercd = %d\n", ercd));
  419:         return ercd;
  420: }
  421: 
  422: /*
  423:  * End segment manager
  424:  */
  425: EXPORT ER finish_segmgr( void )
  426: {
  427:         ER     ercd, ret = E_OK;
  428: 
  429:         /* Finish system exception manager */
  430:         ercd = finish_excmgr();
  431:         if ( ercd < E_OK ) {
  432:                 ret = ercd;
  433:         }
  434: 
  435:         /* Delete subsystem registration */
  436:         ercd = tk_def_ssy(SEG_SVC, NULL);
  437:         if ( ercd < E_OK ) {
  438:                 ret = ercd;
  439:         }
  440: 
  441:         /* Remove segment manager lock */
  442:         DeleteLock(&SegLock);
  443: 
  444: #ifdef DEBUG
  445:         if ( ret < E_OK ) {
  446:                 TM_DEBUG_PRINT(("finish_segmgr ercd = %d\n", ret));
  447:         }
  448: #endif
  449:         return ret;
  450: }