1:     2:     3:     4:     5:     6:     7:     8:     9:    10:    11:    12:    13: 
   14: 
   15:    16:    17:    18:    19:    20:    21:    22:    23:    24: 
   25: 
   26: #include <basic.h>
   27: #include <tk/syslib.h>
   28: #include <tk/sysdef.h>
   29: 
   30:    31:    32:    33: 
   34: #define AINT(n)         ( 0xc0020000 + (n) )   
   35: #define SINT(n)         ( 0xcc010000 + (n) )   
   36: 
   37: #define IT0_IEN0        AINT(0x0000)   
   38: #define IT0_IEN1        AINT(0x0004)   
   39: #define IT0_IEN2        AINT(0x0100)   
   40: #define IT0_IDS0        AINT(0x0008)   
   41: #define IT0_IDS1        AINT(0x000C)   
   42: #define IT0_IDS2        AINT(0x0104)   
   43: #define IT0_RAW0        AINT(0x0010)   
   44: #define IT0_RAW1        AINT(0x0014)   
   45: #define IT0_RAW2        AINT(0x0108)   
   46: #define IT0_MST0        AINT(0x0018)   
   47: #define IT0_MST1        AINT(0x001C)   
   48: #define IT0_MST2        AINT(0x010C)   
   49: #define IT0_IIR         AINT(0x0024)   
   50: #define IT0_FIE         AINT(0x0080)   
   51: #define IT0_FID         AINT(0x0084)   
   52: #define IT_PINV_SET0    AINT(0x0300)       
   53: #define IT_PINV_SET1    AINT(0x0304)       
   54: #define IT_PINV_SET2    AINT(0x0308)       
   55: #define IT_PINV_CLR0    AINT(0x0310)       
   56: #define IT_PINV_CLR1    AINT(0x0314)       
   57: #define IT_PINV_CLR2    AINT(0x0318)       
   58: #define IT_LIIS         AINT(0x0320)   
   59: #define IT_LIIR         AINT(0x0324)   
   60: 
   61: #define IT0_IENS0       SINT(0xE200)  
   62: #define IT0_IENS1       SINT(0xE204)  
   63: #define IT0_IENS2       SINT(0xE208)  
   64: #define IT0_IDSS0       SINT(0xE20C)  
   65: #define IT0_IDSS1       SINT(0xE210)  
   66: #define IT0_IDSS2       SINT(0xE214)  
   67: 
   68: LOCAL const struct aint_reg {
   69:         UINT   IT0_IEN;  
   70:         UINT   IT0_IDS;  
   71:         UINT   IT0_RAW;  
   72:         UINT   IT0_MST;  
   73:         UINT   IT_PINV_SET;      
   74:         UINT   IT_PINV_CLR;      
   75:         UINT   IT0_IENS; 
   76:         UINT   IT0_IDSS; 
   77: } AINT[3] = {
   78:         { IT0_IEN0, IT0_IDS0, IT0_RAW0, IT0_MST0, IT_PINV_SET0, IT_PINV_CLR0,
   79:           IT0_IENS0, IT0_IDSS0 },
   80:         { IT0_IEN1, IT0_IDS1, IT0_RAW1, IT0_MST1, IT_PINV_SET1, IT_PINV_CLR1,
   81:           IT0_IENS1, IT0_IDSS1 },
   82:         { IT0_IEN2, IT0_IDS2, IT0_RAW2, IT0_MST2, IT_PINV_SET2, IT_PINV_CLR2,
   83:           IT0_IENS2, IT0_IDSS2 }
   84: };
   85: 
   86:    87:    88:    89: 
   90: #define GIO(b, n)       ( (b) + (n) )         
   91: #define _L              ( 0xc0050000 + 0x000 )
   92: #define _H              ( 0xc0050000 + 0x040 )
   93: #define _HH             ( 0xc0050000 + 0x080 )
   94: #define _HHH            ( 0xc0050000 + 0x200 )
   95: 
   96: #define GIO_IIA(b)      GIO(b,0x0014)        
   97: #define GIO_IEN(b)      GIO(b,0x0018)        
   98: #define GIO_IDS(b)      GIO(b,0x001C)        
   99: #define GIO_IIM(b)      GIO(b,0x001C)        
  100: #define GIO_RAW(b)      GIO(b,0x0020)        
  101: #define GIO_MST(b)      GIO(b,0x0024)        
  102: #define GIO_IIR(b)      GIO(b,0x0028)        
  103: #define GIO_GSW(b)      GIO(b,0x003C)        
  104: #define GIO_IDT(n,b)    GIO(b,0x0100+(n)*4) 
  105: #define GIO_RAWBL(b)    GIO(b,0x0110)      
  106: #define GIO_RAWBH(b)    GIO(b,0x0114)      
  107: #define GIO_IRBL(b)     GIO(b,0x0118)       
  108: #define GIO_IRBH(b)     GIO(b,0x011C)       
  109: 
  110: LOCAL const UINT        GIOB[4] = { _L, _H, _HH, _HHH };
  111: 
  112: #define AINTNO(intvec)  ( ((intvec) - IV_IRQ(0)) / 32 )          
  113: #define GIONO(intvec)   ( ((intvec) - IV_GPIO(0)) / 32 )  
  114: #define BITNO(intvec)   ( ((intvec) - IV_IRQ(0)) % 32 )           
  115: 
  116: 
  117: 
  118:   119:   120: 
  121: Inline UW _disint( void )
  122: {
  123:         UW     imask;
  124:         Asm("  mrs      %0, cpsr     \n"
  125:         "      orr  ip, %0, %1       \n"
  126:         "      msr  cpsr_xc, ip      "
  127:                 : "=r"(imask)
  128:                 : "i"(PSR_DI)
  129:                 : "ip" );
  130:         return imask;
  131: }
  132: Inline void _enaint( UW imask )
  133: {
  134:         Asm("msr cpsr_xc, %0":: "r"(imask));
  135: }
  136: #define _DI(imask)      ( imask = _disint() )
  137: #define _EI(imask)      ( _enaint(imask) )
  138: 
  139:   140:   141:   142:   143:   144:   145:   146:   147:   148:   149:   150:   151:   152:   153:   154:   155:   156:   157:   158:   159:   160:   161:   162:   163:   164:   165:   166:   167:   168:   169:   170:   171:   172:   173:   174:   175: 
  176: EXPORT void SetIntMode( INTVEC intvec, UINT mode )
  177: {
  178:         UW     m = 1 << BITNO(intvec);
  179:         UINT   imask;
  180: 
  181:         if ( intvec < IV_GPIO(0) ) {
  182:                 
  183:                 const struct aint_reg *r = AINT + AINTNO(intvec);
  184: 
  185:                 out_w(r->IT0_IDS,  m);        
  186:                 out_w(r->IT0_IDSS, m);        
  187:                 if ( (mode & IM_ENA) == 0 ) return;
  188: 
  189:                 if ( (mode & IM_INV) == 0 ) out_w(r->IT_PINV_CLR, m);
  190:                 else                      out_w(r->IT_PINV_SET, m);
  191: 
  192:                 out_w(r->IT0_IENS, m);        
  193:         } else {
  194:                 
  195:                 UINT  gb = GIOB[GIONO(intvec)];
  196:                 UINT  n;
  197:                 UW    mm, mv;
  198: 
  199:                 _DI(imask);
  200:                 out_w(GIO_IDS(gb), m);                            
  201:                 out_w(GIO_IIA(gb), in_w(GIO_IIA(gb)) & ~m); 
  202:                 _EI(imask);
  203:                 if ( (mode & IM_ENA) == 0 ) return;
  204: 
  205:                 n = (intvec - IV_GPIO(0)) % 8 * 4;
  206:                 mm = 0xf << n;
  207:                 mv = ((mode >> 8) & 0xf) << n;
  208:                 n = (intvec - IV_GPIO(0)) % 32 / 8;
  209:                 _DI(imask);
  210:                 out_w(GIO_IDT(n, gb), (in_w(GIO_IDT(n, gb)) & ~mm) | mv);
  211:                 out_w(GIO_IIA(gb), in_w(GIO_IIA(gb)) | m); 
  212:                 _EI(imask);
  213:         }
  214: }
  215: 
  216:   217:   218:   219: 
  220: EXPORT void EnableInt( INTVEC intvec )
  221: {
  222:         UW     m = 1 << BITNO(intvec);
  223: 
  224:         if ( intvec < IV_GPIO(0) ) {
  225:                 
  226:                 const struct aint_reg *r = AINT + AINTNO(intvec);
  227:                 out_w(r->IT0_IEN, m);
  228:         } else {
  229:                 
  230:                 UINT  gb = GIOB[GIONO(intvec)];
  231:                 out_w(GIO_IEN(gb), m);
  232:         }
  233: }
  234: 
  235:   236:   237:   238: 
  239: EXPORT void DisableInt( INTVEC intvec )
  240: {
  241:         UW     m = 1 << BITNO(intvec);
  242: 
  243:         if ( intvec < IV_GPIO(0) ) {
  244:                 
  245:                 const struct aint_reg *r = AINT + AINTNO(intvec);
  246:                 out_w(r->IT0_IDS, m);
  247:         } else {
  248:                 
  249:                 UINT  gb = GIOB[GIONO(intvec)];
  250:                 out_w(GIO_IDS(gb), m);
  251:         }
  252: }
  253: 
  254:   255:   256:   257:   258: 
  259: EXPORT void ClearInt( INTVEC intvec )
  260: {
  261:         UW     m = 1 << BITNO(intvec);
  262: 
  263:         if ( intvec < IV_IRQ(32 ) ) {
  264:                 
  265: 
  266:         } else if ( intvec < IV_IRQ(64) ) {
  267:                 
  268:                 out_w(IT0_IIR, m);
  269: 
  270:         } else if ( intvec < IV_GPIO(0) ) {
  271:                 
  272: 
  273:         } else {
  274:                 
  275:                 UINT  gb = GIOB[GIONO(intvec)];
  276:                 out_w(GIO_IIR(gb), m);
  277:         }
  278: }
  279: 
  280:   281:   282:   283:   284:   285:   286:   287: 
  288: EXPORT BOOL CheckInt( INTVEC intvec )
  289: {
  290:         UW     sts;
  291: 
  292:         if ( intvec < IV_GPIO(0) ) {
  293:                 
  294:                 const struct aint_reg *r = AINT + AINTNO(intvec);
  295:                 sts = in_w(r->IT0_RAW);
  296:         } else {
  297:                 
  298:                 UINT  gb = GIOB[GIONO(intvec)];
  299:                 sts = in_w(GIO_RAW(gb));
  300:         }
  301: 
  302:         return (sts >> BITNO(intvec)) & 1;
  303: }