/*
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 * Copyright (C) 2015-2019 Cadence Design Systems, Inc.
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * https://www.FreeRTOS.org
 * https://github.com/FreeRTOS
 *
 */

/*
 * Xtensa-specific interrupt and exception functions for RTOS ports.
 * Also see xtensa_intr_asm.S.
 */

#include <stdlib.h>

#include <xtensa/config/core.h>

#include "xtensa_api.h"


#if XCHAL_HAVE_EXCEPTIONS

/* Handler table is in xtensa_intr_asm.S */

    extern xt_exc_handler _xt_exception_table[ XCHAL_EXCCAUSE_NUM ];


/*
 * Default handler for unhandled exceptions.
 */
    void xt_unhandled_exception( XtExcFrame * frame )
    {
        exit( -1 );
    }


/*
 * This function registers a handler for the specified exception.
 * The function returns the address of the previous handler.
 * On error, it returns 0.
 */
    xt_exc_handler xt_set_exception_handler( int n,
                                             xt_exc_handler f )
    {
        xt_exc_handler old;

        if( ( n < 0 ) || ( n >= XCHAL_EXCCAUSE_NUM ) )
        {
            return 0; /* invalid exception number */
        }

        old = _xt_exception_table[ n ];

        if( f )
        {
            _xt_exception_table[ n ] = f;
        }
        else
        {
            _xt_exception_table[ n ] = &xt_unhandled_exception;
        }

        return( ( old == &xt_unhandled_exception ) ? 0 : old );
    }

#endif /* if XCHAL_HAVE_EXCEPTIONS */

#if XCHAL_HAVE_INTERRUPTS

/* Handler table is in xtensa_intr_asm.S */

    typedef struct xt_handler_table_entry
    {
        void * handler;
        void * arg;
    } xt_handler_table_entry;

    extern xt_handler_table_entry _xt_interrupt_table[ XCHAL_NUM_INTERRUPTS ];


/*
 * Default handler for unhandled interrupts.
 */
    void xt_unhandled_interrupt( void * arg )
    {
        exit( -1 );
    }


/*
 * This function registers a handler for the specified interrupt. The "arg"
 * parameter specifies the argument to be passed to the handler when it is
 * invoked. The function returns the address of the previous handler.
 * On error, it returns 0.
 */
    xt_handler xt_set_interrupt_handler( int n,
                                         xt_handler f,
                                         void * arg )
    {
        xt_handler_table_entry * entry;
        xt_handler old;

        if( ( n < 0 ) || ( n >= XCHAL_NUM_INTERRUPTS ) )
        {
            return 0; /* invalid interrupt number */
        }

        if( Xthal_intlevel[ n ] > XCHAL_EXCM_LEVEL )
        {
            return 0; /* priority level too high to safely handle in C */
        }

        entry = _xt_interrupt_table + n;
        old = entry->handler;

        if( f )
        {
            entry->handler = f;
            entry->arg = arg;
        }
        else
        {
            entry->handler = &xt_unhandled_interrupt;
            entry->arg = ( void * ) n;
        }

        return( ( old == &xt_unhandled_interrupt ) ? 0 : old );
    }


#endif /* XCHAL_HAVE_INTERRUPTS */
