mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-20 23:36:13 +08:00
2001-04-11 Eric Valette <valette@crf.canon.fr>
* clock/.cvsignore, clock/Makefile.am, clock/p_clock.c, include/8xx_immap.h, include/commproc.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 file. * Switch the eth_comm BSP to use the "new exception processing model."
This commit is contained in:
@@ -1,3 +1,13 @@
|
||||
2001-04-11 Eric Valette <valette@crf.canon.fr>
|
||||
|
||||
* clock/.cvsignore, clock/Makefile.am, clock/p_clock.c,
|
||||
include/8xx_immap.h, include/commproc.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 file.
|
||||
* Switch the eth_comm BSP to use the "new exception processing model."
|
||||
|
||||
2001-04-11 Eric Valette <valette@crf.canon.fr>
|
||||
|
||||
* Makefile.am, configure.in, console/console.c,
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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_ETH_COMM_IRQ_IRQ_H
|
||||
#define LIBBSP_POWERPC_ETH_COMM_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
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/* 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/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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_ETH_COMM_VECTORS_H
|
||||
#define LIBBSP_POWERPC_Eth_Comm_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 */
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user