Subversion Repositories HelenOS

Rev

Rev 4377 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2007 Petr Stepan
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup arm32
  30.  * @{
  31.  */
  32. /** @file
  33.  *  @brief Exception handlers and exception initialization routines.
  34.  */
  35.  
  36. #include <arch/exception.h>
  37. #include <arch/memstr.h>
  38. #include <arch/regutils.h>
  39. #include <interrupt.h>
  40. #include <arch/mm/page_fault.h>
  41. #include <arch/barrier.h>
  42. #include <print.h>
  43. #include <syscall/syscall.h>
  44. #include <udebug/udebug.h>
  45.  
  46. #ifdef MACHINE_testarm
  47.     #include <arch/mach/testarm/testarm.h>
  48. #endif
  49.  
  50. #ifdef MACHINE_integratorcp
  51.     #include <arch/mach/integratorcp/integratorcp.h>
  52. #endif
  53.  
  54. /** Offset used in calculation of exception handler's relative address.
  55.  *
  56.  * @see install_handler()
  57.  */
  58. #define PREFETCH_OFFSET      0x8
  59.  
  60. /** LDR instruction's code */
  61. #define LDR_OPCODE           0xe59ff000
  62.  
  63. /** Number of exception vectors. */
  64. #define EXC_VECTORS          8
  65.  
  66. /** Size of memory block occupied by exception vectors. */
  67. #define EXC_VECTORS_SIZE     (EXC_VECTORS * 4)
  68.  
  69. /** Updates specified exception vector to jump to given handler.
  70.  *
  71.  *  Addresses of handlers are stored in memory following exception vectors.
  72.  */
  73. static void install_handler(unsigned handler_addr, unsigned *vector)
  74. {
  75.     /* relative address (related to exc. vector) of the word
  76.      * where handler's address is stored
  77.     */
  78.     volatile uint32_t handler_address_ptr = EXC_VECTORS_SIZE -
  79.         PREFETCH_OFFSET;
  80.    
  81.     /* make it LDR instruction and store at exception vector */
  82.     *vector = handler_address_ptr | LDR_OPCODE;
  83.     smc_coherence(*vector);
  84.    
  85.     /* store handler's address */
  86.     *(vector + EXC_VECTORS) = handler_addr;
  87.  
  88. }
  89.  
  90. /** Software Interrupt handler.
  91.  *
  92.  * Dispatches the syscall.
  93.  */
  94. static void swi_exception(int exc_no, istate_t *istate)
  95. {
  96.     istate->r0 = syscall_handler(istate->r0, istate->r1, istate->r2,
  97.         istate->r3, istate->r4, istate->r5, istate->r6);
  98. }
  99.  
  100. /** Fills exception vectors with appropriate exception handlers. */
  101. void install_exception_handlers(void)
  102. {
  103.     install_handler((unsigned) reset_exception_entry,
  104.         (unsigned *) EXC_RESET_VEC);
  105.    
  106.     install_handler((unsigned) undef_instr_exception_entry,
  107.         (unsigned *) EXC_UNDEF_INSTR_VEC);
  108.    
  109.     install_handler((unsigned) swi_exception_entry,
  110.         (unsigned *) EXC_SWI_VEC);
  111.    
  112.     install_handler((unsigned) prefetch_abort_exception_entry,
  113.         (unsigned *) EXC_PREFETCH_ABORT_VEC);
  114.    
  115.     install_handler((unsigned) data_abort_exception_entry,
  116.         (unsigned *) EXC_DATA_ABORT_VEC);
  117.    
  118.     install_handler((unsigned) irq_exception_entry,
  119.         (unsigned *) EXC_IRQ_VEC);
  120.    
  121.     install_handler((unsigned) fiq_exception_entry,
  122.         (unsigned *) EXC_FIQ_VEC);
  123. }
  124.  
  125. #ifdef HIGH_EXCEPTION_VECTORS
  126. /** Activates use of high exception vectors addresses. */
  127. static void high_vectors(void)
  128. {
  129.     uint32_t control_reg;
  130.    
  131.     asm volatile (
  132.         "mrc p15, 0, %[control_reg], c1, c1"
  133.         : [control_reg] "=r" (control_reg)
  134.     );
  135.    
  136.     /* switch on the high vectors bit */
  137.     control_reg |= CP15_R1_HIGH_VECTORS_BIT;
  138.    
  139.     asm volatile (
  140.         "mcr p15, 0, %[control_reg], c1, c1"
  141.         :: [control_reg] "r" (control_reg)
  142.     );
  143. }
  144. #endif
  145.  
  146. /** Interrupt Exception handler.
  147.  *
  148.  * Determines the sources of interrupt and calls their handlers.
  149.  */
  150. static void irq_exception(int exc_no, istate_t *istate)
  151. {
  152.     machine_irq_exception(exc_no, istate);
  153. }
  154.  
  155. /** Initializes exception handling.
  156.  *
  157.  * Installs low-level exception handlers and then registers
  158.  * exceptions and their handlers to kernel exception dispatcher.
  159.  */
  160. void exception_init(void)
  161. {
  162. #ifdef HIGH_EXCEPTION_VECTORS
  163.     high_vectors();
  164. #endif
  165.     install_exception_handlers();
  166.    
  167.     exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception);
  168.     exc_register(EXC_PREFETCH_ABORT, "prefetch abort",
  169.         (iroutine) prefetch_abort);
  170.     exc_register(EXC_DATA_ABORT, "data abort", (iroutine) data_abort);
  171.     exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception);
  172. }
  173.  
  174. /** Prints #istate_t structure content.
  175.  *
  176.  * @param istate Structure to be printed.
  177.  */
  178. void print_istate(istate_t *istate)
  179. {
  180.     printf("istate dump:\n");
  181.    
  182.     printf(" r0: %x    r1: %x    r2: %x    r3: %x\n",
  183.         istate->r0, istate->r1, istate->r2, istate->r3);
  184.     printf(" r4: %x    r5: %x    r6: %x    r7: %x\n",
  185.         istate->r4, istate->r5, istate->r6, istate->r7);
  186.     printf(" r8: %x    r8: %x   r10: %x   r11: %x\n",
  187.         istate->r8, istate->r9, istate->r10, istate->r11);
  188.     printf(" r12: %x    sp: %x    lr: %x  spsr: %x\n",
  189.         istate->r12, istate->sp, istate->lr, istate->spsr);
  190.    
  191.     printf(" pc: %x\n", istate->pc);
  192. }
  193.  
  194. /** @}
  195.  */
  196.