forked from Imagelibrary/rtems
bsp/genmcf548x: Add interrupt extension support
This commit is contained in:
@@ -9,6 +9,12 @@ include_HEADERS += include/tm27.h
|
|||||||
|
|
||||||
nodist_include_HEADERS = include/bspopts.h
|
nodist_include_HEADERS = include/bspopts.h
|
||||||
nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
|
nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
|
||||||
|
|
||||||
|
include_bsp_HEADERS =
|
||||||
|
include_bsp_HEADERS += ../../shared/include/irq-generic.h
|
||||||
|
include_bsp_HEADERS += ../../shared/include/irq-info.h
|
||||||
|
include_bsp_HEADERS += include/irq.h
|
||||||
|
|
||||||
DISTCLEANFILES = include/bspopts.h
|
DISTCLEANFILES = include/bspopts.h
|
||||||
noinst_PROGRAMS =
|
noinst_PROGRAMS =
|
||||||
|
|
||||||
@@ -42,6 +48,14 @@ libbsp_a_SOURCES += console/console.c
|
|||||||
# timer
|
# timer
|
||||||
libbsp_a_SOURCES += timer/timer.c
|
libbsp_a_SOURCES += timer/timer.c
|
||||||
|
|
||||||
|
# IRQ
|
||||||
|
libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c
|
||||||
|
libbsp_a_SOURCES += ../../shared/src/irq-info.c
|
||||||
|
libbsp_a_SOURCES += ../../shared/src/irq-legacy.c
|
||||||
|
libbsp_a_SOURCES += ../../shared/src/irq-server.c
|
||||||
|
libbsp_a_SOURCES += ../../shared/src/irq-shell.c
|
||||||
|
libbsp_a_SOURCES += irq/irq.c
|
||||||
|
|
||||||
if HAS_NETWORKING
|
if HAS_NETWORKING
|
||||||
network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
|
network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
|
||||||
noinst_PROGRAMS += network.rel
|
noinst_PROGRAMS += network.rel
|
||||||
|
|||||||
79
c/src/lib/libbsp/m68k/genmcf548x/include/irq.h
Normal file
79
c/src/lib/libbsp/m68k/genmcf548x/include/irq.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBBSP_M68K_MCF548X_IRQ_H
|
||||||
|
#define LIBBSP_M68K_MCF548X_IRQ_H
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/irq.h>
|
||||||
|
#include <rtems/irq-extension.h>
|
||||||
|
|
||||||
|
#define MCF548X_IRQ_EPORT_EPF1 1
|
||||||
|
#define MCF548X_IRQ_EPORT_EPF2 2
|
||||||
|
#define MCF548X_IRQ_EPORT_EPF3 3
|
||||||
|
#define MCF548X_IRQ_EPORT_EPF4 4
|
||||||
|
#define MCF548X_IRQ_EPORT_EPF5 5
|
||||||
|
#define MCF548X_IRQ_EPORT_EPF6 6
|
||||||
|
#define MCF548X_IRQ_EPORT_EPF7 7
|
||||||
|
#define MCF548X_IRQ_USB_EP0ISR 15
|
||||||
|
#define MCF548X_IRQ_USB_EP1ISR 16
|
||||||
|
#define MCF548X_IRQ_USB_EP2ISR 17
|
||||||
|
#define MCF548X_IRQ_USB_EP3ISR 18
|
||||||
|
#define MCF548X_IRQ_USB_EP4ISR 19
|
||||||
|
#define MCF548X_IRQ_USB_EP5ISR 20
|
||||||
|
#define MCF548X_IRQ_USB_EP6ISR 21
|
||||||
|
#define MCF548X_IRQ_USB_ISR 22
|
||||||
|
#define MCF548X_IRQ_USB_AISR 23
|
||||||
|
#define MCF548X_IRQ_DSPI_RFOF_TFUF 25
|
||||||
|
#define MCF548X_IRQ_DSPI_RFOF 26
|
||||||
|
#define MCF548X_IRQ_DSPI_RFDF 27
|
||||||
|
#define MCF548X_IRQ_DSPI_TFUF 28
|
||||||
|
#define MCF548X_IRQ_DSPI_TCF 29
|
||||||
|
#define MCF548X_IRQ_DSPI_TFFF 30
|
||||||
|
#define MCF548X_IRQ_DSPI_EOQF 31
|
||||||
|
#define MCF548X_IRQ_DSPI 25
|
||||||
|
#define MCF548X_IRQ_PSC3 32
|
||||||
|
#define MCF548X_IRQ_PSC2 33
|
||||||
|
#define MCF548X_IRQ_PSC1 34
|
||||||
|
#define MCF548X_IRQ_PSC0 35
|
||||||
|
#define MCF548X_IRQ_PSC(i) (35 - (i))
|
||||||
|
#define MCF548X_IRQ_COMMTIM 36
|
||||||
|
#define MCF548X_IRQ_SEC 37
|
||||||
|
#define MCF548X_IRQ_FEC1 38
|
||||||
|
#define MCF548X_IRQ_FEC0 39
|
||||||
|
#define MCF548X_IRQ_FEC(i) (39 - (i))
|
||||||
|
#define MCF548X_IRQ_I2C 40
|
||||||
|
#define MCF548X_IRQ_PCIARB 41
|
||||||
|
#define MCF548X_IRQ_CBPCI 42
|
||||||
|
#define MCF548X_IRQ_XLBPCI 43
|
||||||
|
#define MCF548X_IRQ_XLBARB 47
|
||||||
|
#define MCF548X_IRQ_DMA 48
|
||||||
|
#define MCF548X_IRQ_CAN0_ERROR 49
|
||||||
|
#define MCF548X_IRQ_CAN0_BUSOFF 50
|
||||||
|
#define MCF548X_IRQ_CAN0_MBOR 51
|
||||||
|
#define MCF548X_IRQ_SLT1 53
|
||||||
|
#define MCF548X_IRQ_SLT0 54
|
||||||
|
#define MCF548X_IRQ_CAN1_ERROR 55
|
||||||
|
#define MCF548X_IRQ_CAN1_BUSOFF 56
|
||||||
|
#define MCF548X_IRQ_CAN1_MBOR 57
|
||||||
|
#define MCF548X_IRQ_GPT3 59
|
||||||
|
#define MCF548X_IRQ_GPT2 60
|
||||||
|
#define MCF548X_IRQ_GPT1 61
|
||||||
|
#define MCF548X_IRQ_GPT0 62
|
||||||
|
|
||||||
|
#define BSP_INTERRUPT_VECTOR_MIN 1
|
||||||
|
|
||||||
|
#define BSP_INTERRUPT_VECTOR_MAX 63
|
||||||
|
|
||||||
|
#endif /* LIBBSP_M68K_MCF548X_IRQ_H */
|
||||||
235
c/src/lib/libbsp/m68k/genmcf548x/irq/irq.c
Normal file
235
c/src/lib/libbsp/m68k/genmcf548x/irq/irq.c
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bsp/irq-generic.h>
|
||||||
|
|
||||||
|
#include <mcf548x/mcf548x.h>
|
||||||
|
|
||||||
|
void asm_default_interrupt(void);
|
||||||
|
|
||||||
|
typedef void (*void_func)(void);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rtems_interrupt_handler handler;
|
||||||
|
void *arg;
|
||||||
|
const char *info;
|
||||||
|
} interrupt_control;
|
||||||
|
|
||||||
|
static interrupt_control interrupt_controls[BSP_INTERRUPT_VECTOR_MAX + 1];
|
||||||
|
|
||||||
|
static uint32_t vector_to_reg(rtems_vector_number vector)
|
||||||
|
{
|
||||||
|
return ((vector + 32U) >> 5) & 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t vector_to_bit(rtems_vector_number vector)
|
||||||
|
{
|
||||||
|
return 1U << (vector & 0x1fU);
|
||||||
|
}
|
||||||
|
|
||||||
|
static volatile uint32_t *vector_to_imr(rtems_vector_number vector)
|
||||||
|
{
|
||||||
|
volatile uint32_t *imr = &MCF548X_INTC_IMRH;
|
||||||
|
|
||||||
|
return &imr[vector_to_reg(vector)];
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtems_vector_number exception_vector_to_vector(
|
||||||
|
rtems_vector_number exception_vector
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return exception_vector - 64U;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtems_vector_number vector_to_exception_vector(
|
||||||
|
rtems_vector_number vector
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return vector + 64U;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
|
||||||
|
if (bsp_interrupt_is_valid_vector(vector)) {
|
||||||
|
volatile uint32_t *imr = vector_to_imr(vector);
|
||||||
|
uint32_t bit = vector_to_bit(vector);
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
*imr &= ~bit;
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
} else {
|
||||||
|
sc = RTEMS_INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
|
||||||
|
if (bsp_interrupt_is_valid_vector(vector)) {
|
||||||
|
volatile uint32_t *imr = vector_to_imr(vector);
|
||||||
|
uint32_t bit = vector_to_bit(vector);
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
*imr |= bit;
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
} else {
|
||||||
|
sc = RTEMS_INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void_func get_exception_handler(rtems_vector_number vector)
|
||||||
|
{
|
||||||
|
void_func *exception_table;
|
||||||
|
|
||||||
|
m68k_get_vbr(exception_table);
|
||||||
|
|
||||||
|
return exception_table[vector_to_exception_vector(vector)];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_exception_handler(rtems_vector_number vector, void_func handler)
|
||||||
|
{
|
||||||
|
void_func *exception_table;
|
||||||
|
|
||||||
|
m68k_get_vbr(exception_table);
|
||||||
|
|
||||||
|
exception_table[vector_to_exception_vector(vector)] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dispatch_handler(rtems_vector_number exception_vector)
|
||||||
|
{
|
||||||
|
const interrupt_control *ic =
|
||||||
|
&interrupt_controls[exception_vector_to_vector(exception_vector)];
|
||||||
|
|
||||||
|
(*ic->handler)(ic->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t get_intc_icr(rtems_vector_number vector)
|
||||||
|
{
|
||||||
|
volatile uint8_t *icr = &MCF548X_INTC_ICR0;
|
||||||
|
|
||||||
|
return icr[vector];
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_status_code rtems_interrupt_handler_install(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
const char *info,
|
||||||
|
rtems_option options,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
|
||||||
|
if (bsp_interrupt_is_valid_vector(vector)) {
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
|
||||||
|
if (
|
||||||
|
get_exception_handler(vector) == asm_default_interrupt
|
||||||
|
&& get_intc_icr(vector) != 0
|
||||||
|
) {
|
||||||
|
interrupt_control *ic = &interrupt_controls[vector];
|
||||||
|
|
||||||
|
ic->handler = handler;
|
||||||
|
ic->arg = arg;
|
||||||
|
ic->info = info;
|
||||||
|
|
||||||
|
_ISR_Vector_table[vector_to_exception_vector(vector)]
|
||||||
|
= dispatch_handler;
|
||||||
|
set_exception_handler(vector, _ISR_Handler);
|
||||||
|
bsp_interrupt_vector_enable(vector);
|
||||||
|
} else {
|
||||||
|
sc = RTEMS_RESOURCE_IN_USE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
} else {
|
||||||
|
sc = RTEMS_INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_occupied_by_us(rtems_vector_number vector)
|
||||||
|
{
|
||||||
|
return get_exception_handler(vector) == _ISR_Handler
|
||||||
|
&& _ISR_Vector_table[vector_to_exception_vector(vector)]
|
||||||
|
== dispatch_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_status_code rtems_interrupt_handler_remove(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
|
||||||
|
if (bsp_interrupt_is_valid_vector(vector)) {
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
interrupt_control *ic = &interrupt_controls[vector];
|
||||||
|
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
|
||||||
|
if (
|
||||||
|
is_occupied_by_us(vector)
|
||||||
|
&& ic->handler == handler
|
||||||
|
&& ic->arg == arg
|
||||||
|
) {
|
||||||
|
bsp_interrupt_vector_disable(vector);
|
||||||
|
set_exception_handler(vector, asm_default_interrupt);
|
||||||
|
|
||||||
|
memset(ic, 0, sizeof(*ic));
|
||||||
|
} else {
|
||||||
|
sc = RTEMS_UNSATISFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
} else {
|
||||||
|
sc = RTEMS_INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_status_code rtems_interrupt_handler_iterate(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
rtems_interrupt_per_handler_routine routine,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
|
||||||
|
if (bsp_interrupt_is_valid_vector(vector)) {
|
||||||
|
if (is_occupied_by_us(vector)) {
|
||||||
|
const interrupt_control *ic = &interrupt_controls[vector];
|
||||||
|
|
||||||
|
(*routine)(arg, ic->info, RTEMS_INTERRUPT_UNIQUE, ic->handler, ic->arg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sc = RTEMS_INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
@@ -49,6 +49,18 @@ $(PROJECT_INCLUDE)/bsp/bootcard.h: ../../shared/include/bootcard.h $(PROJECT_INC
|
|||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
|
$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
|
||||||
|
|||||||
Reference in New Issue
Block a user