Converted to use shared

exception and interrupt code.
This commit is contained in:
Thomas Doerfler
2008-09-03 15:39:03 +00:00
parent 9ac98838d6
commit 82bd8d9d66
15 changed files with 685 additions and 863 deletions

View File

@@ -19,7 +19,7 @@
#include <rtems.h> #include <rtems.h>
#include <rtems/error.h> #include <rtems/error.h>
#include <bsp.h> #include <bsp.h>
#include "../irq/irq.h" #include <bsp/irq.h>
#include "../include/mpc5200.h" #include "../include/mpc5200.h"
#include "include/ppctypes.h" /* uint32, et. al. */ #include "include/ppctypes.h" /* uint32, et. al. */
#include "dma_image.h" #include "dma_image.h"

View File

@@ -39,7 +39,7 @@ __declspec(section ".text") extern const uint32 taskTableBytes;
__declspec(section ".text") extern const uint32 taskTableTasks; __declspec(section ".text") extern const uint32 taskTableTasks;
__declspec(section ".text") extern const uint32 offsetEntry; __declspec(section ".text") extern const uint32 offsetEntry;
#else #else
extern const uint32 taskTable; extern const uint32 taskTable [];
extern const uint32 taskTableBytes; extern const uint32 taskTableBytes;
extern const uint32 taskTableTasks; extern const uint32 taskTableTasks;
extern const uint32 offsetEntry; extern const uint32 offsetEntry;
@@ -71,7 +71,7 @@ void TasksLoadImage(sdma_regs *sdma)
SCTDT_T *tt; SCTDT_T *tt;
/* copy task table from source to destination */ /* copy task table from source to destination */
memcpy((void *)((uint8 *)(sdma->taskBar) - MBarPhysOffsetGlobal), &taskTable, taskTableBytes); memcpy((void *)((uint8 *)(sdma->taskBar) - MBarPhysOffsetGlobal), taskTable, taskTableBytes);
/* adjust addresses in task table */ /* adjust addresses in task table */
for (i=0; i < (uint32) taskTableTasks; i++) { for (i=0; i < (uint32) taskTableTasks; i++) {
tt = (SCTDT_T *)(((uint8 *)(sdma->taskBar) - MBarPhysOffsetGlobal) + (uint32) offsetEntry + (i * sizeof (SCTDT_T))); tt = (SCTDT_T *)(((uint8 *)(sdma->taskBar) - MBarPhysOffsetGlobal) + (uint32) offsetEntry + (i * sizeof (SCTDT_T)));

View File

@@ -103,7 +103,7 @@
#include <bsp.h> #include <bsp.h>
#include <rtems/bspIo.h> #include <rtems/bspIo.h>
#include "../irq/irq.h" #include <bsp/irq.h>
#include <rtems.h> #include <rtems.h>
#include <rtems/clockdrv.h> #include <rtems/clockdrv.h>
@@ -114,6 +114,8 @@
#define GPT (BSP_PERIODIC_TIMER - BSP_SIU_IRQ_TMR0) #define GPT (BSP_PERIODIC_TIMER - BSP_SIU_IRQ_TMR0)
extern uint32_t bsp_clicks_per_usec;
/* this lets us do nanoseconds since last tick */ /* this lets us do nanoseconds since last tick */
uint64_t Clock_last_TBR; uint64_t Clock_last_TBR;
volatile uint32_t counter_value; volatile uint32_t counter_value;
@@ -122,7 +124,7 @@ volatile int ClockInitialized = 0;
/* /*
* ISR Handlers * ISR Handlers
*/ */
void mpc5200_gpt_clock_isr(rtems_irq_hdl_param handle) void mpc5200_gpt_clock_isr(rtems_vector_number vector, void *handle)
{ {
uint32_t status; uint32_t status;
struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)handle; struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)handle;
@@ -218,45 +220,32 @@ uint32_t mpc5200_check_gpt_status(uint32_t gpt_no)
return ((gpt->emsel) & (GPT_EMSEL_CE | GPT_EMSEL_INTEN)); return ((gpt->emsel) & (GPT_EMSEL_CE | GPT_EMSEL_INTEN));
} }
void clockOn(const rtems_irq_connect_data* irq) void clockOn()
{ {
uint32_t gpt_no; uint32_t gpt_no;
extern uint32_t bsp_clicks_per_usec;
gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name); gpt_no = BSP_SIU_IRQ_TMR0 - BSP_PERIODIC_TIMER;
counter_value = rtems_configuration_get_microseconds_per_tick() * counter_value = rtems_configuration_get_microseconds_per_tick() *
bsp_clicks_per_usec; bsp_clicks_per_usec;
mpc5200_set_gpt_count(counter_value, (uint32_t)gpt_no); mpc5200_set_gpt_count(counter_value, gpt_no);
mpc5200_enable_gpt_int((uint32_t)gpt_no); mpc5200_enable_gpt_int(gpt_no);
ClockInitialized = 1; ClockInitialized = 1;
} }
void clockOff(const rtems_irq_connect_data* irq) void clockOff()
{ {
uint32_t gpt_no; uint32_t gpt_no;
gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name); gpt_no = BSP_SIU_IRQ_TMR0 - BSP_PERIODIC_TIMER;
mpc5200_disable_gpt_int((uint32_t)gpt_no); mpc5200_disable_gpt_int(gpt_no);
ClockInitialized = 0; ClockInitialized = 0;
} }
int clockIsOn(const rtems_irq_connect_data* irq)
{
uint32_t gpt_no;
gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name);
if (mpc5200_check_gpt_status(gpt_no) && ClockInitialized)
return ClockInitialized;
return 0;
}
int BSP_get_clock_irq_level(void) int BSP_get_clock_irq_level(void)
{ {
/* /*
@@ -266,56 +255,51 @@ int BSP_get_clock_irq_level(void)
return BSP_PERIODIC_TIMER; return BSP_PERIODIC_TIMER;
} }
int BSP_disconnect_clock_handler (unsigned gpt_no)
int BSP_disconnect_clock_handler (void)
{ {
rtems_irq_connect_data clockIrqData; rtems_status_code sc = RTEMS_SUCCESSFUL;
clockIrqData.name = BSP_PERIODIC_TIMER;
if ((gpt_no < GPT0) || (gpt_no > GPT7)) {
if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) { return 0;
printk("Unable to stop system clock\n");
rtems_fatal_error_occurred(1);
} }
return BSP_remove_rtems_irq_handler (&clockIrqData); clockOff( BSP_PERIODIC_TIMER);
sc = rtems_interrupt_handler_remove(
BSP_PERIODIC_TIMER,
mpc5200_gpt_clock_isr,
&mpc5200.gpt [gpt_no]
);
if (sc != RTEMS_SUCCESSFUL) {
return 0;
} }
return 1;
}
int BSP_connect_clock_handler (uint32_t gpt_no) int BSP_connect_clock_handler (unsigned gpt_no)
{ {
rtems_irq_hdl hdl = 0; rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_irq_connect_data clockIrqData;
/* if ((gpt_no < GPT0) || (gpt_no > GPT7)) {
* Reinit structure
*/
clockIrqData.name = BSP_PERIODIC_TIMER;
if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
printk("Unable to get system clock handler\n");
rtems_fatal_error_occurred(1);
}
if (!BSP_remove_rtems_irq_handler (&clockIrqData)) {
printk("Unable to remove current system clock handler\n");
rtems_fatal_error_occurred(1);
}
if ((gpt_no >= GPT0) || (gpt_no <= GPT7)) {
hdl = (rtems_irq_hdl_param )&mpc5200.gpt[gpt_no];
} else {
printk("Unable to set system clock handler\n"); printk("Unable to set system clock handler\n");
rtems_fatal_error_occurred(1); rtems_fatal_error_occurred(1);
} }
clockIrqData.hdl = mpc5200_gpt_clock_isr; sc = rtems_interrupt_handler_install(
clockIrqData.handle = (rtems_irq_hdl_param) hdl; BSP_PERIODIC_TIMER,
clockIrqData.on = clockOn; "Clock",
clockIrqData.off = clockOff; RTEMS_INTERRUPT_UNIQUE,
clockIrqData.isOn = clockIsOn; mpc5200_gpt_clock_isr,
&mpc5200.gpt [gpt_no]
);
if (sc != RTEMS_SUCCESSFUL) {
return 0;
}
return BSP_install_rtems_irq_handler (&clockIrqData); clockOn();
return 1;
} }
#define CLOCK_VECTOR 0 #define CLOCK_VECTOR 0
@@ -342,7 +326,6 @@ int BSP_connect_clock_handler (uint32_t gpt_no)
/* This driver does this in clockOn called at connection time */ /* This driver does this in clockOn called at connection time */
#define Clock_driver_support_initialize_hardware() \ #define Clock_driver_support_initialize_hardware() \
do { \ do { \
extern uint32_t bsp_clicks_per_usec; \
counter_value = rtems_configuration_get_microseconds_per_tick() * \ counter_value = rtems_configuration_get_microseconds_per_tick() * \
bsp_clicks_per_usec; \ bsp_clicks_per_usec; \
mpc5200_init_gpt(GPT); \ mpc5200_init_gpt(GPT); \
@@ -354,7 +337,7 @@ int BSP_connect_clock_handler (uint32_t gpt_no)
#define Clock_driver_support_shutdown_hardware() \ #define Clock_driver_support_shutdown_hardware() \
do { \ do { \
(void) BSP_disconnect_clock_handler (); \ (void) BSP_disconnect_clock_handler (GPT); \
} while (0) } while (0)
#include "../../../shared/clockdrv_shell.c" #include "../../../shared/clockdrv_shell.c"

View File

@@ -98,7 +98,7 @@
#include <rtems.h> #include <rtems.h>
#include "../include/mpc5200.h" #include "../include/mpc5200.h"
#include <bsp.h> #include <bsp.h>
#include "../irq/irq.h" #include <bsp/irq.h>
#include <rtems/bspIo.h> #include <rtems/bspIo.h>
#include <rtems/libio.h> #include <rtems/libio.h>

View File

@@ -34,7 +34,7 @@
*/ */
#include "mpc5200mbus.h" #include "mpc5200mbus.h"
#include "../include/mpc5200.h" #include "../include/mpc5200.h"
#include "../irq/irq.h" #include <bsp/irq.h>
#include "../include/i2c.h" #include "../include/i2c.h"
/* Events of I2C machine */ /* Events of I2C machine */

View File

@@ -18,7 +18,7 @@
\*===============================================================*/ \*===============================================================*/
#include <rtems.h> #include <rtems.h>
#include <bsp.h> #include <bsp.h>
#include "../irq/irq.h" #include <bsp/irq.h>
#include "../include/mpc5200.h" #include "../include/mpc5200.h"
#include "./pcmcia_ide.h" #include "./pcmcia_ide.h"

View File

@@ -78,7 +78,7 @@
#include <rtems.h> #include <rtems.h>
#include <rtems/error.h> #include <rtems/error.h>
#include <bsp.h> #include <bsp.h>
#include "../irq/irq.h" #include <bsp/irq.h>
#include "../include/mpc5200.h" #include "../include/mpc5200.h"
#include "./pcmcia_ide.h" #include "./pcmcia_ide.h"

View File

@@ -23,6 +23,44 @@
#ifndef __GEN5200_BSP_h #ifndef __GEN5200_BSP_h
#define __GEN5200_BSP_h #define __GEN5200_BSP_h
#include <libcpu/powerpc-utility.h>
/*
* Some symbols defined in the linker command file.
*/
LINKER_SYMBOL(bsp_ram_start);
LINKER_SYMBOL(bsp_ram_end);
LINKER_SYMBOL(bsp_ram_size);
LINKER_SYMBOL(bsp_rom_start);
LINKER_SYMBOL(bsp_rom_end);
LINKER_SYMBOL(bsp_rom_size);
LINKER_SYMBOL(bsp_dpram_start);
LINKER_SYMBOL(bsp_dpram_end);
LINKER_SYMBOL(bsp_dpram_size);
LINKER_SYMBOL(bsp_section_text_start);
LINKER_SYMBOL(bsp_section_text_end);
LINKER_SYMBOL(bsp_section_text_size);
LINKER_SYMBOL(bsp_section_data_start);
LINKER_SYMBOL(bsp_section_data_end);
LINKER_SYMBOL(bsp_section_data_size);
LINKER_SYMBOL(bsp_section_bss_start);
LINKER_SYMBOL(bsp_section_bss_end);
LINKER_SYMBOL(bsp_section_bss_size);
LINKER_SYMBOL(bsp_interrupt_stack_start);
LINKER_SYMBOL(bsp_interrupt_stack_end);
LINKER_SYMBOL(bsp_interrupt_stack_size);
LINKER_SYMBOL(bsp_work_area_start);
LINKER_SYMBOL(MBAR);
/* /*
* distinguish board characteristics * distinguish board characteristics
*/ */
@@ -56,27 +94,6 @@
#define GPIOPCR_INITVAL 0x91050444 #define GPIOPCR_INITVAL 0x91050444
/* we have PSC1/2/3 */ /* we have PSC1/2/3 */
#define GEN5200_UART_AVAIL_MASK 0x07 #define GEN5200_UART_AVAIL_MASK 0x07
/*
* address range definitions
*/
/* ROM definitions (2 MB) */
#define ROM_START 0xFFE00000
#define ROM_SIZE 0x00200000
#define ROM_END (ROM_START+ROM_SIZE-1)
#define BOOT_START ROM_START
#define BOOT_END ROM_END
/* SDRAM definitions (256 MB) */
#define RAM_START 0x00000000
#define RAM_SIZE 0x10000000
#define RAM_END (RAM_START+RAM_SIZE-1)
/* DPRAM definitions (64 KB) */
#define DPRAM_START 0xFF000000
#define DPRAM_END 0xFF0003FF
/* internal memory map definitions (64 KB) */
#define MBAR 0xF0000000
/* we need the low level initialization in start.S*/ /* we need the low level initialization in start.S*/
#define NEED_LOW_LEVEL_INIT #define NEED_LOW_LEVEL_INIT
@@ -84,10 +101,6 @@
#define HAS_NVRAM_93CXX #define HAS_NVRAM_93CXX
#elif defined (PM520) #elif defined (PM520)
/*
* MicroSys PM520 internal memory map definitions
*/
#define MBAR 0xF0000000
#define HAS_UBOOT #define HAS_UBOOT
#elif defined (icecube) #elif defined (icecube)
@@ -107,8 +120,6 @@
/* we only have PSC1 */ /* we only have PSC1 */
#define GEN5200_UART_AVAIL_MASK 0x01 #define GEN5200_UART_AVAIL_MASK 0x01
#define MBAR 0xF0000000
/* We want to prompt for a reset and then reset the board */ /* We want to prompt for a reset and then reset the board */
#define BSP_PRESS_KEY_FOR_RESET 1 #define BSP_PRESS_KEY_FOR_RESET 1
#define BSP_RESET_BOARD_AT_EXIT 1 #define BSP_RESET_BOARD_AT_EXIT 1
@@ -269,6 +280,8 @@ void BSP_IRQ_Benchmarking_Report(void);
); );
#endif #endif
void cpu_init(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -73,37 +73,24 @@
/* */ /* */
/***********************************************************************/ /***********************************************************************/
#include <bsp.h>
#include <rtems.h> #include <rtems.h>
#include "../irq/irq.h"
#include <rtems/score/apiext.h> #include <libcpu/powerpc-utility.h>
#include <rtems/bspIo.h>
#include <libcpu/raw_exception.h> #include <libcpu/raw_exception.h>
#include "../vectors/vectors.h"
#include "../include/mpc5200.h"
#include <bsp.h>
extern uint32_t irqMaskTable[]; #include <bsp/irq.h>
#include <bsp/vectors.h>
/* #include <bsp/ppc_exc_bspsupp.h>
* default handler connected on each irq after bsp initialization #include <bsp/irq-generic.h>
*/ #include <bsp/mpc5200.h>
static rtems_irq_connect_data default_rtems_entry;
/*
* location used to store initial tables used for interrupt
* management.
*/
static rtems_irq_global_settings* internal_config;
static rtems_irq_connect_data* rtems_hdl_tbl;
/* /*
* bit in the SIU mask registers (PPC bit numbering) that should * bit in the SIU mask registers (PPC bit numbering) that should
* be set to enable the relevant interrupt, mask of 32 is for unused entries * be set to enable the relevant interrupt, mask of 32 is for unused entries
* *
*/ */
const static unsigned int SIU_MaskBit[BSP_SIU_IRQ_NUMBER] = const static unsigned int SIU_MaskBit [BSP_SIU_IRQ_NUMBER] = {
{
0, 1, 2, 3, /* smart_comm, psc1, psc2, psc3 */ 0, 1, 2, 3, /* smart_comm, psc1, psc2, psc3 */
4, 5, 6, 7, /* irda/psc6, eth, usb, ata */ 4, 5, 6, 7, /* irda/psc6, eth, usb, ata */
8, 9, 10, 11, /* pci_ctrl, pci_sc_rx, pci_sc_tx, psc4 */ 8, 9, 10, 11, /* pci_ctrl, pci_sc_rx, pci_sc_tx, psc4 */
@@ -117,54 +104,79 @@ const static unsigned int SIU_MaskBit[BSP_SIU_IRQ_NUMBER] =
32, 32, 32 /* res, res, res */ 32, 32, 32 /* res, res, res */
}; };
static unsigned char irqPrioTable [BSP_SIU_IRQ_NUMBER] = {
/* per. int. priorities (0-7) / 4bit coding / msb is HI/LO selection */
/* msb = 0 -> non-critical per. int. is routed to main int. (LO_int) */
/* msb = 1 -> critical per. int. is routed to critical int. (HI_int) */
0xF, 0, 0, 0, /* smart_comm (do not change!), psc1, psc2, psc3 */
0, 0, 0, 0, /* irda, eth, usb, ata */
0, 0, 0, 0, /* pci_ctrl, pci_sc_rx, pci_sc_tx, res */
0, 0, 0, 0, /* res, spi_modf, spi_spif, i2c1 */
0, 0, 0, 0, /* i2c, can1, can2, ir_rx */
0, 0, /* ir_rx, xlb_arb */
/* main interrupt priorities (0-7) / 4bit coding / msb is INT/SMI selection */
/* msb = 0 -> main int. is routed to processor INT (low vector base 0x500 ) */
/* msb = 1 -> main int. is routed to processor SMI (low vector base 0x1400 ) */
0, 0, /* slice_tim2, irq1 */
0, 0, 0, 0, /* irq2, irq3, lo_int, rtc_pint */
0, 0, 0, 0, /* rtc_sint, gpio_std, gpio_wkup, tmr0 */
0, 0, 0, 0, /* tmr1, tmr2, tmr3, tmr4 */
0, 0, 0, /* tmr5, tmr6, tmr7 */
/* critical interrupt priorities (0-3) / 2bit coding / no special purpose of msb */
0, /* irq0 */
0, 0, 0 /* slice_tim1, hi_int, ccs_wkup */
};
static uint32_t irqMaskTable [BSP_PER_IRQ_NUMBER + BSP_MAIN_IRQ_NUMBER];
/* /*
* Check if symbolic IRQ name is a Processor IRQ * Check if symbolic IRQ name is a Processor IRQ
*/ */
static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine) static inline bool is_processor_irq( rtems_vector_number irqLine)
{ {
return (((int)irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) & return ((irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET)
((int)irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)); && (irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET));
} }
/* /*
* Check for SIU IRQ and return base index * Check for SIU IRQ and return base index
*/ */
static inline int is_siu_irq(const rtems_irq_symbolic_name irqLine) static inline bool is_siu_irq( rtems_vector_number irqLine)
{ {
return (((int)irqLine <= BSP_SIU_IRQ_MAX_OFFSET) && return ((irqLine <= BSP_SIU_IRQ_MAX_OFFSET)
((int)irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET)); && (irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET));
} }
/* /*
* Check for SIU IRQ and return base index * Check for SIU IRQ and return base index
*/ */
static inline int get_siu_irq_base_index(const rtems_irq_symbolic_name irqLine) static inline int get_siu_irq_base_index( rtems_vector_number irqLine)
{ {
if (irqLine <= BSP_PER_IRQ_MAX_OFFSET) if (irqLine <= BSP_PER_IRQ_MAX_OFFSET)
return BSP_PER_IRQ_LOWEST_OFFSET; return BSP_PER_IRQ_LOWEST_OFFSET;
if (irqLine <= BSP_MAIN_IRQ_MAX_OFFSET) if (irqLine <= BSP_MAIN_IRQ_MAX_OFFSET)
return BSP_MAIN_IRQ_LOWEST_OFFSET; return BSP_MAIN_IRQ_LOWEST_OFFSET;
if (irqLine <= BSP_CRIT_IRQ_MAX_OFFSET) if (irqLine <= BSP_CRIT_IRQ_MAX_OFFSET)
return BSP_CRIT_IRQ_LOWEST_OFFSET; return BSP_CRIT_IRQ_LOWEST_OFFSET;
return -1; return -1;
} }
static inline void BSP_enable_per_irq_at_siu( static inline void BSP_enable_per_irq_at_siu(
const rtems_irq_symbolic_name irqLine rtems_vector_number irqLine
) )
{ {
uint8_t lo_hi_ind = 0, prio_index_offset; uint8_t lo_hi_ind = 0,
prio_index_offset;
uint32_t *reg; uint32_t *reg;
rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl; volatile uint32_t per_pri_1,
volatile uint32_t per_pri_1,main_pri_1, crit_pri_main_mask, per_mask; main_pri_1,
crit_pri_main_mask,
per_mask;
/* calculate the index offset of priority value bit field */ /* calculate the index offset of priority value bit field */
prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8; prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8;
@@ -210,7 +222,6 @@ static inline void BSP_enable_per_irq_at_siu(
~(0x80000000 >> SIU_MaskBit [BSP_SIU_IRQ_LO_INT]); ~(0x80000000 >> SIU_MaskBit [BSP_SIU_IRQ_LO_INT]);
} }
/* enable (unmask) peripheral interrupt */ /* enable (unmask) peripheral interrupt */
mpc5200.per_mask &= ~(0x80000000 >> SIU_MaskBit [irqLine]); mpc5200.per_mask &= ~(0x80000000 >> SIU_MaskBit [irqLine]);
@@ -219,18 +230,15 @@ static inline void BSP_enable_per_irq_at_siu(
per_pri_1 = mpc5200.per_pri_1; per_pri_1 = mpc5200.per_pri_1;
per_mask = mpc5200.per_mask; per_mask = mpc5200.per_mask;
} }
static inline void BSP_enable_main_irq_at_siu( static inline void BSP_enable_main_irq_at_siu(
const rtems_irq_symbolic_name irqLine rtems_vector_number irqLine
) )
{ {
uint8_t prio_index_offset; uint8_t prio_index_offset;
uint32_t *reg; uint32_t *reg;
rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl;
/* calculate the index offset of priority value bit field */ /* calculate the index offset of priority value bit field */
prio_index_offset = (irqLine - BSP_MAIN_IRQ_LOWEST_OFFSET) % 8; prio_index_offset = (irqLine - BSP_MAIN_IRQ_LOWEST_OFFSET) % 8;
@@ -258,14 +266,12 @@ static inline void BSP_enable_main_irq_at_siu(
} }
static inline void BSP_enable_crit_irq_at_siu( static inline void BSP_enable_crit_irq_at_siu(
const rtems_irq_symbolic_name irqLine rtems_vector_number irqLine
) )
{ {
uint8_t prio_index_offset; uint8_t prio_index_offset;
uint32_t *reg; uint32_t *reg;
rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl;
prio_index_offset = irqLine - BSP_CRIT_IRQ_LOWEST_OFFSET; prio_index_offset = irqLine - BSP_CRIT_IRQ_LOWEST_OFFSET;
@@ -276,7 +282,6 @@ static inline void BSP_enable_crit_irq_at_siu(
*/ */
mpc5200.ext_en_type |= 1; mpc5200.ext_en_type |= 1;
/* set critical interrupt priorities */ /* set critical interrupt priorities */
if (irqPrioTable [irqLine] <= 3) { if (irqPrioTable [irqLine] <= 3) {
@@ -294,9 +299,8 @@ static inline void BSP_enable_crit_irq_at_siu(
} }
} }
static inline void BSP_disable_per_irq_at_siu( static inline void BSP_disable_per_irq_at_siu(
const rtems_irq_symbolic_name irqLine rtems_vector_number irqLine
) )
{ {
uint8_t prio_index_offset; uint8_t prio_index_offset;
@@ -314,9 +318,8 @@ static inline void BSP_disable_per_irq_at_siu(
*reg &= ~(15 << (28 - (prio_index_offset << 2))); *reg &= ~(15 << (28 - (prio_index_offset << 2)));
} }
static inline void BSP_disable_main_irq_at_siu( static inline void BSP_disable_main_irq_at_siu(
const rtems_irq_symbolic_name irqLine rtems_vector_number irqLine
) )
{ {
uint8_t prio_index_offset; uint8_t prio_index_offset;
@@ -339,10 +342,8 @@ static inline void BSP_disable_main_irq_at_siu(
*reg &= ~(15 << (28 - (prio_index_offset << 2))); *reg &= ~(15 << (28 - (prio_index_offset << 2)));
} }
static inline void BSP_disable_crit_irq_at_siu( rtems_vector_number
static inline void BSP_disable_crit_irq_at_siu( irqLine)
const rtems_irq_symbolic_name irqLine
)
{ {
uint8_t prio_index_offset; uint8_t prio_index_offset;
uint32_t *reg; uint32_t *reg;
@@ -359,33 +360,17 @@ static inline void BSP_disable_crit_irq_at_siu(
} }
} }
/*
* ------------------------ RTEMS Irq helper functions ----------------
*/
/*
* This function check that the value given for the irq line
* is valid.
*/
static int isValidInterrupt(int irq)
{
if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET) )
return 0;
return 1;
}
/* /*
* This function enables a given siu interrupt * This function enables a given siu interrupt
*/ */
int BSP_irq_enable_at_siu(const rtems_irq_symbolic_name irqLine) rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number irqLine)
{ {
int base_index; int base_index = get_siu_irq_base_index( irqLine);
if (is_siu_irq( irqLine)) { if (is_siu_irq( irqLine)) {
if ((base_index = get_siu_irq_base_index(irqLine)) != -1) { rtems_interrupt_level level;
rtems_interrupt_disable( level);
switch (base_index) { switch (base_index) {
case BSP_PER_IRQ_LOWEST_OFFSET: case BSP_PER_IRQ_LOWEST_OFFSET:
@@ -398,23 +383,28 @@ int BSP_irq_enable_at_siu(const rtems_irq_symbolic_name irqLine)
BSP_enable_crit_irq_at_siu( irqLine); BSP_enable_crit_irq_at_siu( irqLine);
break; break;
default: default:
rtems_interrupt_enable( level);
printk( "No valid base index\n"); printk( "No valid base index\n");
break; return RTEMS_INVALID_NUMBER;
} }
rtems_interrupt_enable( level);
} }
}
return 0; return RTEMS_SUCCESSFUL;
} }
/* /*
* This function disables a given siu interrupt * This function disables a given siu interrupt
*/ */
int BSP_irq_disable_at_siu(const rtems_irq_symbolic_name irqLine) rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqLine)
{ {
int base_index; int base_index = get_siu_irq_base_index( irqLine);
if ( (base_index = get_siu_irq_base_index(irqLine)) == -1) if (is_siu_irq( irqLine)) {
return 1; rtems_interrupt_level level;
rtems_interrupt_disable( level);
switch (base_index) { switch (base_index) {
case BSP_PER_IRQ_LOWEST_OFFSET: case BSP_PER_IRQ_LOWEST_OFFSET:
@@ -427,208 +417,15 @@ int BSP_irq_disable_at_siu(const rtems_irq_symbolic_name irqLine)
BSP_disable_crit_irq_at_siu( irqLine); BSP_disable_crit_irq_at_siu( irqLine);
break; break;
default: default:
rtems_interrupt_enable( level);
printk( "No valid base index\n"); printk( "No valid base index\n");
break; return RTEMS_INVALID_NUMBER;
}
return 0;
}
/*
* --------------------- RTEMS Single Irq Handler Mngt Routines -------------
*/
/*
* This function removes the default entry and installs a device
* interrupt handler
*/
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_interrupt_level level;
if (!isValidInterrupt(irq->name)) {
printk("not a valid interrupt\n");
return 0;
}
/*
* Check if default handler is actually connected. If not issue an error.
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
printk( "Default handler not there\n" );
return 0;
}
rtems_interrupt_disable(level);
/*
* store the data provided by user
*/
rtems_hdl_tbl[irq->name] = *irq;
if (is_siu_irq(irq->name)) {
/*
* Enable interrupt at siu level
*/
BSP_irq_enable_at_siu(irq->name);
} else {
if (is_processor_irq(irq->name)) {
/*
* Should Enable exception at processor level but not needed.
* Will restore EE flags at the end of the routine anyway.
*/
} else {
printk("not a valid interrupt\n");
return 0;
}
}
/*
* Enable interrupt on device
*/
if (irq->on)
irq->on(irq);
rtems_interrupt_enable(level);
return 1;
}
/*
* This function procures the current interrupt handler
*/
int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
{
if (!isValidInterrupt(irq->name)) {
return 0;
}
*irq = rtems_hdl_tbl[irq->name];
return 1;
}
/*
* This function removes a device interrupt handler and restores
* the default entry
*/
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_interrupt_level level;
if (!isValidInterrupt(irq->name)) {
return 0;
}
/*
* Check if default handler is actually connected. If not issue an error.
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
return 0;
}
rtems_interrupt_disable(level);
if (is_siu_irq(irq->name)) {
/*
* disable interrupt at PIC level
*/
BSP_irq_disable_at_siu(irq->name);
}
if (is_processor_irq(irq->name)) {
/*
* disable exception at processor level
*/
}
/*
* Disable interrupt on device
*/
if (irq->off)
irq->off(irq);
/*
* restore the default irq value
*/
rtems_hdl_tbl[irq->name] = default_rtems_entry;
rtems_interrupt_enable(level);
return 1;
}
/*
* --------------------- RTEMS Global Irq Handler Mngt Routines -------------
*/
/*
* This function set up interrupt management dependent on the
* given configuration
*/
int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
{
int i;
rtems_interrupt_level level;
/*
* Store various code accelerators
*/
internal_config = config;
default_rtems_entry = config->defaultEntry;
rtems_hdl_tbl = config->irqHdlTbl;
rtems_interrupt_disable(level);
/*
* start with SIU IRQs
*/
for (i=BSP_SIU_IRQ_LOWEST_OFFSET;
i < BSP_SIU_IRQ_LOWEST_OFFSET + BSP_SIU_IRQ_NUMBER ;
i++) {
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
BSP_irq_enable_at_siu(i);
if (rtems_hdl_tbl[i].on)
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
} else {
if (rtems_hdl_tbl[i].off)
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
BSP_irq_disable_at_siu(i);
}
}
/*
* finish with Processor exceptions handled like IRQs
*/
for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER;
i++) {
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
if (rtems_hdl_tbl[i].on)
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
} else {
if (rtems_hdl_tbl[i].off)
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
}
} }
rtems_interrupt_enable( level); rtems_interrupt_enable( level);
return 1;
} }
return RTEMS_SUCCESSFUL;
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
{
*config = internal_config;
return 0;
} }
#if (BENCHMARK_IRQ_PROCESSING == 0) #if (BENCHMARK_IRQ_PROCESSING == 0)
@@ -644,12 +441,14 @@ uint64_t BSP_Starting_TBR;
uint64_t BSP_Total_in_ISR; uint64_t BSP_Total_in_ISR;
uint32_t BSP_ISR_Count; uint32_t BSP_ISR_Count;
uint32_t BSP_Worst_ISR; uint32_t BSP_Worst_ISR;
#define BSP_COUNTED_IRQ 16 #define BSP_COUNTED_IRQ 16
uint32_t BSP_ISR_Count_Per [BSP_COUNTED_IRQ + 1]; uint32_t BSP_ISR_Count_Per [BSP_COUNTED_IRQ + 1];
void BSP_IRQ_Benchmarking_Reset( void) void BSP_IRQ_Benchmarking_Reset( void)
{ {
int i; int i;
BSP_Starting_TBR = PPC_Get_timebase_register(); BSP_Starting_TBR = PPC_Get_timebase_register();
BSP_Total_in_ISR = 0; BSP_Total_in_ISR = 0;
BSP_ISR_Count = 0; BSP_ISR_Count = 0;
@@ -658,10 +457,7 @@ void BSP_IRQ_Benchmarking_Reset(void)
BSP_ISR_Count_Per [i] = 0; BSP_ISR_Count_Per [i] = 0;
} }
static const char * u64tostring( static const char *u64tostring( char *buffer, uint64_t v)
char *buffer,
uint64_t v
)
{ {
sprintf( buffer, "%lld cycles %lld usecs", v, (v / 33)); sprintf( buffer, "%lld cycles %lld usecs", v, (v / 33));
return buffer; return buffer;
@@ -692,12 +488,16 @@ void BSP_IRQ_Benchmarking_Report(void)
int C_dispatch_irq_handler( CPU_Interrupt_frame * frame, unsigned int excNum) int C_dispatch_irq_handler( CPU_Interrupt_frame * frame, unsigned int excNum)
{ {
register unsigned int irq; register unsigned int irq;
register unsigned int msr;
register unsigned int new_msr;
register unsigned int pmce; register unsigned int pmce;
register unsigned int crit_pri_main_mask, per_mask; register unsigned int crit_pri_main_mask,
per_mask;
uint32_t msr;
#if (BENCHMARK_IRQ_PROCESSING == 1) #if (BENCHMARK_IRQ_PROCESSING == 1)
uint64_t start, stop, thisTime; uint64_t start,
stop,
thisTime;
start = PPC_Get_timebase_register(); start = PPC_Get_timebase_register();
BSP_ISR_Count++; BSP_ISR_Count++;
@@ -713,8 +513,8 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
*/ */
case ASM_DEC_VECTOR: case ASM_DEC_VECTOR:
/* call the module specific handler and pass the specific handler */ /* Dispatch interrupt handlers */
rtems_hdl_tbl[BSP_DECREMENTER].hdl(0); bsp_interrupt_handler_dispatch( BSP_DECREMENTER);
break; break;
@@ -769,19 +569,15 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* enable interrupt nesting */ /* enable interrupt nesting */
_CPU_MSR_GET(msr); msr = ppc_external_exceptions_enable();
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
#endif #endif
/* call the module specific handler and pass the /* Dispatch interrupt handlers */
* specific handler bsp_interrupt_handler_dispatch( irq);
*/
rtems_hdl_tbl[irq].hdl(0);
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* disable interrupt nesting */ /* disable interrupt nesting */
_CPU_MSR_SET(msr); ppc_external_exceptions_disable( msr);
#endif #endif
/* restore original interrupt mask */ /* restore original interrupt mask */
@@ -810,19 +606,15 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* enable interrupt nesting */ /* enable interrupt nesting */
_CPU_MSR_GET(msr); msr = ppc_external_exceptions_enable();
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
#endif #endif
/* call the module specific handler and pass /* Dispatch interrupt handlers */
* the specific handler bsp_interrupt_handler_dispatch( irq);
*/
rtems_hdl_tbl[irq].hdl(0);
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* disable interrupt nesting */ /* disable interrupt nesting */
_CPU_MSR_SET(msr); ppc_external_exceptions_disable( msr);
#endif #endif
/* restore original interrupt mask */ /* restore original interrupt mask */
@@ -859,8 +651,8 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
/* critical interrupts may be routed to the core_int /* critical interrupts may be routed to the core_int
* dependent on premature initialization, see bit 31 (CEbsH) * dependent on premature initialization, see bit 31 (CEbsH)
*/ */
while((CHK_CE_SHADOW(pmce) && CHK_CSE_STICKY(pmce)) || while ((CHK_CE_SHADOW( pmce) && CHK_CSE_STICKY( pmce))
CHK_MSE_STICKY(pmce) || CHK_PSE_STICKY(pmce) ) { || CHK_MSE_STICKY( pmce) || CHK_PSE_STICKY( pmce)) {
/* first: check for critical interrupt sources (hierarchical order) /* first: check for critical interrupt sources (hierarchical order)
* -> HI_int indicates peripheral sources * -> HI_int indicates peripheral sources
@@ -878,9 +670,9 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
* handler array */ * handler array */
irq += BSP_CRIT_IRQ_LOWEST_OFFSET; irq += BSP_CRIT_IRQ_LOWEST_OFFSET;
/* call the module specific handler and pass the /* Dispatch interrupt handlers */
* specific handler */ bsp_interrupt_handler_dispatch( irq);
rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
break; break;
/* peripheral HI_int interrupt source detected */ /* peripheral HI_int interrupt source detected */
@@ -901,17 +693,15 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* enable interrupt nesting */ /* enable interrupt nesting */
_CPU_MSR_GET(msr); msr = ppc_external_exceptions_enable();
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
#endif #endif
/* call the module specific handler and pass the /* Dispatch interrupt handlers */
* specific handler */ bsp_interrupt_handler_dispatch( irq);
rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
_CPU_MSR_SET(msr); /* disable interrupt nesting */
ppc_external_exceptions_disable( msr);
#endif #endif
/* restore original interrupt mask */ /* restore original interrupt mask */
@@ -970,18 +760,15 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* enable interrupt nesting */ /* enable interrupt nesting */
_CPU_MSR_GET(msr); msr = ppc_external_exceptions_enable();
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
#endif #endif
/* call the module specific handler and pass the specific /* Dispatch interrupt handlers */
* handler */ bsp_interrupt_handler_dispatch( irq);
rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* disable interrupt nesting */ /* disable interrupt nesting */
_CPU_MSR_SET(msr); ppc_external_exceptions_disable( msr);
#endif #endif
/* restore original interrupt mask */ /* restore original interrupt mask */
@@ -1006,18 +793,15 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* enable interrupt nesting */ /* enable interrupt nesting */
_CPU_MSR_GET(msr); msr = ppc_external_exceptions_enable();
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
#endif #endif
/* call the module specific handler and pass the /* Dispatch interrupt handlers */
* specific handler */ bsp_interrupt_handler_dispatch( irq);
rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
#if (ALLOW_IRQ_NESTING == 1) #if (ALLOW_IRQ_NESTING == 1)
/* disable interrupt nesting */ /* disable interrupt nesting */
_CPU_MSR_SET(msr); ppc_external_exceptions_disable( msr);
#endif #endif
/* restore original interrupt mask */ /* restore original interrupt mask */
@@ -1050,6 +834,7 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
break; break;
} /* end of switch( excNum) */ } /* end of switch( excNum) */
#if (BENCHMARK_IRQ_PROCESSING == 1) #if (BENCHMARK_IRQ_PROCESSING == 1)
stop = PPC_Get_timebase_register(); stop = PPC_Get_timebase_register();
thisTime = stop - start; thisTime = stop - start;
@@ -1057,28 +842,111 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
if (thisTime > BSP_Worst_ISR) if (thisTime > BSP_Worst_ISR)
BSP_Worst_ISR = thisTime; BSP_Worst_ISR = thisTime;
#endif #endif
return 0; return 0;
} }
void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
{
/* /*
* Process pending signals that have not already been * setup irqMaskTable to support a priorized/nested interrupt environment
* processed by _Thread_Displatch. This happens quite
* unfrequently : the ISR must have posted an action
* to the current running thread.
*/ */
if ( _Thread_Do_post_task_switch_extension || void setup_irqMaskTable( void)
_Thread_Executing->do_post_task_switch_extension ) {
rtems_irq_prio prio = 0;
uint32_t i = 0,
j = 0,
mask = 0;
/* set up the priority dependent masks for peripheral interrupts */
for (i = BSP_PER_IRQ_LOWEST_OFFSET; i <= BSP_PER_IRQ_MAX_OFFSET; i++) {
prio = irqPrioTable [i];
mask = 0;
for (j = BSP_PER_IRQ_LOWEST_OFFSET; j <= BSP_PER_IRQ_MAX_OFFSET; j++) {
if (prio > irqPrioTable [j]) {
mask |= (1 << (31 - j + BSP_PER_IRQ_LOWEST_OFFSET));
}
if ((prio == irqPrioTable [j]) && (j >= i)) {
mask |= (1 << (31 - j + BSP_PER_IRQ_LOWEST_OFFSET));
}
}
irqMaskTable [i] = mask;
}
/* set up the priority dependent masks for main interrupts */
for (i = BSP_MAIN_IRQ_LOWEST_OFFSET; i <= BSP_MAIN_IRQ_MAX_OFFSET; i++) {
prio = irqPrioTable [i];
mask = 0;
for (j = BSP_MAIN_IRQ_LOWEST_OFFSET; j <= BSP_MAIN_IRQ_MAX_OFFSET; j++) {
if (prio > irqPrioTable [j]) {
mask |= (1 << (16 - j + BSP_MAIN_IRQ_LOWEST_OFFSET));
}
if ((prio == irqPrioTable [j]) && (j >= i)) {
mask |= (1 << (16 - j + BSP_MAIN_IRQ_LOWEST_OFFSET));
}
}
irqMaskTable [i] = mask;
}
}
/*
* Initialize MPC5x00 SIU interrupt management
*/
void BSP_SIU_irq_init( void)
{ {
_Thread_Executing->do_post_task_switch_extension = FALSE; /* disable all peripheral interrupts */
_API_extensions_Run_postswitch(); mpc5200.per_mask = 0xFFFFFC00;
/* peripheral interrupt priorities according to reset value */
mpc5200.per_pri_1 = 0xF0000000;
mpc5200.per_pri_2 = 0x00000000;
mpc5200.per_pri_3 = 0x00000000;
/* disable external interrupts IRQ0-4 / critical interrupts are routed to core_int */
mpc5200.ext_en_type = 0x0F000001;
/* disable main interrupts / crit. int. priorities according to reset values */
mpc5200.crit_pri_main_mask = 0x0001FFFF;
/* main priorities according to reset value */
mpc5200.main_pri_1 = 0;
mpc5200.main_pri_2 = 0;
/* reset all status indicators */
mpc5200.csa = 0x0001FFFF;
mpc5200.msa = 0x0001FFFF;
mpc5200.psa = 0x003FFFFF;
mpc5200.psa_be = 0x03000000;
setup_irqMaskTable();
}
rtems_status_code bsp_interrupt_facility_initialize( void)
{
BSP_SIU_irq_init();
/* Install exception handler */
if (ppc_exc_set_handler( ASM_EXT_VECTOR, C_dispatch_irq_handler)) {
return RTEMS_IO_ERROR;
}
if (ppc_exc_set_handler( ASM_DEC_VECTOR, C_dispatch_irq_handler)) {
return RTEMS_IO_ERROR;
}
if (ppc_exc_set_handler( ASM_E300_SYSMGMT_VECTOR, C_dispatch_irq_handler)) {
return RTEMS_IO_ERROR;
}
return RTEMS_SUCCESSFUL;
}
void bsp_interrupt_handler_default( rtems_vector_number vector)
{
if (vector != BSP_DECREMENTER) {
printk( "Spurious interrupt: 0x%08x\n", vector);
} }
/*
* I plan to process other thread related events here.
* This will include DEBUG session requested from keyboard...
*/
} }

View File

@@ -65,7 +65,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/if_ether.h> #include <netinet/if_ether.h>
#include <bsp.h> #include <bsp.h>
#include "../irq/irq.h" #include <bsp/irq.h>
#include "../include/mpc5200.h" #include "../include/mpc5200.h"
#include <net/if_var.h> #include <net/if_var.h>
#include <errno.h> #include <errno.h>

View File

@@ -99,13 +99,13 @@
#include <bsp.h> #include <bsp.h>
#include <rtems/bspIo.h> #include <rtems/bspIo.h>
#include "../irq/irq.h" #include <bsp/irq.h>
#include <rtems.h> #include <rtems.h>
#include <rtems/clockdrv.h> #include <rtems/clockdrv.h>
#include <rtems/libio.h> #include <rtems/libio.h>
#include "../irq/irq.h" #include <bsp/irq.h>
#include "../include/mpc5200.h" #include "../include/mpc5200.h"
#include "../slicetimer/slicetimer.h" #include "../slicetimer/slicetimer.h"
#include <stdio.h> #include <stdio.h>

View File

@@ -90,56 +90,10 @@
/* */ /* */
/***********************************************************************/ /***********************************************************************/
#include <rtems/asm.h>
#include <rtems/powerpc/cache.h> #include <rtems/powerpc/cache.h>
#include <rtems/powerpc/registers.h>
#include "../include/mpc5200.h"
#include "../include/bsp.h"
/* Macro definitions to load a register with a 32-bit address. #include <bsp.h>
Both functions identically. Sometimes one mnemonic is more #include <bsp/mpc5200.h>
appropriate than the other.
reg -> register to load
value -> value to be loaded
LA reg,value ("Load Address")
LWI reg,value ("Load Word Immediate") */
.macro LA reg, value
lis \reg , \value@h
ori \reg , \reg, \value@l
sync
.endm
.macro LWI reg, value
lis \reg , (\value)@h
ori \reg , \reg, (\value)@l
sync
.endm
/* Macro definitions to test, set or clear a single
bit or bit pattern in a given 32bit GPR.
reg1 -> register content to be tested
reg2 -> 2nd register only needed for computation
mask -> any bit pattern */
.macro TSTBITS reg1, reg2, mask /* Match is indicated by EQ=0 (CR) */
LWI \reg2, \mask /* Unmatch is indicated by EQ=1 (CR) */
and \reg1, \reg1, \reg2
cmplw \reg1, \reg2
sync
.endm
.macro SETBITS reg1, reg2, mask
LWI \reg2, \mask
or \reg1, \reg1, \reg2
sync
.endm
.macro CLRBITS reg1, reg2, mask
LWI \reg2, \mask
andc \reg1, \reg1, \reg2
sync
.endm
/* Some register offsets of MPC5x00 memory map registers */ /* Some register offsets of MPC5x00 memory map registers */
.set CS0STR, 0x04 .set CS0STR, 0x04
@@ -200,15 +154,7 @@
.set CSCONTROL_VAL, 0x91000000 .set CSCONTROL_VAL, 0x91000000
.set CFG_VAL, 0x00000100 .set CFG_VAL, 0x00000100
.extern _bss_start
.extern _bss_size
.extern _data_start
.extern _data_size
.extern _text_start
.extern _text_size
/*.extern _s_got*/
.extern boot_card .extern boot_card
.extern MBAR
.section ".entry" .section ".entry"
PUBLIC_VAR (start) PUBLIC_VAR (start)
@@ -262,7 +208,7 @@ start:
#if defined(NEED_LOW_LEVEL_INIT) #if defined(NEED_LOW_LEVEL_INIT)
/* detect RAM/ROM startup (common for RAM/ROM startup) */ /* detect RAM/ROM startup (common for RAM/ROM startup) */
LWI r20, ROM_START /* set the relocation offset */ LWI r20, bsp_rom_start /* set the relocation offset */
LWI r30, CFG_VAL /* get CFG register content */ LWI r30, CFG_VAL /* get CFG register content */
@@ -295,12 +241,11 @@ start:
/* FIXME: map BOOT ROM into final location with CS0 registers */ /* FIXME: map BOOT ROM into final location with CS0 registers */
LWI r30, ROM_START LWI r30, bsp_rom_start
rlwinm r30, r30,17,15,31 rlwinm r30, r30,17,15,31
stw r30, CS0STR(r31) /* Set CS0STR */ stw r30, CS0STR(r31) /* Set CS0STR */
lis r30, ROM_END@h LWI r30, bsp_rom_end
ori r30, r30, ROM_END@l
rlwinm r30, r30,17,15,31 rlwinm r30, r30,17,15,31
stw r30, CS0STP(r31) /* Set CS0STP */ stw r30, CS0STP(r31) /* Set CS0STP */
@@ -311,9 +256,9 @@ start:
isync isync
/* jump to same code in final BOOT ROM location */ /* jump to same code in final BOOT ROM location */
LWI r30, reloc_in_CS0 LWI r30, reloc_in_CS0
LWI r29, RAM_START LWI r29, bsp_ram_start
sub r30,r30,r29 sub r30,r30,r29
LWI r29, ROM_START LWI r29, bsp_rom_start
add r30,r30,r29 add r30,r30,r29
mtctr r30 mtctr r30
bctr bctr
@@ -325,11 +270,12 @@ reloc_in_CS0:
stw r30, ADREN(r31) /* disable BOOT mapping */ stw r30, ADREN(r31) /* disable BOOT mapping */
/* init SDRAM */ /* init SDRAM */
LWI r30, RAM_START LWI r30, bsp_ram_start
ori r30, r30, 0x1a /* size code: bank is 128MByte */ ori r30, r30, 0x1a /* size code: bank is 128MByte */
stw r30, SDRAMCS0(r31) /* Set SDRAMCS0 */ stw r30, SDRAMCS0(r31) /* Set SDRAMCS0 */
LWI r30,(RAM_SIZE)>>1 LWI r30, bsp_ram_size
srawi r30, r30, 1
ori r30, r30, 0x1a /* size code: bank is 128MByte */ ori r30, r30, 0x1a /* size code: bank is 128MByte */
stw r30, SDRAMCS1(r31) /* Set SDRAMCS1 */ stw r30, SDRAMCS1(r31) /* Set SDRAMCS1 */
@@ -348,32 +294,32 @@ reloc_in_CS0:
LWI r30, 0x0000001e LWI r30, 0x0000001e
stw r30, ARBSNOOP(r31) /* Set ARBSNOOP */ stw r30, ARBSNOOP(r31) /* Set ARBSNOOP */
/* copy .text section from ROM to RAM location (unique for ROM startup) */ /* copy .text section from ROM to RAM location (unique for ROM startup) */
LA r30, _text_start /* get start address of text section in RAM */ LA r30, bsp_section_text_start /* get start address of text section in RAM */
add r30, r20, r30 /* get start address of text section in ROM (add reloc offset) */ add r30, r20, r30 /* get start address of text section in ROM (add reloc offset) */
LA r29, _text_start /* get start address of text section in RAM */ LA r29, bsp_section_text_start /* get start address of text section in RAM */
LA r28, _text_size /* get size of RAM image */ LA r28, bsp_section_text_size /* get size of RAM image */
bl copy_image /* copy text section from ROM to RAM location */ bl copy_image /* copy text section from ROM to RAM location */
/* copy .data section from ROM to RAM location (unique for ROM startup) */ /* copy .data section from ROM to RAM location (unique for ROM startup) */
LA r30, _data_start /* get start address of data section in RAM */ LA r30, bsp_section_data_start /* get start address of data section in RAM */
add r30, r20, r30 /* get start address of data section in ROM (add reloc offset) */ add r30, r20, r30 /* get start address of data section in ROM (add reloc offset) */
LA r29, _data_start /* get start address of data section in RAM */ LA r29, bsp_section_data_start /* get start address of data section in RAM */
LA r28, _data_size /* get size of RAM image */ LA r28, bsp_section_data_size /* get size of RAM image */
bl copy_image /* copy initialized data section from ROM to RAM location */ bl copy_image /* copy initialized data section from ROM to RAM location */
@@ -429,10 +375,12 @@ skip_ROM_start:
stw r30, CS1CONF(r31) stw r30, CS1CONF(r31)
/* map external DPRAM (CS1) */ /* map external DPRAM (CS1) */
LWI r30,(DPRAM_START>>16) LWI r30, bsp_dpram_start
srawi r30, r30, 16
stw r30, CS1STR(r31) stw r30, CS1STR(r31)
LWI r30,((DPRAM_END)>>16) LWI r30, bsp_dpram_end
srawi r30, r30, 16
stw r30, CS1STP(r31) stw r30, CS1STP(r31)
lwz r30, ADREN(r31) /* get content of ADREN */ lwz r30, ADREN(r31) /* get content of ADREN */
@@ -451,17 +399,18 @@ skip_ROM_start:
#endif /* defined(BRS5L) */ #endif /* defined(BRS5L) */
/* clear .bss section (unique for ROM startup) */ /* clear .bss section (unique for ROM startup) */
LWI r30, _bss_start /* get start address of bss section */ LWI r30, bsp_section_bss_start /* get start address of bss section */
LWI r29, _bss_size /* get size of bss section */ LWI r29, bsp_section_bss_size /* get size of bss section */
bl clr_mem /* Clear the bss section */ bl clr_mem /* Clear the bss section */
/* set stack pointer (common for RAM/ROM startup) */ /* set stack pointer (common for RAM/ROM startup) */
LA r1, _text_start LA r1, bsp_section_text_start
addi r1, r1, -0x10 /* Set up stack pointer = beginning of text section - 0x10 */ addi r1, r1, -0x10 /* Set up stack pointer = beginning of text section - 0x10 */
bl __eabi /* Set up EABI and SYSV environment */
/* enable dynamic power management(common for RAM/ROM startup) */ /* enable dynamic power management(common for RAM/ROM startup) */
bl PPC_HID0_rd /* Get the content of HID0 */ bl PPC_HID0_rd /* Get the content of HID0 */
@@ -622,7 +571,7 @@ FID_DCache:
bne FID_DCache_exit /* If data cache is switched of, skip further actions */ bne FID_DCache_exit /* If data cache is switched of, skip further actions */
li r29, PPC_D_CACHE /* 16 Kb data cache on 603e */ li r29, PPC_D_CACHE /* 16 Kb data cache on 603e */
LWI r28, _text_start /* Load base address (begin of RAM) */ LWI r28, bsp_section_text_start /* Load base address (begin of RAM) */
FID_DCache_loop_1: FID_DCache_loop_1:
lwz r27, 0(r28) /* Load data at address */ lwz r27, 0(r28) /* Load data at address */
@@ -633,7 +582,7 @@ FID_DCache_loop_1:
bne FID_DCache_loop_1 /* Loop until cache size is reached */ bne FID_DCache_loop_1 /* Loop until cache size is reached */
li r29, PPC_D_CACHE /* 16 Kb data cache on 603e */ li r29, PPC_D_CACHE /* 16 Kb data cache on 603e */
LWI r28, _text_start /* Reload base address (begin of RAM) */ LWI r28, bsp_section_text_start /* Reload base address (begin of RAM) */
xor r27, r27, r27 xor r27, r27, r27
FID_DCache_loop_2: FID_DCache_loop_2:
@@ -697,7 +646,7 @@ FPU_init:
mtmsr r30 /* enable FPU and FPU exceptions */ mtmsr r30 /* enable FPU and FPU exceptions */
#if 0 #if 0
LA r29, RAM_START LA r29, bsp_ram_start
stw r29, 0x0(r29) stw r29, 0x0(r29)
#endif #endif

View File

@@ -14,7 +14,8 @@
#include <rtems.h> #include <rtems.h>
#include <rtems/bspIo.h> #include <rtems/bspIo.h>
#include <bsp.h> #include <bsp.h>
#include <mpc5200.h> #include <bsp/mpc5200.h>
#include <bsp/bootcard.h>
extern int mpc5200_uart_pollRead(int minor); extern int mpc5200_uart_pollRead(int minor);

View File

@@ -96,42 +96,31 @@
#warning The interrupt disable mask is now stored in SPRG0, please verify that this is compatible to this BSP (see also bootcard.c). #warning The interrupt disable mask is now stored in SPRG0, please verify that this is compatible to this BSP (see also bootcard.c).
#include <bsp.h> #include <string.h>
#include <rtems/libio.h> #include <rtems/libio.h>
#include <rtems/libcsupport.h> #include <rtems/libcsupport.h>
#include <rtems/powerpc/powerpc.h>
#include <rtems/score/thread.h> #include <rtems/score/thread.h>
#include <rtems/bspIo.h> #include <libcpu/powerpc-utility.h>
#include <libcpu/cpuIdent.h> #include <libcpu/raw_exception.h>
#include <libcpu/spr.h>
#include "../irq/irq.h"
#include <string.h> #include <bsp.h>
#include <bsp/bootcard.h>
#include <bsp/ppc_exc_bspsupp.h>
#include <bsp/irq.h>
#if defined(HAS_UBOOT) #if defined(HAS_UBOOT)
bd_t *uboot_bdinfo_ptr = (bd_t *)1; /* will be overwritten from startup code */ bd_t *uboot_bdinfo_ptr = (bd_t *)1; /* will be overwritten from startup code */
bd_t uboot_bdinfo_copy; /* will be overwritten with copy of bdinfo */ bd_t uboot_bdinfo_copy; /* will be overwritten with copy of bdinfo */
#endif #endif
SPR_RW(SPRG1)
extern unsigned long intrStackPtr;
/* /*
* Driver configuration parameters * Driver configuration parameters
*/ */
uint32_t bsp_clicks_per_usec; uint32_t bsp_clicks_per_usec;
/*
* Use the shared implementations of the following routines.
* Look in rtems/c/src/lib/libbsp/shared/bsplibc.c.
*/
void bsp_libc_init( void *, uint32_t, int );
extern void initialize_exceptions(void);
extern void cpu_init(void);
void BSP_panic(char *s) void BSP_panic(char *s)
{ {
printk("%s PANIC %s\n",_RTEMS_version, s); printk("%s PANIC %s\n",_RTEMS_version, s);
@@ -144,48 +133,23 @@ void _BSP_Fatal_error(unsigned int v)
__asm__ __volatile ("sc"); __asm__ __volatile ("sc");
} }
/* void bsp_get_work_area(
* Function: bsp_pretasking_hook void **work_area_start,
* Created: 95/03/10 size_t *work_area_size,
* void **heap_start,
* Description: size_t *heap_size)
* BSP pretasking hook. Called just before drivers are initialized.
* Used to setup libc and install any BSP extensions.
*
* NOTES:
* Must not use libc (to do io) from here, since drivers are
* not yet initialized.
*
*/
void
bsp_pretasking_hook(void)
{ {
/* #ifdef HAS_UBOOT
* These are assigned addresses in the linkcmds file for the BSP. This char *ram_end = (char *) uboot_bdinfo_ptr->bi_memstart +
* approach is better than having these defined as manifest constants and uboot_bdinfo_ptr->bi_memsize;
* compiled into the kernel, but it is still not ideal when dealing with #else /* HAS_UBOOT */
* multiprocessor configuration in which each board as a different memory char *ram_end = bsp_ram_end;
* map. A better place for defining these symbols might be the makefiles. #endif /* HAS_UBOOT */
* Consideration should also be given to developing an approach in which
* the kernel and the application can be linked and burned into ROM
* independently of each other.
*/
#if defined(HAS_UBOOT) *work_area_start = bsp_work_area_start;
extern unsigned char _HeapStart; *work_area_size = ram_end - bsp_work_area_start;
*heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
bsp_libc_init( &_HeapStart, *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
uboot_bdinfo_ptr->bi_memstart
+ uboot_bdinfo_ptr->bi_memsize
- (uint32_t)&_HeapStart
, 0 );
#else
extern unsigned char _HeapStart;
extern unsigned char _HeapEnd;
bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 );
#endif
} }
void bsp_predriver_hook(void) void bsp_predriver_hook(void)
@@ -219,10 +183,8 @@ void bsp_predriver_hook(void)
void bsp_start(void) void bsp_start(void)
{ {
extern void *_WorkspaceBase;
ppc_cpu_id_t myCpu; ppc_cpu_id_t myCpu;
ppc_cpu_revision_t myCpuRevision; ppc_cpu_revision_t myCpuRevision;
register unsigned char* intrStack;
/* /*
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
@@ -246,22 +208,8 @@ void bsp_start(void)
cpu_init(); cpu_init();
/*
* Initialize some SPRG registers related to irq handling
*/
intrStack = (((unsigned char*)&intrStackPtr) - PPC_MINIMUM_STACK_FRAME_SIZE);
_write_SPRG1((unsigned int)intrStack);
bsp_clicks_per_usec = (IPB_CLOCK/1000000); bsp_clicks_per_usec = (IPB_CLOCK/1000000);
/*
* Install our own set of exception vectors
*/
initialize_exceptions();
/* /*
* Enable instruction and data caches. Do not force writethrough mode. * Enable instruction and data caches. Do not force writethrough mode.
*/ */
@@ -272,21 +220,18 @@ void bsp_start(void)
rtems_cache_enable_data(); rtems_cache_enable_data();
#endif #endif
/* /* Initialize exception handler */
* Need to "allocate" the memory for the RTEMS Workspace and ppc_exc_cache_wb_check = 0;
* tell the RTEMS configuration where it is. This memory is ppc_exc_initialize(
* not malloc'ed. It is just "pulled from the air". PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
*/ (uint32_t) bsp_interrupt_stack_start,
Configuration.work_space_start = (void *)&_WorkspaceBase; (uint32_t) bsp_interrupt_stack_size
#ifdef SHOW_MORE_INIT_SETTINGS );
printk( "workspace=%p\n", Configuration.work_space_start );
printk( "workspace size=%d\n", Configuration.work_space_size );
#endif
/* /* Initalize interrupt support */
* Initalize RTEMS IRQ system if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
*/ BSP_panic( "Cannot intitialize interrupt support\n");
BSP_rtems_irq_mng_init(0); }
/* /*
* If the BSP was built with IRQ benchmarking enabled, * If the BSP was built with IRQ benchmarking enabled,

View File

@@ -117,30 +117,73 @@ void cpu_init_bsp(void)
{ {
BAT dbat; BAT dbat;
calc_dbat_regvals(&dbat,RAM_START,RAM_SIZE,1,0,0,0,BPP_RW); calc_dbat_regvals(
&dbat,
(uint32_t) bsp_ram_start,
(uint32_t) bsp_ram_size,
true,
false,
false,
false,
BPP_RW
);
SET_DBAT(0,dbat.batu,dbat.batl); SET_DBAT(0,dbat.batu,dbat.batl);
calc_dbat_regvals(&dbat,ROM_START,ROM_SIZE,1,0,0,0,BPP_RX); calc_dbat_regvals(
&dbat,
(uint32_t) bsp_rom_start,
(uint32_t) bsp_rom_size,
true,
false,
false,
false,
BPP_RX
);
SET_DBAT(1,dbat.batu,dbat.batl); SET_DBAT(1,dbat.batu,dbat.batl);
calc_dbat_regvals(&dbat,MBAR,128*1024,1,1,1,1,BPP_RW); calc_dbat_regvals(
&dbat,
(uint32_t) MBAR,
128 * 1024,
false,
true,
false,
true,
BPP_RW
);
SET_DBAT(2,dbat.batu,dbat.batl); SET_DBAT(2,dbat.batu,dbat.batl);
calc_dbat_regvals(&dbat,DPRAM_START,128*1024,1,1,1,1,BPP_RW); calc_dbat_regvals(
&dbat,
(uint32_t) bsp_dpram_start,
128 * 1024,
false,
true,
false,
true,
BPP_RW
);
SET_DBAT(3,dbat.batu,dbat.batl); SET_DBAT(3,dbat.batu,dbat.batl);
} }
#elif defined (HAS_UBOOT) #elif defined (HAS_UBOOT)
void cpu_init_bsp(void) void cpu_init_bsp(void)
{ {
BAT dbat; BAT dbat;
uint32_t start = 0;
/* /*
* Program BAT0 for RAM * Program BAT0 for RAM
*/ */
calc_dbat_regvals(&dbat, calc_dbat_regvals(
&dbat,
uboot_bdinfo_ptr->bi_memstart, uboot_bdinfo_ptr->bi_memstart,
uboot_bdinfo_ptr->bi_memsize, uboot_bdinfo_ptr->bi_memsize,
1,0,0,0,BPP_RW); true,
false,
false,
false,
BPP_RW
);
SET_DBAT(0,dbat.batu,dbat.batl); SET_DBAT(0,dbat.batu,dbat.batl);
/* /*
@@ -150,33 +193,53 @@ void cpu_init_bsp(void)
* U-Boot that lies about the starting address of Flash. This check * U-Boot that lies about the starting address of Flash. This check
* corrects that. * corrects that.
*/ */
if ( (uboot_bdinfo_ptr->bi_flashstart + uboot_bdinfo_ptr->bi_flashsize) < if ((uboot_bdinfo_ptr->bi_flashstart + uboot_bdinfo_ptr->bi_flashsize)
uboot_bdinfo_ptr->bi_flashstart ) { < uboot_bdinfo_ptr->bi_flashstart) {
uint32_t start = 0 - uboot_bdinfo_ptr->bi_flashsize; start = 0 - uboot_bdinfo_ptr->bi_flashsize;
calc_dbat_regvals(&dbat,
start, uboot_bdinfo_ptr->bi_flashsize, 1,0,0,0,BPP_RX);
} else { } else {
calc_dbat_regvals(&dbat, start = uboot_bdinfo_ptr->bi_flashstart;
uboot_bdinfo_ptr->bi_flashstart,
uboot_bdinfo_ptr->bi_flashsize,
1,0,0,0,BPP_RX);
} }
calc_dbat_regvals(
&dbat,
start,
uboot_bdinfo_ptr->bi_flashsize,
true,
false,
false,
false,
BPP_RX
);
SET_DBAT(1,dbat.batu,dbat.batl); SET_DBAT(1,dbat.batu,dbat.batl);
/* /*
* Program BAT2 for the MBAR * Program BAT2 for the MBAR
*/ */
calc_dbat_regvals(&dbat,MBAR,128*1024,1,1,1,1,BPP_RW); calc_dbat_regvals(
&dbat,
(uint32_t) MBAR,
128 * 1024,
false,
true,
false,
true,
BPP_RW
);
SET_DBAT(2,dbat.batu,dbat.batl); SET_DBAT(2,dbat.batu,dbat.batl);
/* /*
* If there is SRAM, program BAT3 for that memory * If there is SRAM, program BAT3 for that memory
*/ */
if (uboot_bdinfo_ptr->bi_sramsize != 0) { if (uboot_bdinfo_ptr->bi_sramsize != 0) {
calc_dbat_regvals(&dbat, calc_dbat_regvals(
&dbat,
uboot_bdinfo_ptr->bi_sramstart, uboot_bdinfo_ptr->bi_sramstart,
uboot_bdinfo_ptr->bi_sramsize, uboot_bdinfo_ptr->bi_sramsize,
0,1,1,1,BPP_RW); false,
true,
true,
true,
BPP_RW
);
SET_DBAT(3,dbat.batu,dbat.batl); SET_DBAT(3,dbat.batu,dbat.batl);
} }
} }