Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:25

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @addtogroup RTEMSScoreCPU
0007  *
0008  * @brief OR1K exception support implementation.
0009  */
0010 
0011 /*
0012  *  COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary@gmail.com>
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  *
0035  */
0036 
0037 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040 
0041 #include <rtems/asm.h>
0042 #include <rtems/score/percpu.h>
0043 #include "rtems/score/or1k-utility.h"
0044 
0045 .align 4
0046 .text
0047 PUBLIC(_ISR_Handler)
0048 .type    _ISR_Handler,@function
0049 
0050  SYM(_ISR_Handler):
0051 
0052   l.addi  r1, r1, -140
0053 
0054   l.sw  8(r1),r2
0055   /* r3 is saved by BSP exception handler */
0056   l.sw  16(r1),r4
0057   l.sw  20(r1),r5
0058   l.sw  24(r1),r6
0059   l.sw  28(r1),r7
0060   l.sw  32(r1),r8
0061   l.sw  36(r1),r9
0062   l.sw  40(r1),r10
0063   l.sw  44(r1),r11
0064   l.sw  48(r1),r12
0065   l.sw  52(r1),r13
0066   l.sw  56(r1),r14
0067   l.sw  60(r1),r15
0068   l.sw  64(r1),r16
0069   l.sw  68(r1),r17
0070   l.sw  72(r1),r18
0071   l.sw  76(r1),r19
0072   l.sw  80(r1),r20
0073   l.sw  84(r1),r21
0074   l.sw  88(r1),r22
0075   l.sw  92(r1),r23
0076   l.sw  96(r1),r24
0077   l.sw  100(r1),r25
0078   l.sw  104(r1),r26
0079   l.sw  108(r1),r27
0080   l.sw  112(r1),r28
0081   l.sw  116(r1),r29
0082   l.sw  120(r1),r30
0083   l.sw  124(r1),r31
0084 
0085   /* Exception level related registers */
0086 
0087   /* EPCR */
0088   l.mfspr r13, r0, CPU_OR1K_SPR_EPCR0
0089   l.sw  128(r1), r13 /* epcr */
0090 
0091   /* EEAR */
0092   l.mfspr r13, r0, CPU_OR1K_SPR_EEAR0
0093   l.sw  132(r1), r13 /* eear */
0094 
0095   /* ESR */
0096   l.mfspr r13, r0, CPU_OR1K_SPR_ESR0
0097   l.sw  136(r1), r13  /* esr */
0098 
0099   /* Increment nesting level */
0100   l.movhi r6, hi(ISR_NEST_LEVEL)
0101   l.ori   r6, r6, lo(ISR_NEST_LEVEL)
0102 
0103   /* Disable multitasking */
0104   l.movhi r8, hi(THREAD_DISPATCH_DISABLE_LEVEL)
0105   l.ori   r8, r8, lo(THREAD_DISPATCH_DISABLE_LEVEL)
0106 
0107   l.lwz   r5, 0(r6)
0108   l.lwz   r7, 0(r8)
0109   l.addi  r5, r5, 1
0110   l.addi  r7, r7, 1
0111   l.sw    0(r6), r5
0112   l.sw    0(r8), r7
0113 
0114   /* Save interrupted task stack pointer */
0115   l.addi r4, r1, 340
0116   l.sw   4(r1), r4
0117 
0118   /* Save interrupted task r3 (first arg) value */
0119   l.addi r4, r1, 140
0120   l.lwz  r4, 0(r4)
0121   l.sw  12(r1), r4
0122 
0123   /* Keep r1 (Exception frame address) in r14 */
0124   l.add   r14, r1, r0
0125 
0126   /* Call the exception handler from vector table */
0127 
0128   /* First function arg for C handler is vector number,
0129    * and the second is a pointer to exception frame.
0130    */
0131   l.add  r13, r3, r0
0132   l.add  r4, r1, r0
0133   l.slli r13, r13, 2
0134   l.addi r13, r13, lo(bsp_start_vector_table_begin)
0135   l.lwz  r13, 0(r13)
0136 
0137   /* Do not switch stacks if we are in a nested interrupt. At
0138    * this point r5 should be holding ISR_NEST_LEVEL value.
0139    */
0140   l.sfgtui r5, 1
0141   l.bf jump_to_c_handler
0142   l.nop
0143 
0144    /* Switch to RTEMS dedicated interrupt stack */
0145   l.movhi r1, hi(INTERRUPT_STACK_HIGH)
0146   l.ori   r1, r1, lo(INTERRUPT_STACK_HIGH)
0147   l.lwz   r1, 0(r1)
0148 
0149 jump_to_c_handler:
0150   l.jalr r13
0151   l.nop
0152 
0153   /* Switch back to the interrupted task stack */
0154   l.add r1, r14, r0
0155 
0156   /* Decrement nesting level */
0157   l.movhi r6, hi(ISR_NEST_LEVEL)
0158   l.ori   r6, r6, lo(ISR_NEST_LEVEL)
0159 
0160   /* Enable multitasking */
0161   l.movhi r8, hi(THREAD_DISPATCH_DISABLE_LEVEL)
0162   l.ori   r8, r8, lo(THREAD_DISPATCH_DISABLE_LEVEL)
0163 
0164   l.lwz   r5, 0(r6)
0165   l.lwz   r7, 0(r8)
0166   l.addi  r5, r5, -1
0167   l.addi  r7, r7, -1
0168   l.sw    0(r6), r5
0169   l.sw    0(r8), r7
0170 
0171   /* Check if _ISR_Nest_level > 0 */
0172   l.sfgtui r5, 0
0173   l.bf exception_frame_restore
0174   l.nop
0175 
0176   /* Check if _Thread_Dispatch_disable_level > 0 */
0177   l.sfgtui r7, 0
0178   l.bf exception_frame_restore
0179   l.nop
0180 
0181   /* Check if dispatch needed */
0182   l.movhi r31, hi(DISPATCH_NEEDED)
0183   l.ori   r31, r31, lo(DISPATCH_NEEDED)
0184   l.lwz   r31, 0(r31)
0185   l.sfeq  r31, r0
0186   l.bf    exception_frame_restore
0187   l.nop
0188 
0189   l.movhi r13, hi(_Thread_Dispatch)
0190   l.ori   r13, r13, lo(_Thread_Dispatch)
0191   l.jalr  r13
0192   l.nop
0193 
0194  SYM(exception_frame_restore):
0195 
0196   /* Exception level related registers */
0197 
0198   /* EPCR */
0199   l.lwz  r13,  128(r1)
0200   l.mtspr r0, r13, CPU_OR1K_SPR_EPCR0
0201 
0202   /* EEAR */
0203   l.lwz  r13,  132(r1)
0204   l.mtspr r0, r13, CPU_OR1K_SPR_EEAR0
0205 
0206   /* ESR */
0207   l.lwz  r13,  136(r1)
0208   l.mtspr r0, r13, CPU_OR1K_SPR_ESR0
0209 
0210   l.lwz  r2,  8(r1)
0211   l.lwz  r3,  12(r1)
0212   l.lwz  r4,  16(r1)
0213   l.lwz  r5,  20(r1)
0214   l.lwz  r6,  24(r1)
0215   l.lwz  r7,  28(r1)
0216   l.lwz  r8,  32(r1)
0217   l.lwz  r9,  36(r1)
0218   l.lwz  r10, 40(r1)
0219   l.lwz  r11, 44(r1)
0220   l.lwz  r12, 48(r1)
0221   l.lwz  r13, 52(r1)
0222   l.lwz  r14, 56(r1)
0223   l.lwz  r15, 60(r1)
0224   l.lwz  r16, 64(r1)
0225   l.lwz  r17, 68(r1)
0226   l.lwz  r18, 72(r1)
0227   l.lwz  r19, 76(r1)
0228   l.lwz  r20, 80(r1)
0229   l.lwz  r21, 84(r1)
0230   l.lwz  r22, 88(r1)
0231   l.lwz  r23, 92(r1)
0232   l.lwz  r24, 96(r1)
0233   l.lwz  r25, 100(r1)
0234   l.lwz  r26, 104(r1)
0235   l.lwz  r27, 108(r1)
0236   l.lwz  r28, 112(r1)
0237   l.lwz  r29, 116(r1)
0238   l.lwz  r30, 120(r1)
0239   l.lwz  r31, 124(r1)
0240 
0241   /* Unwind exception frame */
0242   l.addi r1, r1, 140
0243 
0244   /* Red-zone */
0245   l.addi r1, r1, 200
0246 
0247   l.rfe
0248   l.nop