forked from Imagelibrary/rtems
2001-03-30 Eric Valette <valette@crf.canon.fr>
* clock/.cvsignore, clock/Makefile.am, clock/p_clock.c, include/8xx_immap.h, include/commproc.h, include/mbx.h, irq/.cvsignore, irq/Makefile.am, irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c, vectors/.cvsignore, vectors/Makefile.am, vectors/vectors.S, vectors/vectors.h, vectors/vectors_init.c: New files. * Makefile.am, configure.in, console/console.c, include/Makefile.am, network/network.c, startup/Makefile.am, startup/bspstart.c, startup/imbx8xx.c, startup/linkcmds, startup/mmutlbtab.c, startup/start.S, wrapup/Makefile.am: The modifications to this BSP reflect the conversion of the mpc8xx CPU to the "new exception processing model."
This commit is contained in:
@@ -1,3 +1,18 @@
|
||||
2001-03-30 Eric Valette <valette@crf.canon.fr>
|
||||
|
||||
* clock/.cvsignore, clock/Makefile.am, clock/p_clock.c,
|
||||
include/8xx_immap.h, include/commproc.h, include/mbx.h,
|
||||
irq/.cvsignore, irq/Makefile.am, irq/irq.c, irq/irq.h,
|
||||
irq/irq_asm.S, irq/irq_init.c, vectors/.cvsignore,
|
||||
vectors/Makefile.am, vectors/vectors.S, vectors/vectors.h,
|
||||
vectors/vectors_init.c: New files.
|
||||
* Makefile.am, configure.in, console/console.c,
|
||||
include/Makefile.am, network/network.c, startup/Makefile.am,
|
||||
startup/bspstart.c, startup/imbx8xx.c, startup/linkcmds,
|
||||
startup/mmutlbtab.c, startup/start.S, wrapup/Makefile.am:
|
||||
The modifications to this BSP reflect the conversion of the
|
||||
mpc8xx CPU to the "new exception processing model."
|
||||
|
||||
2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
||||
|
||||
* Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
|
||||
|
||||
@@ -7,7 +7,7 @@ ACLOCAL_AMFLAGS = -I ../../../../../../aclocal
|
||||
|
||||
# wrapup is the one that actually builds and installs the library
|
||||
# from the individual .rel files built in other directories
|
||||
SUBDIRS = console include network startup wrapup
|
||||
SUBDIRS = clock console include irq network startup vectors wrapup
|
||||
|
||||
include $(top_srcdir)/../../bsp.am
|
||||
|
||||
|
||||
2
c/src/lib/libbsp/powerpc/mbx8xx/clock/.cvsignore
Normal file
2
c/src/lib/libbsp/powerpc/mbx8xx/clock/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
26
c/src/lib/libbsp/powerpc/mbx8xx/clock/Makefile.am
Normal file
26
c/src/lib/libbsp/powerpc/mbx8xx/clock/Makefile.am
Normal file
@@ -0,0 +1,26 @@
|
||||
##
|
||||
## $Id$
|
||||
##
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
VPATH = @srcdir@:@srcdir@/../../shared/clock
|
||||
|
||||
C_FILES = p_clock.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||
|
||||
OBJS = $(C_O_FILES)
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
include $(top_srcdir)/../../../../../../automake/lib.am
|
||||
|
||||
#
|
||||
# (OPTIONAL) Add local stuff here using +=
|
||||
#
|
||||
|
||||
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
|
||||
|
||||
all-local: $(ARCH) $(OBJS)
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
70
c/src/lib/libbsp/powerpc/mbx8xx/clock/p_clock.c
Normal file
70
c/src/lib/libbsp/powerpc/mbx8xx/clock/p_clock.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Clock Tick interrupt conexion code.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1997.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* Modified to support the MPC750.
|
||||
* Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
extern void clockOn(void*);
|
||||
extern void clockOff (void*);
|
||||
extern int clockIsOn(void*);
|
||||
extern void Clock_isr();
|
||||
|
||||
static rtems_irq_connect_data clockIrqData = {BSP_PERIODIC_TIMER,
|
||||
(rtems_irq_hdl)Clock_isr,
|
||||
(rtems_irq_enable)clockOn,
|
||||
(rtems_irq_disable)clockOff,
|
||||
(rtems_irq_is_enabled)clockIsOn};
|
||||
|
||||
int BSP_get_clock_irq_level()
|
||||
{
|
||||
/*
|
||||
* Caution : if you change this, you must change the
|
||||
* definition of BSP_PERIODIC_TIMER accordingly
|
||||
*/
|
||||
return 6;
|
||||
}
|
||||
|
||||
int BSP_disconnect_clock_handler (void)
|
||||
{
|
||||
if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
|
||||
printk("Unable to stop system clock\n");
|
||||
rtems_fatal_error_occurred(1);
|
||||
}
|
||||
return BSP_remove_rtems_irq_handler (&clockIrqData);
|
||||
}
|
||||
|
||||
int BSP_connect_clock_handler (rtems_irq_hdl hdl)
|
||||
{
|
||||
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);
|
||||
}
|
||||
/*
|
||||
* Reinit structure
|
||||
*/
|
||||
clockIrqData.name = BSP_PERIODIC_TIMER;
|
||||
clockIrqData.hdl = (rtems_irq_hdl) hdl;
|
||||
clockIrqData.on = (rtems_irq_enable)clockOn;
|
||||
clockIrqData.off = (rtems_irq_enable)clockOff;
|
||||
clockIrqData.isOn = (rtems_irq_is_enabled)clockIsOn;
|
||||
|
||||
return BSP_install_rtems_irq_handler (&clockIrqData);
|
||||
}
|
||||
@@ -28,8 +28,11 @@ AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
|
||||
# Explicitly list a Makefile here
|
||||
AC_OUTPUT(
|
||||
Makefile
|
||||
clock/Makefile
|
||||
console/Makefile
|
||||
include/Makefile
|
||||
irq/Makefile
|
||||
network/Makefile
|
||||
startup/Makefile
|
||||
vectors/Makefile
|
||||
wrapup/Makefile)
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#include <bspIo.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
#include <bsp/mbx.h>
|
||||
|
||||
static int _EPPCBug_pollRead( int minor );
|
||||
static int _EPPCBug_pollWrite( int minor, const char *buf, int len );
|
||||
@@ -87,8 +88,9 @@ static void _BSP_output_char( char c );
|
||||
static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg);
|
||||
static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg);
|
||||
|
||||
static void _BSP_null_char( char c ) {return;}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_output_char;
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_null_char;
|
||||
|
||||
|
||||
/*
|
||||
@@ -502,6 +504,20 @@ static void _BSP_output_char( char c )
|
||||
#endif
|
||||
}
|
||||
|
||||
bd_t *eppcbugInfo= (bd_t *)0xdeadbeef;
|
||||
bd_t fakeEppcBugInfo = {
|
||||
0x42444944, /* Should be 0x42444944 "BDID" */
|
||||
sizeof(bd_t), /* Size of this structure */
|
||||
0, /* revision of this structure */
|
||||
0, /* EPPCbug date, i.e. 0x11061997 */
|
||||
0, /* Memory start address */
|
||||
0x1000000, /* Memory (end) size in bytes */
|
||||
0x28, /* Internal Freq, in Hz */
|
||||
0, /* Bus Freq, in Hz */
|
||||
0, /* Boot device controller */
|
||||
0 /* Boot device logical dev */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
***************
|
||||
@@ -566,7 +582,7 @@ rtems_device_driver console_initialize(
|
||||
m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4 */
|
||||
|
||||
#endif /* mpc860 */
|
||||
|
||||
BSP_output_char = _BSP_output_char;
|
||||
#else /* NVRAM_CONFIGURE != 1 */
|
||||
|
||||
console_minor = CONSOLE_MINOR;
|
||||
@@ -609,14 +625,11 @@ rtems_device_driver console_initialize(
|
||||
|
||||
#endif /* mpc860 */
|
||||
|
||||
BSP_output_char = _BSP_output_char;
|
||||
|
||||
#endif /* NVRAM_CONFIGURE != 1 */
|
||||
|
||||
|
||||
/*
|
||||
* Set up interrupts
|
||||
*/
|
||||
m8xx_uart_interrupts_initialize();
|
||||
|
||||
status = rtems_io_register_name ("/dev/tty0", major, SMC1_MINOR);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred (status);
|
||||
|
||||
455
c/src/lib/libbsp/powerpc/mbx8xx/include/8xx_immap.h
Normal file
455
c/src/lib/libbsp/powerpc/mbx8xx/include/8xx_immap.h
Normal file
@@ -0,0 +1,455 @@
|
||||
|
||||
/*
|
||||
* MPC8xx Internal Memory Map
|
||||
* Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
|
||||
*
|
||||
* The I/O on the MPC860 is comprised of blocks of special registers
|
||||
* and the dual port ram for the Communication Processor Module.
|
||||
* Within this space are functional units such as the SIU, memory
|
||||
* controller, system timers, and other control functions. It is
|
||||
* a combination that I found difficult to separate into logical
|
||||
* functional files.....but anyone else is welcome to try. -- Dan
|
||||
*/
|
||||
#ifndef __IMMAP_8XX__
|
||||
#define __IMMAP_8XX__
|
||||
|
||||
/* System configuration registers.
|
||||
*/
|
||||
typedef struct sys_conf {
|
||||
unsigned int sc_siumcr;
|
||||
unsigned int sc_sypcr;
|
||||
unsigned int sc_swt;
|
||||
char res1[2];
|
||||
unsigned short sc_swsr;
|
||||
unsigned int sc_sipend;
|
||||
unsigned int sc_simask;
|
||||
unsigned int sc_siel;
|
||||
unsigned int sc_sivec;
|
||||
unsigned int sc_tesr;
|
||||
char res2[0xc];
|
||||
unsigned int sc_sdcr;
|
||||
char res3[0x4c];
|
||||
} sysconf8xx_t;
|
||||
|
||||
/* PCMCIA configuration registers.
|
||||
*/
|
||||
typedef struct pcmcia_conf {
|
||||
unsigned int pcmc_pbr0;
|
||||
unsigned int pcmc_por0;
|
||||
unsigned int pcmc_pbr1;
|
||||
unsigned int pcmc_por1;
|
||||
unsigned int pcmc_pbr2;
|
||||
unsigned int pcmc_por2;
|
||||
unsigned int pcmc_pbr3;
|
||||
unsigned int pcmc_por3;
|
||||
unsigned int pcmc_pbr4;
|
||||
unsigned int pcmc_por4;
|
||||
unsigned int pcmc_pbr5;
|
||||
unsigned int pcmc_por5;
|
||||
unsigned int pcmc_pbr6;
|
||||
unsigned int pcmc_por6;
|
||||
unsigned int pcmc_pbr7;
|
||||
unsigned int pcmc_por7;
|
||||
char res1[0x20];
|
||||
unsigned int pcmc_pgcra;
|
||||
unsigned int pcmc_pgcrb;
|
||||
unsigned int pcmc_pscr;
|
||||
char res2[4];
|
||||
unsigned int pcmc_pipr;
|
||||
char res3[4];
|
||||
unsigned int pcmc_per;
|
||||
char res4[4];
|
||||
} pcmconf8xx_t;
|
||||
|
||||
/* Memory controller registers.
|
||||
*/
|
||||
typedef struct mem_ctlr {
|
||||
unsigned int memc_br0;
|
||||
unsigned int memc_or0;
|
||||
unsigned int memc_br1;
|
||||
unsigned int memc_or1;
|
||||
unsigned int memc_br2;
|
||||
unsigned int memc_or2;
|
||||
unsigned int memc_br3;
|
||||
unsigned int memc_or3;
|
||||
unsigned int memc_br4;
|
||||
unsigned int memc_or4;
|
||||
unsigned int memc_br5;
|
||||
unsigned int memc_or5;
|
||||
unsigned int memc_br6;
|
||||
unsigned int memc_or6;
|
||||
unsigned int memc_br7;
|
||||
unsigned int memc_or7;
|
||||
char res1[0x24];
|
||||
unsigned int memc_mar;
|
||||
unsigned int memc_mcr;
|
||||
char res2[4];
|
||||
unsigned int memc_mamr;
|
||||
unsigned int memc_mbmr;
|
||||
unsigned short memc_mstat;
|
||||
unsigned short memc_mptpr;
|
||||
unsigned int memc_mdr;
|
||||
char res3[0x80];
|
||||
} memctl8xx_t;
|
||||
|
||||
/* System Integration Timers.
|
||||
*/
|
||||
typedef struct sys_int_timers {
|
||||
unsigned short sit_tbscr;
|
||||
unsigned int sit_tbreff0;
|
||||
unsigned int sit_tbreff1;
|
||||
char res1[0x14];
|
||||
unsigned short sit_rtcsc;
|
||||
unsigned int sit_rtc;
|
||||
unsigned int sit_rtsec;
|
||||
unsigned int sit_rtcal;
|
||||
char res2[0x10];
|
||||
unsigned short sit_piscr;
|
||||
char res3[2];
|
||||
unsigned int sit_pitc;
|
||||
unsigned int sit_pitr;
|
||||
char res4[0x34];
|
||||
} sit8xx_t;
|
||||
|
||||
#define TBSCR_TBIRQ_MASK ((unsigned short)0xff00)
|
||||
#define TBSCR_REFA ((unsigned short)0x0080)
|
||||
#define TBSCR_REFB ((unsigned short)0x0040)
|
||||
#define TBSCR_REFAE ((unsigned short)0x0008)
|
||||
#define TBSCR_REFBE ((unsigned short)0x0004)
|
||||
#define TBSCR_TBF ((unsigned short)0x0002)
|
||||
#define TBSCR_TBE ((unsigned short)0x0001)
|
||||
|
||||
#define RTCSC_RTCIRQ_MASK ((unsigned short)0xff00)
|
||||
#define RTCSC_SEC ((unsigned short)0x0080)
|
||||
#define RTCSC_ALR ((unsigned short)0x0040)
|
||||
#define RTCSC_38K ((unsigned short)0x0010)
|
||||
#define RTCSC_SIE ((unsigned short)0x0008)
|
||||
#define RTCSC_ALE ((unsigned short)0x0004)
|
||||
#define RTCSC_RTF ((unsigned short)0x0002)
|
||||
#define RTCSC_RTE ((unsigned short)0x0001)
|
||||
|
||||
#define PISCR_PIRQ_MASK ((unsigned short)0xff00)
|
||||
#define PISCR_PS ((unsigned short)0x0080)
|
||||
#define PISCR_PIE ((unsigned short)0x0004)
|
||||
#define PISCR_PTF ((unsigned short)0x0002)
|
||||
#define PISCR_PTE ((unsigned short)0x0001)
|
||||
|
||||
/* Clocks and Reset.
|
||||
*/
|
||||
typedef struct clk_and_reset {
|
||||
unsigned int car_sccr;
|
||||
unsigned int car_plprcr;
|
||||
unsigned int car_rsr;
|
||||
char res[0x74]; /* Reserved area */
|
||||
} car8xx_t;
|
||||
|
||||
/* System Integration Timers keys.
|
||||
*/
|
||||
typedef struct sitk {
|
||||
unsigned int sitk_tbscrk;
|
||||
unsigned int sitk_tbreff0k;
|
||||
unsigned int sitk_tbreff1k;
|
||||
unsigned int sitk_tbk;
|
||||
char res1[0x10];
|
||||
unsigned int sitk_rtcsck;
|
||||
unsigned int sitk_rtck;
|
||||
unsigned int sitk_rtseck;
|
||||
unsigned int sitk_rtcalk;
|
||||
char res2[0x10];
|
||||
unsigned int sitk_piscrk;
|
||||
unsigned int sitk_pitck;
|
||||
char res3[0x38];
|
||||
} sitk8xx_t;
|
||||
|
||||
/* Clocks and reset keys.
|
||||
*/
|
||||
typedef struct cark {
|
||||
unsigned int cark_sccrk;
|
||||
unsigned int cark_plprcrk;
|
||||
unsigned int cark_rsrk;
|
||||
char res[0x474];
|
||||
} cark8xx_t;
|
||||
|
||||
/* The key to unlock registers maintained by keep-alive power.
|
||||
*/
|
||||
#define KAPWR_KEY ((unsigned int)0x55ccaa33)
|
||||
|
||||
/* LCD interface. MPC821 Only.
|
||||
*/
|
||||
typedef struct lcd {
|
||||
unsigned short lcd_lcolr[16];
|
||||
char res[0x20];
|
||||
unsigned int lcd_lccr;
|
||||
unsigned int lcd_lchcr;
|
||||
unsigned int lcd_lcvcr;
|
||||
char res2[4];
|
||||
unsigned int lcd_lcfaa;
|
||||
unsigned int lcd_lcfba;
|
||||
char lcd_lcsr;
|
||||
char res3[0x7];
|
||||
} lcd8xx_t;
|
||||
|
||||
/* I2C
|
||||
*/
|
||||
typedef struct i2c {
|
||||
unsigned char i2c_i2mod;
|
||||
char res1[3];
|
||||
unsigned char i2c_i2add;
|
||||
char res2[3];
|
||||
unsigned char i2c_i2brg;
|
||||
char res3[3];
|
||||
unsigned char i2c_i2com;
|
||||
char res4[3];
|
||||
unsigned char i2c_i2cer;
|
||||
char res5[3];
|
||||
unsigned char i2c_i2cmr;
|
||||
char res6[0x8b];
|
||||
} i2c8xx_t;
|
||||
|
||||
/* DMA control/status registers.
|
||||
*/
|
||||
typedef struct sdma_csr {
|
||||
char res1[4];
|
||||
unsigned int sdma_sdar;
|
||||
unsigned char sdma_sdsr;
|
||||
char res3[3];
|
||||
unsigned char sdma_sdmr;
|
||||
char res4[3];
|
||||
unsigned char sdma_idsr1;
|
||||
char res5[3];
|
||||
unsigned char sdma_idmr1;
|
||||
char res6[3];
|
||||
unsigned char sdma_idsr2;
|
||||
char res7[3];
|
||||
unsigned char sdma_idmr2;
|
||||
char res8[0x13];
|
||||
} sdma8xx_t;
|
||||
|
||||
/* Communication Processor Module Interrupt Controller.
|
||||
*/
|
||||
typedef struct cpm_ic {
|
||||
unsigned short cpic_civr;
|
||||
char res[0xe];
|
||||
unsigned int cpic_cicr;
|
||||
unsigned int cpic_cipr;
|
||||
unsigned int cpic_cimr;
|
||||
unsigned int cpic_cisr;
|
||||
} cpic8xx_t;
|
||||
|
||||
/* Input/Output Port control/status registers.
|
||||
*/
|
||||
typedef struct io_port {
|
||||
unsigned short iop_padir;
|
||||
unsigned short iop_papar;
|
||||
unsigned short iop_paodr;
|
||||
unsigned short iop_padat;
|
||||
char res1[8];
|
||||
unsigned short iop_pcdir;
|
||||
unsigned short iop_pcpar;
|
||||
unsigned short iop_pcso;
|
||||
unsigned short iop_pcdat;
|
||||
unsigned short iop_pcint;
|
||||
char res2[6];
|
||||
unsigned short iop_pddir;
|
||||
unsigned short iop_pdpar;
|
||||
char res3[2];
|
||||
unsigned short iop_pddat;
|
||||
char res4[8];
|
||||
} iop8xx_t;
|
||||
|
||||
/* Communication Processor Module Timers
|
||||
*/
|
||||
typedef struct cpm_timers {
|
||||
unsigned short cpmt_tgcr;
|
||||
char res1[0xe];
|
||||
unsigned short cpmt_tmr1;
|
||||
unsigned short cpmt_tmr2;
|
||||
unsigned short cpmt_trr1;
|
||||
unsigned short cpmt_trr2;
|
||||
unsigned short cpmt_tcr1;
|
||||
unsigned short cpmt_tcr2;
|
||||
unsigned short cpmt_tcn1;
|
||||
unsigned short cpmt_tcn2;
|
||||
unsigned short cpmt_tmr3;
|
||||
unsigned short cpmt_tmr4;
|
||||
unsigned short cpmt_trr3;
|
||||
unsigned short cpmt_trr4;
|
||||
unsigned short cpmt_tcr3;
|
||||
unsigned short cpmt_tcr4;
|
||||
unsigned short cpmt_tcn3;
|
||||
unsigned short cpmt_tcn4;
|
||||
unsigned short cpmt_ter1;
|
||||
unsigned short cpmt_ter2;
|
||||
unsigned short cpmt_ter3;
|
||||
unsigned short cpmt_ter4;
|
||||
char res2[8];
|
||||
} cpmtimer8xx_t;
|
||||
|
||||
/* Finally, the Communication Processor stuff.....
|
||||
*/
|
||||
typedef struct scc { /* Serial communication channels */
|
||||
unsigned int scc_gsmrl;
|
||||
unsigned int scc_gsmrh;
|
||||
unsigned short scc_pmsr;
|
||||
char res1[2];
|
||||
unsigned short scc_todr;
|
||||
unsigned short scc_dsr;
|
||||
unsigned short scc_scce;
|
||||
char res2[2];
|
||||
unsigned short scc_sccm;
|
||||
char res3;
|
||||
unsigned char scc_sccs;
|
||||
char res4[8];
|
||||
} scc_t;
|
||||
|
||||
typedef struct smc { /* Serial management channels */
|
||||
char res1[2];
|
||||
unsigned short smc_smcmr;
|
||||
char res2[2];
|
||||
unsigned char smc_smce;
|
||||
char res3[3];
|
||||
unsigned char smc_smcm;
|
||||
char res4[5];
|
||||
} smc_t;
|
||||
|
||||
/* MPC860T Fast Ethernet Controller. It isn't part of the CPM, but
|
||||
* it fits within the address space.
|
||||
*/
|
||||
typedef struct fec {
|
||||
unsigned int fec_addr_low; /* LS 32 bits of station address */
|
||||
unsigned short fec_addr_high; /* MS 16 bits of address */
|
||||
unsigned short res1;
|
||||
unsigned int fec_hash_table_high;
|
||||
unsigned int fec_hash_table_low;
|
||||
unsigned int fec_r_des_start;
|
||||
unsigned int fec_x_des_start;
|
||||
unsigned int fec_r_buff_size;
|
||||
unsigned int res2[9];
|
||||
unsigned int fec_ecntrl;
|
||||
unsigned int fec_ievent;
|
||||
unsigned int fec_imask;
|
||||
unsigned int fec_ivec;
|
||||
unsigned int fec_r_des_active;
|
||||
unsigned int fec_x_des_active;
|
||||
unsigned int res3[10];
|
||||
unsigned int fec_mii_data;
|
||||
unsigned int fec_mii_speed;
|
||||
unsigned int res4[17];
|
||||
unsigned int fec_r_bound;
|
||||
unsigned int fec_r_fstart;
|
||||
unsigned int res5[6];
|
||||
unsigned int fec_x_fstart;
|
||||
unsigned int res6[17];
|
||||
unsigned int fec_fun_code;
|
||||
unsigned int res7[3];
|
||||
unsigned int fec_r_cntrl;
|
||||
unsigned int fec_r_hash;
|
||||
unsigned int res8[14];
|
||||
unsigned int fec_x_cntrl;
|
||||
unsigned int res9[0x1e];
|
||||
} fec_t;
|
||||
|
||||
typedef struct comm_proc {
|
||||
/* General control and status registers.
|
||||
*/
|
||||
unsigned short cp_cpcr;
|
||||
char res1[2];
|
||||
unsigned short cp_rccr;
|
||||
char res2[6];
|
||||
unsigned short cp_cpmcr1;
|
||||
unsigned short cp_cpmcr2;
|
||||
unsigned short cp_cpmcr3;
|
||||
unsigned short cp_cpmcr4;
|
||||
char res3[2];
|
||||
unsigned short cp_rter;
|
||||
char res4[2];
|
||||
unsigned short cp_rtmr;
|
||||
char res5[0x14];
|
||||
|
||||
/* Baud rate generators.
|
||||
*/
|
||||
unsigned int cp_brgc1;
|
||||
unsigned int cp_brgc2;
|
||||
unsigned int cp_brgc3;
|
||||
unsigned int cp_brgc4;
|
||||
|
||||
/* Serial Communication Channels.
|
||||
*/
|
||||
scc_t cp_scc[4];
|
||||
|
||||
/* Serial Management Channels.
|
||||
*/
|
||||
smc_t cp_smc[2];
|
||||
|
||||
/* Serial Peripheral Interface.
|
||||
*/
|
||||
unsigned short cp_spmode;
|
||||
char res6[4];
|
||||
unsigned char cp_spie;
|
||||
char res7[3];
|
||||
unsigned char cp_spim;
|
||||
char res8[2];
|
||||
unsigned char cp_spcom;
|
||||
char res9[2];
|
||||
|
||||
/* Parallel Interface Port.
|
||||
*/
|
||||
char res10[2];
|
||||
unsigned short cp_pipc;
|
||||
char res11[2];
|
||||
unsigned short cp_ptpr;
|
||||
unsigned int cp_pbdir;
|
||||
unsigned int cp_pbpar;
|
||||
char res12[2];
|
||||
unsigned short cp_pbodr;
|
||||
unsigned int cp_pbdat;
|
||||
char res13[0x18];
|
||||
|
||||
/* Serial Interface and Time Slot Assignment.
|
||||
*/
|
||||
unsigned int cp_simode;
|
||||
unsigned char cp_sigmr;
|
||||
char res14;
|
||||
unsigned char cp_sistr;
|
||||
unsigned char cp_sicmr;
|
||||
char res15[4];
|
||||
unsigned int cp_sicr;
|
||||
unsigned int cp_sirp;
|
||||
char res16[0x10c];
|
||||
unsigned char cp_siram[0x200];
|
||||
|
||||
/* The fast ethernet controller is not really part of the CPM,
|
||||
* but it resides in the address space.
|
||||
*/
|
||||
fec_t cp_fec;
|
||||
char res18[0x1000];
|
||||
|
||||
/* Dual Ported RAM follows.
|
||||
* There are many different formats for this memory area
|
||||
* depending upon the devices used and options chosen.
|
||||
*/
|
||||
unsigned char cp_dpmem[0x1000]; /* BD / Data / ucode */
|
||||
unsigned char res19[0xc00];
|
||||
unsigned char cp_dparam[0x400]; /* Parameter RAM */
|
||||
} cpm8xx_t;
|
||||
|
||||
/* Internal memory map.
|
||||
*/
|
||||
typedef struct immap {
|
||||
sysconf8xx_t im_siu_conf; /* SIU Configuration */
|
||||
pcmconf8xx_t im_pcmcia; /* PCMCIA Configuration */
|
||||
memctl8xx_t im_memctl; /* Memory Controller */
|
||||
sit8xx_t im_sit; /* System integration timers */
|
||||
car8xx_t im_clkrst; /* Clocks and reset */
|
||||
sitk8xx_t im_sitk; /* Sys int timer keys */
|
||||
cark8xx_t im_clkrstk; /* Clocks and reset keys */
|
||||
lcd8xx_t im_lcd; /* LCD (821 only) */
|
||||
i2c8xx_t im_i2c; /* I2C control/status */
|
||||
sdma8xx_t im_sdma; /* SDMA control/status */
|
||||
cpic8xx_t im_cpic; /* CPM Interrupt Controller */
|
||||
iop8xx_t im_ioport; /* IO Port control/status */
|
||||
cpmtimer8xx_t im_cpmtimer; /* CPM timers */
|
||||
cpm8xx_t im_cpm; /* Communication processor */
|
||||
} immap_t;
|
||||
|
||||
#endif /* __IMMAP_8XX__ */
|
||||
@@ -6,17 +6,33 @@ AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
H_FILES = bsp.h coverhd.h
|
||||
|
||||
BSP_H_FILES = mbx.h commproc.h 8xx_immap.h
|
||||
|
||||
$(PROJECT_INCLUDE):
|
||||
$(mkinstalldirs) $@
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp:
|
||||
$(mkinstalldirs) $@
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp.h: bsp.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
$(PROJECT_INCLUDE)/coverhd.h: coverhd.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(PROJECT_INCLUDE)/bsp.h \
|
||||
$(PROJECT_INCLUDE)/coverhd.h
|
||||
$(PROJECT_INCLUDE)/bsp/mbx.h : mbx.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/commproc.h : commproc.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/8xx_immap.h : 8xx_immap.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(PROJECT_INCLUDE)/bsp \
|
||||
$(PROJECT_INCLUDE)/bsp.h \
|
||||
$(PROJECT_INCLUDE)/coverhd.h $(PROJECT_INCLUDE)/bsp/mbx.h \
|
||||
$(PROJECT_INCLUDE)/bsp/commproc.h $(PROJECT_INCLUDE)/bsp/8xx_immap.h
|
||||
|
||||
all-local: $(PREINSTALL_FILES)
|
||||
|
||||
|
||||
529
c/src/lib/libbsp/powerpc/mbx8xx/include/commproc.h
Normal file
529
c/src/lib/libbsp/powerpc/mbx8xx/include/commproc.h
Normal file
@@ -0,0 +1,529 @@
|
||||
|
||||
/*
|
||||
* MPC8xx Communication Processor Module.
|
||||
* Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
|
||||
*
|
||||
* This file contains structures and information for the communication
|
||||
* processor channels. Some CPM control and status is available
|
||||
* throught the MPC8xx internal memory map. See immap.h for details.
|
||||
* This file only contains what I need for the moment, not the total
|
||||
* CPM capabilities. I (or someone else) will add definitions as they
|
||||
* are needed. -- Dan
|
||||
*
|
||||
* On the MBX board, EPPC-Bug loads CPM microcode into the first 512
|
||||
* bytes of the DP RAM and relocates the I2C parameter area to the
|
||||
* IDMA1 space. The remaining DP RAM is available for buffer descriptors
|
||||
* or other use.
|
||||
*/
|
||||
#ifndef __CPM_8XX__
|
||||
#define __CPM_8XX__
|
||||
|
||||
#include <bsp/8xx_immap.h>
|
||||
|
||||
/* CPM Command register.
|
||||
*/
|
||||
#define CPM_CR_RST ((ushort)0x8000)
|
||||
#define CPM_CR_OPCODE ((ushort)0x0f00)
|
||||
#define CPM_CR_CHAN ((ushort)0x00f0)
|
||||
#define CPM_CR_FLG ((ushort)0x0001)
|
||||
|
||||
/* Some commands (there are more...later)
|
||||
*/
|
||||
#define CPM_CR_INIT_TRX ((ushort)0x0000)
|
||||
#define CPM_CR_INIT_RX ((ushort)0x0001)
|
||||
#define CPM_CR_INIT_TX ((ushort)0x0002)
|
||||
#define CPM_CR_STOP_TX ((ushort)0x0004)
|
||||
#define CPM_CR_RESTART_TX ((ushort)0x0006)
|
||||
#define CPM_CR_SET_GADDR ((ushort)0x0008)
|
||||
|
||||
/* Channel numbers.
|
||||
*/
|
||||
#define CPM_CR_CH_SCC1 ((ushort)0x0000)
|
||||
#define CPM_CR_CH_I2C ((ushort)0x0001) /* I2C and IDMA1 */
|
||||
#define CPM_CR_CH_SCC2 ((ushort)0x0004)
|
||||
#define CPM_CR_CH_SPI ((ushort)0x0005) /* SPI / IDMA2 / Timers */
|
||||
#define CPM_CR_CH_SCC3 ((ushort)0x0008)
|
||||
#define CPM_CR_CH_SMC1 ((ushort)0x0009) /* SMC1 / DSP1 */
|
||||
#define CPM_CR_CH_SCC4 ((ushort)0x000c)
|
||||
#define CPM_CR_CH_SMC2 ((ushort)0x000d) /* SMC2 / DSP2 */
|
||||
|
||||
#define mk_cr_cmd(CH, CMD) ((CMD << 8) | (CH << 4))
|
||||
|
||||
/* The dual ported RAM is multi-functional. Some areas can be (and are
|
||||
* being) used for microcode. There is an area that can only be used
|
||||
* as data ram for buffer descriptors, which is all we use right now.
|
||||
* Currently the first 512 and last 256 bytes are used for microcode.
|
||||
*/
|
||||
#define CPM_DATAONLY_BASE ((uint)0x0800)
|
||||
#define CPM_DATAONLY_SIZE ((uint)0x0700)
|
||||
#define CPM_DP_NOSPACE ((uint)0x7fffffff)
|
||||
|
||||
/* Export the base address of the communication processor registers
|
||||
* and dual port ram.
|
||||
*/
|
||||
extern cpm8xx_t *cpmp; /* Pointer to comm processor */
|
||||
uint m8xx_cpm_dpalloc(uint size);
|
||||
uint m8xx_cpm_hostalloc(uint size);
|
||||
void m8xx_cpm_setbrg(uint brg, uint rate);
|
||||
|
||||
/* Buffer descriptors used by many of the CPM protocols.
|
||||
*/
|
||||
typedef struct cpm_buf_desc {
|
||||
ushort cbd_sc; /* Status and Control */
|
||||
ushort cbd_datlen; /* Data length in buffer */
|
||||
uint cbd_bufaddr; /* Buffer address in host memory */
|
||||
} cbd_t;
|
||||
|
||||
#define BD_SC_EMPTY ((ushort)0x8000) /* Recieve is empty */
|
||||
#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */
|
||||
#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */
|
||||
#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */
|
||||
#define BD_SC_CM ((ushort)0x0200) /* Continous mode */
|
||||
#define BD_SC_ID ((ushort)0x0100) /* Rec'd too many idles */
|
||||
#define BD_SC_P ((ushort)0x0100) /* xmt preamble */
|
||||
#define BD_SC_BR ((ushort)0x0020) /* Break received */
|
||||
#define BD_SC_FR ((ushort)0x0010) /* Framing error */
|
||||
#define BD_SC_PR ((ushort)0x0008) /* Parity error */
|
||||
#define BD_SC_OV ((ushort)0x0002) /* Overrun */
|
||||
#define BD_SC_CD ((ushort)0x0001) /* ?? */
|
||||
|
||||
/* Parameter RAM offsets.
|
||||
*/
|
||||
#define PROFF_SCC1 ((uint)0x0000)
|
||||
#define PROFF_SCC2 ((uint)0x0100)
|
||||
#define PROFF_SCC3 ((uint)0x0200)
|
||||
#define PROFF_SMC1 ((uint)0x0280)
|
||||
#define PROFF_SCC4 ((uint)0x0300)
|
||||
#define PROFF_SMC2 ((uint)0x0380)
|
||||
|
||||
/* Define enough so I can at least use the serial port as a UART.
|
||||
*/
|
||||
typedef struct smc_uart {
|
||||
ushort smc_rbase; /* Rx Buffer descriptor base address */
|
||||
ushort smc_tbase; /* Tx Buffer descriptor base address */
|
||||
u_char smc_rfcr; /* Rx function code */
|
||||
u_char smc_tfcr; /* Tx function code */
|
||||
ushort smc_mrblr; /* Max receive buffer length */
|
||||
uint smc_rstate; /* Internal */
|
||||
uint smc_idp; /* Internal */
|
||||
ushort smc_rbptr; /* Internal */
|
||||
ushort smc_ibc; /* Internal */
|
||||
uint smc_rxtmp; /* Internal */
|
||||
uint smc_tstate; /* Internal */
|
||||
uint smc_tdp; /* Internal */
|
||||
ushort smc_tbptr; /* Internal */
|
||||
ushort smc_tbc; /* Internal */
|
||||
uint smc_txtmp; /* Internal */
|
||||
ushort smc_maxidl; /* Maximum idle characters */
|
||||
ushort smc_tmpidl; /* Temporary idle counter */
|
||||
ushort smc_brklen; /* Last received break length */
|
||||
ushort smc_brkec; /* rcv'd break condition counter */
|
||||
ushort smc_brkcr; /* xmt break count register */
|
||||
ushort smc_rmask; /* Temporary bit mask */
|
||||
} smc_uart_t;
|
||||
|
||||
/* Function code bits.
|
||||
*/
|
||||
#define SMC_EB ((u_char)0x10) /* Set big endian byte order */
|
||||
|
||||
/* SMC uart mode register.
|
||||
*/
|
||||
#define SMCMR_REN ((ushort)0x0001)
|
||||
#define SMCMR_TEN ((ushort)0x0002)
|
||||
#define SMCMR_DM ((ushort)0x000c)
|
||||
#define SMCMR_SM_GCI ((ushort)0x0000)
|
||||
#define SMCMR_SM_UART ((ushort)0x0020)
|
||||
#define SMCMR_SM_TRANS ((ushort)0x0030)
|
||||
#define SMCMR_SM_MASK ((ushort)0x0030)
|
||||
#define SMCMR_PM_EVEN ((ushort)0x0100) /* Even parity, else odd */
|
||||
#define SMCMR_PEN ((ushort)0x0200) /* Parity enable */
|
||||
#define SMCMR_SL ((ushort)0x0400) /* Two stops, else one */
|
||||
#define SMCR_CLEN_MASK ((ushort)0x7800) /* Character length */
|
||||
#define smcr_mk_clen(C) (((C) << 11) & SMCR_CLEN_MASK)
|
||||
|
||||
/* SMC Event and Mask register.
|
||||
*/
|
||||
#define SMCM_TXE ((unsigned char)0x10)
|
||||
#define SMCM_BSY ((unsigned char)0x04)
|
||||
#define SMCM_TX ((unsigned char)0x02)
|
||||
#define SMCM_RX ((unsigned char)0x01)
|
||||
|
||||
/* Baud rate generators.
|
||||
*/
|
||||
#define CPM_BRG_RST ((uint)0x00020000)
|
||||
#define CPM_BRG_EN ((uint)0x00010000)
|
||||
#define CPM_BRG_EXTC_INT ((uint)0x00000000)
|
||||
#define CPM_BRG_EXTC_CLK2 ((uint)0x00004000)
|
||||
#define CPM_BRG_EXTC_CLK6 ((uint)0x00008000)
|
||||
#define CPM_BRG_ATB ((uint)0x00002000)
|
||||
#define CPM_BRG_CD_MASK ((uint)0x00001ffe)
|
||||
#define CPM_BRG_DIV16 ((uint)0x00000001)
|
||||
|
||||
/* SCCs.
|
||||
*/
|
||||
#define SCC_GSMRH_IRP ((uint)0x00040000)
|
||||
#define SCC_GSMRH_GDE ((uint)0x00010000)
|
||||
#define SCC_GSMRH_TCRC_CCITT ((uint)0x00008000)
|
||||
#define SCC_GSMRH_TCRC_BISYNC ((uint)0x00004000)
|
||||
#define SCC_GSMRH_TCRC_HDLC ((uint)0x00000000)
|
||||
#define SCC_GSMRH_REVD ((uint)0x00002000)
|
||||
#define SCC_GSMRH_TRX ((uint)0x00001000)
|
||||
#define SCC_GSMRH_TTX ((uint)0x00000800)
|
||||
#define SCC_GSMRH_CDP ((uint)0x00000400)
|
||||
#define SCC_GSMRH_CTSP ((uint)0x00000200)
|
||||
#define SCC_GSMRH_CDS ((uint)0x00000100)
|
||||
#define SCC_GSMRH_CTSS ((uint)0x00000080)
|
||||
#define SCC_GSMRH_TFL ((uint)0x00000040)
|
||||
#define SCC_GSMRH_RFW ((uint)0x00000020)
|
||||
#define SCC_GSMRH_TXSY ((uint)0x00000010)
|
||||
#define SCC_GSMRH_SYNL16 ((uint)0x0000000c)
|
||||
#define SCC_GSMRH_SYNL8 ((uint)0x00000008)
|
||||
#define SCC_GSMRH_SYNL4 ((uint)0x00000004)
|
||||
#define SCC_GSMRH_RTSM ((uint)0x00000002)
|
||||
#define SCC_GSMRH_RSYN ((uint)0x00000001)
|
||||
|
||||
#define SCC_GSMRL_SIR ((uint)0x80000000) /* SCC2 only */
|
||||
#define SCC_GSMRL_EDGE_NONE ((uint)0x60000000)
|
||||
#define SCC_GSMRL_EDGE_NEG ((uint)0x40000000)
|
||||
#define SCC_GSMRL_EDGE_POS ((uint)0x20000000)
|
||||
#define SCC_GSMRL_EDGE_BOTH ((uint)0x00000000)
|
||||
#define SCC_GSMRL_TCI ((uint)0x10000000)
|
||||
#define SCC_GSMRL_TSNC_3 ((uint)0x0c000000)
|
||||
#define SCC_GSMRL_TSNC_4 ((uint)0x08000000)
|
||||
#define SCC_GSMRL_TSNC_14 ((uint)0x04000000)
|
||||
#define SCC_GSMRL_TSNC_INF ((uint)0x00000000)
|
||||
#define SCC_GSMRL_RINV ((uint)0x02000000)
|
||||
#define SCC_GSMRL_TINV ((uint)0x01000000)
|
||||
#define SCC_GSMRL_TPL_128 ((uint)0x00c00000)
|
||||
#define SCC_GSMRL_TPL_64 ((uint)0x00a00000)
|
||||
#define SCC_GSMRL_TPL_48 ((uint)0x00800000)
|
||||
#define SCC_GSMRL_TPL_32 ((uint)0x00600000)
|
||||
#define SCC_GSMRL_TPL_16 ((uint)0x00400000)
|
||||
#define SCC_GSMRL_TPL_8 ((uint)0x00200000)
|
||||
#define SCC_GSMRL_TPL_NONE ((uint)0x00000000)
|
||||
#define SCC_GSMRL_TPP_ALL1 ((uint)0x00180000)
|
||||
#define SCC_GSMRL_TPP_01 ((uint)0x00100000)
|
||||
#define SCC_GSMRL_TPP_10 ((uint)0x00080000)
|
||||
#define SCC_GSMRL_TPP_ZEROS ((uint)0x00000000)
|
||||
#define SCC_GSMRL_TEND ((uint)0x00040000)
|
||||
#define SCC_GSMRL_TDCR_32 ((uint)0x00030000)
|
||||
#define SCC_GSMRL_TDCR_16 ((uint)0x00020000)
|
||||
#define SCC_GSMRL_TDCR_8 ((uint)0x00010000)
|
||||
#define SCC_GSMRL_TDCR_1 ((uint)0x00000000)
|
||||
#define SCC_GSMRL_RDCR_32 ((uint)0x0000c000)
|
||||
#define SCC_GSMRL_RDCR_16 ((uint)0x00008000)
|
||||
#define SCC_GSMRL_RDCR_8 ((uint)0x00004000)
|
||||
#define SCC_GSMRL_RDCR_1 ((uint)0x00000000)
|
||||
#define SCC_GSMRL_RENC_DFMAN ((uint)0x00003000)
|
||||
#define SCC_GSMRL_RENC_MANCH ((uint)0x00002000)
|
||||
#define SCC_GSMRL_RENC_FM0 ((uint)0x00001000)
|
||||
#define SCC_GSMRL_RENC_NRZI ((uint)0x00000800)
|
||||
#define SCC_GSMRL_RENC_NRZ ((uint)0x00000000)
|
||||
#define SCC_GSMRL_TENC_DFMAN ((uint)0x00000600)
|
||||
#define SCC_GSMRL_TENC_MANCH ((uint)0x00000400)
|
||||
#define SCC_GSMRL_TENC_FM0 ((uint)0x00000200)
|
||||
#define SCC_GSMRL_TENC_NRZI ((uint)0x00000100)
|
||||
#define SCC_GSMRL_TENC_NRZ ((uint)0x00000000)
|
||||
#define SCC_GSMRL_DIAG_LE ((uint)0x000000c0) /* Loop and echo */
|
||||
#define SCC_GSMRL_DIAG_ECHO ((uint)0x00000080)
|
||||
#define SCC_GSMRL_DIAG_LOOP ((uint)0x00000040)
|
||||
#define SCC_GSMRL_DIAG_NORM ((uint)0x00000000)
|
||||
#define SCC_GSMRL_ENR ((uint)0x00000020)
|
||||
#define SCC_GSMRL_ENT ((uint)0x00000010)
|
||||
#define SCC_GSMRL_MODE_ENET ((uint)0x0000000c)
|
||||
#define SCC_GSMRL_MODE_DDCMP ((uint)0x00000009)
|
||||
#define SCC_GSMRL_MODE_BISYNC ((uint)0x00000008)
|
||||
#define SCC_GSMRL_MODE_V14 ((uint)0x00000007)
|
||||
#define SCC_GSMRL_MODE_AHDLC ((uint)0x00000006)
|
||||
#define SCC_GSMRL_MODE_PROFIBUS ((uint)0x00000005)
|
||||
#define SCC_GSMRL_MODE_UART ((uint)0x00000004)
|
||||
#define SCC_GSMRL_MODE_SS7 ((uint)0x00000003)
|
||||
#define SCC_GSMRL_MODE_ATALK ((uint)0x00000002)
|
||||
#define SCC_GSMRL_MODE_HDLC ((uint)0x00000000)
|
||||
|
||||
#define SCC_TODR_TOD ((ushort)0x8000)
|
||||
|
||||
/* SCC Event and Mask register.
|
||||
*/
|
||||
#define SCCM_TXE ((unsigned char)0x10)
|
||||
#define SCCM_BSY ((unsigned char)0x04)
|
||||
#define SCCM_TX ((unsigned char)0x02)
|
||||
#define SCCM_RX ((unsigned char)0x01)
|
||||
|
||||
typedef struct scc_param {
|
||||
ushort scc_rbase; /* Rx Buffer descriptor base address */
|
||||
ushort scc_tbase; /* Tx Buffer descriptor base address */
|
||||
u_char scc_rfcr; /* Rx function code */
|
||||
u_char scc_tfcr; /* Tx function code */
|
||||
ushort scc_mrblr; /* Max receive buffer length */
|
||||
uint scc_rstate; /* Internal */
|
||||
uint scc_idp; /* Internal */
|
||||
ushort scc_rbptr; /* Internal */
|
||||
ushort scc_ibc; /* Internal */
|
||||
uint scc_rxtmp; /* Internal */
|
||||
uint scc_tstate; /* Internal */
|
||||
uint scc_tdp; /* Internal */
|
||||
ushort scc_tbptr; /* Internal */
|
||||
ushort scc_tbc; /* Internal */
|
||||
uint scc_txtmp; /* Internal */
|
||||
uint scc_rcrc; /* Internal */
|
||||
uint scc_tcrc; /* Internal */
|
||||
} sccp_t;
|
||||
|
||||
/* Function code bits.
|
||||
*/
|
||||
#define SCC_EB ((u_char)0x10) /* Set big endian byte order */
|
||||
|
||||
/* CPM Ethernet through SCC1.
|
||||
*/
|
||||
typedef struct scc_enet {
|
||||
sccp_t sen_genscc;
|
||||
uint sen_cpres; /* Preset CRC */
|
||||
uint sen_cmask; /* Constant mask for CRC */
|
||||
uint sen_crcec; /* CRC Error counter */
|
||||
uint sen_alec; /* alignment error counter */
|
||||
uint sen_disfc; /* discard frame counter */
|
||||
ushort sen_pads; /* Tx short frame pad character */
|
||||
ushort sen_retlim; /* Retry limit threshold */
|
||||
ushort sen_retcnt; /* Retry limit counter */
|
||||
ushort sen_maxflr; /* maximum frame length register */
|
||||
ushort sen_minflr; /* minimum frame length register */
|
||||
ushort sen_maxd1; /* maximum DMA1 length */
|
||||
ushort sen_maxd2; /* maximum DMA2 length */
|
||||
ushort sen_maxd; /* Rx max DMA */
|
||||
ushort sen_dmacnt; /* Rx DMA counter */
|
||||
ushort sen_maxb; /* Max BD byte count */
|
||||
ushort sen_gaddr1; /* Group address filter */
|
||||
ushort sen_gaddr2;
|
||||
ushort sen_gaddr3;
|
||||
ushort sen_gaddr4;
|
||||
uint sen_tbuf0data0; /* Save area 0 - current frame */
|
||||
uint sen_tbuf0data1; /* Save area 1 - current frame */
|
||||
uint sen_tbuf0rba; /* Internal */
|
||||
uint sen_tbuf0crc; /* Internal */
|
||||
ushort sen_tbuf0bcnt; /* Internal */
|
||||
ushort sen_paddrh; /* physical address (MSB) */
|
||||
ushort sen_paddrm;
|
||||
ushort sen_paddrl; /* physical address (LSB) */
|
||||
ushort sen_pper; /* persistence */
|
||||
ushort sen_rfbdptr; /* Rx first BD pointer */
|
||||
ushort sen_tfbdptr; /* Tx first BD pointer */
|
||||
ushort sen_tlbdptr; /* Tx last BD pointer */
|
||||
uint sen_tbuf1data0; /* Save area 0 - current frame */
|
||||
uint sen_tbuf1data1; /* Save area 1 - current frame */
|
||||
uint sen_tbuf1rba; /* Internal */
|
||||
uint sen_tbuf1crc; /* Internal */
|
||||
ushort sen_tbuf1bcnt; /* Internal */
|
||||
ushort sen_txlen; /* Tx Frame length counter */
|
||||
ushort sen_iaddr1; /* Individual address filter */
|
||||
ushort sen_iaddr2;
|
||||
ushort sen_iaddr3;
|
||||
ushort sen_iaddr4;
|
||||
ushort sen_boffcnt; /* Backoff counter */
|
||||
|
||||
/* NOTE: Some versions of the manual have the following items
|
||||
* incorrectly documented. Below is the proper order.
|
||||
*/
|
||||
ushort sen_taddrh; /* temp address (MSB) */
|
||||
ushort sen_taddrm;
|
||||
ushort sen_taddrl; /* temp address (LSB) */
|
||||
} scc_enet_t;
|
||||
|
||||
/* Bits in parallel I/O port registers that have to be set/cleared
|
||||
* to configure the pins for SCC1 use. The TCLK and RCLK seem unique
|
||||
* to the MBX860 board. Any two of the four available clocks could be
|
||||
* used, and the MPC860 cookbook manual has an example using different
|
||||
* clock pins.
|
||||
*/
|
||||
#define PA_ENET_RXD ((ushort)0x0001)
|
||||
#define PA_ENET_TXD ((ushort)0x0002)
|
||||
#define PA_ENET_TCLK ((ushort)0x0200)
|
||||
#define PA_ENET_RCLK ((ushort)0x0800)
|
||||
#define PC_ENET_TENA ((ushort)0x0001)
|
||||
#define PC_ENET_CLSN ((ushort)0x0010)
|
||||
#define PC_ENET_RENA ((ushort)0x0020)
|
||||
|
||||
/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
|
||||
* SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
|
||||
*/
|
||||
#define SICR_ENET_MASK ((uint)0x000000ff)
|
||||
#define SICR_ENET_CLKRT ((uint)0x0000003d)
|
||||
|
||||
/* SCC Event register as used by Ethernet.
|
||||
*/
|
||||
#define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */
|
||||
#define SCCE_ENET_TXE ((ushort)0x0010) /* Transmit Error */
|
||||
#define SCCE_ENET_RXF ((ushort)0x0008) /* Full frame received */
|
||||
#define SCCE_ENET_BSY ((ushort)0x0004) /* All incoming buffers full */
|
||||
#define SCCE_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */
|
||||
#define SCCE_ENET_RXB ((ushort)0x0001) /* A buffer was received */
|
||||
|
||||
/* SCC Mode Register (PMSR) as used by Ethernet.
|
||||
*/
|
||||
#define SCC_PMSR_HBC ((ushort)0x8000) /* Enable heartbeat */
|
||||
#define SCC_PMSR_FC ((ushort)0x4000) /* Force collision */
|
||||
#define SCC_PMSR_RSH ((ushort)0x2000) /* Receive short frames */
|
||||
#define SCC_PMSR_IAM ((ushort)0x1000) /* Check individual hash */
|
||||
#define SCC_PMSR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */
|
||||
#define SCC_PMSR_PRO ((ushort)0x0200) /* Promiscuous mode */
|
||||
#define SCC_PMSR_BRO ((ushort)0x0100) /* Catch broadcast pkts */
|
||||
#define SCC_PMSR_SBT ((ushort)0x0080) /* Special backoff timer */
|
||||
#define SCC_PMSR_LPB ((ushort)0x0040) /* Set Loopback mode */
|
||||
#define SCC_PMSR_SIP ((ushort)0x0020) /* Sample Input Pins */
|
||||
#define SCC_PMSR_LCW ((ushort)0x0010) /* Late collision window */
|
||||
#define SCC_PMSR_NIB22 ((ushort)0x000a) /* Start frame search */
|
||||
#define SCC_PMSR_FDE ((ushort)0x0001) /* Full duplex enable */
|
||||
|
||||
/* Buffer descriptor control/status used by Ethernet receive.
|
||||
*/
|
||||
#define BD_ENET_RX_EMPTY ((ushort)0x8000)
|
||||
#define BD_ENET_RX_WRAP ((ushort)0x2000)
|
||||
#define BD_ENET_RX_INTR ((ushort)0x1000)
|
||||
#define BD_ENET_RX_LAST ((ushort)0x0800)
|
||||
#define BD_ENET_RX_FIRST ((ushort)0x0400)
|
||||
#define BD_ENET_RX_MISS ((ushort)0x0100)
|
||||
#define BD_ENET_RX_LG ((ushort)0x0020)
|
||||
#define BD_ENET_RX_NO ((ushort)0x0010)
|
||||
#define BD_ENET_RX_SH ((ushort)0x0008)
|
||||
#define BD_ENET_RX_CR ((ushort)0x0004)
|
||||
#define BD_ENET_RX_OV ((ushort)0x0002)
|
||||
#define BD_ENET_RX_CL ((ushort)0x0001)
|
||||
#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */
|
||||
|
||||
/* Buffer descriptor control/status used by Ethernet transmit.
|
||||
*/
|
||||
#define BD_ENET_TX_READY ((ushort)0x8000)
|
||||
#define BD_ENET_TX_PAD ((ushort)0x4000)
|
||||
#define BD_ENET_TX_WRAP ((ushort)0x2000)
|
||||
#define BD_ENET_TX_INTR ((ushort)0x1000)
|
||||
#define BD_ENET_TX_LAST ((ushort)0x0800)
|
||||
#define BD_ENET_TX_TC ((ushort)0x0400)
|
||||
#define BD_ENET_TX_DEF ((ushort)0x0200)
|
||||
#define BD_ENET_TX_HB ((ushort)0x0100)
|
||||
#define BD_ENET_TX_LC ((ushort)0x0080)
|
||||
#define BD_ENET_TX_RL ((ushort)0x0040)
|
||||
#define BD_ENET_TX_RCMASK ((ushort)0x003c)
|
||||
#define BD_ENET_TX_UN ((ushort)0x0002)
|
||||
#define BD_ENET_TX_CSL ((ushort)0x0001)
|
||||
#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */
|
||||
|
||||
/* SCC as UART
|
||||
*/
|
||||
typedef struct scc_uart {
|
||||
sccp_t scc_genscc;
|
||||
uint scc_res1; /* Reserved */
|
||||
uint scc_res2; /* Reserved */
|
||||
ushort scc_maxidl; /* Maximum idle chars */
|
||||
ushort scc_idlc; /* temp idle counter */
|
||||
ushort scc_brkcr; /* Break count register */
|
||||
ushort scc_parec; /* receive parity error counter */
|
||||
ushort scc_frmec; /* receive framing error counter */
|
||||
ushort scc_nosec; /* receive noise counter */
|
||||
ushort scc_brkec; /* receive break condition counter */
|
||||
ushort scc_brkln; /* last received break length */
|
||||
ushort scc_uaddr1; /* UART address character 1 */
|
||||
ushort scc_uaddr2; /* UART address character 2 */
|
||||
ushort scc_rtemp; /* Temp storage */
|
||||
ushort scc_toseq; /* Transmit out of sequence char */
|
||||
ushort scc_char1; /* control character 1 */
|
||||
ushort scc_char2; /* control character 2 */
|
||||
ushort scc_char3; /* control character 3 */
|
||||
ushort scc_char4; /* control character 4 */
|
||||
ushort scc_char5; /* control character 5 */
|
||||
ushort scc_char6; /* control character 6 */
|
||||
ushort scc_char7; /* control character 7 */
|
||||
ushort scc_char8; /* control character 8 */
|
||||
ushort scc_rccm; /* receive control character mask */
|
||||
ushort scc_rccr; /* receive control character register */
|
||||
ushort scc_rlbc; /* receive last break character */
|
||||
} scc_uart_t;
|
||||
|
||||
/* SCC Event and Mask registers when it is used as a UART.
|
||||
*/
|
||||
#define UART_SCCM_GLR ((ushort)0x1000)
|
||||
#define UART_SCCM_GLT ((ushort)0x0800)
|
||||
#define UART_SCCM_AB ((ushort)0x0200)
|
||||
#define UART_SCCM_IDL ((ushort)0x0100)
|
||||
#define UART_SCCM_GRA ((ushort)0x0080)
|
||||
#define UART_SCCM_BRKE ((ushort)0x0040)
|
||||
#define UART_SCCM_BRKS ((ushort)0x0020)
|
||||
#define UART_SCCM_CCR ((ushort)0x0008)
|
||||
#define UART_SCCM_BSY ((ushort)0x0004)
|
||||
#define UART_SCCM_TX ((ushort)0x0002)
|
||||
#define UART_SCCM_RX ((ushort)0x0001)
|
||||
|
||||
/* The SCC PMSR when used as a UART.
|
||||
*/
|
||||
#define SCU_PMSR_FLC ((ushort)0x8000)
|
||||
#define SCU_PMSR_SL ((ushort)0x4000)
|
||||
#define SCU_PMSR_CL ((ushort)0x3000)
|
||||
#define SCU_PMSR_UM ((ushort)0x0c00)
|
||||
#define SCU_PMSR_FRZ ((ushort)0x0200)
|
||||
#define SCU_PMSR_RZS ((ushort)0x0100)
|
||||
#define SCU_PMSR_SYN ((ushort)0x0080)
|
||||
#define SCU_PMSR_DRT ((ushort)0x0040)
|
||||
#define SCU_PMSR_PEN ((ushort)0x0010)
|
||||
#define SCU_PMSR_RPM ((ushort)0x000c)
|
||||
#define SCU_PMSR_REVP ((ushort)0x0008)
|
||||
#define SCU_PMSR_TPM ((ushort)0x0003)
|
||||
#define SCU_PMSR_TEVP ((ushort)0x0003)
|
||||
|
||||
/* CPM Transparent mode SCC.
|
||||
*/
|
||||
typedef struct scc_trans {
|
||||
sccp_t st_genscc;
|
||||
uint st_cpres; /* Preset CRC */
|
||||
uint st_cmask; /* Constant mask for CRC */
|
||||
} scc_trans_t;
|
||||
|
||||
/* CPM interrupts. There are nearly 32 interrupts generated by CPM
|
||||
* channels or devices. All of these are presented to the PPC core
|
||||
* as a single interrupt. The CPM interrupt handler dispatches its
|
||||
* own handlers, in a similar fashion to the PPC core handler. We
|
||||
* use the table as defined in the manuals (i.e. no special high
|
||||
* priority and SCC1 == SCCa, etc...).
|
||||
*/
|
||||
#define CPMVEC_NR 32
|
||||
#define CPMVEC_PIO_PC15 ((ushort)0x1f)
|
||||
#define CPMVEC_SCC1 ((ushort)0x1e)
|
||||
#define CPMVEC_SCC2 ((ushort)0x1d)
|
||||
#define CPMVEC_SCC3 ((ushort)0x1c)
|
||||
#define CPMVEC_SCC4 ((ushort)0x1b)
|
||||
#define CPMVEC_PIO_PC14 ((ushort)0x1a)
|
||||
#define CPMVEC_TIMER1 ((ushort)0x19)
|
||||
#define CPMVEC_PIO_PC13 ((ushort)0x18)
|
||||
#define CPMVEC_PIO_PC12 ((ushort)0x17)
|
||||
#define CPMVEC_SDMA_CB_ERR ((ushort)0x16)
|
||||
#define CPMVEC_IDMA1 ((ushort)0x15)
|
||||
#define CPMVEC_IDMA2 ((ushort)0x14)
|
||||
#define CPMVEC_TIMER2 ((ushort)0x12)
|
||||
#define CPMVEC_RISCTIMER ((ushort)0x11)
|
||||
#define CPMVEC_I2C ((ushort)0x10)
|
||||
#define CPMVEC_PIO_PC11 ((ushort)0x0f)
|
||||
#define CPMVEC_PIO_PC10 ((ushort)0x0e)
|
||||
#define CPMVEC_TIMER3 ((ushort)0x0c)
|
||||
#define CPMVEC_PIO_PC9 ((ushort)0x0b)
|
||||
#define CPMVEC_PIO_PC8 ((ushort)0x0a)
|
||||
#define CPMVEC_PIO_PC7 ((ushort)0x09)
|
||||
#define CPMVEC_TIMER4 ((ushort)0x07)
|
||||
#define CPMVEC_PIO_PC6 ((ushort)0x06)
|
||||
#define CPMVEC_SPI ((ushort)0x05)
|
||||
#define CPMVEC_SMC1 ((ushort)0x04)
|
||||
#define CPMVEC_SMC2 ((ushort)0x03)
|
||||
#define CPMVEC_PIO_PC5 ((ushort)0x02)
|
||||
#define CPMVEC_PIO_PC4 ((ushort)0x01)
|
||||
#define CPMVEC_ERROR ((ushort)0x00)
|
||||
|
||||
extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
|
||||
|
||||
/* CPM interrupt configuration vector.
|
||||
*/
|
||||
#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */
|
||||
#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */
|
||||
#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */
|
||||
#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */
|
||||
#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrrupt */
|
||||
#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */
|
||||
#define CICR_IEN ((uint)0x00000080) /* Int. enable */
|
||||
#define CICR_SPS ((uint)0x00000001) /* SCC Spread */
|
||||
#endif /* __CPM_8XX__ */
|
||||
62
c/src/lib/libbsp/powerpc/mbx8xx/include/mbx.h
Normal file
62
c/src/lib/libbsp/powerpc/mbx8xx/include/mbx.h
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
/*
|
||||
* A collection of structures, addresses, and values associated with
|
||||
* the Motorola MBX boards. This was originally created for the
|
||||
* MBX860, and probably needs revisions for other boards (like the 821).
|
||||
* When this file gets out of control, we can split it up into more
|
||||
* meaningful pieces.
|
||||
*
|
||||
* Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
|
||||
*/
|
||||
#ifndef __MACH_MBX_DEFS
|
||||
#define __MACH_MBX_DEFS
|
||||
|
||||
/* A Board Information structure that is given to a program when
|
||||
* EPPC-Bug starts it up.
|
||||
*/
|
||||
typedef struct bd_info {
|
||||
unsigned int bi_tag; /* Should be 0x42444944 "BDID" */
|
||||
unsigned int bi_size; /* Size of this structure */
|
||||
unsigned int bi_revision; /* revision of this structure */
|
||||
unsigned int bi_bdate; /* EPPCbug date, i.e. 0x11061997 */
|
||||
unsigned int bi_memstart; /* Memory start address */
|
||||
unsigned int bi_memsize; /* Memory (end) size in bytes */
|
||||
unsigned int bi_intfreq; /* Internal Freq, in Hz */
|
||||
unsigned int bi_busfreq; /* Bus Freq, in Hz */
|
||||
unsigned int bi_clun; /* Boot device controller */
|
||||
unsigned int bi_dlun; /* Boot device logical dev */
|
||||
} bd_t;
|
||||
|
||||
/* Memory map for the MBX as configured by EPPC-Bug. We could reprogram
|
||||
* The SIU and PCI bridge, and try to use larger MMU pages, but the
|
||||
* performance gain is not measureable and it certainly complicates the
|
||||
* generic MMU model.
|
||||
*
|
||||
* In a effort to minimize memory usage for embedded applications, any
|
||||
* PCI driver or ISA driver must request or map the region required by
|
||||
* the device. For convenience (and since we can map up to 4 Mbytes with
|
||||
* a single page table page), the MMU initialization will map the
|
||||
* NVRAM, Status/Control registers, CPM Dual Port RAM, and the PCI
|
||||
* Bridge CSRs 1:1 into the kernel address space.
|
||||
*/
|
||||
#define PCI_ISA_IO_ADDR ((unsigned int)0x80000000)
|
||||
#define PCI_ISA_IO_SIZE ((unsigned int)(512 * 1024 * 1024))
|
||||
#define PCI_ISA_MEM_ADDR ((unsigned int)0xc0000000)
|
||||
#define PCI_ISA_MEM_SIZE ((unsigned int)(512 * 1024 * 1024))
|
||||
#define PCMCIA_MEM_ADDR ((unsigned int)0xe0000000)
|
||||
#define PCMCIA_MEM_SIZE ((unsigned int)(64 * 1024 * 1024))
|
||||
#define PCMCIA_DMA_ADDR ((unsigned int)0xe4000000)
|
||||
#define PCMCIA_DMA_SIZE ((unsigned int)(64 * 1024 * 1024))
|
||||
#define PCMCIA_ATTRB_ADDR ((unsigned int)0xe8000000)
|
||||
#define PCMCIA_ATTRB_SIZE ((unsigned int)(64 * 1024 * 1024))
|
||||
#define PCMCIA_IO_ADDR ((unsigned int)0xec000000)
|
||||
#define PCMCIA_IO_SIZE ((unsigned int)(64 * 1024 * 1024))
|
||||
#define NVRAM_ADDR ((unsigned int)0xfa000000)
|
||||
#define NVRAM_SIZE ((unsigned int)(1 * 1024 * 1024))
|
||||
#define MBX_CSR_ADDR ((unsigned int)0xfa100000)
|
||||
#define MBX_CSR_SIZE ((unsigned int)(1 * 1024 * 1024))
|
||||
#define IMAP_ADDR ((unsigned int)0xfa200000)
|
||||
#define IMAP_SIZE ((unsigned int)(64 * 1024))
|
||||
#define PCI_CSR_ADDR ((unsigned int)0xfa210000)
|
||||
#define PCI_CSR_SIZE ((unsigned int)(64 * 1024))
|
||||
#endif
|
||||
2
c/src/lib/libbsp/powerpc/mbx8xx/irq/.cvsignore
Normal file
2
c/src/lib/libbsp/powerpc/mbx8xx/irq/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
46
c/src/lib/libbsp/powerpc/mbx8xx/irq/Makefile.am
Normal file
46
c/src/lib/libbsp/powerpc/mbx8xx/irq/Makefile.am
Normal file
@@ -0,0 +1,46 @@
|
||||
##
|
||||
## $Id$
|
||||
##
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
C_FILES = irq.c irq_init.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||
|
||||
H_FILES = irq.h
|
||||
|
||||
S_FILES = irq_asm.S
|
||||
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
|
||||
|
||||
OBJS = $(C_O_FILES) $(S_O_FILES)
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
include $(top_srcdir)/../../../../../../automake/lib.am
|
||||
|
||||
SORDID_HACK:
|
||||
rm -f $(PROJECT_INCLUDE)/bsp/irq.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp:
|
||||
$(mkinstalldirs) $@
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/%.h: %.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp \
|
||||
$(H_FILES:%.h=$(PROJECT_INCLUDE)/bsp/%.h)
|
||||
|
||||
#
|
||||
# (OPTIONAL) Add local stuff here using +=
|
||||
#
|
||||
|
||||
$(PGM): $(OBJS)
|
||||
$(make-rel)
|
||||
|
||||
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
|
||||
|
||||
all-local: SORDID_HACK $(PREINSTALL_FILES) $(ARCH) $(OBJS) $(PGM)
|
||||
|
||||
EXTRA_DIST = irq.c irq.h irq_asm.S irq_init.c
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
506
c/src/lib/libbsp/powerpc/mbx8xx/irq/irq.c
Normal file
506
c/src/lib/libbsp/powerpc/mbx8xx/irq/irq.c
Normal file
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
*
|
||||
* This file contains the implementation of the function described in irq.h
|
||||
*
|
||||
* Copyright (C) 1998, 1999 valette@crf.canon.fr
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/apiext.h>
|
||||
#include <libcpu/raw_exception.h>
|
||||
#include <bsp/vectors.h>
|
||||
#include <libcpu/cpu.h>
|
||||
#include <bsp/8xx_immap.h>
|
||||
#include <bsp/mbx.h>
|
||||
#include <bsp/commproc.h>
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* Check if symbolic IRQ name is an SIU IRQ
|
||||
*/
|
||||
static inline int is_siu_irq(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
return (((int) irqLine <= BSP_SIU_IRQ_MAX_OFFSET) &
|
||||
((int) irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if symbolic IRQ name is an CPM IRQ
|
||||
*/
|
||||
static inline int is_cpm_irq(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
return (((int) irqLine <= BSP_CPM_IRQ_MAX_OFFSET) &
|
||||
((int) irqLine >= BSP_CPM_IRQ_LOWEST_OFFSET)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if symbolic IRQ name is a Processor IRQ
|
||||
*/
|
||||
static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
|
||||
((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* masks used to mask off the interrupts. For exmaple, for ILVL2, the
|
||||
* mask is used to mask off interrupts ILVL2, IRQ3, ILVL3, ... IRQ7
|
||||
* and ILVL7.
|
||||
*
|
||||
*/
|
||||
const static unsigned int SIU_IvectMask[BSP_SIU_IRQ_NUMBER] =
|
||||
{
|
||||
/* IRQ0 ILVL0 IRQ1 ILVL1 */
|
||||
0x00000000, 0x80000000, 0xC0000000, 0xE0000000,
|
||||
|
||||
/* IRQ2 ILVL2 IRQ3 ILVL3 */
|
||||
0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000,
|
||||
|
||||
/* IRQ4 ILVL4 IRQ5 ILVL5 */
|
||||
0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000,
|
||||
|
||||
/* IRQ6 ILVL6 IRQ7 ILVL7 */
|
||||
0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000
|
||||
};
|
||||
|
||||
/*
|
||||
* ------------------------ RTEMS Irq helper functions ----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Caution : this function assumes the variable "internal_config"
|
||||
* is already set and that the tables it contains are still valid
|
||||
* and accessible.
|
||||
*/
|
||||
static void compute_SIU_IvectMask_from_prio ()
|
||||
{
|
||||
/*
|
||||
* In theory this is feasible. No time to code it yet. See i386/shared/irq.c
|
||||
* for an example based on 8259 controller mask. The actual masks defined
|
||||
* correspond to the priorities defined for the SIU in irq_init.c.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* 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) || (irq == BSP_CPM_INTERRUPT) )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BSP_irq_enable_at_cpm(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
int cpm_irq_index;
|
||||
|
||||
if (!is_cpm_irq(irqLine))
|
||||
return 1;
|
||||
|
||||
cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
|
||||
((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << cpm_irq_index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BSP_irq_disable_at_cpm(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
int cpm_irq_index;
|
||||
|
||||
if (!is_cpm_irq(irqLine))
|
||||
return 1;
|
||||
|
||||
cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
|
||||
((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << cpm_irq_index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BSP_irq_enabled_at_cpm(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
int cpm_irq_index;
|
||||
|
||||
if (!is_cpm_irq(irqLine))
|
||||
return 0;
|
||||
|
||||
cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
|
||||
return (((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr & (1 << cpm_irq_index));
|
||||
}
|
||||
|
||||
int BSP_irq_enable_at_siu(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
int siu_irq_index;
|
||||
|
||||
if (!is_siu_irq(irqLine))
|
||||
return 1;
|
||||
|
||||
siu_irq_index = ((int) (irqLine) - BSP_SIU_IRQ_LOWEST_OFFSET);
|
||||
ppc_cached_irq_mask |= (1 << (31-siu_irq_index));
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BSP_irq_disable_at_siu(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
int siu_irq_index;
|
||||
|
||||
if (!is_siu_irq(irqLine))
|
||||
return 1;
|
||||
|
||||
siu_irq_index = ((int) (irqLine) - BSP_SIU_IRQ_LOWEST_OFFSET);
|
||||
ppc_cached_irq_mask &= ~(1 << (31-siu_irq_index));
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BSP_irq_enabled_at_siu (const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
int siu_irq_index;
|
||||
|
||||
if (!is_siu_irq(irqLine))
|
||||
return 0;
|
||||
|
||||
siu_irq_index = ((int) (irqLine) - BSP_SIU_IRQ_LOWEST_OFFSET);
|
||||
return ppc_cached_irq_mask & (1 << (31-siu_irq_index));
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
|
||||
*/
|
||||
|
||||
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
|
||||
{
|
||||
unsigned int level;
|
||||
|
||||
if (!isValidInterrupt(irq->name)) {
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Check if default handler is actually connected. If not issue an error.
|
||||
* You must first get the current handler via i386_get_current_idt_entry
|
||||
* and then disconnect it using i386_delete_idt_entry.
|
||||
* 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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
|
||||
/*
|
||||
* store the data provided by user
|
||||
*/
|
||||
rtems_hdl_tbl[irq->name] = *irq;
|
||||
|
||||
if (is_cpm_irq(irq->name)) {
|
||||
/*
|
||||
* Enable interrupt at PIC level
|
||||
*/
|
||||
BSP_irq_enable_at_cpm (irq->name);
|
||||
}
|
||||
|
||||
if (is_siu_irq(irq->name)) {
|
||||
/*
|
||||
* Enable interrupt at SIU level
|
||||
*/
|
||||
BSP_irq_enable_at_siu (irq->name);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
}
|
||||
/*
|
||||
* Enable interrupt on device
|
||||
*/
|
||||
irq->on(irq);
|
||||
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
|
||||
{
|
||||
unsigned int level;
|
||||
|
||||
if (!isValidInterrupt(irq->name)) {
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Check if default handler is actually connected. If not issue an error.
|
||||
* You must first get the current handler via i386_get_current_idt_entry
|
||||
* and then disconnect it using i386_delete_idt_entry.
|
||||
* 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;
|
||||
}
|
||||
_CPU_ISR_Disable(level);
|
||||
|
||||
if (is_cpm_irq(irq->name)) {
|
||||
/*
|
||||
* disable interrupt at PIC level
|
||||
*/
|
||||
BSP_irq_disable_at_cpm (irq->name);
|
||||
}
|
||||
if (is_siu_irq(irq->name)) {
|
||||
/*
|
||||
* disable interrupt at OPENPIC level
|
||||
*/
|
||||
BSP_irq_disable_at_siu (irq->name);
|
||||
}
|
||||
if (is_processor_irq(irq->name)) {
|
||||
/*
|
||||
* disable exception at processor level
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable interrupt on device
|
||||
*/
|
||||
irq->off(irq);
|
||||
|
||||
/*
|
||||
* restore the default irq value
|
||||
*/
|
||||
rtems_hdl_tbl[irq->name] = default_rtems_entry;
|
||||
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
|
||||
*/
|
||||
|
||||
int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
|
||||
{
|
||||
int i;
|
||||
unsigned int level;
|
||||
/*
|
||||
* Store various code accelerators
|
||||
*/
|
||||
internal_config = config;
|
||||
default_rtems_entry = config->defaultEntry;
|
||||
rtems_hdl_tbl = config->irqHdlTbl;
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
/*
|
||||
* start with CPM IRQ
|
||||
*/
|
||||
for (i=BSP_CPM_IRQ_LOWEST_OFFSET; i < BSP_CPM_IRQ_LOWEST_OFFSET + BSP_CPM_IRQ_NUMBER ; i++) {
|
||||
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
|
||||
BSP_irq_enable_at_cpm (i);
|
||||
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
|
||||
}
|
||||
else {
|
||||
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
|
||||
BSP_irq_disable_at_cpm (i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* continue with PCI IRQ
|
||||
*/
|
||||
/*
|
||||
* set up internal tables used by rtems interrupt prologue
|
||||
*/
|
||||
compute_SIU_IvectMask_from_prio ();
|
||||
|
||||
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);
|
||||
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
|
||||
}
|
||||
else {
|
||||
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
|
||||
BSP_irq_disable_at_siu (i);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Must enable CPM interrupt on SIU. CPM on SIU Interrupt level has already been
|
||||
* set up in BSP_CPM_irq_init.
|
||||
*/
|
||||
((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN;
|
||||
BSP_irq_enable_at_siu (BSP_CPM_INTERRUPT);
|
||||
/*
|
||||
* finish with Processor exceptions handled like IRQ
|
||||
*/
|
||||
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) {
|
||||
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
|
||||
}
|
||||
else {
|
||||
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
|
||||
}
|
||||
}
|
||||
_CPU_ISR_Enable(level);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
|
||||
{
|
||||
*config = internal_config;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DISPATCH_HANDLER_STAT
|
||||
volatile unsigned int maxLoop = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* High level IRQ handler called from shared_raw_irq_code_entry
|
||||
*/
|
||||
void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
|
||||
{
|
||||
register unsigned int irq;
|
||||
register unsigned cpmIntr; /* boolean */
|
||||
register unsigned oldMask; /* old siu pic masks */
|
||||
register unsigned msr;
|
||||
register unsigned new_msr;
|
||||
unsigned loopCounter;
|
||||
|
||||
/*
|
||||
* Handle decrementer interrupt
|
||||
*/
|
||||
if (excNum == ASM_DEC_VECTOR) {
|
||||
_CPU_MSR_GET(msr);
|
||||
new_msr = msr | MSR_EE;
|
||||
_CPU_MSR_SET(new_msr);
|
||||
|
||||
rtems_hdl_tbl[BSP_DECREMENTER].hdl();
|
||||
|
||||
_CPU_MSR_SET(msr);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Handle external interrupt generated by SIU on PPC core
|
||||
*/
|
||||
#ifdef DISPATCH_HANDLER_STAT
|
||||
loopCounter = 0;
|
||||
#endif
|
||||
while (1) {
|
||||
if ((ppc_cached_irq_mask & ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend) == 0) {
|
||||
#ifdef DISPATCH_HANDLER_STAT
|
||||
if (loopCounter > maxLoop) maxLoop = loopCounter;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
irq = (((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26);
|
||||
cpmIntr = (irq == BSP_CPM_INTERRUPT);
|
||||
/*
|
||||
* Disable the interrupt of the same and lower priority.
|
||||
*/
|
||||
oldMask = ppc_cached_irq_mask;
|
||||
ppc_cached_irq_mask = oldMask & SIU_IvectMask[irq];
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
|
||||
/*
|
||||
* Acknowledge current interrupt. This has no effect on internal level interrupt.
|
||||
*/
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = (1 << (31 - irq));
|
||||
|
||||
if (cpmIntr) {
|
||||
/*
|
||||
* We will reenable the SIU CPM interrupt to allow nesting of CPM interrupt.
|
||||
* We must before acknowledege the current irq at CPM level to avoid trigerring
|
||||
* the interrupt again.
|
||||
*/
|
||||
/*
|
||||
* Acknowledge and get the vector.
|
||||
*/
|
||||
((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
|
||||
irq = (((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr >> 11);
|
||||
/*
|
||||
* transform IRQ to normalized irq table index.
|
||||
*/
|
||||
irq += BSP_CPM_IRQ_LOWEST_OFFSET;
|
||||
/*
|
||||
* Unmask CPM interrupt at SIU level
|
||||
*/
|
||||
ppc_cached_irq_mask |= (1 << (31 - BSP_CPM_INTERRUPT));
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
|
||||
}
|
||||
_CPU_MSR_GET(msr);
|
||||
new_msr = msr | MSR_EE;
|
||||
_CPU_MSR_SET(new_msr);
|
||||
|
||||
rtems_hdl_tbl[irq].hdl();
|
||||
|
||||
_CPU_MSR_SET(msr);
|
||||
|
||||
if (cpmIntr) {
|
||||
irq -= BSP_CPM_IRQ_LOWEST_OFFSET;
|
||||
((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr = (1 << irq);
|
||||
}
|
||||
ppc_cached_irq_mask |= (oldMask & ~(SIU_IvectMask[irq]));
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
|
||||
#ifdef DISPATCH_HANDLER_STAT
|
||||
++ loopCounter;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
if ( _Thread_Do_post_task_switch_extension ||
|
||||
_Thread_Executing->do_post_task_switch_extension ) {
|
||||
_Thread_Executing->do_post_task_switch_extension = FALSE;
|
||||
_API_extensions_Run_postswitch();
|
||||
}
|
||||
/*
|
||||
* I plan to process other thread related events here.
|
||||
* This will include DEBUG session requested from keyboard...
|
||||
*/
|
||||
}
|
||||
331
c/src/lib/libbsp/powerpc/mbx8xx/irq/irq.h
Normal file
331
c/src/lib/libbsp/powerpc/mbx8xx/irq/irq.h
Normal file
@@ -0,0 +1,331 @@
|
||||
/* irq.h
|
||||
*
|
||||
* This include file describe the data structure and the functions implemented
|
||||
* by rtems to write interrupt handlers.
|
||||
*
|
||||
* CopyRight (C) 1999 valette@crf.canon.fr
|
||||
*
|
||||
* This code is heavilly inspired by the public specification of STREAM V2
|
||||
* that can be found at :
|
||||
*
|
||||
* <http://www.chorus.com/Documentation/index.html> by following
|
||||
* the STREAM API Specification Document link.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_POWERPC_MBX8XX_IRQ_IRQ_H
|
||||
#define LIBBSP_POWERPC_MBX8XX_IRQ_IRQ_H
|
||||
|
||||
|
||||
#define BSP_ASM_IRQ_VECTOR_BASE 0x0
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
extern volatile unsigned int ppc_cached_irq_mask;
|
||||
|
||||
/*
|
||||
* Symblolic IRQ names and related definitions.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* Base vector for our SIU IRQ handlers. */
|
||||
BSP_SIU_VECTOR_BASE = BSP_ASM_IRQ_VECTOR_BASE,
|
||||
/*
|
||||
* SIU IRQ handler related definitions
|
||||
*/
|
||||
BSP_SIU_IRQ_NUMBER = 16, /* 16 reserved but in the future... */
|
||||
BSP_SIU_IRQ_LOWEST_OFFSET = 0,
|
||||
BSP_SIU_IRQ_MAX_OFFSET = BSP_SIU_IRQ_LOWEST_OFFSET + BSP_SIU_IRQ_NUMBER - 1,
|
||||
/*
|
||||
* CPM IRQ handlers related definitions
|
||||
* CAUTION : BSP_CPM_IRQ_LOWEST_OFFSET should be equal to OPENPIC_VEC_SOURCE
|
||||
*/
|
||||
BSP_CPM_IRQ_NUMBER = 32,
|
||||
BSP_CPM_IRQ_LOWEST_OFFSET = BSP_SIU_IRQ_NUMBER + BSP_SIU_VECTOR_BASE,
|
||||
BSP_CPM_IRQ_MAX_OFFSET = BSP_CPM_IRQ_LOWEST_OFFSET + BSP_CPM_IRQ_NUMBER - 1,
|
||||
/*
|
||||
* PowerPc exceptions handled as interrupt where a rtems managed interrupt
|
||||
* handler might be connected
|
||||
*/
|
||||
BSP_PROCESSOR_IRQ_NUMBER = 1,
|
||||
BSP_PROCESSOR_IRQ_LOWEST_OFFSET = BSP_CPM_IRQ_MAX_OFFSET + 1,
|
||||
BSP_PROCESSOR_IRQ_MAX_OFFSET = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1,
|
||||
/*
|
||||
* Summary
|
||||
*/
|
||||
BSP_IRQ_NUMBER = BSP_PROCESSOR_IRQ_MAX_OFFSET + 1,
|
||||
BSP_LOWEST_OFFSET = BSP_SIU_IRQ_LOWEST_OFFSET,
|
||||
BSP_MAX_OFFSET = BSP_PROCESSOR_IRQ_MAX_OFFSET,
|
||||
/*
|
||||
* Some SIU IRQ symbolic name definition. Please note that
|
||||
* INT IRQ are defined but a single one will be used to
|
||||
* redirect all CPM interrupt.
|
||||
*/
|
||||
BSP_SIU_EXT_IRQ_0 = 0,
|
||||
BSP_SIU_INT_IRQ_0 = 1,
|
||||
|
||||
BSP_SIU_EXT_IRQ_1 = 2,
|
||||
BSP_SIU_INT_IRQ_1 = 3,
|
||||
|
||||
BSP_SIU_EXT_IRQ_2 = 4,
|
||||
BSP_SIU_INT_IRQ_2 = 5,
|
||||
|
||||
BSP_SIU_EXT_IRQ_3 = 6,
|
||||
BSP_SIU_INT_IRQ_3 = 7,
|
||||
|
||||
BSP_SIU_EXT_IRQ_4 = 8,
|
||||
BSP_SIU_INT_IRQ_4 = 9,
|
||||
|
||||
BSP_SIU_EXT_IRQ_5 = 10,
|
||||
BSP_SIU_INT_IRQ_5 = 11,
|
||||
|
||||
BSP_SIU_EXT_IRQ_6 = 12,
|
||||
BSP_SIU_INT_IRQ_6 = 13,
|
||||
|
||||
BSP_SIU_EXT_IRQ_7 = 14,
|
||||
BSP_SIU_INT_IRQ_7 = 15,
|
||||
/*
|
||||
* Symbolic name for CPM interrupt on SIU Internal level 2
|
||||
*/
|
||||
BSP_CPM_INTERRUPT = BSP_SIU_INT_IRQ_2,
|
||||
BSP_PERIODIC_TIMER = BSP_SIU_INT_IRQ_6,
|
||||
BSP_FAST_ETHERNET_CTRL = BSP_SIU_INT_IRQ_3,
|
||||
/*
|
||||
* Some CPM IRQ symbolic name definition
|
||||
*/
|
||||
BSP_CPM_IRQ_ERROR = BSP_CPM_IRQ_LOWEST_OFFSET,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC4 = BSP_CPM_IRQ_LOWEST_OFFSET + 1,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC5 = BSP_CPM_IRQ_LOWEST_OFFSET + 2,
|
||||
BSP_CPM_IRQ_SMC2_OR_PIP = BSP_CPM_IRQ_LOWEST_OFFSET + 3,
|
||||
BSP_CPM_IRQ_SMC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 4,
|
||||
BSP_CPM_IRQ_SPI = BSP_CPM_IRQ_LOWEST_OFFSET + 5,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC6 = BSP_CPM_IRQ_LOWEST_OFFSET + 6,
|
||||
BSP_CPM_IRQ_TIMER_4 = BSP_CPM_IRQ_LOWEST_OFFSET + 7,
|
||||
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC7 = BSP_CPM_IRQ_LOWEST_OFFSET + 9,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC8 = BSP_CPM_IRQ_LOWEST_OFFSET + 10,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC9 = BSP_CPM_IRQ_LOWEST_OFFSET + 11,
|
||||
BSP_CPM_IRQ_TIMER_3 = BSP_CPM_IRQ_LOWEST_OFFSET + 12,
|
||||
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC10 = BSP_CPM_IRQ_LOWEST_OFFSET + 14,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC11 = BSP_CPM_IRQ_LOWEST_OFFSET + 15,
|
||||
BSP_CPM_I2C = BSP_CPM_IRQ_LOWEST_OFFSET + 16,
|
||||
BSP_CPM_RISC_TIMER_TABLE = BSP_CPM_IRQ_LOWEST_OFFSET + 17,
|
||||
BSP_CPM_IRQ_TIMER_2 = BSP_CPM_IRQ_LOWEST_OFFSET + 18,
|
||||
|
||||
BSP_CPM_IDMA2 = BSP_CPM_IRQ_LOWEST_OFFSET + 20,
|
||||
BSP_CPM_IDMA1 = BSP_CPM_IRQ_LOWEST_OFFSET + 21,
|
||||
BSP_CPM_SDMA_CHANNEL_BUS_ERR = BSP_CPM_IRQ_LOWEST_OFFSET + 22,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC12 = BSP_CPM_IRQ_LOWEST_OFFSET + 23,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC13 = BSP_CPM_IRQ_LOWEST_OFFSET + 24,
|
||||
BSP_CPM_IRQ_TIMER_1 = BSP_CPM_IRQ_LOWEST_OFFSET + 25,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC14 = BSP_CPM_IRQ_LOWEST_OFFSET + 26,
|
||||
BSP_CPM_IRQ_SCC4 = BSP_CPM_IRQ_LOWEST_OFFSET + 27,
|
||||
BSP_CPM_IRQ_SCC3 = BSP_CPM_IRQ_LOWEST_OFFSET + 28,
|
||||
BSP_CPM_IRQ_SCC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 29,
|
||||
BSP_CPM_IRQ_SCC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 30,
|
||||
BSP_CPM_IRQ_PARALLEL_IO_PC15 = BSP_CPM_IRQ_LOWEST_OFFSET + 31,
|
||||
/*
|
||||
* Some Processor exception handled as rtems IRQ symbolic name definition
|
||||
*/
|
||||
BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET
|
||||
|
||||
}rtems_irq_symbolic_name;
|
||||
|
||||
#define CPM_INTERRUPT
|
||||
|
||||
|
||||
/*
|
||||
* Type definition for RTEMS managed interrupts
|
||||
*/
|
||||
typedef unsigned char rtems_irq_prio;
|
||||
struct __rtems_irq_connect_data__; /* forward declaratiuon */
|
||||
|
||||
typedef void (*rtems_irq_hdl) (void);
|
||||
typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
|
||||
typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
|
||||
typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
|
||||
|
||||
typedef struct __rtems_irq_connect_data__ {
|
||||
/*
|
||||
* IRQ line
|
||||
*/
|
||||
rtems_irq_symbolic_name name;
|
||||
/*
|
||||
* handler. See comment on handler properties below in function prototype.
|
||||
*/
|
||||
rtems_irq_hdl hdl;
|
||||
/*
|
||||
* function for enabling interrupts at device level (ONLY!).
|
||||
* The BSP code will automatically enable it at SIU level and CPM level.
|
||||
* RATIONALE : anyway such code has to exist in current driver code.
|
||||
* It is usually called immediately AFTER connecting the interrupt handler.
|
||||
* RTEMS may well need such a function when restoring normal interrupt
|
||||
* processing after a debug session.
|
||||
*
|
||||
*/
|
||||
rtems_irq_enable on;
|
||||
/*
|
||||
* function for disabling interrupts at device level (ONLY!).
|
||||
* The code will disable it at SIU and CPM level. RATIONALE : anyway
|
||||
* such code has to exist for clean shutdown. It is usually called
|
||||
* BEFORE disconnecting the interrupt. RTEMS may well need such
|
||||
* a function when disabling normal interrupt processing for
|
||||
* a debug session. May well be a NOP function.
|
||||
*/
|
||||
rtems_irq_disable off;
|
||||
/*
|
||||
* function enabling to know what interrupt may currently occur
|
||||
* if someone manipulates the i8259s interrupt mask without care...
|
||||
*/
|
||||
rtems_irq_is_enabled isOn;
|
||||
}rtems_irq_connect_data;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* size of all the table fields (*Tbl) described below.
|
||||
*/
|
||||
unsigned int irqNb;
|
||||
/*
|
||||
* Default handler used when disconnecting interrupts.
|
||||
*/
|
||||
rtems_irq_connect_data defaultEntry;
|
||||
/*
|
||||
* Table containing initials/current value.
|
||||
*/
|
||||
rtems_irq_connect_data* irqHdlTbl;
|
||||
/*
|
||||
* actual value of BSP_SIU_IRQ_VECTOR_BASE...
|
||||
*/
|
||||
rtems_irq_symbolic_name irqBase;
|
||||
/*
|
||||
* software priorities associated with interrupts.
|
||||
* if irqPrio [i] > intrPrio [j] it means that
|
||||
* interrupt handler hdl connected for interrupt name i
|
||||
* will not be interrupted by the handler connected for interrupt j
|
||||
* The interrupt source will be physically masked at i8259 level.
|
||||
*/
|
||||
rtems_irq_prio* irqPrioTbl;
|
||||
}rtems_irq_global_settings;
|
||||
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function Prototypes.
|
||||
+--------------------------------------------------------------------------*/
|
||||
/*
|
||||
* ------------------------ PPC SIU Mngt Routines -------
|
||||
*/
|
||||
|
||||
/*
|
||||
* function to disable a particular irq at 8259 level. After calling
|
||||
* this function, even if the device asserts the interrupt line it will
|
||||
* not be propagated further to the processor
|
||||
*/
|
||||
int BSP_irq_disable_at_siu (const rtems_irq_symbolic_name irqLine);
|
||||
/*
|
||||
* function to enable a particular irq at 8259 level. After calling
|
||||
* this function, if the device asserts the interrupt line it will
|
||||
* be propagated further to the processor
|
||||
*/
|
||||
int BSP_irq_enable_at_siu (const rtems_irq_symbolic_name irqLine);
|
||||
/*
|
||||
* function to acknoledge a particular irq at 8259 level. After calling
|
||||
* this function, if a device asserts an enabled interrupt line it will
|
||||
* be propagated further to the processor. Mainly usefull for people
|
||||
* writting raw handlers as this is automagically done for rtems managed
|
||||
* handlers.
|
||||
*/
|
||||
int BSP_irq_ack_at_siu (const rtems_irq_symbolic_name irqLine);
|
||||
/*
|
||||
* function to check if a particular irq is enabled at 8259 level. After calling
|
||||
*/
|
||||
int BSP_irq_enabled_at_siu (const rtems_irq_symbolic_name irqLine);
|
||||
/*
|
||||
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
|
||||
*/
|
||||
/*
|
||||
* function to connect a particular irq handler. This hanlder will NOT be called
|
||||
* directly as the result of the corresponding interrupt. Instead, a RTEMS
|
||||
* irq prologue will be called that will :
|
||||
*
|
||||
* 1) save the C scratch registers,
|
||||
* 2) switch to a interrupt stack if the interrupt is not nested,
|
||||
* 4) modify them to disable the current interrupt at SIU level (and may
|
||||
* be others depending on software priorities)
|
||||
* 5) aknowledge the SIU',
|
||||
* 6) demask the processor,
|
||||
* 7) call the application handler
|
||||
*
|
||||
* As a result the hdl function provided
|
||||
*
|
||||
* a) can perfectly be written is C,
|
||||
* b) may also well directly call the part of the RTEMS API that can be used
|
||||
* from interrupt level,
|
||||
* c) It only responsible for handling the jobs that need to be done at
|
||||
* the device level including (aknowledging/re-enabling the interrupt at device,
|
||||
* level, getting the data,...)
|
||||
*
|
||||
* When returning from the function, the following will be performed by
|
||||
* the RTEMS irq epilogue :
|
||||
*
|
||||
* 1) masks the interrupts again,
|
||||
* 2) restore the original SIU interrupt masks
|
||||
* 3) switch back on the orinal stack if needed,
|
||||
* 4) perform rescheduling when necessary,
|
||||
* 5) restore the C scratch registers...
|
||||
* 6) restore initial execution flow
|
||||
*
|
||||
*/
|
||||
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
|
||||
/*
|
||||
* function to get the current RTEMS irq handler for ptr->name. It enables to
|
||||
* define hanlder chain...
|
||||
*/
|
||||
int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
|
||||
/*
|
||||
* function to get disconnect the RTEMS irq handler for ptr->name.
|
||||
* This function checks that the value given is the current one for safety reason.
|
||||
* The user can use the previous function to get it.
|
||||
*/
|
||||
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
|
||||
|
||||
/*
|
||||
* ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
|
||||
*/
|
||||
/*
|
||||
* (Re) Initialize the RTEMS interrupt management.
|
||||
*
|
||||
* The result of calling this function will be the same as if each individual
|
||||
* handler (config->irqHdlTbl[i].hdl) different from "config->defaultEntry.hdl"
|
||||
* has been individualy connected via
|
||||
* BSP_install_rtems_irq_handler(&config->irqHdlTbl[i])
|
||||
* And each handler currently equal to config->defaultEntry.hdl
|
||||
* has been previously disconnected via
|
||||
* BSP_remove_rtems_irq_handler (&config->irqHdlTbl[i])
|
||||
*
|
||||
* This is to say that all information given will be used and not just
|
||||
* only the space.
|
||||
*
|
||||
* CAUTION : the various table address contained in config will be used
|
||||
* directly by the interrupt mangement code in order to save
|
||||
* data size so they must stay valid after the call => they should
|
||||
* not be modified or declared on a stack.
|
||||
*/
|
||||
|
||||
int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config);
|
||||
/*
|
||||
* (Re) get info on current RTEMS interrupt management.
|
||||
*/
|
||||
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings**);
|
||||
|
||||
extern void BSP_rtems_irq_mng_init(unsigned cpuId);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
329
c/src/lib/libbsp/powerpc/mbx8xx/irq/irq_asm.S
Normal file
329
c/src/lib/libbsp/powerpc/mbx8xx/irq/irq_asm.S
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* This file contains the assembly code for the PowerPC
|
||||
* IRQ veneers for RTEMS.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* Modified to support the MCP750.
|
||||
* Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <bsp/vectors.h>
|
||||
#include <libcpu/cpu.h>
|
||||
#include <libcpu/raw_exception.h>
|
||||
#include <rtems/score/cpuopts.h> /* for PPC_HAS_FPU */
|
||||
#include "asm.h"
|
||||
|
||||
|
||||
#define SYNC \
|
||||
sync; \
|
||||
isync
|
||||
|
||||
.text
|
||||
.p2align 5
|
||||
|
||||
PUBLIC_VAR(decrementer_exception_vector_prolog_code)
|
||||
|
||||
SYM (decrementer_exception_vector_prolog_code):
|
||||
/*
|
||||
* let room for exception frame
|
||||
*/
|
||||
stwu r1, - (EXCEPTION_FRAME_END)(r1)
|
||||
stw r4, GPR4_OFFSET(r1)
|
||||
li r4, ASM_DEC_VECTOR
|
||||
ba shared_raw_irq_code_entry
|
||||
|
||||
PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
|
||||
|
||||
decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
|
||||
|
||||
PUBLIC_VAR(external_exception_vector_prolog_code)
|
||||
|
||||
SYM (external_exception_vector_prolog_code):
|
||||
/*
|
||||
* let room for exception frame
|
||||
*/
|
||||
stwu r1, - (EXCEPTION_FRAME_END)(r1)
|
||||
stw r4, GPR4_OFFSET(r1)
|
||||
li r4, ASM_EXT_VECTOR
|
||||
ba shared_raw_irq_code_entry
|
||||
|
||||
PUBLIC_VAR (external_exception_vector_prolog_code_size)
|
||||
|
||||
external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
|
||||
|
||||
PUBLIC_VAR(shared_raw_irq_code_entry)
|
||||
PUBLIC_VAR(C_dispatch_irq_handler)
|
||||
|
||||
.p2align 5
|
||||
SYM (shared_raw_irq_code_entry):
|
||||
/*
|
||||
* Entry conditions :
|
||||
* Registers already saved : R1, R4
|
||||
* R1 : points to a location with enough room for the
|
||||
* interrupt frame
|
||||
* R4 : vector number
|
||||
*/
|
||||
/*
|
||||
* Save SRR0/SRR1 As soon As possible as it is the minimal needed
|
||||
* to reenable exception processing
|
||||
*/
|
||||
stw r0, GPR0_OFFSET(r1)
|
||||
stw r2, GPR2_OFFSET(r1)
|
||||
stw r3, GPR3_OFFSET(r1)
|
||||
|
||||
mfsrr0 r0
|
||||
mfsrr1 r2
|
||||
mfmsr r3
|
||||
|
||||
stw r0, SRR0_FRAME_OFFSET(r1)
|
||||
stw r2, SRR1_FRAME_OFFSET(r1)
|
||||
/*
|
||||
* Enable data and instruction address translation, exception recovery
|
||||
*
|
||||
* also, on CPUs with FP, enable FP so that FP context can be
|
||||
* saved and restored (using FP instructions)
|
||||
*/
|
||||
#if (PPC_HAS_FPU == 0)
|
||||
ori r3, r3, MSR_RI | MSR_IR | MSR_DR
|
||||
#else
|
||||
ori r3, r3, MSR_RI | MSR_IR | MSR_DR | MSR_FP
|
||||
#endif
|
||||
mtmsr r3
|
||||
SYNC
|
||||
/*
|
||||
* Push C scratch registers on the current stack. It may
|
||||
* actually be the thread stack or the interrupt stack.
|
||||
* Anyway we have to make it in order to be able to call C/C++
|
||||
* functions. Depending on the nesting interrupt level, we will
|
||||
* switch to the right stack later.
|
||||
*/
|
||||
stw r5, GPR5_OFFSET(r1)
|
||||
stw r6, GPR6_OFFSET(r1)
|
||||
stw r7, GPR7_OFFSET(r1)
|
||||
stw r8, GPR8_OFFSET(r1)
|
||||
stw r9, GPR9_OFFSET(r1)
|
||||
stw r10, GPR10_OFFSET(r1)
|
||||
stw r11, GPR11_OFFSET(r1)
|
||||
stw r12, GPR12_OFFSET(r1)
|
||||
stw r13, GPR13_OFFSET(r1)
|
||||
|
||||
mfcr r5
|
||||
mfctr r6
|
||||
mfxer r7
|
||||
mflr r8
|
||||
|
||||
stw r5, EXC_CR_OFFSET(r1)
|
||||
stw r6, EXC_CTR_OFFSET(r1)
|
||||
stw r7, EXC_XER_OFFSET(r1)
|
||||
stw r8, EXC_LR_OFFSET(r1)
|
||||
|
||||
/*
|
||||
* Add some non volatile registers to store information
|
||||
* that will be used when returning from C handler
|
||||
*/
|
||||
stw r14, GPR14_OFFSET(r1)
|
||||
stw r15, GPR15_OFFSET(r1)
|
||||
/*
|
||||
* save current stack pointer location in R14
|
||||
*/
|
||||
addi r14, r1, 0
|
||||
/*
|
||||
* store part of _Thread_Dispatch_disable_level address in R15
|
||||
*/
|
||||
addis r15,0, _Thread_Dispatch_disable_level@ha
|
||||
/*
|
||||
* Get current nesting level in R2
|
||||
*/
|
||||
mfspr r2, SPRG0
|
||||
/*
|
||||
* Check if stack switch is necessary
|
||||
*/
|
||||
cmpwi r2,0
|
||||
bne nested
|
||||
mfspr r1, SPRG1
|
||||
|
||||
nested:
|
||||
/*
|
||||
* Start Incrementing nesting level in R2
|
||||
*/
|
||||
addi r2,r2,1
|
||||
/*
|
||||
* Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
|
||||
*/
|
||||
lwz r6,_Thread_Dispatch_disable_level@l(r15)
|
||||
/*
|
||||
* store new nesting level in SPRG0
|
||||
*/
|
||||
mtspr SPRG0, r2
|
||||
|
||||
addi r6, r6, 1
|
||||
mfmsr r5
|
||||
/*
|
||||
* store new _Thread_Dispatch_disable_level value
|
||||
*/
|
||||
stw r6, _Thread_Dispatch_disable_level@l(r15)
|
||||
/*
|
||||
* We are now running on the interrupt stack. External and decrementer
|
||||
* exceptions are still disabled. I see no purpose trying to optimize
|
||||
* further assembler code.
|
||||
*/
|
||||
/*
|
||||
* Call C exception handler for decrementer Interrupt frame is passed just
|
||||
* in case...
|
||||
*/
|
||||
addi r3, r14, 0x8
|
||||
bl C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
|
||||
/*
|
||||
* start decrementing nesting level. Note : do not test result against 0
|
||||
* value as an easy exit condition because if interrupt nesting level > 1
|
||||
* then _Thread_Dispatch_disable_level > 1
|
||||
*/
|
||||
mfspr r2, SPRG0
|
||||
/*
|
||||
* start decrementing _Thread_Dispatch_disable_level
|
||||
*/
|
||||
lwz r3,_Thread_Dispatch_disable_level@l(r15)
|
||||
addi r2, r2, -1 /* Continue decrementing nesting level */
|
||||
addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */
|
||||
mtspr SPRG0, r2 /* End decrementing nesting level */
|
||||
stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
|
||||
cmpwi r3, 0
|
||||
/*
|
||||
* switch back to original stack (done here just optimize registers
|
||||
* contention. Could have been done before...)
|
||||
*/
|
||||
addi r1, r14, 0
|
||||
bne easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
|
||||
/*
|
||||
* Here we are running again on the thread system stack.
|
||||
* We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
|
||||
* Interrupt are still disabled. Time to check if scheduler request to
|
||||
* do something with the current thread...
|
||||
*/
|
||||
addis r4, 0, _Context_Switch_necessary@ha
|
||||
lwz r5, _Context_Switch_necessary@l(r4)
|
||||
cmpwi r5, 0
|
||||
bne switch
|
||||
|
||||
addis r6, 0, _ISR_Signals_to_thread_executing@ha
|
||||
lwz r7, _ISR_Signals_to_thread_executing@l(r6)
|
||||
cmpwi r7, 0
|
||||
li r8, 0
|
||||
beq easy_exit
|
||||
stw r8, _ISR_Signals_to_thread_executing@l(r6)
|
||||
/*
|
||||
* going to call _ThreadProcessSignalsFromIrq
|
||||
* Push a complete exception like frame...
|
||||
*/
|
||||
stmw r16, GPR16_OFFSET(r1)
|
||||
addi r3, r1, 0x8
|
||||
/*
|
||||
* compute SP at exception entry
|
||||
*/
|
||||
addi r2, r1, EXCEPTION_FRAME_END
|
||||
/*
|
||||
* store it at the right place
|
||||
*/
|
||||
stw r2, GPR1_OFFSET(r1)
|
||||
/*
|
||||
* Call High Level signal handling code
|
||||
*/
|
||||
bl _ThreadProcessSignalsFromIrq
|
||||
/*
|
||||
* start restoring exception like frame
|
||||
*/
|
||||
lwz r31, EXC_CTR_OFFSET(r1)
|
||||
lwz r30, EXC_XER_OFFSET(r1)
|
||||
lwz r29, EXC_CR_OFFSET(r1)
|
||||
lwz r28, EXC_LR_OFFSET(r1)
|
||||
|
||||
mtctr r31
|
||||
mtxer r30
|
||||
mtcr r29
|
||||
mtlr r28
|
||||
|
||||
lmw r4, GPR4_OFFSET(r1)
|
||||
lwz r2, GPR2_OFFSET(r1)
|
||||
lwz r0, GPR0_OFFSET(r1)
|
||||
|
||||
/*
|
||||
* Disable data and instruction translation. Make path non recoverable...
|
||||
*/
|
||||
mfmsr r3
|
||||
xori r3, r3, MSR_RI | MSR_IR | MSR_DR
|
||||
mtmsr r3
|
||||
SYNC
|
||||
/*
|
||||
* Restore rfi related settings
|
||||
*/
|
||||
|
||||
lwz r3, SRR1_FRAME_OFFSET(r1)
|
||||
mtsrr1 r3
|
||||
lwz r3, SRR0_FRAME_OFFSET(r1)
|
||||
mtsrr0 r3
|
||||
|
||||
lwz r3, GPR3_OFFSET(r1)
|
||||
addi r1,r1, EXCEPTION_FRAME_END
|
||||
SYNC
|
||||
rfi
|
||||
|
||||
switch:
|
||||
bl SYM (_Thread_Dispatch)
|
||||
|
||||
easy_exit:
|
||||
/*
|
||||
* start restoring interrupt frame
|
||||
*/
|
||||
lwz r3, EXC_CTR_OFFSET(r1)
|
||||
lwz r4, EXC_XER_OFFSET(r1)
|
||||
lwz r5, EXC_CR_OFFSET(r1)
|
||||
lwz r6, EXC_LR_OFFSET(r1)
|
||||
|
||||
mtctr r3
|
||||
mtxer r4
|
||||
mtcr r5
|
||||
mtlr r6
|
||||
|
||||
lwz r15, GPR15_OFFSET(r1)
|
||||
lwz r14, GPR14_OFFSET(r1)
|
||||
lwz r13, GPR13_OFFSET(r1)
|
||||
lwz r12, GPR12_OFFSET(r1)
|
||||
lwz r11, GPR11_OFFSET(r1)
|
||||
lwz r10, GPR10_OFFSET(r1)
|
||||
lwz r9, GPR9_OFFSET(r1)
|
||||
lwz r8, GPR8_OFFSET(r1)
|
||||
lwz r7, GPR7_OFFSET(r1)
|
||||
lwz r6, GPR6_OFFSET(r1)
|
||||
lwz r5, GPR5_OFFSET(r1)
|
||||
|
||||
/*
|
||||
* Disable nested exception processing, data and instruction
|
||||
* translation.
|
||||
*/
|
||||
mfmsr r3
|
||||
xori r3, r3, MSR_RI | MSR_IR | MSR_DR
|
||||
mtmsr r3
|
||||
SYNC
|
||||
/*
|
||||
* Restore rfi related settings
|
||||
*/
|
||||
|
||||
lwz r4, SRR1_FRAME_OFFSET(r1)
|
||||
lwz r2, SRR0_FRAME_OFFSET(r1)
|
||||
lwz r3, GPR3_OFFSET(r1)
|
||||
lwz r0, GPR0_OFFSET(r1)
|
||||
|
||||
mtsrr1 r4
|
||||
mtsrr0 r2
|
||||
lwz r4, GPR4_OFFSET(r1)
|
||||
lwz r2, GPR2_OFFSET(r1)
|
||||
addi r1,r1, EXCEPTION_FRAME_END
|
||||
SYNC
|
||||
rfi
|
||||
|
||||
162
c/src/lib/libbsp/powerpc/mbx8xx/irq/irq_init.c
Normal file
162
c/src/lib/libbsp/powerpc/mbx8xx/irq/irq_init.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/* irq_init.c
|
||||
*
|
||||
* This file contains the implementation of rtems initialization
|
||||
* related to interrupt handling.
|
||||
*
|
||||
* CopyRight (C) 2001 valette@crf.canon.fr
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp.h>
|
||||
#include <libcpu/raw_exception.h>
|
||||
#include <bsp/8xx_immap.h>
|
||||
#include <bsp/mbx.h>
|
||||
#include <bsp/commproc.h>
|
||||
|
||||
extern unsigned int external_exception_vector_prolog_code_size;
|
||||
extern void external_exception_vector_prolog_code();
|
||||
extern unsigned int decrementer_exception_vector_prolog_code_size;
|
||||
extern void decrementer_exception_vector_prolog_code();
|
||||
|
||||
volatile unsigned int ppc_cached_irq_mask;
|
||||
|
||||
/*
|
||||
* default on/off function
|
||||
*/
|
||||
static void nop_func(){}
|
||||
/*
|
||||
* default isOn function
|
||||
*/
|
||||
static int not_connected() {return 0;}
|
||||
/*
|
||||
* default possible isOn function
|
||||
*/
|
||||
static int connected() {return 1;}
|
||||
|
||||
static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER];
|
||||
static rtems_irq_global_settings initial_config;
|
||||
static rtems_irq_connect_data defaultIrq = {
|
||||
/* vectorIdex, hdl , on , off , isOn */
|
||||
0, nop_func , nop_func , nop_func , not_connected
|
||||
};
|
||||
static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
|
||||
/*
|
||||
* actual rpiorities for interrupt :
|
||||
* 0 means that only current interrupt is masked
|
||||
* 255 means all other interrupts are masked
|
||||
*/
|
||||
/*
|
||||
* SIU interrupts.
|
||||
*/
|
||||
7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1, 0,0,
|
||||
/*
|
||||
* CPM Interrupts
|
||||
*/
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
/*
|
||||
* Processor exceptions handled as interrupts
|
||||
*/
|
||||
0
|
||||
};
|
||||
|
||||
void BSP_SIU_irq_init()
|
||||
{
|
||||
/*
|
||||
* In theory we should initialize two registers at least :
|
||||
* SIMASK, SIEL. SIMASK is reset at 0 value meaning no interrupt. But
|
||||
* we should take care that a monitor may have restoreed to another value.
|
||||
* If someone find a reasonnable value for SIEL, AND THE NEED TO CHANGE IT
|
||||
* please feel free to add it here.
|
||||
*/
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = 0;
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 0xffff0000;
|
||||
ppc_cached_irq_mask = 0;
|
||||
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel = ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize CPM interrupt management
|
||||
*/
|
||||
void
|
||||
BSP_CPM_irq_init(void)
|
||||
{
|
||||
/*
|
||||
* Initialize the CPM interrupt controller.
|
||||
*/
|
||||
((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr =
|
||||
#ifdef mpc860
|
||||
(CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
|
||||
#else
|
||||
(CICR_SCB_SCC2 | CICR_SCA_SCC1) |
|
||||
#endif
|
||||
((BSP_CPM_INTERRUPT/2) << 13) | CICR_HP_MASK;
|
||||
((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr = 0;
|
||||
|
||||
((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN;
|
||||
}
|
||||
|
||||
void BSP_rtems_irq_mng_init(unsigned cpuId)
|
||||
{
|
||||
rtems_raw_except_connect_data vectorDesc;
|
||||
int i;
|
||||
|
||||
BSP_SIU_irq_init();
|
||||
BSP_CPM_irq_init();
|
||||
/*
|
||||
* Initialize Rtems management interrupt table
|
||||
*/
|
||||
/*
|
||||
* re-init the rtemsIrq table
|
||||
*/
|
||||
for (i = 0; i < BSP_IRQ_NUMBER; i++) {
|
||||
rtemsIrq[i] = defaultIrq;
|
||||
rtemsIrq[i].name = i;
|
||||
}
|
||||
/*
|
||||
* Init initial Interrupt management config
|
||||
*/
|
||||
initial_config.irqNb = BSP_IRQ_NUMBER;
|
||||
initial_config.defaultEntry = defaultIrq;
|
||||
initial_config.irqHdlTbl = rtemsIrq;
|
||||
initial_config.irqBase = BSP_ASM_IRQ_VECTOR_BASE;
|
||||
initial_config.irqPrioTbl = irqPrioTable;
|
||||
|
||||
if (!BSP_rtems_irq_mngt_set(&initial_config)) {
|
||||
/*
|
||||
* put something here that will show the failure...
|
||||
*/
|
||||
BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* We must connect the raw irq handler for the two
|
||||
* expected interrupt sources : decrementer and external interrupts.
|
||||
*/
|
||||
vectorDesc.exceptIndex = ASM_DEC_VECTOR;
|
||||
vectorDesc.hdl.vector = ASM_DEC_VECTOR;
|
||||
vectorDesc.hdl.raw_hdl = decrementer_exception_vector_prolog_code;
|
||||
vectorDesc.hdl.raw_hdl_size = (unsigned) &decrementer_exception_vector_prolog_code_size;
|
||||
vectorDesc.on = nop_func;
|
||||
vectorDesc.off = nop_func;
|
||||
vectorDesc.isOn = connected;
|
||||
if (!mpc8xx_set_exception (&vectorDesc)) {
|
||||
BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
|
||||
}
|
||||
vectorDesc.exceptIndex = ASM_EXT_VECTOR;
|
||||
vectorDesc.hdl.vector = ASM_EXT_VECTOR;
|
||||
vectorDesc.hdl.raw_hdl = external_exception_vector_prolog_code;
|
||||
vectorDesc.hdl.raw_hdl_size = (unsigned) &external_exception_vector_prolog_code_size;
|
||||
if (!mpc8xx_set_exception (&vectorDesc)) {
|
||||
BSP_panic("Unable to initialize RTEMS external raw exception\n");
|
||||
}
|
||||
#ifdef TRACE_IRQ_INIT
|
||||
printk("RTEMS IRQ management is now operationnal\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
/*
|
||||
* Number of interfaces supported by this driver
|
||||
@@ -79,8 +80,6 @@
|
||||
# error "Driver must have MCLBYTES > RBUF_SIZE"
|
||||
#endif
|
||||
|
||||
extern unsigned32 simask_copy;
|
||||
|
||||
/*
|
||||
* Per-device data
|
||||
*/
|
||||
@@ -124,11 +123,26 @@ struct m8xx_enet_struct {
|
||||
static struct m8xx_enet_struct enet_driver[NIFACES];
|
||||
|
||||
|
||||
static void m8xx_scc1_ethernet_on(const rtems_irq_connect_data* ptr)
|
||||
{
|
||||
}
|
||||
|
||||
static void m8xx_scc1_ethernet_off(const rtems_irq_connect_data* ptr)
|
||||
{
|
||||
/*
|
||||
* Please put relevant code there
|
||||
*/
|
||||
}
|
||||
|
||||
static void m8xx_scc1_ethernet_isOn(const rtems_irq_connect_data* ptr)
|
||||
{
|
||||
return BSP_irq_enabled_at_cpm (ptr->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* SCC1 interrupt handler
|
||||
*/
|
||||
static rtems_isr
|
||||
m8xx_scc1_interrupt_handler (rtems_vector_number v)
|
||||
static void m8xx_scc1_interrupt_handler ()
|
||||
{
|
||||
/* Frame received? */
|
||||
if ((m8xx.scc1.sccm & 0x8) && (m8xx.scc1.scce & 0x8)) {
|
||||
@@ -145,15 +159,13 @@ m8xx_scc1_interrupt_handler (rtems_vector_number v)
|
||||
enet_driver[0].txInterrupts++; /* Tx int has occurred */
|
||||
rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
|
||||
}
|
||||
m8xx.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
|
||||
}
|
||||
|
||||
#ifdef MPC860T
|
||||
/*
|
||||
* FEC interrupt handler
|
||||
*/
|
||||
static rtems_isr
|
||||
m860_fec_interrupt_handler (rtems_vector_number v)
|
||||
static void m860_fec_interrupt_handler ()
|
||||
{
|
||||
/*
|
||||
* Frame received?
|
||||
@@ -175,6 +187,13 @@ m860_fec_interrupt_handler (rtems_vector_number v)
|
||||
}
|
||||
#endif
|
||||
|
||||
static rtems_irq_connect_data ethernetSCC1IrqData = {
|
||||
BSP_CPM_IRQ_SCC1,
|
||||
(rtems_irq_hdl) m8xx_scc1_interrupt_handler,
|
||||
(rtems_irq_enable) m8xx_scc1_ethernet_on,
|
||||
(rtems_irq_disable) m8xx_scc1_ethernet_off,
|
||||
(rtems_irq_is_enabled)m8xx_scc1_ethernet_isOn
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the ethernet hardware
|
||||
@@ -348,15 +367,12 @@ m8xx_enet_initialize (struct m8xx_enet_struct *sc)
|
||||
/*
|
||||
* Set up interrupts
|
||||
*/
|
||||
status = rtems_interrupt_catch (m8xx_scc1_interrupt_handler,
|
||||
PPC_IRQ_CPM_SCC1,
|
||||
&old_handler);
|
||||
status = BSP_install_rtems_irq_handler (ðernetSCC1IrqData);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
rtems_panic ("Can't attach M8xx SCC1 interrupt handler: %s\n",
|
||||
rtems_status_text (status));
|
||||
}
|
||||
m8xx.scc1.sccm = 0; /* No interrupts unmasked till necessary */
|
||||
m8xx.cimr |= (1UL << 30); /* Enable SCC1 interrupt */
|
||||
|
||||
/*
|
||||
* Set up General SCC Mode Register
|
||||
@@ -395,27 +411,6 @@ m8xx_enet_initialize (struct m8xx_enet_struct *sc)
|
||||
m8xx.pcpar |= 0x1;
|
||||
m8xx.pcdir &= ~0x1;
|
||||
|
||||
|
||||
/*
|
||||
* Set up interrupts
|
||||
* FIXME: DANGER: WARNING:
|
||||
* CICR and SIMASK must be set in any module that uses
|
||||
* the CPM. Currently those are console-generic.c and
|
||||
* network.c. If the registers are not set the same
|
||||
* in both places, strange things may happen.
|
||||
* If they are only set in one place, then an application
|
||||
* that uses only the other module won't work correctly.
|
||||
* Put this comment in each module that sets these 2 registers
|
||||
*/
|
||||
#ifdef mpc860
|
||||
m8xx.cicr = 0x00e43f80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
|
||||
SCdP=SCC4, IRL=1, HP=PC15, IEN=1 */
|
||||
#else
|
||||
m8xx.cicr = 0x00043F80; /* SCaP=SCC1, SCbP=SCC2, IRL=1, HP=PC15, IEN=1 */
|
||||
#endif
|
||||
simask_copy = m8xx.simask | M8xx_SIMASK_LVM1; /* Enable level interrupts */
|
||||
m8xx.simask |= M8xx_SIMASK_LVM1; /* Enable level interrupts */
|
||||
|
||||
/*
|
||||
* Enable receiver and transmitter
|
||||
*/
|
||||
@@ -424,6 +419,25 @@ m8xx_enet_initialize (struct m8xx_enet_struct *sc)
|
||||
|
||||
|
||||
#ifdef MPC860T
|
||||
/*
|
||||
* Please organize FEC controller code better by moving code from
|
||||
* m860_fec_initialize_hardware to m8xx_fec_ethernet_on
|
||||
*/
|
||||
static void m8xx_fec_ethernet_on(){};
|
||||
static void m8xx_fec_ethernet_off(){};
|
||||
static int m8xx_fec_ethernet_isOn (const rtems_irq_connect_data* ptr)
|
||||
{
|
||||
return BSP_irq_enabled_at_siu (ptr->name);
|
||||
}
|
||||
|
||||
static rtems_irq_connect_data ethernetFECIrqData = {
|
||||
BSP_FAST_ETHERNET_CTRL,
|
||||
(rtems_irq_hdl) m8xx_fec_interrupt_handler,
|
||||
(rtems_irq_enable) m8xx_fec_ethernet_on,
|
||||
(rtems_irq_disable) m8xx_fec_ethernet_off,
|
||||
(rtems_irq_is_enabled)m8xx_fec_ethernet_isOn
|
||||
};
|
||||
|
||||
static void
|
||||
m860_fec_initialize_hardware (struct m860_enet_struct *sc)
|
||||
{
|
||||
@@ -458,7 +472,7 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
|
||||
* Set SIU interrupt level to LVL2
|
||||
*
|
||||
*/
|
||||
m8xx.fec.ivec = 0x02 << 29;
|
||||
m8xx.fec.ivec = ((((unsigned) BSP_FAST_ETHERNET_CTRL)/2) << 29);
|
||||
|
||||
/*
|
||||
* Set the TX and RX fifo sizes. For now, we'll split it evenly
|
||||
@@ -572,9 +586,7 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
|
||||
/*
|
||||
* Set up interrupts
|
||||
*/
|
||||
status = rtems_interrupt_catch (m860_fec_interrupt_handler,
|
||||
PPC_IRQ_LVL2,
|
||||
&old_handler);
|
||||
status = status = BSP_install_rtems_irq_handler (ðernetFECIrqData);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_panic ("Can't attach M860 FEC interrupt handler: %s\n",
|
||||
rtems_status_text (status));
|
||||
@@ -1566,7 +1578,7 @@ rtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config)
|
||||
/*
|
||||
* Process options
|
||||
*/
|
||||
#if NVRAM_CONFIGURE == 1
|
||||
#if NVRAM_CONFIGURE == 1
|
||||
|
||||
/* Configure from NVRAM */
|
||||
if ( (addr = nvram->ipaddr) ) {
|
||||
@@ -1607,7 +1619,7 @@ rtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config)
|
||||
rtems_panic("No Ethernet address specified!\n");
|
||||
}
|
||||
|
||||
#else /* NVRAM_CONFIGURE != 1 */
|
||||
#else /* NVRAM_CONFIGURE != 1 */
|
||||
|
||||
if (config->hardware_address) {
|
||||
memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
|
||||
|
||||
@@ -9,7 +9,7 @@ VPATH = @srcdir@:@srcdir@/../../../shared
|
||||
PGM = $(ARCH)/startup.rel
|
||||
|
||||
C_FILES = bspclean.c bsplibc.c bsppost.c bspstart.c bootcard.c imbx8xx.c \
|
||||
main.c mmutlbtab.c sbrk.c setvec.c gnatinstallhandler.c
|
||||
main.c mmutlbtab.c sbrk.c gnatinstallhandler.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||
|
||||
S_FILES = start.s
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
* the .bss section (RAM).
|
||||
*/
|
||||
extern rtems_configuration_table Configuration;
|
||||
extern unsigned long intrStackPtr;
|
||||
rtems_configuration_table BSP_Configuration;
|
||||
|
||||
rtems_cpu_table Cpu_table;
|
||||
@@ -46,6 +47,18 @@ char *rtems_progname;
|
||||
void bsp_postdriver_hook(void);
|
||||
void bsp_libc_init( void *, unsigned32, int );
|
||||
|
||||
void BSP_panic(char *s)
|
||||
{
|
||||
printk("%s PANIC %s\n",_RTEMS_version, s);
|
||||
__asm__ __volatile ("sc");
|
||||
}
|
||||
|
||||
void _BSP_Fatal_error(unsigned int v)
|
||||
{
|
||||
printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
|
||||
__asm__ __volatile ("sc");
|
||||
}
|
||||
|
||||
/*
|
||||
* bsp_pretasking_hook
|
||||
*
|
||||
@@ -116,6 +129,18 @@ void bsp_start(void)
|
||||
{
|
||||
extern void *_WorkspaceBase;
|
||||
|
||||
ppc_cpu_id_t myCpu;
|
||||
ppc_cpu_revision_t myCpuRevision;
|
||||
register unsigned char* intrStack;
|
||||
register unsigned int intrNestingLevel = 0;
|
||||
|
||||
/*
|
||||
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
||||
* store the result in global variables so that it can be used latter...
|
||||
*/
|
||||
myCpu = get_ppc_cpu_type();
|
||||
myCpuRevision = get_ppc_cpu_revision();
|
||||
|
||||
mmu_init();
|
||||
|
||||
/*
|
||||
@@ -134,7 +159,20 @@ void bsp_start(void)
|
||||
rtems_cache_enable_data();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize some SPRG registers related to irq handling
|
||||
*/
|
||||
|
||||
intrStack = (((unsigned char*)&intrStackPtr) - CPU_MINIMUM_STACK_FRAME_SIZE);
|
||||
asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack));
|
||||
asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel));
|
||||
|
||||
/*
|
||||
* Install our own set of exception vectors
|
||||
*/
|
||||
initialize_exceptions();
|
||||
|
||||
|
||||
/*
|
||||
* Allocate the memory for the RTEMS Work Space. This can come from
|
||||
* a variety of places: hard coded address, malloc'ed from outside
|
||||
@@ -181,5 +219,13 @@ void bsp_start(void)
|
||||
m8xx.scc2p.rbase=0;
|
||||
m8xx.scc2p.tbase=0;
|
||||
m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
|
||||
/*
|
||||
* Initalize RTEMS IRQ system
|
||||
*/
|
||||
BSP_rtems_irq_mng_init(0);
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("Exit from bspstart\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ void _InitMBX8xx (void)
|
||||
|
||||
/* Initialize the Periodic Interrupt Status and Control Register (PISCR) */
|
||||
m8xx.piscrk = M8xx_UNLOCK_KEY; /* unlock PISCR */
|
||||
m8xx.piscr = 0x0083; /* Default MBX and firmware value. */
|
||||
m8xx.piscr = 0x0083; /* Default MBX and firmware value. */
|
||||
|
||||
/* Initialize the System Clock and Reset Control Register (SCCR)
|
||||
* Set the clock sources and division factors:
|
||||
|
||||
@@ -198,7 +198,15 @@ SECTIONS
|
||||
bss.size = bss.end - bss.start;
|
||||
text.size = text.end - text.start;
|
||||
PROVIDE(_end = bss.end);
|
||||
|
||||
/*
|
||||
* Interrupt stack setup
|
||||
*/
|
||||
|
||||
IntrStack_start = ALIGN(0x10);
|
||||
. += 0x4000;
|
||||
intrStack = .;
|
||||
PROVIDE(intrStackPtr = intrStack);
|
||||
|
||||
_HeapStart = .;
|
||||
__HeapStart = .;
|
||||
. += HeapSize; /* XXX -- Old gld can't handle this */
|
||||
|
||||
@@ -103,15 +103,15 @@ MMU_TLB_table_t MMU_TLB_table[] = {
|
||||
/*
|
||||
*
|
||||
* Board Control/Status Register #1/#2: CS4, Start address 0xFA100000, (4 x 8 bits?)
|
||||
* ASID=0x0, APG=0x0, guarded memory, copyback data cache policy,
|
||||
* ASID=0x0, APG=0x0, guarded memory, write-through data cache policy,
|
||||
* R/W,X for all, no ASID comparison, cache-inhibited.
|
||||
* EPN TWC RPN
|
||||
*/
|
||||
{ 0xFA100200, 0x11, 0xFA1009F7 }, /* BCSR - PS=4K */
|
||||
{ 0xFA100200, 0x13, 0xFA1009F7 }, /* BCSR - PS=4K */
|
||||
/*
|
||||
*
|
||||
* (IMMR-SPRs) Dual Port RAM: Start address 0xFA200000, 16K,
|
||||
* ASID=0x0, APG=0x0, guarded memory, copyback data cache policy,
|
||||
* ASID=0x0, APG=0x0, guarded memory, write-through data cache policy,
|
||||
* R/W,X for all, no ASID comparison, cache-inhibited.
|
||||
*
|
||||
* Note: We use the value in MBXA/PG2, which is also the value that
|
||||
@@ -120,7 +120,7 @@ MMU_TLB_table_t MMU_TLB_table[] = {
|
||||
* of the firmware.
|
||||
* EPN TWC RPN
|
||||
*/
|
||||
{ 0xFA200200, 0x11, 0xFA2009FF }, /* IMMR - PS=16K */
|
||||
{ 0xFA200200, 0x13, 0xFA2009FF }, /* IMMR - PS=16K */
|
||||
/*
|
||||
*
|
||||
* Flash: CS0, Start address 0xFE000000, 4M, (BootROM-EPPCBug)
|
||||
|
||||
@@ -239,14 +239,20 @@ spin:
|
||||
lwz r3, spin@l(r3)
|
||||
cmpwi r3, 0x1
|
||||
beq .spin
|
||||
|
||||
/*
|
||||
* #define LOADED_BY_EPPCBUG
|
||||
*/
|
||||
/*
|
||||
* Initialization code
|
||||
*/
|
||||
.startup:
|
||||
/* Get the start address. */
|
||||
mflr r1
|
||||
|
||||
#ifdef LOADED_BY_EPPCBUG
|
||||
/* Save pointer to residual/board data */
|
||||
lis r9,eppcbugInfo@ha
|
||||
stw r3,eppcbugInfo@l(r9)
|
||||
#endif
|
||||
/* Initialize essential registers. */
|
||||
bl initregs
|
||||
nop
|
||||
@@ -270,8 +276,8 @@ spin:
|
||||
bl bssclr
|
||||
nop
|
||||
|
||||
lis 5,environ@ha
|
||||
la 5,environ@l(5) /* environp */
|
||||
lis r5,environ@ha
|
||||
la r5,environ@l(r5) /* environp */
|
||||
/* clear argc and argv */
|
||||
xor r3, r3, r3
|
||||
xor r4, r4, r4
|
||||
@@ -358,7 +364,7 @@ initregs:
|
||||
mr r8, r0
|
||||
mr r9, r0
|
||||
mr r10, r0
|
||||
mr r11, r0
|
||||
mr r11, r0
|
||||
mr r12, r0
|
||||
mr r13, r0
|
||||
mr r14, r0
|
||||
|
||||
2
c/src/lib/libbsp/powerpc/mbx8xx/vectors/.cvsignore
Normal file
2
c/src/lib/libbsp/powerpc/mbx8xx/vectors/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
40
c/src/lib/libbsp/powerpc/mbx8xx/vectors/Makefile.am
Normal file
40
c/src/lib/libbsp/powerpc/mbx8xx/vectors/Makefile.am
Normal file
@@ -0,0 +1,40 @@
|
||||
##
|
||||
## $Id$
|
||||
##
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
VPATH = @srcdir@:
|
||||
|
||||
C_FILES = vectors_init.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||
|
||||
H_FILES = vectors.h
|
||||
|
||||
S_FILES = vectors.S
|
||||
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
|
||||
|
||||
OBJS = $(S_O_FILES) $(C_O_FILES)
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
include $(top_srcdir)/../../../../../../automake/lib.am
|
||||
|
||||
#
|
||||
# (OPTIONAL) Add local stuff here using +=
|
||||
#
|
||||
|
||||
$(PGM): $(OBJS)
|
||||
$(make-rel)
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp:
|
||||
$(mkinstalldirs) $@
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/vectors.h: vectors.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp $(PROJECT_INCLUDE)/bsp/vectors.h
|
||||
|
||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS)
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
143
c/src/lib/libbsp/powerpc/mbx8xx/vectors/vectors.S
Normal file
143
c/src/lib/libbsp/powerpc/mbx8xx/vectors/vectors.S
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* (c) 1999, Eric Valette valette@crf.canon.fr
|
||||
*
|
||||
*
|
||||
* This file contains the assembly code for the PowerPC
|
||||
* exception veneers for RTEMS.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <bsp/vectors.h>
|
||||
#include <libcpu/cpu.h>
|
||||
#include <rtems/score/targopts.h>
|
||||
#include "asm.h"
|
||||
|
||||
|
||||
#define SYNC \
|
||||
sync; \
|
||||
isync
|
||||
|
||||
.text
|
||||
.p2align 5
|
||||
|
||||
PUBLIC_VAR(default_exception_vector_code_prolog)
|
||||
SYM (default_exception_vector_code_prolog):
|
||||
/*
|
||||
* let room for exception frame
|
||||
*/
|
||||
stwu r1, - (EXCEPTION_FRAME_END)(r1)
|
||||
stw r3, GPR3_OFFSET(r1)
|
||||
stw r2, GPR2_OFFSET(r1)
|
||||
mflr r2
|
||||
stw r2, EXC_LR_OFFSET(r1)
|
||||
bl 0f
|
||||
0: /*
|
||||
* r3 = exception vector entry point
|
||||
* (256 * vector number) + few instructions
|
||||
*/
|
||||
mflr r3
|
||||
/*
|
||||
* r3 = r3 >> 8 = vector
|
||||
*/
|
||||
srwi r3,r3,8
|
||||
ba push_normalized_frame
|
||||
|
||||
PUBLIC_VAR (default_exception_vector_code_prolog_size)
|
||||
|
||||
default_exception_vector_code_prolog_size= . - default_exception_vector_code_prolog
|
||||
|
||||
.p2align 5
|
||||
PUBLIC_VAR (push_normalized_frame)
|
||||
SYM (push_normalized_frame):
|
||||
stw r3, EXCEPTION_NUMBER_OFFSET(r1)
|
||||
stw r0, GPR0_OFFSET(r1)
|
||||
mfsrr0 r2
|
||||
stw r2, SRR0_FRAME_OFFSET(r1)
|
||||
mfsrr1 r3
|
||||
stw r3, SRR1_FRAME_OFFSET(r1)
|
||||
/*
|
||||
* Save general purpose registers
|
||||
* Already saved in prolog : R1, R2, R3, LR.
|
||||
* Saved a few line above : R0
|
||||
*
|
||||
* Manual says that "stmw" instruction may be slower than
|
||||
* series of individual "stw" but who cares about performance
|
||||
* for the DEFAULT exception handler?
|
||||
*/
|
||||
stmw r4, GPR4_OFFSET(r1) /* save R4->R31 */
|
||||
|
||||
mfcr r31
|
||||
stw r31, EXC_CR_OFFSET(r1)
|
||||
mfctr r30
|
||||
stw r30, EXC_CTR_OFFSET(r1)
|
||||
mfxer r28
|
||||
stw r28, EXC_XER_OFFSET(r1)
|
||||
/*
|
||||
* compute SP at exception entry
|
||||
*/
|
||||
addi r2, r1, EXCEPTION_FRAME_END
|
||||
/*
|
||||
* store it at the right place
|
||||
*/
|
||||
stw r2, GPR1_OFFSET(r1)
|
||||
/*
|
||||
* Enable data and instruction address translation, exception nesting
|
||||
*/
|
||||
mfmsr r3
|
||||
ori r3,r3, MSR_RI | MSR_IR | MSR_DR
|
||||
mtmsr r3
|
||||
SYNC
|
||||
|
||||
/*
|
||||
* Call C exception handler
|
||||
*/
|
||||
/*
|
||||
* store the execption frame address in r3 (first param)
|
||||
*/
|
||||
addi r3, r1, 0x8
|
||||
/*
|
||||
* globalExceptHdl(r3)
|
||||
*/
|
||||
addis r4, 0, globalExceptHdl@ha
|
||||
lwz r5, globalExceptHdl@l(r4)
|
||||
mtlr r5
|
||||
blrl
|
||||
/*
|
||||
* Restore registers status
|
||||
*/
|
||||
lwz r31, EXC_CR_OFFSET(r1)
|
||||
mtcr r31
|
||||
lwz r30, EXC_CTR_OFFSET(r1)
|
||||
mtctr r30
|
||||
lwz r29, EXC_LR_OFFSET(r1)
|
||||
mtlr r29
|
||||
lwz r28, EXC_XER_OFFSET(r1)
|
||||
mtxer r28
|
||||
|
||||
lmw r4, GPR4_OFFSET(r1)
|
||||
lwz r2, GPR2_OFFSET(r1)
|
||||
lwz r0, GPR0_OFFSET(r1)
|
||||
|
||||
/*
|
||||
* Disable data and instruction translation. Make path non recoverable...
|
||||
*/
|
||||
mfmsr r3
|
||||
xori r3, r3, MSR_RI | MSR_IR | MSR_DR
|
||||
mtmsr r3
|
||||
SYNC
|
||||
/*
|
||||
* Restore rfi related settings
|
||||
*/
|
||||
|
||||
lwz r3, SRR1_FRAME_OFFSET(r1)
|
||||
mtsrr1 r3
|
||||
lwz r3, SRR0_FRAME_OFFSET(r1)
|
||||
mtsrr0 r3
|
||||
|
||||
lwz r3, GPR3_OFFSET(r1)
|
||||
addi r1,r1, EXCEPTION_FRAME_END
|
||||
SYNC
|
||||
rfi
|
||||
144
c/src/lib/libbsp/powerpc/mbx8xx/vectors/vectors.h
Normal file
144
c/src/lib/libbsp/powerpc/mbx8xx/vectors/vectors.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* vectors.h Exception frame related contant and API.
|
||||
*
|
||||
* This include file describe the data structure and the functions implemented
|
||||
* by rtems to handle exceptions.
|
||||
*
|
||||
* CopyRight (C) 1999 valette@crf.canon.fr
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
#ifndef LIBBSP_POWERPC_MBX8XX_VECTORS_H
|
||||
#define LIBBSP_POWERPC_MBX8xx_VECTORS_H
|
||||
|
||||
/*
|
||||
* The callee (high level exception code written in C)
|
||||
* will store the Link Registers (return address) at entry r1 + 4 !!!.
|
||||
* So let room for it!!!.
|
||||
*/
|
||||
#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4
|
||||
#define SRR0_FRAME_OFFSET 8
|
||||
#define SRR1_FRAME_OFFSET 12
|
||||
#define EXCEPTION_NUMBER_OFFSET 16
|
||||
#define GPR0_OFFSET 20
|
||||
#define GPR1_OFFSET 24
|
||||
#define GPR2_OFFSET 28
|
||||
#define GPR3_OFFSET 32
|
||||
#define GPR4_OFFSET 36
|
||||
#define GPR5_OFFSET 40
|
||||
#define GPR6_OFFSET 44
|
||||
#define GPR7_OFFSET 48
|
||||
#define GPR8_OFFSET 52
|
||||
#define GPR9_OFFSET 56
|
||||
#define GPR10_OFFSET 60
|
||||
#define GPR11_OFFSET 64
|
||||
#define GPR12_OFFSET 68
|
||||
#define GPR13_OFFSET 72
|
||||
#define GPR14_OFFSET 76
|
||||
#define GPR15_OFFSET 80
|
||||
#define GPR16_OFFSET 84
|
||||
#define GPR17_OFFSET 88
|
||||
#define GPR18_OFFSET 92
|
||||
#define GPR19_OFFSET 96
|
||||
#define GPR20_OFFSET 100
|
||||
#define GPR21_OFFSET 104
|
||||
#define GPR22_OFFSET 108
|
||||
#define GPR23_OFFSET 112
|
||||
#define GPR24_OFFSET 116
|
||||
#define GPR25_OFFSET 120
|
||||
#define GPR26_OFFSET 124
|
||||
#define GPR27_OFFSET 128
|
||||
#define GPR28_OFFSET 132
|
||||
#define GPR29_OFFSET 136
|
||||
#define GPR30_OFFSET 140
|
||||
#define GPR31_OFFSET 144
|
||||
#define EXC_CR_OFFSET 148
|
||||
#define EXC_CTR_OFFSET 152
|
||||
#define EXC_XER_OFFSET 156
|
||||
#define EXC_LR_OFFSET 160
|
||||
#define EXC_DAR_OFFSET 164
|
||||
/*
|
||||
* maintain the EABI requested 8 bytes aligment
|
||||
* As SVR4 ABI requires 16, make it 16 (as some
|
||||
* exception may need more registers to be processed...)
|
||||
*/
|
||||
#define EXCEPTION_FRAME_END 176
|
||||
|
||||
#ifndef ASM
|
||||
/*
|
||||
* default raw exception handlers
|
||||
*/
|
||||
|
||||
extern void default_exception_vector_code_prolog();
|
||||
extern int default_exception_vector_code_prolog_size;
|
||||
|
||||
/* codemove is like memmove, but it also gets the cache line size
|
||||
* as 4th parameter to synchronize them. If this last parameter is
|
||||
* zero, it performs more or less like memmove. No copy is performed if
|
||||
* source and destination addresses are equal. However the caches
|
||||
* are synchronized. Note that the size is always rounded up to the
|
||||
* next mutiple of 4.
|
||||
*/
|
||||
extern void * codemove(void *, const void *, unsigned int, unsigned long);
|
||||
extern void initialize_exceptions();
|
||||
|
||||
typedef struct {
|
||||
unsigned EXC_SRR0;
|
||||
unsigned EXC_SRR1;
|
||||
unsigned _EXC_number;
|
||||
unsigned GPR0;
|
||||
unsigned GPR1;
|
||||
unsigned GPR2;
|
||||
unsigned GPR3;
|
||||
unsigned GPR4;
|
||||
unsigned GPR5;
|
||||
unsigned GPR6;
|
||||
unsigned GPR7;
|
||||
unsigned GPR8;
|
||||
unsigned GPR9;
|
||||
unsigned GPR10;
|
||||
unsigned GPR11;
|
||||
unsigned GPR12;
|
||||
unsigned GPR13;
|
||||
unsigned GPR14;
|
||||
unsigned GPR15;
|
||||
unsigned GPR16;
|
||||
unsigned GPR17;
|
||||
unsigned GPR18;
|
||||
unsigned GPR19;
|
||||
unsigned GPR20;
|
||||
unsigned GPR21;
|
||||
unsigned GPR22;
|
||||
unsigned GPR23;
|
||||
unsigned GPR24;
|
||||
unsigned GPR25;
|
||||
unsigned GPR26;
|
||||
unsigned GPR27;
|
||||
unsigned GPR28;
|
||||
unsigned GPR29;
|
||||
unsigned GPR30;
|
||||
unsigned GPR31;
|
||||
unsigned EXC_CR;
|
||||
unsigned EXC_CTR;
|
||||
unsigned EXC_XER;
|
||||
unsigned EXC_LR;
|
||||
unsigned EXC_MSR;
|
||||
unsigned EXC_DAR;
|
||||
}BSP_Exception_frame;
|
||||
|
||||
|
||||
typedef void (*exception_handler_t) (BSP_Exception_frame* excPtr);
|
||||
extern exception_handler_t globalExceptHdl;
|
||||
/*
|
||||
* Compatibility with pc386
|
||||
*/
|
||||
typedef BSP_Exception_frame CPU_Exception_frame;
|
||||
typedef exception_handler_t cpuExcHandlerType;
|
||||
|
||||
#endif /* ASM */
|
||||
|
||||
#endif /* LIBBSP_POWERPC_MCP750_VECTORS_H */
|
||||
134
c/src/lib/libbsp/powerpc/mbx8xx/vectors/vectors_init.c
Normal file
134
c/src/lib/libbsp/powerpc/mbx8xx/vectors/vectors_init.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* vectors_init.c Exception hanlding initialisation (and generic handler).
|
||||
*
|
||||
* This include file describe the data structure and the functions implemented
|
||||
* by rtems to handle exceptions.
|
||||
*
|
||||
* CopyRight (C) 1999 valette@crf.canon.fr
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
#include <bsp/vectors.h>
|
||||
#include <libcpu/raw_exception.h>
|
||||
#include <bsp.h>
|
||||
|
||||
static rtems_raw_except_global_settings exception_config;
|
||||
static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1];
|
||||
|
||||
exception_handler_t globalExceptHdl;
|
||||
|
||||
void C_exception_handler(BSP_Exception_frame* excPtr)
|
||||
{
|
||||
int recoverable = 0;
|
||||
|
||||
printk("exception handler called for exception %d\n", excPtr->_EXC_number);
|
||||
printk("\t Next PC or Address of fault = %x\n", excPtr->EXC_SRR0);
|
||||
printk("\t Saved MSR = %x\n", excPtr->EXC_SRR1);
|
||||
printk("\t R0 = %x\n", excPtr->GPR0);
|
||||
printk("\t R1 = %x\n", excPtr->GPR1);
|
||||
printk("\t R2 = %x\n", excPtr->GPR2);
|
||||
printk("\t R3 = %x\n", excPtr->GPR3);
|
||||
printk("\t R4 = %x\n", excPtr->GPR4);
|
||||
printk("\t R5 = %x\n", excPtr->GPR5);
|
||||
printk("\t R6 = %x\n", excPtr->GPR6);
|
||||
printk("\t R7 = %x\n", excPtr->GPR7);
|
||||
printk("\t R8 = %x\n", excPtr->GPR8);
|
||||
printk("\t R9 = %x\n", excPtr->GPR9);
|
||||
printk("\t R10 = %x\n", excPtr->GPR10);
|
||||
printk("\t R11 = %x\n", excPtr->GPR11);
|
||||
printk("\t R12 = %x\n", excPtr->GPR12);
|
||||
printk("\t R13 = %x\n", excPtr->GPR13);
|
||||
printk("\t R14 = %x\n", excPtr->GPR14);
|
||||
printk("\t R15 = %x\n", excPtr->GPR15);
|
||||
printk("\t R16 = %x\n", excPtr->GPR16);
|
||||
printk("\t R17 = %x\n", excPtr->GPR17);
|
||||
printk("\t R18 = %x\n", excPtr->GPR18);
|
||||
printk("\t R19 = %x\n", excPtr->GPR19);
|
||||
printk("\t R20 = %x\n", excPtr->GPR20);
|
||||
printk("\t R21 = %x\n", excPtr->GPR21);
|
||||
printk("\t R22 = %x\n", excPtr->GPR22);
|
||||
printk("\t R23 = %x\n", excPtr->GPR23);
|
||||
printk("\t R24 = %x\n", excPtr->GPR24);
|
||||
printk("\t R25 = %x\n", excPtr->GPR25);
|
||||
printk("\t R26 = %x\n", excPtr->GPR26);
|
||||
printk("\t R27 = %x\n", excPtr->GPR27);
|
||||
printk("\t R28 = %x\n", excPtr->GPR28);
|
||||
printk("\t R29 = %x\n", excPtr->GPR29);
|
||||
printk("\t R30 = %x\n", excPtr->GPR30);
|
||||
printk("\t R31 = %x\n", excPtr->GPR31);
|
||||
printk("\t CR = %x\n", excPtr->EXC_CR);
|
||||
printk("\t CTR = %x\n", excPtr->EXC_CTR);
|
||||
printk("\t XER = %x\n", excPtr->EXC_XER);
|
||||
printk("\t LR = %x\n", excPtr->EXC_LR);
|
||||
printk("\t MSR = %x\n", excPtr->EXC_MSR);
|
||||
if (excPtr->_EXC_number == ASM_DEC_VECTOR)
|
||||
recoverable = 1;
|
||||
if (excPtr->_EXC_number == ASM_SYS_VECTOR)
|
||||
#ifdef TEST_RAW_EXCEPTION_CODE
|
||||
recoverable = 1;
|
||||
#else
|
||||
recoverable = 0;
|
||||
#endif
|
||||
if (!recoverable) {
|
||||
printk("unrecoverable exception!!! Push reset button\n");
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
void nop_except_enable(const rtems_raw_except_connect_data* ptr)
|
||||
{
|
||||
}
|
||||
int except_always_enabled(const rtems_raw_except_connect_data* ptr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void initialize_exceptions()
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Initialize pointer used by low level execption handling
|
||||
*/
|
||||
globalExceptHdl = C_exception_handler;
|
||||
/*
|
||||
* Put default_exception_vector_code_prolog at relevant exception
|
||||
* code entry addresses
|
||||
*/
|
||||
exception_config.exceptSize = LAST_VALID_EXC + 1;
|
||||
exception_config.rawExceptHdlTbl = &exception_table[0];
|
||||
exception_config.defaultRawEntry.exceptIndex = 0;
|
||||
exception_config.defaultRawEntry.hdl.vector = 0;
|
||||
exception_config.defaultRawEntry.hdl.raw_hdl = default_exception_vector_code_prolog;
|
||||
/*
|
||||
* Note that next line the '&' before default_exception_vector_code_prolog_size
|
||||
* is not a bug as it is defined a .set directly in asm...
|
||||
*/
|
||||
exception_config.defaultRawEntry.hdl.raw_hdl_size = (unsigned) &default_exception_vector_code_prolog_size;
|
||||
for (i=0; i <= exception_config.exceptSize; i++) {
|
||||
printk("installing exception number %d\n", i);
|
||||
if (!mpc8xx_vector_is_valid (i)) {
|
||||
continue;
|
||||
}
|
||||
exception_table[i].exceptIndex = i;
|
||||
exception_table[i].hdl = exception_config.defaultRawEntry.hdl;
|
||||
exception_table[i].hdl.vector = i;
|
||||
exception_table[i].on = nop_except_enable;
|
||||
exception_table[i].off = nop_except_enable;
|
||||
exception_table[i].isOn = except_always_enabled;
|
||||
}
|
||||
if (!mpc8xx_init_exceptions(&exception_config)) {
|
||||
/*
|
||||
* At this stage we may not call BSP_Panic because it uses exceptions!!!
|
||||
*/
|
||||
printk("Exception handling initialization failed\n");
|
||||
printk("System locked\n"); while(1);
|
||||
}
|
||||
else {
|
||||
printk("Exception handling initialization done\n");
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ if HAS_NETWORKING
|
||||
NETWORKING = network
|
||||
endif
|
||||
|
||||
BSP_PIECES = startup console $(NETWORKING)
|
||||
BSP_PIECES = clock irq startup console vectors $(NETWORKING)
|
||||
# pieces to pick up out of libcpu/ppc
|
||||
# CPU_PIECES = mpc8xx/clock mpc8xx/console-generic mpc8xx/cpm \
|
||||
# mpc8xx/mmu mpc8xx/timer mpc8xx/vectors
|
||||
@@ -17,7 +17,7 @@ BSP_PIECES = startup console $(NETWORKING)
|
||||
# bummer; have to use $foreach since % pattern subst rules only replace 1x
|
||||
OBJS = $(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.o)) \
|
||||
$(wildcard ../../../../libcpu/$(RTEMS_CPU)/shared/*/$(ARCH)/*.o) \
|
||||
$(wildcard ../../../../libcpu/powerpc/old_exception_processing/$(ARCH)/*.rel) \
|
||||
$(wildcard ../../../../libcpu/powerpc/new_exception_processing/$(ARCH)/*.rel) \
|
||||
$(wildcard ../../../../libcpu/$(RTEMS_CPU)/mpc8xx/*/$(ARCH)/*.o)
|
||||
LIB = $(ARCH)/libbsp.a
|
||||
|
||||
|
||||
Reference in New Issue
Block a user