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/error.h>
#include <bsp.h>
#include "../irq/irq.h"
#include <bsp/irq.h>
#include "../include/mpc5200.h"
#include "include/ppctypes.h" /* uint32, et. al. */
#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 offsetEntry;
#else
extern const uint32 taskTable;
extern const uint32 taskTable [];
extern const uint32 taskTableBytes;
extern const uint32 taskTableTasks;
extern const uint32 offsetEntry;
@@ -71,7 +71,7 @@ void TasksLoadImage(sdma_regs *sdma)
SCTDT_T *tt;
/* 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 */
for (i=0; i < (uint32) taskTableTasks; i++) {
tt = (SCTDT_T *)(((uint8 *)(sdma->taskBar) - MBarPhysOffsetGlobal) + (uint32) offsetEntry + (i * sizeof (SCTDT_T)));

View File

@@ -103,7 +103,7 @@
#include <bsp.h>
#include <rtems/bspIo.h>
#include "../irq/irq.h"
#include <bsp/irq.h>
#include <rtems.h>
#include <rtems/clockdrv.h>
@@ -114,6 +114,8 @@
#define GPT (BSP_PERIODIC_TIMER - BSP_SIU_IRQ_TMR0)
extern uint32_t bsp_clicks_per_usec;
/* this lets us do nanoseconds since last tick */
uint64_t Clock_last_TBR;
volatile uint32_t counter_value;
@@ -122,7 +124,7 @@ volatile int ClockInitialized = 0;
/*
* 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;
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));
}
void clockOn(const rtems_irq_connect_data* irq)
void clockOn()
{
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() *
bsp_clicks_per_usec;
mpc5200_set_gpt_count(counter_value, (uint32_t)gpt_no);
mpc5200_enable_gpt_int((uint32_t)gpt_no);
mpc5200_set_gpt_count(counter_value, gpt_no);
mpc5200_enable_gpt_int(gpt_no);
ClockInitialized = 1;
}
void clockOff(const rtems_irq_connect_data* irq)
void clockOff()
{
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;
}
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)
{
/*
@@ -266,56 +255,51 @@ int BSP_get_clock_irq_level(void)
return BSP_PERIODIC_TIMER;
}
int BSP_disconnect_clock_handler (void)
int BSP_disconnect_clock_handler (unsigned gpt_no)
{
rtems_irq_connect_data clockIrqData;
clockIrqData.name = BSP_PERIODIC_TIMER;
rtems_status_code sc = RTEMS_SUCCESSFUL;
if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
printk("Unable to stop system clock\n");
rtems_fatal_error_occurred(1);
if ((gpt_no < GPT0) || (gpt_no > GPT7)) {
return 0;
}
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_irq_connect_data clockIrqData;
rtems_status_code sc = RTEMS_SUCCESSFUL;
/*
* 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 {
if ((gpt_no < GPT0) || (gpt_no > GPT7)) {
printk("Unable to set system clock handler\n");
rtems_fatal_error_occurred(1);
}
clockIrqData.hdl = mpc5200_gpt_clock_isr;
clockIrqData.handle = (rtems_irq_hdl_param) hdl;
clockIrqData.on = clockOn;
clockIrqData.off = clockOff;
clockIrqData.isOn = clockIsOn;
sc = rtems_interrupt_handler_install(
BSP_PERIODIC_TIMER,
"Clock",
RTEMS_INTERRUPT_UNIQUE,
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
@@ -342,7 +326,6 @@ int BSP_connect_clock_handler (uint32_t gpt_no)
/* This driver does this in clockOn called at connection time */
#define Clock_driver_support_initialize_hardware() \
do { \
extern uint32_t bsp_clicks_per_usec; \
counter_value = rtems_configuration_get_microseconds_per_tick() * \
bsp_clicks_per_usec; \
mpc5200_init_gpt(GPT); \
@@ -354,7 +337,7 @@ int BSP_connect_clock_handler (uint32_t gpt_no)
#define Clock_driver_support_shutdown_hardware() \
do { \
(void) BSP_disconnect_clock_handler (); \
(void) BSP_disconnect_clock_handler (GPT); \
} while (0)
#include "../../../shared/clockdrv_shell.c"

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,6 +23,44 @@
#ifndef __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
*/
@@ -56,27 +94,6 @@
#define GPIOPCR_INITVAL 0x91050444
/* we have PSC1/2/3 */
#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*/
#define NEED_LOW_LEVEL_INIT
@@ -84,10 +101,6 @@
#define HAS_NVRAM_93CXX
#elif defined (PM520)
/*
* MicroSys PM520 internal memory map definitions
*/
#define MBAR 0xF0000000
#define HAS_UBOOT
#elif defined (icecube)
@@ -107,8 +120,6 @@
/* we only have PSC1 */
#define GEN5200_UART_AVAIL_MASK 0x01
#define MBAR 0xF0000000
/* We want to prompt for a reset and then reset the board */
#define BSP_PRESS_KEY_FOR_RESET 1
#define BSP_RESET_BOARD_AT_EXIT 1
@@ -269,6 +280,8 @@ void BSP_IRQ_Benchmarking_Report(void);
);
#endif
void cpu_init(void);
#ifdef __cplusplus
}
#endif

