gonzui


Format: Advanced Search

tkernel_2/monitor/hwdepend/tef_em1d/src/eitent.Sbare 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:  *      eitentry.S
   17:  *
   18:  *       EM1D512 (ARM1176JZF-S) exception branch handling
   19:  */
   20: 
   21: #define _in_asm_source_
   22: 
   23: #include <machine.h>
   24: #include <tk/sysdef.h>
   25: #include <arm/em1d512.h>
   26: #include <sys/sysinfo.h>
   27: 
   28: #define base(n)         ( (n) & 0xfffff000 )
   29: #define offs(n)         ( (n) & 0x00000fff )
   30: 
   31: // see <sys/sysdepend/tef_em1d/sysinfo_depend.h>
   32: #define N_INTVEC        256
   33: 
   34: /*
   35:  *       EIT entry
   36:  */
   37: 
   38:         .section EITBRA, "ax"
   39:         .arm
   40:         .org   0x00000000
   41:         b      startup_entry                // 00 : reset
   42:         b      undef_entry          // 04 : undefined instruction exception
   43:         b      svc_entry            // 08 : supervisor call (SVC)
   44:         b      iabort_entry         // 0C : prefetch abort
   45:         b      dabort_entry         // 10 : data abort
   46:         nop                            // 14 : (reserved)
   47:         b      irq_entry            // 18 : interrupt
   48:         .org   0x0000001c                // 1C : fast interrupt
   49: 
   50: /*
   51:  * fast interrupt
   52:  *       calls the handler defined at FIQ interrupt vector unconditionally.
   53:  *       no saving of registers to stack is performed.
   54:  *       the content of R12_fiq(ip) register is overwritten.
   55:  */
   56: fiq_entry:
   57:         ldr    ip, =base(EIT_VECTBL)
   58:         ldr    ip, [ip, #offs(EITVEC(EIT_FIQ))]
   59:         bx     ip
   60: 
   61: /*
   62:  * interrupt
   63:  *       ACPU interrupt mask status register of Interrupt controller (AINT)
   64:  *      Judge the priority of interrupts using (IT0_MST0,1,2),
   65:  *       the highest interrupt's handler is called by jumping into it.
   66:  *       Interrupt priority is descending order of interrupt factor (INT 0-95) , and INT 95 (IRQ 95) is highest.
   67:  *       INT 0 (IRQ 0) has the lowest priority.
   68:  *       If there is no cause of the interrupt, the handler of INT 95 (IRQ95) is called.
   69:  *              +---------------+
   70:  *      sp  ->       |R3           |
   71:  *              |R12=ip             |
   72:  *              |R14=lr         | <- return address from interrupt
   73:  *              |SPSR               |
   74:  *              +---------------+
   75:  *      registers upon handler invocation
   76:  *       ip = vector table address
   77:  *       lr = indeterminate
   78:  */
   79: irq_entry:
   80:         sub    lr, lr, #4         // return address adjustment
   81:         srsdb  sp!, #PSR_IRQ            // save registers
   82:         stmfd  sp!, {r3, ip}
   83: 
   84:         ldr    lr, =base(AINTBase)
   85:         ldr    ip, =EITVEC(EIT_IRQ(95))
   86: 
   87:         ldr    r3, [lr, #offs(IT0_MST2)]
   88:         cmp    r3, #0
   89:         bne    l_irq_br
   90: 
   91:         sub    ip, ip, #32*4
   92:         ldr    r3, [lr, #offs(IT0_MST1)]
   93:         cmp    r3, #0
   94:         bne    l_irq_br
   95: 
   96:         sub    ip, ip, #32*4
   97:         ldr    r3, [lr, #offs(IT0_MST0)]
   98:         cmp    r3, #0
   99:         bne    l_irq_br
  100: 
  101:         ldr    ip, =EITVEC(EIT_IRQ(95))
  102: 
  103:   l_irq_br:
  104:         clzne  r3, r3
  105:         ldr    lr, [ip, -r3, lsl #2]!
  106:         cmp    lr, #0
  107:         bxne   lr
  108:         b      default_entry
  109: 
  110: /*
  111:  * GPIO interrupt
  112:  *      Interrupt obtained by means of input port interrupt maskable status register (GIO_MST)
  113:  *       is analyzed to check the interrupt priority, and if appropriate, the highest priority interrupt handler is entered.
  114:  *       branch and call handler.
  115:  *       interrupt priority is descending order of input port NUMBER (port 0 - port 127). port 127 has the highest priority, and
  116:  *       port 0 has the lowest priority GPIO interrupts are grouped : each group has 16 interrupts, and
  117:  *       their priorities are considered only within the context of each group.
  118:  *       if there is no cause of interupt, the handler of IRQ95 is called.
  119:  *              +---------------+
  120:  *      sp  ->       |R3           |
  121:  *              |R12=ip             |
  122:  *              |R14=lr         | <- return address from interrupt
  123:  *              |SPSR               |
  124:  *              +---------------+
  125:  *      registers upon handler invocation
  126:  *       ip = vector table address
  127:  *       lr = indeterminate
  128:  */
  129:  .macro gio_e reg, vec
  130:         ldr    lr, =base(\reg)
  131:         ldr    r3, [lr, #offs(\reg)]
  132:         lsls   r3, r3, #16
  133:         beq    l_gio_spurious
  134: 
  135:         ldr    ip, =\vec
  136:         clz    r3, r3
  137:         ldr    lr, [ip, -r3, lsl #2]!
  138:         cmp    lr, #0
  139:         bxne   lr
  140:         b      default_entry
  141:  .endm
  142:  .macro gio_o reg, vec
  143:         ldr    lr, =base(\reg)
  144:         ldr    r3, [lr, #offs(\reg)]
  145:         lsrs   ip, r3, #16
  146:         beq    l_gio_spurious
  147: 
  148:         ldr    ip, =\vec
  149:         clz    r3, r3
  150:         ldr    lr, [ip, -r3, lsl #2]!
  151:         cmp    lr, #0
  152:         bxne   lr
  153:         b      default_entry
  154:  .endm
  155: 
  156:         .globl Csym(_gio0Hdr)
  157:         .type  Csym(_gio0Hdr), %function
  158:         .globl Csym(_gio1Hdr)
  159:         .type  Csym(_gio1Hdr), %function
  160:         .globl Csym(_gio2Hdr)
  161:         .type  Csym(_gio2Hdr), %function
  162:         .globl Csym(_gio3Hdr)
  163:         .type  Csym(_gio3Hdr), %function
  164:         .globl Csym(_gio4Hdr)
  165:         .type  Csym(_gio4Hdr), %function
  166:         .globl Csym(_gio5Hdr)
  167:         .type  Csym(_gio5Hdr), %function
  168:         .globl Csym(_gio6Hdr)
  169:         .type  Csym(_gio6Hdr), %function
  170:         .globl Csym(_gio7Hdr)
  171:         .type  Csym(_gio7Hdr), %function
  172: Csym(_gio0Hdr): gio_e   GIO_MST(GIO_L),   EITVEC(EIT_GPIO( 15))
  173: Csym(_gio1Hdr): gio_o   GIO_MST(GIO_L),   EITVEC(EIT_GPIO( 31))
  174: Csym(_gio2Hdr): gio_e   GIO_MST(GIO_H),   EITVEC(EIT_GPIO( 47))
  175: Csym(_gio3Hdr): gio_o   GIO_MST(GIO_H),   EITVEC(EIT_GPIO( 63))
  176: Csym(_gio4Hdr): gio_e   GIO_MST(GIO_HH),  EITVEC(EIT_GPIO( 79))
  177: Csym(_gio5Hdr): gio_o   GIO_MST(GIO_HH),  EITVEC(EIT_GPIO( 95))
  178: Csym(_gio6Hdr): gio_e   GIO_MST(GIO_HHH), EITVEC(EIT_GPIO(111))
  179: Csym(_gio7Hdr): gio_o   GIO_MST(GIO_HHH), EITVEC(EIT_GPIO(127))
  180: 
  181:   l_gio_spurious:
  182:         ldr    ip, =base(EITVEC(EIT_IRQ(95)))
  183:         ldr    lr, [ip, #offs(EITVEC(EIT_IRQ(95)))]!
  184:         cmp    lr, #0
  185:         bxne   lr
  186:         b      default_entry
  187: 
  188: /*
  189:  * undefined instruction
  190:  *              +---------------+
  191:  *      sp  ->       |R12=ip               |
  192:  *              |R14=lr         | <- the return address, i.e., the next address that follows the undefined instruction
  193:  *              |SPSR               |
  194:  *              +---------------+
  195:  *      registers upon handler invocation
  196:  *       ip = vector table address
  197:  *       lr = indeterminate
  198:  */
  199: undef_entry:
  200:         srsdb  sp!, #PSR_UND            // save registers
  201:         stmfd  sp!, {ip}
  202: 
  203:         ldr    ip, =base(EITVEC(EIT_UNDEF))
  204:         ldr    lr, [ip, #offs(EITVEC(EIT_UNDEF))]!
  205:         cmp    lr, #0
  206:         bxne   lr
  207:         b      default_entry
  208: 
  209: /*
  210:  * supervisor call(SVC)
  211:  *      the valid range of supervisor call number is 0-255 (N_INTVEC - 1).
  212:  *       if an out of range value is given, treat it as SVC 0, and invokes the default handler.
  213:  *              +---------------+
  214:  *      sp  ->       |R12=ip               |
  215:  *              |R14=lr         | <- return address: the address that follows the SVC instruction
  216:  *              |SPSR               |
  217:  *              +---------------+
  218:  *      registers upon handler invocation
  219:  *       ip = vector table address
  220:  *       lr = indeterminate
  221:  */
  222: svc_entry:
  223:         srsdb  sp!, #PSR_SVC            // save registers
  224:         stmfd  sp!, {ip}
  225: 
  226:         mrs    ip, spsr
  227:         tst    ip, #PSR_T
  228:         ldrneh ip, [lr, #-2]           // Thumb instruction
  229:         ldreq  ip, [lr, #-4]            // ARM instruction
  230:         bicne  lr, ip, #0xff00
  231:         biceq  lr, ip, #0xff000000
  232:         cmp    lr, #N_INTVEC              // lr = software interrupt number
  233:         movge  lr, #0
  234: 
  235:         ldr    ip, =EIT_VECTBL
  236:         ldr    lr, [ip, lr, lsl #2]!
  237:         cmp    lr, #0
  238:         bxne   lr
  239:         b      default_entry
  240: 
  241: /*
  242:  * prefetch abort
  243:  *       in the case of debug event, debug abort (instruction) handler is called.
  244:  *       Otherwise, prefetch abort handler is called.
  245:  *              +---------------+
  246:  *      sp  ->       |R12=ip               |
  247:  *              |R14=lr         | <- return address: the address of aborted instruction
  248:  *              |SPSR               |
  249:  *              +---------------+
  250:  *      registers upon handler invocation
  251:  *       ip = vector table address
  252:  *       lr = indeterminate
  253:  */
  254: iabort_entry:
  255:         sub    lr, lr, #4         // return address adjustment
  256:         srsdb  sp!, #PSR_ABT            // save registers
  257:         stmfd  sp!, {ip}
  258: 
  259:         mrc    p15, 0, ip, c5, c0, 1      // IFSR
  260:         tst    ip, #0x400         // FS[4]
  261:         and    ip, ip, #0x00f             // FS[3:0]
  262:         cmpeq  ip, #FSR_DebugEvent
  263: 
  264:         ldr    ip, =base(EITVEC(EIT_IABORT))
  265:         ldrne  lr, [ip, #offs(EITVEC(EIT_IABORT))]!
  266:         ldreq  lr, [ip, #offs(EITVEC(EIT_IDEBUG))]!
  267:         cmp    lr, #0
  268:         bxne   lr
  269:         b      default_entry
  270: 
  271: /*
  272:  * data abort
  273:  *       in the case of debug event, debug abort (data) handler is called.
  274:  *       Otherwise, data abort handler is called.
  275:  *              +---------------+
  276:  *      sp  ->       |R12=ip               |
  277:  *              |R14=lr         | <- return address: the address of aborted instruction
  278:  *              |SPSR               |
  279:  *              +---------------+
  280:  *      registers upon handler invocation
  281:  *       ip = vector table address
  282:  *       lr = indeterminate
  283:  */
  284: dabort_entry:
  285:         sub    lr, lr, #8         // return address adjustment
  286:         srsdb  sp!, #PSR_ABT            // save registers
  287:         stmfd  sp!, {ip}
  288: 
  289:         mrc    p15, 0, ip, c5, c0, 0      // DFSR
  290:         tst    ip, #0x400         // FS[4]
  291:         and    ip, ip, #0x00f             // FS[3:0]
  292:         cmpeq  ip, #FSR_DebugEvent
  293: 
  294:         ldr    ip, =base(EITVEC(EIT_DABORT))
  295:         ldrne  lr, [ip, #offs(EITVEC(EIT_DABORT))]!
  296:         ldreq  lr, [ip, #offs(EITVEC(EIT_DDEBUG))]!
  297:         cmp    lr, #0
  298:         bxne   lr
  299:         b      default_entry
  300: 
  301: /*
  302:  * default handler
  303:  *       stack contains the details of the generated exception.
  304:  *      registers upon handler invocation
  305:  *       ip = address of the vector table for the raised exception
  306:  *       lr = indeterminate
  307:  */
  308: default_entry:
  309:         ldr    lr, =base(EITVEC(EIT_DEFAULT))
  310:         ldr    lr, [lr, #offs(EITVEC(EIT_DEFAULT))]
  311:         bx     lr
  312: 
  313:         .pool