gonzui


Format: Advanced Search

tkernel_2/monitor/hwdepend/tef_em1d/src/system.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 2011/09/08.
   11:  *    Modified by T-Engine Forum at 2013/03/04.
   12:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   13:  *
   14:  *----------------------------------------------------------------------
   15:  */
   16: 
   17: /*
   18:  *      system.c
   19:  *
   20:  *       system-related processing
   21:  *
   22:  *       target: EM1D-512
   23:  */
   24: 
   25: #include "sysdepend.h"
   26: #include <arm/em1d512.h>
   27: 
   28: EXPORT  UW       DipSw;                /* DipSw status */
   29: 
   30: /* hardware dependent functions */
   31: IMPORT  UW       DipSwStatus(void);
   32: IMPORT  void     usbPower(BOOL power);
   33: IMPORT  void     powerOff(void);
   34: IMPORT  void     resetStart(void);
   35: 
   36: /* interrupt entry point (eitent.S) */
   37: IMPORT  void     _gio0Hdr(void);
   38: IMPORT  void     _gio1Hdr(void);
   39: IMPORT  void     _gio2Hdr(void);
   40: IMPORT  void     _gio3Hdr(void);
   41: IMPORT  void     _gio4Hdr(void);
   42: IMPORT  void     _gio5Hdr(void);
   43: IMPORT  void     _gio6Hdr(void);
   44: IMPORT  void     _gio7Hdr(void);
   45: 
   46: /* default handler (cmdsvc) */
   47: IMPORT  void     _defaultHdr(void);
   48: 
   49: /* macros for manipulating cache/MMU/PMIC */
   50: #define EnbCacheMMU(x)  setCacheMMU(ENB_CACHEMMU)
   51: #define DisCacheMMU(x)  setCacheMMU(ENB_MMUONLY) /* MMU can't be turned off */
   52: 
   53: /* ------------------------------------------------------------------------ */
   54: 
   55: IMPORT  char     __loadaddr; /* monitor load address */
   56: IMPORT  MEMSEG   NoMemSeg[];       /* memory unused area */
   57: IMPORT  W        N_NoMemSeg;
   58: 
   59: /*
   60:         power management controller (DA9052) handler routines
   61: */
   62: #define SPIPol  0x0092
   63: 
   64: /* initialize SPI for PMIC communication */
   65: LOCAL   void      pmicInit(void)
   66: {
   67:         out_w(SPn_MODE(SP0), 0x2700);          // 8bit, CS0, Master, CPU mode
   68:         out_w(SPn_TIECS(SP0), 0x000f);         // CS0: follow the specification by SPn_POL
   69:         out_w(SPn_POL(SP0), SPIPol);
   70:         out_w(SPn_ENCLR(SP0), ~0);             // interrupt disable
   71: 
   72:         out_w(SPn_CONTROL(SP0), 0x0100);       // start reset
   73:         waitUsec(10);
   74:         out_w(SPn_CONTROL(SP0), 0x0000);       // release reset
   75:         out_w(SPn_CONTROL2(SP0), 0x0000);
   76: 
   77:         return;
   78: }
   79: 
   80: /* wait for data of SPI for PMIC communication */
   81: LOCAL   void      pmicWait(void)
   82: {
   83:         W      i;
   84: 
   85:         for (i = 1000000; i > 0; i--) {
   86:                 if (in_w(SPn_RAW_STATUS(SP0)) & 0x0004) break;
   87:                 waitUsec(1);
   88:         }
   89:         if (!i) pmicInit();
   90: 
   91:         return;
   92: }
   93: 
   94: /* contro CS line of SPI for PMIC communication */
   95: LOCAL   void      pmicCSassert(BOOL cs)
   96: {
   97:         waitNsec(200);
   98:         out_w(SPn_POL(SP0), SPIPol ^ (cs ? 0x0001 : 0x0000));
   99:         waitNsec(200);
  100: 
  101:         return;
  102: }
  103: 
  104: /* read PMIC register */
  105: EXPORT  W        pmicRead(W reg)
  106: {
  107:         W      dat;
  108: 
  109:         pmicCSassert(TRUE);                    // CS assert
  110: 
  111:         out_w(SPn_FFCLR(SP0), ~0);             // status flag is cleared
  112:         out_w(SPn_TX_DATA(SP0), (reg << 1) | 1);        // send register number
  113:         out_w(SPn_CONTROL(SP0), 0x0009);       // send start
  114:         pmicWait();
  115: 
  116:         out_w(SPn_FFCLR(SP0), ~0);             // status flag is cleared
  117:         out_w(SPn_CONTROL(SP0), 0x0005);       // start receive
  118:         pmicWait();
  119:         dat = in_w(SPn_RX_DATA(SP0));          // data received
  120: 
  121:         pmicCSassert(FALSE);                   // CS de-assert
  122: 
  123:         return dat;
  124: }
  125: 
  126: /* write PMIC register */
  127: EXPORT  void     pmicWrite(W reg, W dat)
  128: {
  129:         pmicCSassert(TRUE);                    // CS assert
  130: 
  131:         out_w(SPn_FFCLR(SP0), ~0);             // status flag is cleared
  132:         out_w(SPn_TX_DATA(SP0), reg << 1);     // send register number
  133:         out_w(SPn_CONTROL(SP0), 0x0009);       // send start
  134:         pmicWait();
  135: 
  136:         out_w(SPn_FFCLR(SP0), ~0);             // status flag is cleared
  137:         out_w(SPn_TX_DATA(SP0), dat);          // send data
  138:         out_w(SPn_CONTROL(SP0), 0x0009);       // send start
  139:         pmicWait();
  140: 
  141:         pmicCSassert(FALSE);                   // CS de-assert
  142: 
  143:         return;
  144: }
  145: 
  146: /* ------------------------------------------------------------------------ */
  147: 
  148: /* basic system set up (performed during reset, and Disk Boot) */
  149: EXPORT  void     resetSystem(W boot)
  150: {
  151:         MEMSEG *mp;
  152:         UW     i, va;
  153: 
  154:         /* obtain DipSw status */
  155:         if (!boot) DipSw = DipSwStatus();
  156: 
  157:         DisCacheMMU();
  158: 
  159:         /* set up interrupt controller */
  160:         out_w(IT0_IDS0, ~0);           // CPU: all interrupts disabled
  161:         out_w(IT0_IDS1, ~0);
  162:         out_w(IT0_IDS2, ~0);
  163:         out_w(IT0_IIR, ~0);
  164:         out_w(IT3_IPI0_CLR, 0x0000003f);
  165:         out_w(IT3_IDS0, ~0);           // DSP: all interrupts disabled
  166:         out_w(IT3_IDS1, ~0);
  167:         out_w(IT3_IDS2, ~0);
  168:         out_w(IT3_IIR, ~0);
  169:         out_w(IT0_IPI3_CLR, 0x0000003f);
  170:         out_w(IT0_FID, 0x00000001);    // CPU: FIQ disabled
  171:         out_w(GIO_IIA(GIO_L), 0);      // GPIO: interrupt disabled
  172:         out_w(GIO_IIA(GIO_H), 0);
  173:         out_w(GIO_IIA(GIO_HH), 0);
  174:         out_w(GIO_IIA(GIO_HHH), 0);
  175:         out_w(GIO_GSW(GIO_L), 0);      // GPIO: FIQ interrupt disabled
  176:         out_w(GIO_GSW(GIO_H), 0);
  177:         out_w(GIO_GSW(GIO_HH), 0);
  178:         out_w(GIO_GSW(GIO_HHH), 0);
  179:         out_w(IT0_LIIR, 0x0000000f);   // internal interrupt disabled
  180:         out_w(IT_PINV_CLR0, ~0);       // inhibit interrupt polarity inversion
  181:         out_w(IT_PINV_CLR1, ~0);
  182:         out_w(IT_PINV_CLR2, ~0);
  183:         out_w(IT0_IEN0, 0x0c000000);   // CPU: GPIO interrupt enabled
  184:         out_w(IT0_IEN1, 0x003c0000);
  185:         out_w(IT0_IEN2, 0x00018000);
  186: 
  187:         /* power on controller initialization */
  188:         pmicInit();
  189: 
  190:         /* USB power on */
  191:         usbPower(TRUE);
  192: 
  193:         /* clear system common area (vector table, and SysInfo) */
  194:         memset(&SCInfo, 0, sizeof(SysCommonInfo));
  195:         memset(SCArea, 0, sizeof(SysCommonArea));
  196: 
  197:         /* if monitor is loaded into RAM, exclude the RAM area */
  198:         mp = MemArea(MSA_OS, 1);
  199:         va = (UW)&__loadaddr;
  200:         if (va >= mp->top && va < mp->end) mp->end = va;
  201: 
  202:         /* exclude the area where ROM disk data is stored */
  203:         va = (UW)ROMInfo->userarea;
  204:         if (va >= mp->top && va < mp->end) mp->end = va;
  205: 
  206:         /* initialize system common information (SysInfo) */
  207:         SCInfo.ramtop = (void*)mp->top;
  208:         if (va < mp->top || va > mp->end) va = mp->end;
  209:         SCInfo.ramend = (void*)va;
  210: 
  211:         /* set up EIT vectors */
  212:         // we do not need _defaultHdr absolutely, but just in case set it up
  213:         SCArea->intvec[EIT_DEFAULT]    = _defaultHdr;     // default handler
  214:         SCArea->intvec[EIT_UNDEF]      = _defaultHdr;       // undefined instruction
  215:         SCArea->intvec[SWI_MONITOR]    = _defaultHdr;     // SWI - monitor SVC
  216:         SCArea->intvec[EIT_IRQ(26)]    = _gio6Hdr;        // GPIO branch
  217:         SCArea->intvec[EIT_IRQ(27)]    = _gio7Hdr;
  218:         SCArea->intvec[EIT_IRQ(50)]    = _gio0Hdr;
  219:         SCArea->intvec[EIT_IRQ(51)]    = _gio1Hdr;
  220:         SCArea->intvec[EIT_IRQ(52)]    = _gio2Hdr;
  221:         SCArea->intvec[EIT_IRQ(53)]    = _gio3Hdr;
  222:         SCArea->intvec[EIT_IRQ(79)]    = _gio4Hdr;
  223:         SCArea->intvec[EIT_IRQ(80)]    = _gio5Hdr;
  224:         SCArea->intvec[EIT_GPIO(8)]    = _defaultHdr;     // abort switch
  225: 
  226:         /* set up initial page table */
  227:         for (i = 0; i < N_MemSeg; ++i) {
  228:                 mp = &MemSeg[i];
  229:                 if (!mp->pa) continue;
  230: 
  231:                 /* FlashROM has already been mapped, and so do not touch it */
  232:                 if (mp->attr == MSA_FROM) continue;
  233: 
  234:                 /* set up in unit of section (1MB) */
  235:                 for ( va  = (mp->top & 0xfff00000);
  236:                       va != ((mp->end + 0x000fffff) & 0xfff00000);
  237:                       va += 0x00100000 ) {
  238:                         TopPageTable[va / 0x00100000] =
  239:                                 ((mp->pa & 0xfff00000) + va) |
  240:                                  (mp->pa & 0x000fffff);
  241:                 }
  242:         }
  243: 
  244:         for (i = 0; i < N_NoMemSeg; ++i) {
  245:                 mp = &NoMemSeg[i];
  246: 
  247:                 /* set up in unit of section (1MB) */
  248:                 for ( va  = (mp->top & 0xfff00000);
  249:                       va != ((mp->end + 0x000fffff) & 0xfff00000);
  250:                       va += 0x00100000 ) {
  251:                         TopPageTable[va / 0x00100000] = 0;
  252:                 }
  253:         }
  254: 
  255:         DSB();
  256:         Asm("mcr p15, 0, %0, cr8, c7, 0":: "r"(0));    // I/D TLB invalidate
  257:         Asm("mcr p15, 0, %0, cr7, c5, 6":: "r"(0));    // invalidate BTC
  258:         DSB();
  259:         ISB();
  260: 
  261:         EnbCacheMMU();
  262: 
  263:         return;
  264: }
  265: 
  266: /* ------------------------------------------------------------------------ */
  267: 
  268: /*
  269:         system termination: reset / system power off
  270:         reset   0       power off
  271:                 -1      reboot
  272:                 0xaa55  halt boot and power off
  273: */
  274: EXPORT  void     sysExit(W reset)
  275: {
  276:         DisCacheMMU();
  277: 
  278:         // after this point, delay such as waitUsec() spends more time than the number indicates //
  279: 
  280:         /* LED off */
  281:         cpuLED(0x00);
  282: 
  283:         /* all interrupts disabled */
  284:         out_w(IT0_IDS0, ~0);           // CPU: all interrupts disabled
  285:         out_w(IT0_IDS1, ~0);
  286:         out_w(IT0_IDS2, ~0);
  287:         out_w(IT3_IPI0_CLR, 0x0000003f);
  288:         out_w(IT3_IDS0, ~0);           // DSP: all interrupts disabled
  289:         out_w(IT3_IDS1, ~0);
  290:         out_w(IT3_IDS2, ~0);
  291:         out_w(IT0_IPI3_CLR, 0x0000003f);
  292:         out_w(IT0_FID, 0x00000001);    // FIQ disabled
  293:         out_w(IT0_LIIR, 0x0000000f);   // internal interrupt disabled
  294: 
  295:         /* power on controller initialization */
  296:         pmicInit();
  297: 
  298:         /* USB power off */
  299:         usbPower(FALSE);
  300: 
  301:         if (reset >= 0) powerOff();
  302: 
  303:         /* reset start */
  304:         resetStart();
  305: }
  306: 
  307: /* ------------------------------------------------------------------------ */