View File

@@ -73,37 +73,24 @@
/* */
/***********************************************************************/
#include <bsp.h>
#include <rtems.h>
#include "../irq/irq.h"
#include <rtems/score/apiext.h>
#include <rtems/bspIo.h>
#include <libcpu/powerpc-utility.h>
#include <libcpu/raw_exception.h>
#include "../vectors/vectors.h"
#include "../include/mpc5200.h"
extern uint32_t irqMaskTable[];
/*
* default handler connected on each irq after bsp initialization
*/
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;
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/vectors.h>
#include <bsp/ppc_exc_bspsupp.h>
#include <bsp/irq-generic.h>
#include <bsp/mpc5200.h>
/*
* 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
*
*/
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 */
4, 5, 6, 7, /* irda/psc6, eth, usb, ata */
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 */
};
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
*/
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) &
((int)irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET));
return ((irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET)
&& (irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET));
}
/*
* 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) &&
((int)irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET));
return ((irqLine <= BSP_SIU_IRQ_MAX_OFFSET)
&& (irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET));
}
/*
* 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)
return BSP_PER_IRQ_LOWEST_OFFSET;
if (irqLine <= BSP_MAIN_IRQ_MAX_OFFSET)
return BSP_MAIN_IRQ_LOWEST_OFFSET;
if (irqLine <= BSP_CRIT_IRQ_MAX_OFFSET)
return BSP_CRIT_IRQ_LOWEST_OFFSET;
return -1;
}
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;
rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl;
volatile uint32_t per_pri_1,main_pri_1, crit_pri_main_mask, per_mask;
volatile uint32_t per_pri_1,
main_pri_1,
crit_pri_main_mask,
per_mask;
/* calculate the index offset of priority value bit field */
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]);
}
/* enable (unmask) peripheral interrupt */
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_mask = mpc5200.per_mask;
}
static inline void BSP_enable_main_irq_at_siu(
const rtems_irq_symbolic_name irqLine
rtems_vector_number irqLine
)
{
uint8_t prio_index_offset;
uint32_t *reg;
rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl;
/* calculate the index offset of priority value bit field */
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(
const rtems_irq_symbolic_name irqLine
rtems_vector_number irqLine
)
{
uint8_t prio_index_offset;
uint32_t *reg;
rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl;
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;
/* set critical interrupt priorities */
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(
const rtems_irq_symbolic_name irqLine
rtems_vector_number irqLine
)
{
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)));
}
static inline void BSP_disable_main_irq_at_siu(
const rtems_irq_symbolic_name irqLine
rtems_vector_number irqLine
)
{
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)));
}
static inline void BSP_disable_crit_irq_at_siu(
const rtems_irq_symbolic_name irqLine
)
static inline void BSP_disable_crit_irq_at_siu( rtems_vector_number
irqLine)
{
uint8_t prio_index_offset;
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
*/
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 ((base_index = get_siu_irq_base_index(irqLine)) != -1) {
rtems_interrupt_level level;
rtems_interrupt_disable( level);
switch (base_index) {
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);
break;
default:
rtems_interrupt_enable( level);
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
*/
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)
return 1;
if (is_siu_irq( irqLine)) {
rtems_interrupt_level level;
rtems_interrupt_disable( level);
switch (base_index) {
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);
break;
default:
rtems_interrupt_enable( level);
printk( "No valid base index\n");
break;
}
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]);
}
return RTEMS_INVALID_NUMBER;
}
rtems_interrupt_enable( level);
return 1;
}
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
{
*config = internal_config;
return 0;
return RTEMS_SUCCESSFUL;
}
#if (BENCHMARK_IRQ_PROCESSING == 0)
@@ -644,12 +441,14 @@ uint64_t BSP_Starting_TBR;
uint64_t BSP_Total_in_ISR;
uint32_t BSP_ISR_Count;
uint32_t BSP_Worst_ISR;
#define BSP_COUNTED_IRQ 16
uint32_t BSP_ISR_Count_Per [BSP_COUNTED_IRQ + 1];
void BSP_IRQ_Benchmarking_Reset( void)
{
int i;
BSP_Starting_TBR = PPC_Get_timebase_register();
BSP_Total_in_ISR = 0;
BSP_ISR_Count = 0;
@@ -658,10 +457,7 @@ void BSP_IRQ_Benchmarking_Reset(void)
BSP_ISR_Count_Per [i] = 0;
}
static const char * u64tostring(
char *buffer,
uint64_t v
)
static const char *u64tostring( char *buffer, uint64_t v)
{
sprintf( buffer, "%lld cycles %lld usecs", v, (v / 33));
return buffer;
@@ -692,12 +488,16 @@ void BSP_IRQ_Benchmarking_Report(void)
int C_dispatch_irq_handler( CPU_Interrupt_frame * frame, unsigned int excNum)
{
register unsigned int irq;
register unsigned int msr;
register unsigned int new_msr;
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)
uint64_t start, stop, thisTime;
uint64_t start,
stop,
thisTime;
start = PPC_Get_timebase_register();
BSP_ISR_Count++;
@@ -713,8 +513,8 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
*/
case ASM_DEC_VECTOR:
/* call the module specific handler and pass the specific handler */
rtems_hdl_tbl[BSP_DECREMENTER].hdl(0);
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( BSP_DECREMENTER);
break;
@@ -769,19 +569,15 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
#if (ALLOW_IRQ_NESTING == 1)
/* enable interrupt nesting */
_CPU_MSR_GET(msr);
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
msr = ppc_external_exceptions_enable();
#endif
/* call the module specific handler and pass the
* specific handler
*/
rtems_hdl_tbl[irq].hdl(0);
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( irq);
#if (ALLOW_IRQ_NESTING == 1)
/* disable interrupt nesting */
_CPU_MSR_SET(msr);
ppc_external_exceptions_disable( msr);
#endif
/* 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)
/* enable interrupt nesting */
_CPU_MSR_GET(msr);
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
msr = ppc_external_exceptions_enable();
#endif
/* call the module specific handler and pass
* the specific handler
*/
rtems_hdl_tbl[irq].hdl(0);
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( irq);
#if (ALLOW_IRQ_NESTING == 1)
/* disable interrupt nesting */
_CPU_MSR_SET(msr);
ppc_external_exceptions_disable( msr);
#endif
/* 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
* dependent on premature initialization, see bit 31 (CEbsH)
*/
while((CHK_CE_SHADOW(pmce) && CHK_CSE_STICKY(pmce)) ||
CHK_MSE_STICKY(pmce) || CHK_PSE_STICKY(pmce) ) {
while ((CHK_CE_SHADOW( pmce) && CHK_CSE_STICKY( pmce))
|| CHK_MSE_STICKY( pmce) || CHK_PSE_STICKY( pmce)) {
/* first: check for critical interrupt sources (hierarchical order)
* -> HI_int indicates peripheral sources
@@ -878,9 +670,9 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
* handler array */
irq += BSP_CRIT_IRQ_LOWEST_OFFSET;
/* call the module specific handler and pass the
* specific handler */
rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( irq);
break;
/* 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)
/* enable interrupt nesting */
_CPU_MSR_GET(msr);
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
msr = ppc_external_exceptions_enable();
#endif
/* call the module specific handler and pass the
* specific handler */
rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( irq);
#if (ALLOW_IRQ_NESTING == 1)
_CPU_MSR_SET(msr);
/* disable interrupt nesting */
ppc_external_exceptions_disable( msr);
#endif
/* 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)
/* enable interrupt nesting */
_CPU_MSR_GET(msr);
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
msr = ppc_external_exceptions_enable();
#endif
/* call the module specific handler and pass the specific
* handler */
rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( irq);
#if (ALLOW_IRQ_NESTING == 1)
/* disable interrupt nesting */
_CPU_MSR_SET(msr);
ppc_external_exceptions_disable( msr);
#endif
/* 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)
/* enable interrupt nesting */
_CPU_MSR_GET(msr);
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
msr = ppc_external_exceptions_enable();
#endif
/* call the module specific handler and pass the
* specific handler */
rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( irq);
#if (ALLOW_IRQ_NESTING == 1)
/* disable interrupt nesting */
_CPU_MSR_SET(msr);
ppc_external_exceptions_disable( msr);
#endif
/* restore original interrupt mask */
@@ -1050,6 +834,7 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
break;
} /* end of switch( excNum) */
#if (BENCHMARK_IRQ_PROCESSING == 1)
stop = PPC_Get_timebase_register();
thisTime = stop - start;
@@ -1057,28 +842,111 @@ int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
if (thisTime > BSP_Worst_ISR)
BSP_Worst_ISR = thisTime;
#endif
return 0;
}
void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
{
/*
* Process pending signals that have not already been
* processed by _Thread_Displatch. This happens quite
* unfrequently : the ISR must have posted an action
* to the current running thread.
* setup irqMaskTable to support a priorized/nested interrupt environment
*/
if ( _Thread_Do_post_task_switch_extension ||
_Thread_Executing->do_post_task_switch_extension )
void setup_irqMaskTable( void)
{
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;
_API_extensions_Run_postswitch();
/* disable all peripheral interrupts */
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/if_ether.h>
#include <bsp.h>
#include "../irq/irq.h"
#include <bsp/irq.h>
#include "../include/mpc5200.h"
#include <net/if_var.h>
#include <errno.h>

View File

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

View File

@@ -90,56 +90,10 @@
/* */
/***********************************************************************/
#include <rtems/asm.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.
Both functions identically. Sometimes one mnemonic is more
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
#include <bsp.h>
#include <bsp/mpc5200.h>
/* Some register offsets of MPC5x00 memory map registers */
.set CS0STR, 0x04
@@ -200,15 +154,7 @@
.set CSCONTROL_VAL, 0x91000000
.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 MBAR
.section ".entry"
PUBLIC_VAR (start)
@@ -262,7 +208,7 @@ start:
#if defined(NEED_LOW_LEVEL_INIT)
/* 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 */
@@ -295,12 +241,11 @@ start:
/* 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
stw r30, CS0STR(r31) /* Set CS0STR */
lis r30, ROM_END@h
ori r30, r30, ROM_END@l
LWI r30, bsp_rom_end
rlwinm r30, r30,17,15,31
stw r30, CS0STP(r31) /* Set CS0STP */
@@ -311,9 +256,9 @@ start:
isync
/* jump to same code in final BOOT ROM location */
LWI r30, reloc_in_CS0
LWI r29, RAM_START
LWI r29, bsp_ram_start
sub r30,r30,r29
LWI r29, ROM_START
LWI r29, bsp_rom_start
add r30,r30,r29
mtctr r30
bctr
@@ -325,11 +270,12 @@ reloc_in_CS0:
stw r30, ADREN(r31) /* disable BOOT mapping */
/* init SDRAM */
LWI r30, RAM_START
LWI r30, bsp_ram_start
ori r30, r30, 0x1a /* size code: bank is 128MByte */
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 */
stw r30, SDRAMCS1(r31) /* Set SDRAMCS1 */
@@ -348,32 +294,32 @@ reloc_in_CS0:
LWI r30, 0x0000001e
stw r30, ARBSNOOP(r31) /* Set ARBSNOOP */
/* 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) */
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 */
/* 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) */
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 */
@@ -429,10 +375,12 @@ skip_ROM_start:
stw r30, CS1CONF(r31)
/* map external DPRAM (CS1) */
LWI r30,(DPRAM_START>>16)
LWI r30, bsp_dpram_start
srawi r30, r30, 16
stw r30, CS1STR(r31)
LWI r30,((DPRAM_END)>>16)
LWI r30, bsp_dpram_end
srawi r30, r30, 16
stw r30, CS1STP(r31)
lwz r30, ADREN(r31) /* get content of ADREN */
@@ -451,17 +399,18 @@ skip_ROM_start:
#endif /* defined(BRS5L) */
/* clear .bss section (unique for ROM startup) */
LWI r30, _bss_start /* get start address of bss section */
LWI r29, _bss_size /* get size of bss section */
LWI r30, bsp_section_bss_start /* get start address of bss section */
LWI r29, bsp_section_bss_size /* get size of bss section */
bl clr_mem /* Clear the bss section */
/* 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 */
bl __eabi /* Set up EABI and SYSV environment */
/* enable dynamic power management(common for RAM/ROM startup) */
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 */
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:
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 */
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
FID_DCache_loop_2:
@@ -697,7 +646,7 @@ FPU_init:
mtmsr r30 /* enable FPU and FPU exceptions */
#if 0
LA r29, RAM_START
LA r29, bsp_ram_start
stw r29, 0x0(r29)
#endif

View File

@@ -14,7 +14,8 @@
#include <rtems.h>
#include <rtems/bspIo.h>
#include <bsp.h>
#include <mpc5200.h>
#include <bsp/mpc5200.h>
#include <bsp/bootcard.h>
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).
#include <bsp.h>
#include <string.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <rtems/powerpc/powerpc.h>
#include <rtems/score/thread.h>
#include <rtems/bspIo.h>
#include <libcpu/cpuIdent.h>
#include <libcpu/spr.h>
#include "../irq/irq.h"
#include <libcpu/powerpc-utility.h>
#include <libcpu/raw_exception.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)
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 */
#endif
SPR_RW(SPRG1)
extern unsigned long intrStackPtr;
/*
* Driver configuration parameters
*/
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)
{
printk("%s PANIC %s\n",_RTEMS_version, s);
@@ -144,48 +133,23 @@ void _BSP_Fatal_error(unsigned int v)
__asm__ __volatile ("sc");
}
/*
* Function: bsp_pretasking_hook
* Created: 95/03/10
*
* Description:
* 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)
void bsp_get_work_area(
void **work_area_start,
size_t *work_area_size,
void **heap_start,
size_t *heap_size)
{
/*
* These are assigned addresses in the linkcmds file for the BSP. This
* approach is better than having these defined as manifest constants and
* compiled into the kernel, but it is still not ideal when dealing with
* multiprocessor configuration in which each board as a different memory
* map. A better place for defining these symbols might be the makefiles.
* 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.
*/
#ifdef HAS_UBOOT
char *ram_end = (char *) uboot_bdinfo_ptr->bi_memstart +
uboot_bdinfo_ptr->bi_memsize;
#else /* HAS_UBOOT */
char *ram_end = bsp_ram_end;
#endif /* HAS_UBOOT */
#if defined(HAS_UBOOT)
extern unsigned char _HeapStart;
bsp_libc_init( &_HeapStart,
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
*work_area_start = bsp_work_area_start;
*work_area_size = ram_end - bsp_work_area_start;
*heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
*heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
}
void bsp_predriver_hook(void)
@@ -219,10 +183,8 @@ void bsp_predriver_hook(void)
void bsp_start(void)
{
extern void *_WorkspaceBase;
ppc_cpu_id_t myCpu;
ppc_cpu_revision_t myCpuRevision;
register unsigned char* intrStack;
/*
* Get CPU identification dynamically. Note that the get_ppc_cpu_type()
@@ -246,22 +208,8 @@ void bsp_start(void)
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);
/*
* Install our own set of exception vectors
*/
initialize_exceptions();
/*
* Enable instruction and data caches. Do not force writethrough mode.
*/
@@ -272,21 +220,18 @@ void bsp_start(void)
rtems_cache_enable_data();
#endif
/*
* Need to "allocate" the memory for the RTEMS Workspace and
* tell the RTEMS configuration where it is. This memory is
* not malloc'ed. It is just "pulled from the air".
*/
Configuration.work_space_start = (void *)&_WorkspaceBase;
#ifdef SHOW_MORE_INIT_SETTINGS
printk( "workspace=%p\n", Configuration.work_space_start );
printk( "workspace size=%d\n", Configuration.work_space_size );
#endif
/* Initialize exception handler */
ppc_exc_cache_wb_check = 0;
ppc_exc_initialize(
PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
(uint32_t) bsp_interrupt_stack_start,
(uint32_t) bsp_interrupt_stack_size
);
/*
* Initalize RTEMS IRQ system
*/
BSP_rtems_irq_mng_init(0);
/* Initalize interrupt support */
if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
BSP_panic( "Cannot intitialize interrupt support\n");
}
/*
* If the BSP was built with IRQ benchmarking enabled,

View File

@@ -117,30 +117,73 @@ void cpu_init_bsp(void)
{
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);
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);
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);
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);
}
#elif defined (HAS_UBOOT)
void cpu_init_bsp(void)
{
BAT dbat;
uint32_t start = 0;
/*
* Program BAT0 for RAM
*/
calc_dbat_regvals(&dbat,
calc_dbat_regvals(
&dbat,
uboot_bdinfo_ptr->bi_memstart,
uboot_bdinfo_ptr->bi_memsize,
1,0,0,0,BPP_RW);
true,
false,
false,
false,
BPP_RW
);
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
* corrects that.
*/
if ( (uboot_bdinfo_ptr->bi_flashstart + uboot_bdinfo_ptr->bi_flashsize) <
uboot_bdinfo_ptr->bi_flashstart ) {
uint32_t start = 0 - uboot_bdinfo_ptr->bi_flashsize;
calc_dbat_regvals(&dbat,
start, uboot_bdinfo_ptr->bi_flashsize, 1,0,0,0,BPP_RX);
if ((uboot_bdinfo_ptr->bi_flashstart + uboot_bdinfo_ptr->bi_flashsize)
< uboot_bdinfo_ptr->bi_flashstart) {
start = 0 - uboot_bdinfo_ptr->bi_flashsize;
} else {
calc_dbat_regvals(&dbat,
uboot_bdinfo_ptr->bi_flashstart,
uboot_bdinfo_ptr->bi_flashsize,
1,0,0,0,BPP_RX);
start = uboot_bdinfo_ptr->bi_flashstart;
}
calc_dbat_regvals(
&dbat,
start,
uboot_bdinfo_ptr->bi_flashsize,
true,
false,
false,
false,
BPP_RX
);
SET_DBAT(1,dbat.batu,dbat.batl);
/*
* 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);
/*
* If there is SRAM, program BAT3 for that memory
*/
if (uboot_bdinfo_ptr->bi_sramsize != 0) {
calc_dbat_regvals(&dbat,
calc_dbat_regvals(
&dbat,
uboot_bdinfo_ptr->bi_sramstart,
uboot_bdinfo_ptr->bi_sramsize,
0,1,1,1,BPP_RW);
false,
true,
true,
true,
BPP_RW
);
SET_DBAT(3,dbat.batu,dbat.batl);
}
}