From 37731c2bd860f043ef96e20cfd8f58c6823689e9 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 6 Apr 2001 15:54:20 +0000 Subject: 2001-03-30 Eric Valette * mpc8xx/exceptions/.cvsignore, mpc8xx/exceptions/Makefile.am, mpc8xx/exceptions/asm_utils.S, mpc8xx/exceptions/raw_exception.c, mpc8xx/exceptions/raw_exception.h: New files. * configure.in, mpc6xx/mmu/bat.h, mpc8xx/Makefile.am, mpc8xx/clock/clock.c, mpc8xx/console-generic/console-generic.c, mpc8xx/include/mpc8xx.h, mpc8xx/mmu/mmu.c, new_exception_processing/cpu.h, shared/include/byteorder.h, wrapup/Makefile.am: This is conversion of the mpc8xx CPU to the "new exception processing model." --- c/src/lib/libcpu/powerpc/ChangeLog | 13 ++ c/src/lib/libcpu/powerpc/configure.in | 9 +- c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h | 2 +- c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am | 2 +- c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c | 85 ++++---- .../mpc8xx/console-generic/console-generic.c | 221 +++++++++++++-------- .../libcpu/powerpc/mpc8xx/exceptions/.cvsignore | 2 + .../libcpu/powerpc/mpc8xx/exceptions/Makefile.am | 43 ++++ .../libcpu/powerpc/mpc8xx/exceptions/asm_utils.S | 65 ++++++ .../powerpc/mpc8xx/exceptions/raw_exception.c | 199 +++++++++++++++++++ .../powerpc/mpc8xx/exceptions/raw_exception.h | 188 ++++++++++++++++++ c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h | 6 +- c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c | 2 +- .../libcpu/powerpc/new_exception_processing/cpu.h | 14 ++ .../lib/libcpu/powerpc/shared/include/byteorder.h | 4 - c/src/lib/libcpu/powerpc/wrapup/Makefile.am | 5 +- 16 files changed, 720 insertions(+), 140 deletions(-) create mode 100644 c/src/lib/libcpu/powerpc/mpc8xx/exceptions/.cvsignore create mode 100644 c/src/lib/libcpu/powerpc/mpc8xx/exceptions/Makefile.am create mode 100644 c/src/lib/libcpu/powerpc/mpc8xx/exceptions/asm_utils.S create mode 100644 c/src/lib/libcpu/powerpc/mpc8xx/exceptions/raw_exception.c create mode 100644 c/src/lib/libcpu/powerpc/mpc8xx/exceptions/raw_exception.h (limited to 'c/src/lib/libcpu') diff --git a/c/src/lib/libcpu/powerpc/ChangeLog b/c/src/lib/libcpu/powerpc/ChangeLog index b99df7b1a6..c931fe5b5a 100644 --- a/c/src/lib/libcpu/powerpc/ChangeLog +++ b/c/src/lib/libcpu/powerpc/ChangeLog @@ -1,3 +1,16 @@ +2001-03-30 Eric Valette + + * mpc8xx/exceptions/.cvsignore, mpc8xx/exceptions/Makefile.am, + mpc8xx/exceptions/asm_utils.S, mpc8xx/exceptions/raw_exception.c, + mpc8xx/exceptions/raw_exception.h: New files. + * configure.in, mpc6xx/mmu/bat.h, mpc8xx/Makefile.am, + mpc8xx/clock/clock.c, + mpc8xx/console-generic/console-generic.c, + mpc8xx/include/mpc8xx.h, mpc8xx/mmu/mmu.c, + new_exception_processing/cpu.h, shared/include/byteorder.h, + wrapup/Makefile.am: This is conversion of the + mpc8xx CPU to the "new exception processing model." + 2001-02-27 Ralf Corsepius * mpc505/ictrl/Makefile.am, mpc6xx/clock/Makefile.am, diff --git a/c/src/lib/libcpu/powerpc/configure.in b/c/src/lib/libcpu/powerpc/configure.in index 61cfc36089..ddbcae3edf 100644 --- a/c/src/lib/libcpu/powerpc/configure.in +++ b/c/src/lib/libcpu/powerpc/configure.in @@ -37,7 +37,9 @@ AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "mpc750" \ ## there are no 601 or 602 BSPs currently. The 505 BSPs are in user land. AM_CONDITIONAL(new_exception_processing, \ test "$RTEMS_CPU_MODEL" = "mpc750" || \ -test "$RTEMS_CPU_MODEL" = "mpc604") +test "$RTEMS_CPU_MODEL" = "mpc604" || \ +test "$RTEMS_CPU_MODEL" = "mpc8xx" || \ +test "$RTEMS_CPU_MODEL" = "mpc860") ## The goal is to get rid of the old exception processing code but ## but all BSPs in the distribution must be migrated to the new model @@ -45,8 +47,7 @@ test "$RTEMS_CPU_MODEL" = "mpc604") AM_CONDITIONAL(old_exception_processing, \ test "$RTEMS_CPU_MODEL" = "ppc403" || \ test "$RTEMS_CPU_MODEL" = "mpc505" || \ -test "$RTEMS_CPU_MODEL" = "ppc603e" || \ -test "$RTEMS_CPU_MODEL" = "mpc8xx" \ +test "$RTEMS_CPU_MODEL" = "ppc603e" \ ) ## test on CPU type @@ -70,10 +71,10 @@ mpc8xx/Makefile mpc8xx/clock/Makefile mpc8xx/console-generic/Makefile mpc8xx/cpm/Makefile +mpc8xx/exceptions/Makefile mpc8xx/include/Makefile mpc8xx/mmu/Makefile mpc8xx/timer/Makefile -mpc8xx/vectors/Makefile ppc403/Makefile ppc403/clock/Makefile ppc403/console/Makefile diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h index 616f6182a4..1300724a77 100644 --- a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h +++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/bat.h @@ -25,7 +25,7 @@ #include #include -#include +#include #define IO_PAGE (_PAGE_NO_CACHE | _PAGE_GUARDED | _PAGE_RW) diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am index 481921db1c..265284d633 100644 --- a/c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am +++ b/c/src/lib/libcpu/powerpc/mpc8xx/Makefile.am @@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = foreign 1.4 -SUBDIRS = include console-generic clock timer vectors cpm mmu +SUBDIRS = include console-generic clock timer cpm mmu exceptions include $(top_srcdir)/../../../../../automake/subdirs.am include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c b/c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c index 21c8de6df6..63aa11bf76 100644 --- a/c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c +++ b/c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c @@ -45,9 +45,12 @@ volatile rtems_unsigned32 Clock_driver_ticks; extern volatile m8xx_t m8xx; +extern int BSP_get_clock_irq_level(); +extern int BSP_connect_clock_handler(rtems_isr_entry); +extern int BSP_disconnect_clock_handler(); void Clock_exit( void ); - + /* * These are set by clock driver during its init */ @@ -65,62 +68,42 @@ rtems_isr Clock_isr(rtems_vector_number vector) rtems_clock_tick(); } -void Install_clock(rtems_isr_entry clock_isr) +void clockOn(void* unused) { -#ifdef EPPCBUG_SMC1 - extern unsigned32 simask_copy; -#endif /* EPPCBUG_SMC1 */ - - rtems_isr_entry previous_isr; + unsigned desiredLevel; rtems_unsigned32 pit_value; - Clock_driver_ticks = 0; - pit_value = (rtems_configuration_get_microseconds_per_tick() * rtems_cpu_configuration_get_clicks_per_usec()) - 1 ; if (pit_value > 0xffff) { /* pit is only 16 bits long */ rtems_fatal_error_occurred(-1); - } - - /* - * initialize the interval here - * First tick is set to right amount of time in the future - * Future ticks will be incremented over last value set - * in order to provide consistent clicks in the face of - * interrupt overhead - */ - - rtems_interrupt_catch(clock_isr, PPC_IRQ_LVL0, &previous_isr); - + } m8xx.sccr &= ~(1<<24); m8xx.pitc = pit_value; - + + desiredLevel = BSP_get_clock_irq_level(); /* set PIT irq level, enable PIT, PIT interrupts */ /* and clear int. status */ - m8xx.piscr = M8xx_PISCR_PIRQ(0) | - M8xx_PISCR_PTE | M8xx_PISCR_PS | M8xx_PISCR_PIE; - -#ifdef EPPCBUG_SMC1 - simask_copy = m8xx.simask | M8xx_SIMASK_LVM0; -#endif /* EPPCBUG_SMC1 */ - m8xx.simask |= M8xx_SIMASK_LVM0; - atexit(Clock_exit); + m8xx.piscr = M8xx_PISCR_PIRQ(desiredLevel) | + M8xx_PISCR_PTE | M8xx_PISCR_PS | M8xx_PISCR_PIE; } - +/* + * Called via atexit() + * Remove the clock interrupt handler by setting handler to NULL + */ void -ReInstall_clock(rtems_isr_entry new_clock_isr) +clockOff(void* unused) { - rtems_isr_entry previous_isr; - rtems_unsigned32 isrlevel = 0; - - rtems_interrupt_disable(isrlevel); - - rtems_interrupt_catch(new_clock_isr, PPC_IRQ_LVL0, &previous_isr); - - rtems_interrupt_enable(isrlevel); + /* disable PIT and PIT interrupts */ + m8xx.piscr &= ~(M8xx_PISCR_PTE | M8xx_PISCR_PIE); } +int clockIsOn(void* unused) +{ + if (m8xx.piscr & M8xx_PISCR_PIE) return 1; + return 0; +} /* * Called via atexit() @@ -129,12 +112,24 @@ ReInstall_clock(rtems_isr_entry new_clock_isr) void Clock_exit(void) { - /* disable PIT and PIT interrupts */ - m8xx.piscr &= ~(M8xx_PISCR_PTE | M8xx_PISCR_PIE); - - (void) set_vector(0, PPC_IRQ_LVL0, 1); + (void) BSP_disconnect_clock_handler (); } +void Install_clock(rtems_isr_entry clock_isr) +{ + Clock_driver_ticks = 0; + + BSP_connect_clock_handler (clock_isr); + atexit(Clock_exit); +} + +void +ReInstall_clock(rtems_isr_entry new_clock_isr) +{ + BSP_connect_clock_handler (new_clock_isr); +} + + rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_device_minor_number minor, @@ -142,7 +137,7 @@ rtems_device_driver Clock_initialize( ) { Install_clock( Clock_isr ); - + /* * make major/minor avail to others such as shared memory driver */ diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/console-generic.c b/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/console-generic.c index 20d8572157..a9478cd0ab 100644 --- a/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/console-generic.c +++ b/c/src/lib/libcpu/powerpc/mpc8xx/console-generic/console-generic.c @@ -53,16 +53,14 @@ #include #include #include +#include +#include /* for printk */ extern rtems_cpu_table Cpu_table; /* BSP supplied routine */ extern int mbx8xx_console_get_configuration(); -#ifdef EPPCBUG_SMC1 -extern unsigned32 simask_copy; -#endif - /* * Interrupt-driven input buffer */ @@ -88,9 +86,6 @@ static char brg_used[4]; /* Used to track termios private data for callbacks */ struct rtems_termios_tty *ttyp[NUM_PORTS]; -/* Used to record previous ISR */ -static rtems_isr_entry old_handler[NUM_PORTS]; - /* * Device-specific routines */ @@ -99,12 +94,12 @@ static unsigned char m8xx_get_brg_clk(int); void m8xx_console_reserve_resources(rtems_configuration_table *); static int m8xx_smc_set_attributes(int, const struct termios*); static int m8xx_scc_set_attributes(int, const struct termios*); -static rtems_isr m8xx_smc1_interrupt_handler(rtems_vector_number); -static rtems_isr m8xx_smc2_interrupt_handler(rtems_vector_number); -static rtems_isr m8xx_scc2_interrupt_handler(rtems_vector_number); +static void m8xx_smc1_interrupt_handler(void); +static void m8xx_smc2_interrupt_handler(void); +static void m8xx_scc2_interrupt_handler(void); #if defined(mpc860) -static rtems_isr m8xx_scc3_interrupt_handler(rtems_vector_number); -static rtems_isr m8xx_scc4_interrupt_handler(rtems_vector_number); +static void m8xx_scc3_interrupt_handler(void); +static void m8xx_scc4_interrupt_handler(void); #endif /* @@ -387,8 +382,7 @@ m8xx_uart_setAttributes( /* * Interrupt handlers */ -static rtems_isr -m8xx_scc2_interrupt_handler (rtems_vector_number v) +static void m8xx_scc2_interrupt_handler () { int nb_overflow; @@ -425,13 +419,12 @@ m8xx_scc2_interrupt_handler (rtems_vector_number v) (void *)ttyp[SCC2_MINOR], (int)TxBd[SCC2_MINOR]->length); } - m8xx.cisr = 1UL << 29; /* Clear SCC2 interrupt-in-service bit */ } #ifdef mpc860 -static rtems_isr -m8xx_scc3_interrupt_handler (rtems_vector_number v) +static void +m8xx_scc3_interrupt_handler (void) { int nb_overflow; @@ -468,12 +461,11 @@ m8xx_scc3_interrupt_handler (rtems_vector_number v) (void *)ttyp[SCC3_MINOR], (int)TxBd[SCC3_MINOR]->length); } - m8xx.cisr = 1UL << 28; /* Clear SCC3 interrupt-in-service bit */ } -static rtems_isr -m8xx_scc4_interrupt_handler (rtems_vector_number v) +static void +m8xx_scc4_interrupt_handler (void) { int nb_overflow; @@ -510,12 +502,11 @@ m8xx_scc4_interrupt_handler (rtems_vector_number v) (void *)ttyp[SCC4_MINOR], (int)TxBd[SCC4_MINOR]->length); } - m8xx.cisr = 1UL << 27; /* Clear SCC4 interrupt-in-service bit */ } #endif -static rtems_isr -m8xx_smc1_interrupt_handler (rtems_vector_number v) +static void +m8xx_smc1_interrupt_handler (void) { int nb_overflow; @@ -552,12 +543,11 @@ m8xx_smc1_interrupt_handler (rtems_vector_number v) (void *)ttyp[SMC1_MINOR], (int)TxBd[SMC1_MINOR]->length); } - m8xx.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */ } -static rtems_isr -m8xx_smc2_interrupt_handler (rtems_vector_number v) +static void +m8xx_smc2_interrupt_handler (void) { int nb_overflow; @@ -594,16 +584,77 @@ m8xx_smc2_interrupt_handler (rtems_vector_number v) (void *)ttyp[SMC2_MINOR], (int)TxBd[SMC2_MINOR]->length); } - m8xx.cisr = 1UL << 3; /* Clear SMC2 interrupt-in-service bit */ } +void m8xx_scc_enable(const rtems_irq_connect_data* ptr) +{ + volatile m8xxSCCRegisters_t *sccregs = 0; + switch (ptr->name) { +#if defined(mpc860) + case BSP_CPM_IRQ_SCC4 : + sccregs = &m8xx.scc4; + break; + case BSP_CPM_IRQ_SCC3 : + sccregs = &m8xx.scc3; + break; +#endif + case BSP_CPM_IRQ_SCC2 : + sccregs = &m8xx.scc2; + break; + case BSP_CPM_IRQ_SCC1 : + sccregs = &m8xx.scc1; + break; + default: + break; + } + sccregs->sccm = 3; +} +void m8xx_scc_disable(const rtems_irq_connect_data* ptr) +{ + volatile m8xxSCCRegisters_t *sccregs = 0; + switch (ptr->name) { +#if defined(mpc860) + case BSP_CPM_IRQ_SCC4 : + sccregs = &m8xx.scc4; + break; + case BSP_CPM_IRQ_SCC3 : + sccregs = &m8xx.scc3; + break; +#endif + case BSP_CPM_IRQ_SCC2 : + sccregs = &m8xx.scc2; + break; + case BSP_CPM_IRQ_SCC1 : + sccregs = &m8xx.scc1; + break; + default: + break; + } + sccregs->sccm &= (~3); +} + +int m8xx_scc_isOn(const rtems_irq_connect_data* ptr) +{ + return BSP_irq_enabled_at_cpm (ptr->name); +} + +static rtems_irq_connect_data consoleIrqData = +{ + BSP_CPM_IRQ_SCC2, + (rtems_irq_hdl)m8xx_scc2_interrupt_handler, + (rtems_irq_enable) m8xx_scc_enable, + (rtems_irq_disable) m8xx_scc_disable, + (rtems_irq_is_enabled) m8xx_scc_isOn +}; + void m8xx_uart_scc_initialize (int minor) { unsigned char brg; volatile m8xxSCCparms_t *sccparms = 0; volatile m8xxSCCRegisters_t *sccregs = 0; + int res; /* * Check that minor number is valid @@ -777,37 +828,63 @@ m8xx_uart_scc_initialize (int minor) if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) { switch (minor) { case SCC2_MINOR: - rtems_interrupt_catch (m8xx_scc2_interrupt_handler, - PPC_IRQ_CPM_SCC2, - &old_handler[minor]); - - sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */ - m8xx.cimr |= 1UL << 29; /* Enable SCC2 interrupts */ break; #ifdef mpc860 - case SCC3_MINOR: - rtems_interrupt_catch (m8xx_scc3_interrupt_handler, - PPC_IRQ_CPM_SCC3, - &old_handler[minor]); - - sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */ - m8xx.cimr |= 1UL << 28; /* Enable SCC2 interrupts */ - break; + case SCC3_MINOR: + consoleIrqData.name = BSP_CPM_IRQ_SCC3; + consoleIrqData.hdl = m8xx_scc3_interrupt_handler; + break; - case SCC4_MINOR: - rtems_interrupt_catch (m8xx_scc4_interrupt_handler, - PPC_IRQ_CPM_SCC4, - &old_handler[minor]); - - sccregs->sccm = 3; /* Enable SCC2 Rx & Tx interrupts */ - m8xx.cimr |= 1UL << 27; /* Enable SCC2 interrupts */ - break; + case SCC4_MINOR: + consoleIrqData.name = BSP_CPM_IRQ_SCC4; + consoleIrqData.hdl = m8xx_scc4_interrupt_handler; + break; #endif /* mpc860 */ } + if (!BSP_install_rtems_irq_handler (&consoleIrqData)) { + printk("Unable to connect SCC Irq handler\n"); + rtems_fatal_error_occurred(1); + } + } +} + +void m8xx_smc_enable(const rtems_irq_connect_data* ptr) +{ + volatile m8xxSMCRegisters_t *smcregs = 0; + switch (ptr->name) { + case BSP_CPM_IRQ_SMC1 : + smcregs = &m8xx.smc1; + break; + case BSP_CPM_IRQ_SMC2_OR_PIP : + smcregs = &m8xx.smc2; + break; + default: + break; + } + smcregs->smcm = 3; +} + +void m8xx_smc_disable(const rtems_irq_connect_data* ptr) +{ + volatile m8xxSMCRegisters_t *smcregs = 0; + switch (ptr->name) { + case BSP_CPM_IRQ_SMC1 : + smcregs = &m8xx.smc1; + break; + case BSP_CPM_IRQ_SMC2_OR_PIP : + smcregs = &m8xx.smc2; + break; + default: + break; } + smcregs->smcm &= (~3); } +int m8xx_smc_isOn(const rtems_irq_connect_data* ptr) +{ + return BSP_irq_enabled_at_cpm (ptr->name); +} void m8xx_uart_smc_initialize (int minor) @@ -923,24 +1000,23 @@ m8xx_uart_smc_initialize (int minor) */ smcregs->smcmr |= M8xx_SMCMR_TEN | M8xx_SMCMR_REN; if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) { + consoleIrqData.on = m8xx_smc_enable; + consoleIrqData.off = m8xx_smc_disable; + consoleIrqData.isOn = m8xx_smc_isOn; switch (minor) { - case SMC1_MINOR: - rtems_interrupt_catch (m8xx_smc1_interrupt_handler, - PPC_IRQ_CPM_SMC1, - &old_handler[minor]); - - smcregs->smcm = 3; /* Enable SMC1 Rx & Tx interrupts */ - m8xx.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ - break; + case SMC1_MINOR: + consoleIrqData.name = BSP_CPM_IRQ_SMC1; + consoleIrqData.hdl = m8xx_smc1_interrupt_handler; + break; - case SMC2_MINOR: - rtems_interrupt_catch (m8xx_smc2_interrupt_handler, - PPC_IRQ_CPM_SMC2, - &old_handler[minor]); - - smcregs->smcm = 3; /* Enable SMC2 Rx & Tx interrupts */ - m8xx.cimr |= 1UL << 3; /* Enable SMC2 interrupts */ - break; + case SMC2_MINOR: + consoleIrqData.name = BSP_CPM_IRQ_SMC2_OR_PIP; + consoleIrqData.hdl = m8xx_smc2_interrupt_handler; + break; + } + if (!BSP_install_rtems_irq_handler (&consoleIrqData)) { + printk("Unable to connect SMC Irq handler\n"); + rtems_fatal_error_occurred(1); } } } @@ -957,21 +1033,6 @@ m8xx_uart_initialize(void) } -void -m8xx_uart_interrupts_initialize(void) -{ -#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 - m8xx.simask |= M8xx_SIMASK_LVM1; /* Enable level interrupts */ -#ifdef EPPCBUG_SMC1 - simask_copy = m8xx.simask; -#endif -} - int m8xx_uart_pollRead( diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/.cvsignore b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/Makefile.am b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/Makefile.am new file mode 100644 index 0000000000..d79699810d --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/Makefile.am @@ -0,0 +1,43 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 + +PGM = $(ARCH)/exceptions.rel + +C_FILES = raw_exception.c + +S_FILES = asm_utils.S + +H_FILES = raw_exception.h + +exceptions_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o) \ + $(S_FILES:%.S=$(ARCH)/%.o) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../automake/compile.am +include $(top_srcdir)/../../../../../automake/lib.am + +$(PROJECT_INCLUDE)/libcpu: + $(mkinstalldirs) $@ +$(PROJECT_INCLUDE)/libcpu/%.h: %.h + $(INSTALL_DATA) $< $@ + +# +# (OPTIONAL) Add local stuff here using += +# + +$(PGM): $(exceptions_rel_OBJECTS) + $(make-rel) + +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu \ + $(PROJECT_INCLUDE)/libcpu/raw_exception.h + +all-local: $(ARCH) $(PREINSTALL_FILES) $(exceptions_rel_OBJECTS) $(PGM) + +.PRECIOUS: $(PGM) + +EXTRA_DIST = asm_utils.S raw_exception.c raw_exception.h + +include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/asm_utils.S b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/asm_utils.S new file mode 100644 index 0000000000..f046915404 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/asm_utils.S @@ -0,0 +1,65 @@ +/* + * asm_utils.s + * + * $Id$ + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * + * This file contains the low-level support for moving exception + * exception code to appropriate location. + * + */ + +#include +#include +#include +#include "asm.h" + + .globl codemove +codemove: + .type codemove,@function +/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */ + cmplw cr1,r3,r4 + addi r0,r5,3 + srwi. r0,r0,2 + beq cr1,4f /* In place copy is not necessary */ + beq 7f /* Protect against 0 count */ + mtctr r0 + bge cr1,2f + + la r8,-4(r4) + la r7,-4(r3) +1: lwzu r0,4(r8) + stwu r0,4(r7) + bdnz 1b + b 4f + +2: slwi r0,r0,2 + add r8,r4,r0 + add r7,r3,r0 +3: lwzu r0,-4(r8) + stwu r0,-4(r7) + bdnz 3b + +/* Now flush the cache: note that we must start from a cache aligned + * address. Otherwise we might miss one cache line. + */ +4: cmpwi r6,0 + add r5,r3,r5 + beq 7f /* Always flush prefetch queue in any case */ + subi r0,r6,1 + andc r3,r3,r0 + mr r4,r3 +5: cmplw r4,r5 + dcbst 0,r4 + add r4,r4,r6 + blt 5b + sync /* Wait for all dcbst to complete on bus */ + mr r4,r3 +6: cmplw r4,r5 + icbi 0,r4 + add r4,r4,r6 + blt 6b +7: sync /* Wait for all icbi to complete on bus */ + isync + blr diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/raw_exception.c b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/raw_exception.c new file mode 100644 index 0000000000..d1dfde1f12 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/raw_exception.c @@ -0,0 +1,199 @@ +/* + * raw_exception.c - This file contains implementation of C function to + * Instanciate 8xx ppc primary exception entries. + * More detailled information can be found on motorola + * site and more precisely in the following book : + * + * MPC860 + * Risc Microporcessor User's Manual + * Motorola REF : MPC860UM/AD + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * 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 +#include +#include +#include +#include +#include + +static rtems_raw_except_connect_data* raw_except_table; +static rtems_raw_except_connect_data default_raw_except_entry; +static rtems_raw_except_global_settings* local_settings; + +int mpc860_vector_is_valid(rtems_vector vector) +{ + switch(vector) { + case ASM_RESET_VECTOR: /* fall through */ + case ASM_MACH_VECTOR: + case ASM_PROT_VECTOR: + case ASM_ISI_VECTOR: + case ASM_EXT_VECTOR: + case ASM_ALIGN_VECTOR: + case ASM_PROG_VECTOR: + case ASM_FLOAT_VECTOR: + case ASM_DEC_VECTOR: + + case ASM_SYS_VECTOR: + case ASM_TRACE_VECTOR: + case ASM_FLOATASSIST_VECTOR: + + case ASM_SOFTEMUL_VECTOR: + case ASM_ITLBMISS_VECTOR: + case ASM_DTLBMISS_VECTOR: + case ASM_ITLBERROR_VECTOR: + case ASM_DTLBERROR_VECTOR: + + case ASM_DBREAK_VECTOR: + case ASM_IBREAK_VECTOR: + case ASM_PERIFBREAK_VECTOR: + case ASM_DEVPORT_VECTOR: + return 1; + default: return 0; + } +} + +int mpc8xx_vector_is_valid(rtems_vector vector) +{ + switch (current_ppc_cpu) { + case PPC_860: + if (!mpc860_vector_is_valid(vector)) { + return 0; + } + break; + default: + printk("Please complete libcpu/powerpc/mpc8xx/exceptions/raw_exception.c\n"); + printk("current_ppc_cpu = %x\n", current_ppc_cpu); + return 0; + } + return 1; +} + +int mpc8xx_set_exception (const rtems_raw_except_connect_data* except) +{ + unsigned int level; + + if (!mpc8xx_vector_is_valid(except->exceptIndex)) { + return 0; + } + /* + * Check if default handler is actually connected. If not issue an error. + * You must first get the current handler via mpc8xx_get_current_exception + * and then disconnect it using mpc8xx_delete_exception. + * RATIONALE : to always have the same transition by forcing the user + * to get the previous handler before accepting to disconnect. + */ + if (memcmp(mpc8xx_get_vector_addr(except->exceptIndex), (void*)default_raw_except_entry.hdl.raw_hdl,default_raw_except_entry.hdl.raw_hdl_size)) { + return 0; + } + + _CPU_ISR_Disable(level); + + raw_except_table [except->exceptIndex] = *except; + codemove((void*)mpc8xx_get_vector_addr(except->exceptIndex), + except->hdl.raw_hdl, + except->hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + except->on(except); + + _CPU_ISR_Enable(level); + return 1; +} + +int mpc8xx_get_current_exception (rtems_raw_except_connect_data* except) +{ + if (!mpc8xx_vector_is_valid(except->exceptIndex)){ + return 0; + } + + *except = raw_except_table [except->exceptIndex]; + + return 1; +} + +int mpc8xx_delete_exception (const rtems_raw_except_connect_data* except) +{ + unsigned int level; + + if (!mpc8xx_vector_is_valid(except->exceptIndex)){ + return 0; + } + /* + * Check if handler passed is actually connected. If not issue an error. + * You must first get the current handler via mpc8xx_get_current_exception + * and then disconnect it using mpc8xx_delete_exception. + * RATIONALE : to always have the same transition by forcing the user + * to get the previous handler before accepting to disconnect. + */ + if (memcmp(mpc8xx_get_vector_addr(except->exceptIndex), + (void*)except->hdl.raw_hdl, + except->hdl.raw_hdl_size)) { + return 0; + } + _CPU_ISR_Disable(level); + + except->off(except); + codemove((void*)mpc8xx_get_vector_addr(except->exceptIndex), + default_raw_except_entry.hdl.raw_hdl, + default_raw_except_entry.hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + + + raw_except_table[except->exceptIndex] = default_raw_except_entry; + raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex; + + _CPU_ISR_Enable(level); + + return 1; +} + +/* + * Exception global init. + */ +int mpc8xx_init_exceptions (rtems_raw_except_global_settings* config) +{ + unsigned i; + unsigned int level; + + /* + * store various accelerators + */ + raw_except_table = config->rawExceptHdlTbl; + local_settings = config; + default_raw_except_entry = config->defaultRawEntry; + + _CPU_ISR_Disable(level); + + for (i=0; i <= LAST_VALID_EXC; i++) { + if (!mpc8xx_vector_is_valid(i)){ + continue; + } + codemove((void*)mpc8xx_get_vector_addr(i), + raw_except_table[i].hdl.raw_hdl, + raw_except_table[i].hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) { + raw_except_table[i].on(&raw_except_table[i]); + } + else { + raw_except_table[i].off(&raw_except_table[i]); + } + } + _CPU_ISR_Enable(level); + + return 1; +} + +int mpc8xx_get_exception_config (rtems_raw_except_global_settings** config) +{ + *config = local_settings; + return 1; +} + diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/raw_exception.h b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/raw_exception.h new file mode 100644 index 0000000000..20f0fa72b1 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/mpc8xx/exceptions/raw_exception.h @@ -0,0 +1,188 @@ +/* + * raw_execption.h + * + * This file contains implementation of C function to + * Instanciate 8xx ppc primary exception entries. + * More detailled information can be found on motorola + * site and more precisely in the following book : + * + * MPC860 + * Risc Microporcessor User's Manual + * Motorola REF : MPC860UM/AD 07/98 Rev .1 + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * 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 _LIBCPU_MPC8XX_EXCEPTION_RAW_EXCEPTION_H +#define _LIBCPU_MPC8XX_EXCEPTION_RAW_EXCEPTION_H + +/* + * Exception Vectors as defined in the MCP750 manual + */ + +#define ASM_RESET_VECTOR 0x01 +#define ASM_MACH_VECTOR 0x02 +#define ASM_PROT_VECTOR 0x03 +#define ASM_ISI_VECTOR 0x04 +#define ASM_EXT_VECTOR 0x05 +#define ASM_ALIGN_VECTOR 0x06 +#define ASM_PROG_VECTOR 0x07 +#define ASM_FLOAT_VECTOR 0x08 +#define ASM_DEC_VECTOR 0x09 + +#define ASM_SYS_VECTOR 0x0C +#define ASM_TRACE_VECTOR 0x0D +#define ASM_FLOATASSIST_VECTOR 0x0E + +#define ASM_SOFTEMUL_VECTOR 0x10 +#define ASM_ITLBMISS_VECTOR 0x11 +#define ASM_DTLBMISS_VECTOR 0x12 +#define ASM_ITLBERROR_VECTOR 0x13 +#define ASM_DTLBERROR_VECTOR 0x14 + +#define ASM_DBREAK_VECTOR 0x1C +#define ASM_IBREAK_VECTOR 0x1D +#define ASM_PERIFBREAK_VECTOR 0x1E +#define ASM_DEVPORT_VECTOR 0x1F + +#define LAST_VALID_EXC ASM_DEVPORT_VECTOR + +/* + * Vector offsets as defined in the MPC860 manual + */ + +#define ASM_RESET_VECTOR_OFFSET (ASM_RESET_VECTOR << 8) +#define ASM_MACH_VECTOR_OFFSET (ASM_MACH_VECTOR << 8) +#define ASM_PROT_VECTOR_OFFSET (ASM_PROT_VECTOR << 8) +#define ASM_ISI_VECTOR_OFFSET (ASM_ISI_VECTOR << 8) +#define ASM_EXT_VECTOR_OFFSET (ASM_EXT_VECTOR << 8) +#define ASM_ALIGN_VECTOR_OFFSET (ASM_ALIGN_VECTOR << 8) +#define ASM_PROG_VECTOR_OFFSET (ASM_PROG_VECTOR << 8) +#define ASM_FLOAT_VECTOR_OFFSET (ASM_FLOAT_VECTOR << 8) +#define ASM_DEC_VECTOR_OFFSET (ASM_DEC_VECTOR << 8) + +#define ASM_SYS_VECTOR_OFFSET (ASM_SYS_VECTOR << 8) +#define ASM_TRACE_VECTOR_OFFSET (ASM_TRACE_VECTOR << 8) +#define ASM_FLOATASSIST_VECTOR_OFFSET (ASM_FLOATASSIST_VECTOR << 8) + +#define ASM_SOFTEMUL_VECTOR_OFFSET (ASM_SOFTEMUL_VECTOR << 8) +#define ASM_ITLBMISS_VECTOR_OFFSET (ASM_ITLBMISS_VECTOR << 8) +#define ASM_DTLBMISS_VECTOR_OFFSET (ASM_DTLBMISS_VECTOR << 8) +#define ASM_ITLBERROR_VECTOR_OFFSET (ASM_ITLBERROR_VECTOR << 8) +#define ASM_DTLBERROR_VECTOR_OFFSET (ASM_DTLBERROR_VECTOR << 8) + +#define ASM_DBREAK_VECTOR_OFFSET (ASM_DBREAK_VECTOR << 8) +#define ASM_IBREAK_VECTOR_OFFSET (ASM_IBREAK_VECTOR << 8) +#define ASM_PERIFBREAK_VECTOR_OFFSET (ASM_PERIFBREAK_VECTOR << 8) +#define ASM_DEVPORT_VECTOR_OFFSET (ASM_DEVPORT_VECTOR_OFFSET << 8) + +#ifndef ASM + +/* + * Type definition for raw exceptions. + */ + +typedef unsigned char rtems_vector; +struct __rtems_raw_except_connect_data__; +typedef void (*rtems_raw_except_func) (void); +typedef unsigned char rtems_raw_except_hdl_size; + +typedef struct { + rtems_vector vector; + rtems_raw_except_func raw_hdl; + rtems_raw_except_hdl_size raw_hdl_size; +}rtems_raw_except_hdl; + +typedef void (*rtems_raw_except_enable) (const struct __rtems_raw_except_connect_data__*); +typedef void (*rtems_raw_except_disable) (const struct __rtems_raw_except_connect_data__*); +typedef int (*rtems_raw_except_is_enabled) (const struct __rtems_raw_except_connect_data__*); + +typedef struct __rtems_raw_except_connect_data__{ + /* + * Exception vector (As defined in the manual) + */ + rtems_vector exceptIndex; + /* + * Exception raw handler. See comment on handler properties below in function prototype. + */ + rtems_raw_except_hdl hdl; + /* + * function for enabling raw exceptions. In order to be consistent + * with the fact that the raw connexion can defined in the + * libcpu library, this library should have no knowledge of + * board specific hardware to manage exceptions and thus the + * "on" routine must enable the except at processor level only. + * + */ + rtems_raw_except_enable on; + /* + * function for disabling raw exceptions. In order to be consistent + * with the fact that the raw connexion can defined in the + * libcpu library, this library should have no knowledge of + * board specific hardware to manage exceptions and thus the + * "on" routine must disable the except both at device and PIC level. + * + */ + rtems_raw_except_disable off; + /* + * function enabling to know what exception may currently occur + */ + rtems_raw_except_is_enabled isOn; +}rtems_raw_except_connect_data; + +typedef struct { + /* + * size of all the table fields (*Tbl) described below. + */ + unsigned int exceptSize; + /* + * Default handler used when disconnecting exceptions. + */ + rtems_raw_except_connect_data defaultRawEntry; + /* + * Table containing initials/current value. + */ + rtems_raw_except_connect_data* rawExceptHdlTbl; +}rtems_raw_except_global_settings; + +/* + * C callable function enabling to set up one raw idt entry + */ +extern int mpc8xx_set_exception (const rtems_raw_except_connect_data*); + +/* + * C callable function enabling to get one current raw idt entry + */ +extern int mpc8xx_get_current_exception (rtems_raw_except_connect_data*); + +/* + * C callable function enabling to remove one current raw idt entry + */ +extern int mpc8xx_delete_exception (const rtems_raw_except_connect_data*); + +/* + * C callable function enabling to check if vector is valid + */ +extern int mpc8xx_vector_is_valid(rtems_vector vector); + +inline static void* mpc8xx_get_vector_addr(rtems_vector vector) +{ + return ((void*) (((unsigned) vector) << 8)); +} +/* + * Exception global init. + */ +extern int mpc8xx_init_exceptions (rtems_raw_except_global_settings* config); +extern int mpc8xx_get_exception_config (rtems_raw_except_global_settings** config); + +# endif /* ASM */ + +#endif + diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h b/c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h index 566b617baf..fb8e8d0691 100644 --- a/c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h +++ b/c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h @@ -649,9 +649,9 @@ typedef struct m8xxSPIparms_ { ************************************************************************* */ typedef struct m8xxBufferDescriptor_ { - rtems_unsigned16 status; - rtems_unsigned16 length; - volatile void *buffer; + volatile rtems_unsigned16 status; + rtems_unsigned16 length; + volatile void *buffer; } m8xxBufferDescriptor_t; /* diff --git a/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c index 9ae75d84f7..05c93995a0 100644 --- a/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c +++ b/c/src/lib/libcpu/powerpc/mpc8xx/mmu/mmu.c @@ -115,7 +115,7 @@ void mmu_init( void ) /* * Turn on address translation by setting MSR[IR] and MSR[DR]. */ - _CPU_MSR_Value( reg1 ); + _CPU_MSR_GET( reg1 ); reg1 |= PPC_MSR_IR | PPC_MSR_DR; _CPU_MSR_SET( reg1 ); } diff --git a/c/src/lib/libcpu/powerpc/new_exception_processing/cpu.h b/c/src/lib/libcpu/powerpc/new_exception_processing/cpu.h index 303c882740..e54f7fc14e 100644 --- a/c/src/lib/libcpu/powerpc/new_exception_processing/cpu.h +++ b/c/src/lib/libcpu/powerpc/new_exception_processing/cpu.h @@ -440,6 +440,20 @@ typedef struct { unsigned32 clicks_per_usec; /* Timer clicks per microsecond */ boolean exceptions_in_RAM; /* TRUE if in RAM */ +#if (defined(ppc403) || defined(mpc860) || defined(mpc821)) + unsigned32 serial_per_sec; /* Serial clocks per second */ + boolean serial_external_clock; + boolean serial_xon_xoff; + boolean serial_cts_rts; + unsigned32 serial_rate; + unsigned32 timer_average_overhead; /* Average overhead of timer in ticks */ + unsigned32 timer_least_valid; /* Least valid number from timer */ + boolean timer_internal_clock; /* TRUE, when timer runs with CPU clk */ +#endif + +#if (defined(mpc860) || defined(mpc821)) + unsigned32 clock_speed; /* Speed of CPU in Hz */ +#endif } rtems_cpu_table; /* diff --git a/c/src/lib/libcpu/powerpc/shared/include/byteorder.h b/c/src/lib/libcpu/powerpc/shared/include/byteorder.h index e5342967d9..16faebef04 100644 --- a/c/src/lib/libcpu/powerpc/shared/include/byteorder.h +++ b/c/src/lib/libcpu/powerpc/shared/include/byteorder.h @@ -19,10 +19,6 @@ #ifndef _PPC_BYTEORDER_H #define _PPC_BYTEORDER_H -/* - * $Id$ - */ - #ifdef __GNUC__ extern __inline__ unsigned ld_le16(volatile unsigned short *addr) diff --git a/c/src/lib/libcpu/powerpc/wrapup/Makefile.am b/c/src/lib/libcpu/powerpc/wrapup/Makefile.am index 92f86b9870..3cb0a5109d 100644 --- a/c/src/lib/libcpu/powerpc/wrapup/Makefile.am +++ b/c/src/lib/libcpu/powerpc/wrapup/Makefile.am @@ -10,7 +10,10 @@ GENERIC_FILES = shared # So far FAMILY_OBJS is empty and ar dislike it... CPU_SPECIFIC_OBJS = $(wildcard ../$(RTEMS_CPU_MODEL)/*/$(ARCH)/*.o) FAMILY_OBJS = \ - $(wildcard ../shared/$(ARCH)/*.o ../shared/*/$(ARCH)/*.o ../old_exception_processing/*/$(ARCH)/*.o ../new_exception_processing/*/$(ARCH)/*.o ../mpc6xx/*/$(ARCH)/*.o) + $(wildcard ../shared/$(ARCH)/*.o ../shared/*/$(ARCH)/*.o \ + ../old_exception_processing/*/$(ARCH)/*.o \ + ../new_exception_processing/*/$(ARCH)/*.o \ + ../mpc6xx/*/$(ARCH)/*.o) LIB = $(ARCH)/libcpu.a -- cgit v1.2.3