forked from Imagelibrary/rtems
2001-11-08 Dennis Ehlin (ECS) <Dennis.Ehlin@ecs.ericsson.se>
This modification is part of the submitted modifications necessary to support the IBM PPC405 family. This submission was reviewed by Thomas Doerfler <Thomas.Doerfler@imd-systems.de> who ensured it did not negatively impact the ppc403 BSPs. The submission and tracking process was captured as PR50. * ppc403/console/console405.c ppc403/tty_drv/.cvsignore, ppc403/tty_drv/Makefile.am, ppc403/tty_drv/tty_drv.c, ppc403/tty_drv/tty_drv.h: New files. * Makefile.am, README, configure.ac, old_exception_processing/cpu.c, old_exception_processing/cpu.h, ppc403/Makefile.am, ppc403/clock/clock.c, ppc403/console/Makefile.am, ppc403/console/console.c, ppc403/ictrl/ictrl.c, ppc403/ictrl/ictrl.h, ppc403/timer/timer.c: Modified.
This commit is contained in:
@@ -366,7 +366,7 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
|
|||||||
printf("Spurious interrupt on vector %d from %08.8x\n",
|
printf("Spurious interrupt on vector %d from %08.8x\n",
|
||||||
v, i->pc);
|
v, i->pc);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ppc403
|
#if defined(ppc403) || defined(ppc405)
|
||||||
if (v == PPC_IRQ_EXTERNAL)
|
if (v == PPC_IRQ_EXTERNAL)
|
||||||
{
|
{
|
||||||
register int r = 0;
|
register int r = 0;
|
||||||
@@ -627,7 +627,7 @@ unsigned32 ppc_exception_vector_addr(
|
|||||||
Offset = 0x00e00;
|
Offset = 0x00e00;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(ppc403)
|
#if defined(ppc403) || defined(ppc405)
|
||||||
|
|
||||||
/* PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET
|
/* PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET
|
||||||
case PPC_IRQ_CRIT:
|
case PPC_IRQ_CRIT:
|
||||||
|
|||||||
@@ -474,7 +474,7 @@ typedef struct {
|
|||||||
void (*spurious_handler)(unsigned32 vector, CPU_Interrupt_frame *);
|
void (*spurious_handler)(unsigned32 vector, CPU_Interrupt_frame *);
|
||||||
boolean exceptions_in_RAM; /* TRUE if in RAM */
|
boolean exceptions_in_RAM; /* TRUE if in RAM */
|
||||||
|
|
||||||
#if (defined(ppc403) || defined(mpc860) || defined(mpc821))
|
#if (defined(ppc403) || defined(ppc405) || defined(mpc860) || defined(mpc821))
|
||||||
unsigned32 serial_per_sec; /* Serial clocks per second */
|
unsigned32 serial_per_sec; /* Serial clocks per second */
|
||||||
boolean serial_external_clock;
|
boolean serial_external_clock;
|
||||||
boolean serial_xon_xoff;
|
boolean serial_xon_xoff;
|
||||||
@@ -508,7 +508,7 @@ typedef struct {
|
|||||||
#define rtems_cpu_configuration_get_exceptions_in_ram() \
|
#define rtems_cpu_configuration_get_exceptions_in_ram() \
|
||||||
(_CPU_Table.exceptions_in_RAM)
|
(_CPU_Table.exceptions_in_RAM)
|
||||||
|
|
||||||
#if (defined(ppc403) || defined(mpc860) || defined(mpc821))
|
#if (defined(ppc403) || defined(ppc405) || defined(mpc860) || defined(mpc821))
|
||||||
|
|
||||||
#define rtems_cpu_configuration_get_serial_per_sec() \
|
#define rtems_cpu_configuration_get_serial_per_sec() \
|
||||||
(_CPU_Table.serial_per_sec)
|
(_CPU_Table.serial_per_sec)
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
2001-11-08 Dennis Ehlin (ECS) <Dennis.Ehlin@ecs.ericsson.se>
|
||||||
|
|
||||||
|
This modification is part of the submitted modifications necessary to
|
||||||
|
support the IBM PPC405 family. This submission was reviewed by
|
||||||
|
Thomas Doerfler <Thomas.Doerfler@imd-systems.de> who ensured it did
|
||||||
|
not negatively impact the ppc403 BSPs. The submission and tracking
|
||||||
|
process was captured as PR50.
|
||||||
|
* ppc403/console/console405.c ppc403/tty_drv/.cvsignore,
|
||||||
|
ppc403/tty_drv/Makefile.am, ppc403/tty_drv/tty_drv.c,
|
||||||
|
ppc403/tty_drv/tty_drv.h: New files.
|
||||||
|
* Makefile.am, README, configure.ac, old_exception_processing/cpu.c,
|
||||||
|
old_exception_processing/cpu.h, ppc403/Makefile.am,
|
||||||
|
ppc403/clock/clock.c, ppc403/console/Makefile.am,
|
||||||
|
ppc403/console/console.c, ppc403/ictrl/ictrl.c, ppc403/ictrl/ictrl.h,
|
||||||
|
ppc403/timer/timer.c: Modified.
|
||||||
|
|
||||||
2001-11-07 Joel Sherrill <joel@OARcorp.com>
|
2001-11-07 Joel Sherrill <joel@OARcorp.com>
|
||||||
|
|
||||||
* configure.ac: Delete the commented out line that said that
|
* configure.ac: Delete the commented out line that said that
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ endif
|
|||||||
if ppc403
|
if ppc403
|
||||||
CPU_SUBDIR = ppc403
|
CPU_SUBDIR = ppc403
|
||||||
endif
|
endif
|
||||||
|
if ppc405
|
||||||
|
## 403 and 405 chips use the same CPU sources...
|
||||||
|
CPU_SUBDIR = ppc403
|
||||||
|
endif
|
||||||
|
|
||||||
SUBDIRS = $(SHARED_LIB) $(EXCEPTION_SUBDIR) $(CPU_SUBDIR) wrapup
|
SUBDIRS = $(SHARED_LIB) $(EXCEPTION_SUBDIR) $(CPU_SUBDIR) wrapup
|
||||||
|
|
||||||
|
|||||||
@@ -9,17 +9,25 @@ available from IBM and Motorola.
|
|||||||
Since these routines can differ amongst different members
|
Since these routines can differ amongst different members
|
||||||
of the PowerPC family, an entry per CPU type is provided.
|
of the PowerPC family, an entry per CPU type is provided.
|
||||||
|
|
||||||
Initially, (4/December/1995), only the PPC403 was supported.
|
|
||||||
At this time, support is included for the following PowerPC
|
At this time, support is included for the following PowerPC
|
||||||
family members:
|
family members using the new exception processing model:
|
||||||
|
|
||||||
+ mpc505
|
+ mpc505
|
||||||
|
+ mpc6xx
|
||||||
+ mpc750
|
+ mpc750
|
||||||
+ mpc821
|
+ mpc821
|
||||||
|
+ mpc823 (uses mpc821 directory)
|
||||||
|
+ mpc850 (uses mpc860 directory)
|
||||||
+ mpc860
|
+ mpc860
|
||||||
+ ppc403
|
|
||||||
+ mpc8260
|
+ mpc8260
|
||||||
|
|
||||||
|
The following PowerPC family members are supported but
|
||||||
|
still use the old exception processing model:
|
||||||
|
|
||||||
|
+ ppc403
|
||||||
|
+ ppc405 (uses ppc403 directory)
|
||||||
|
+ ppc6xx (no libcpu support)
|
||||||
|
|
||||||
Note that because of similarities in various family members,
|
Note that because of similarities in various family members,
|
||||||
the mpc823 should be able to use the mpc821 code and the
|
the mpc823 should be able to use the mpc821 code and the
|
||||||
mpc850 should be able to use the mpc850 code.
|
mpc850 should be able to use the mpc850 code.
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ test "$RTEMS_CPU_MODEL" = "mpc860" \
|
|||||||
## first.
|
## first.
|
||||||
AM_CONDITIONAL(old_exception_processing, \
|
AM_CONDITIONAL(old_exception_processing, \
|
||||||
test "$RTEMS_CPU_MODEL" = "ppc403" || \
|
test "$RTEMS_CPU_MODEL" = "ppc403" || \
|
||||||
|
test "$RTEMS_CPU_MODEL" = "ppc405" || \
|
||||||
test "$RTEMS_CPU_MODEL" = "mpc505" || \
|
test "$RTEMS_CPU_MODEL" = "mpc505" || \
|
||||||
test "$RTEMS_CPU_MODEL" = "ppc603e" \
|
test "$RTEMS_CPU_MODEL" = "ppc603e" \
|
||||||
)
|
)
|
||||||
@@ -64,6 +65,7 @@ AM_CONDITIONAL(mpc8xx, test "$RTEMS_CPU_MODEL" = "mpc8xx" \
|
|||||||
|| test "$RTEMS_CPU_MODEL" = "mpc860" )
|
|| test "$RTEMS_CPU_MODEL" = "mpc860" )
|
||||||
AM_CONDITIONAL(mpc8260, test "$RTEMS_CPU_MODEL" = "mpc8260")
|
AM_CONDITIONAL(mpc8260, test "$RTEMS_CPU_MODEL" = "mpc8260")
|
||||||
AM_CONDITIONAL(ppc403, test "$RTEMS_CPU_MODEL" = "ppc403")
|
AM_CONDITIONAL(ppc403, test "$RTEMS_CPU_MODEL" = "ppc403")
|
||||||
|
AM_CONDITIONAL(ppc405, test "$RTEMS_CPU_MODEL" = "ppc405")
|
||||||
|
|
||||||
# Explicitly list all Makefiles here
|
# Explicitly list all Makefiles here
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([Makefile
|
||||||
@@ -82,6 +84,7 @@ mpc8xx/timer/Makefile
|
|||||||
ppc403/Makefile
|
ppc403/Makefile
|
||||||
ppc403/clock/Makefile
|
ppc403/clock/Makefile
|
||||||
ppc403/console/Makefile
|
ppc403/console/Makefile
|
||||||
|
ppc403/tty_drv/Makefile
|
||||||
ppc403/ictrl/Makefile
|
ppc403/ictrl/Makefile
|
||||||
ppc403/timer/Makefile
|
ppc403/timer/Makefile
|
||||||
ppc403/vectors/Makefile
|
ppc403/vectors/Makefile
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
|
|||||||
printf("Spurious interrupt on vector %d from %08.8x\n",
|
printf("Spurious interrupt on vector %d from %08.8x\n",
|
||||||
v, i->pc);
|
v, i->pc);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ppc403
|
#if defined(ppc403) || defined(ppc405)
|
||||||
if (v == PPC_IRQ_EXTERNAL)
|
if (v == PPC_IRQ_EXTERNAL)
|
||||||
{
|
{
|
||||||
register int r = 0;
|
register int r = 0;
|
||||||
@@ -627,7 +627,7 @@ unsigned32 ppc_exception_vector_addr(
|
|||||||
Offset = 0x00e00;
|
Offset = 0x00e00;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(ppc403)
|
#if defined(ppc403) || defined(ppc405)
|
||||||
|
|
||||||
/* PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET
|
/* PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET
|
||||||
case PPC_IRQ_CRIT:
|
case PPC_IRQ_CRIT:
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
|
|||||||
printf("Spurious interrupt on vector %d from %08.8x\n",
|
printf("Spurious interrupt on vector %d from %08.8x\n",
|
||||||
v, i->pc);
|
v, i->pc);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ppc403
|
#if defined(ppc403) || defined(ppc405)
|
||||||
if (v == PPC_IRQ_EXTERNAL)
|
if (v == PPC_IRQ_EXTERNAL)
|
||||||
{
|
{
|
||||||
register int r = 0;
|
register int r = 0;
|
||||||
@@ -627,7 +627,7 @@ unsigned32 ppc_exception_vector_addr(
|
|||||||
Offset = 0x00e00;
|
Offset = 0x00e00;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(ppc403)
|
#if defined(ppc403) || defined(ppc405)
|
||||||
|
|
||||||
/* PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET
|
/* PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET
|
||||||
case PPC_IRQ_CRIT:
|
case PPC_IRQ_CRIT:
|
||||||
|
|||||||
@@ -474,7 +474,7 @@ typedef struct {
|
|||||||
void (*spurious_handler)(unsigned32 vector, CPU_Interrupt_frame *);
|
void (*spurious_handler)(unsigned32 vector, CPU_Interrupt_frame *);
|
||||||
boolean exceptions_in_RAM; /* TRUE if in RAM */
|
boolean exceptions_in_RAM; /* TRUE if in RAM */
|
||||||
|
|
||||||
#if (defined(ppc403) || defined(mpc860) || defined(mpc821))
|
#if (defined(ppc403) || defined(ppc405) || defined(mpc860) || defined(mpc821))
|
||||||
unsigned32 serial_per_sec; /* Serial clocks per second */
|
unsigned32 serial_per_sec; /* Serial clocks per second */
|
||||||
boolean serial_external_clock;
|
boolean serial_external_clock;
|
||||||
boolean serial_xon_xoff;
|
boolean serial_xon_xoff;
|
||||||
@@ -508,7 +508,7 @@ typedef struct {
|
|||||||
#define rtems_cpu_configuration_get_exceptions_in_ram() \
|
#define rtems_cpu_configuration_get_exceptions_in_ram() \
|
||||||
(_CPU_Table.exceptions_in_RAM)
|
(_CPU_Table.exceptions_in_RAM)
|
||||||
|
|
||||||
#if (defined(ppc403) || defined(mpc860) || defined(mpc821))
|
#if (defined(ppc403) || defined(ppc405) || defined(mpc860) || defined(mpc821))
|
||||||
|
|
||||||
#define rtems_cpu_configuration_get_serial_per_sec() \
|
#define rtems_cpu_configuration_get_serial_per_sec() \
|
||||||
(_CPU_Table.serial_per_sec)
|
(_CPU_Table.serial_per_sec)
|
||||||
|
|||||||
@@ -4,7 +4,12 @@
|
|||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign 1.4
|
AUTOMAKE_OPTIONS = foreign 1.4
|
||||||
|
|
||||||
|
if ppc403
|
||||||
SUBDIRS = console clock timer vectors ictrl
|
SUBDIRS = console clock timer vectors ictrl
|
||||||
|
endif
|
||||||
|
if ppc405
|
||||||
|
SUBDIRS = console tty_drv clock timer vectors ictrl
|
||||||
|
endif
|
||||||
|
|
||||||
include $(top_srcdir)/../../../../../automake/subdirs.am
|
include $(top_srcdir)/../../../../../automake/subdirs.am
|
||||||
include $(top_srcdir)/../../../../../automake/local.am
|
include $(top_srcdir)/../../../../../automake/local.am
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
* for these modifications:
|
* for these modifications:
|
||||||
* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
|
* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-1999.
|
* COPYRIGHT (c) 1989-1999.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
*
|
*
|
||||||
@@ -33,6 +32,8 @@
|
|||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
|
* Modifications for PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -59,7 +60,11 @@ static inline rtems_unsigned32 get_itimer(void)
|
|||||||
{
|
{
|
||||||
register rtems_unsigned32 rc;
|
register rtems_unsigned32 rc;
|
||||||
|
|
||||||
|
#ifndef ppc405 /* this is a ppc403 */
|
||||||
asm volatile ("mfspr %0, 0x3dd" : "=r" ((rc))); /* TBLO */
|
asm volatile ("mfspr %0, 0x3dd" : "=r" ((rc))); /* TBLO */
|
||||||
|
#else /* ppc405 */
|
||||||
|
asm volatile ("mfspr %0, 0x10c" : "=r" ((rc))); /* 405GP TBL */
|
||||||
|
#endif /* ppc405 */
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -71,11 +76,10 @@ static inline rtems_unsigned32 get_itimer(void)
|
|||||||
rtems_isr
|
rtems_isr
|
||||||
Clock_isr(rtems_vector_number vector)
|
Clock_isr(rtems_vector_number vector)
|
||||||
{
|
{
|
||||||
|
rtems_unsigned32 clicks_til_next_interrupt;
|
||||||
if (!auto_restart)
|
if (!auto_restart)
|
||||||
{
|
{
|
||||||
rtems_unsigned32 clicks_til_next_interrupt;
|
|
||||||
rtems_unsigned32 itimer_value;
|
rtems_unsigned32 itimer_value;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setup for next interrupt; making sure the new value is reasonably
|
* setup for next interrupt; making sure the new value is reasonably
|
||||||
* in the future.... in case we lost out on an interrupt somehow
|
* in the future.... in case we lost out on an interrupt somehow
|
||||||
@@ -131,24 +135,25 @@ Clock_isr(rtems_vector_number vector)
|
|||||||
void Install_clock(rtems_isr_entry clock_isr)
|
void Install_clock(rtems_isr_entry clock_isr)
|
||||||
{
|
{
|
||||||
rtems_isr_entry previous_isr;
|
rtems_isr_entry previous_isr;
|
||||||
rtems_unsigned32 pvr, iocr;
|
rtems_unsigned32 iocr;
|
||||||
register rtems_unsigned32 tcr;
|
register rtems_unsigned32 tcr;
|
||||||
|
#ifdef ppc403
|
||||||
|
rtems_unsigned32 pvr;
|
||||||
|
#endif /* ppc403 */
|
||||||
|
|
||||||
Clock_driver_ticks = 0;
|
Clock_driver_ticks = 0;
|
||||||
|
|
||||||
|
#ifndef ppc405 /* this is a ppc403 */
|
||||||
asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
|
asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
|
||||||
|
|
||||||
if (rtems_cpu_configuration_get_timer_internal_clock()) {
|
if (rtems_cpu_configuration_get_timer_internal_clock()) {
|
||||||
iocr &= ~4; /* timer clocked from system clock */
|
iocr &= ~4; /* timer clocked from system clock */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
iocr |= 4; /* select external timer clock */
|
iocr |= 4; /* select external timer clock */
|
||||||
}
|
}
|
||||||
|
|
||||||
asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
|
asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
|
||||||
|
|
||||||
asm volatile ("mfspr %0, 0x11f" : "=r" ((pvr))); /* PVR */
|
asm volatile ("mfspr %0, 0x11f" : "=r" ((pvr))); /* PVR */
|
||||||
|
|
||||||
if (((pvr & 0xffff0000) >> 16) != 0x0020)
|
if (((pvr & 0xffff0000) >> 16) != 0x0020)
|
||||||
return; /* Not a ppc403 */
|
return; /* Not a ppc403 */
|
||||||
|
|
||||||
@@ -162,10 +167,26 @@ void Install_clock(rtems_isr_entry clock_isr)
|
|||||||
else if ((pvr & 0xff00) == 0x0100) /* 403GB */
|
else if ((pvr & 0xff00) == 0x0100) /* 403GB */
|
||||||
auto_restart = 1;
|
auto_restart = 1;
|
||||||
|
|
||||||
|
#else /* ppc405 */
|
||||||
|
asm volatile ("mfdcr %0, 0x0b2" : "=r" (iocr)); /*405GP CPC0_CR1 */
|
||||||
|
if (rtems_cpu_configuration_get_timer_internal_clock()) {
|
||||||
|
iocr &=~0x800000 ;/* timer clocked from system clock CETE*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
iocr |= 0x800000; /* select external timer clock CETE*/
|
||||||
|
}
|
||||||
|
asm volatile ("mtdcr 0x0b2, %0" : "=r" (iocr) : "0" (iocr)); /* 405GP CPC0_CR1 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable auto restart
|
||||||
|
*/
|
||||||
|
|
||||||
|
auto_restart=1;
|
||||||
|
|
||||||
|
#endif /* ppc405 */
|
||||||
pit_value = rtems_configuration_get_microseconds_per_tick() *
|
pit_value = rtems_configuration_get_microseconds_per_tick() *
|
||||||
rtems_cpu_configuration_get_clicks_per_usec();
|
rtems_cpu_configuration_get_clicks_per_usec();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize the interval here
|
* initialize the interval here
|
||||||
* First tick is set to right amount of time in the future
|
* First tick is set to right amount of time in the future
|
||||||
@@ -176,16 +197,19 @@ void Install_clock(rtems_isr_entry clock_isr)
|
|||||||
|
|
||||||
rtems_interrupt_catch(clock_isr, PPC_IRQ_PIT, &previous_isr);
|
rtems_interrupt_catch(clock_isr, PPC_IRQ_PIT, &previous_isr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set PIT value
|
||||||
|
*/
|
||||||
|
|
||||||
asm volatile ("mtspr 0x3db, %0" : : "r" (pit_value)); /* PIT */
|
asm volatile ("mtspr 0x3db, %0" : : "r" (pit_value)); /* PIT */
|
||||||
|
|
||||||
asm volatile ("mfspr %0, 0x3da" : "=r" ((tcr))); /* TCR */
|
/*
|
||||||
|
* Set timer to autoreload, bit TCR->ARE = 1 0x0400000
|
||||||
tcr &= ~ 0x04400000;
|
* Enable PIT interrupt, bit TCR->PIE = 1 0x4000000
|
||||||
|
*/
|
||||||
tcr |= (auto_restart ? 0x04400000 : 0x04000000);
|
|
||||||
|
|
||||||
tick_time = get_itimer() + pit_value;
|
tick_time = get_itimer() + pit_value;
|
||||||
|
asm volatile ("mfspr %0, 0x3da" : "=r" ((tcr))); /* TCR */
|
||||||
|
tcr = (tcr & ~0x04400000) | (auto_restart ? 0x04400000 : 0x04000000);
|
||||||
asm volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
|
asm volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
|
||||||
|
|
||||||
atexit(Clock_exit);
|
atexit(Clock_exit);
|
||||||
@@ -208,6 +232,9 @@ ReInstall_clock(rtems_isr_entry new_clock_isr)
|
|||||||
/*
|
/*
|
||||||
* Called via atexit()
|
* Called via atexit()
|
||||||
* Remove the clock interrupt handler by setting handler to NULL
|
* Remove the clock interrupt handler by setting handler to NULL
|
||||||
|
*
|
||||||
|
* This will not work on the 405GP because
|
||||||
|
* when bit's are set in TCR they can only be unset by a reset
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ AUTOMAKE_OPTIONS = foreign 1.4
|
|||||||
|
|
||||||
PGM = $(ARCH)/console.rel
|
PGM = $(ARCH)/console.rel
|
||||||
|
|
||||||
|
if ppc403
|
||||||
C_FILES = console.c
|
C_FILES = console.c
|
||||||
|
endif
|
||||||
|
if ppc405
|
||||||
|
C_FILES = console405.c
|
||||||
|
endif
|
||||||
|
|
||||||
console_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
|
console_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||||
|
|
||||||
@@ -25,6 +30,6 @@ all-local: $(ARCH) $(console_rel_OBJECTS) $(PGM)
|
|||||||
|
|
||||||
.PRECIOUS: $(PGM)
|
.PRECIOUS: $(PGM)
|
||||||
|
|
||||||
EXTRA_DIST = console.c console.c.polled
|
EXTRA_DIST = console.c console.c.polled console405.c
|
||||||
|
|
||||||
include $(top_srcdir)/../../../../../automake/local.am
|
include $(top_srcdir)/../../../../../automake/local.am
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ typedef volatile struct async *pasync;
|
|||||||
static const pasync port = (pasync)0x40000000;
|
static const pasync port = (pasync)0x40000000;
|
||||||
|
|
||||||
static void *spittyp; /* handle for termios */
|
static void *spittyp; /* handle for termios */
|
||||||
int ppc403_spi_interrupt = 1; /* do not use interrupts... */
|
int ppc403_spi_interrupt = 1; /* use interrupts... */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rx Interrupt handler
|
* Rx Interrupt handler
|
||||||
|
|||||||
554
c/src/lib/libcpu/powerpc/ppc403/console/console405.c
Normal file
554
c/src/lib/libcpu/powerpc/ppc403/console/console405.c
Normal file
@@ -0,0 +1,554 @@
|
|||||||
|
/*
|
||||||
|
* This file contains the PowerPC 405GP console IO package.
|
||||||
|
*
|
||||||
|
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||||
|
* IMD Ingenieurbuero fuer Microcomputertechnik
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1998 by IMD
|
||||||
|
*
|
||||||
|
* Changes from IMD are covered by the original distributions terms.
|
||||||
|
* changes include interrupt support and termios support
|
||||||
|
* for backward compatibility, the original polled driver has been
|
||||||
|
* renamed to console.c.polled
|
||||||
|
*
|
||||||
|
* This file has been initially created (polled version) by
|
||||||
|
*
|
||||||
|
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies, and that the name of i-cubed limited not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* i-cubed limited makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Modifications for spooling (interrupt driven) console driver
|
||||||
|
* by Thomas Doerfler <td@imd.m.isar.de>
|
||||||
|
* for these modifications:
|
||||||
|
* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies. IMD makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* All rights assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* This material may be reproduced by or for the U.S. Government pursuant
|
||||||
|
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||||
|
* notice must appear in all copies of this file and its derivatives.
|
||||||
|
*
|
||||||
|
* Modifications for PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
|
* console405.c,v 1.4 1995/12/05 19:23:02 joel Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NO_BSP_INIT
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/libio.h>
|
||||||
|
#include "../ictrl/ictrl.h"
|
||||||
|
#include <stdlib.h> /* for atexit() */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct async {
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Data Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char RBR; /* 0x00 */
|
||||||
|
#define THR RBR
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Interrupt registers
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char IER; /* 0x01 */
|
||||||
|
#define IER_RCV 0x01
|
||||||
|
#define IER_XMT 0x02
|
||||||
|
#define IER_LS 0x04
|
||||||
|
#define IER_MS 0x08
|
||||||
|
|
||||||
|
unsigned char ISR; /* 0x02 */
|
||||||
|
#define ISR_MS 0x00
|
||||||
|
#define ISR_nIP 0x01
|
||||||
|
#define ISR_Tx 0x02
|
||||||
|
#define ISR_Rx 0x04
|
||||||
|
#define ISR_LS 0x06
|
||||||
|
#define ISR_RxTO 0x0C
|
||||||
|
#define ISR_64BFIFO 0x20
|
||||||
|
#define ISR_FIFOworks 0x40
|
||||||
|
#define ISR_FIFOen 0x80
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| FIFO Control registers
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
#define FCR ISR
|
||||||
|
#define FCR_FE 0x01 /* FIFO enable */
|
||||||
|
#define FCR_CRF 0x02 /* Clear receive FIFO */
|
||||||
|
#define FCR_CTF 0x04 /* Clear transmit FIFO */
|
||||||
|
#define FCR_DMA 0x08 /* DMA mode select */
|
||||||
|
#define FCR_F64 0x20 /* Enable 64 byte fifo (16750+) */
|
||||||
|
#define FCR_RT14 0xC0 /* Set Rx trigger at 14 */
|
||||||
|
#define FCR_RT8 0x80 /* Set Rx trigger at 8 */
|
||||||
|
#define FCR_RT4 0x40 /* Set Rx trigger at 4 */
|
||||||
|
#define FCR_RT1 0x00 /* Set Rx trigger at 1 */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Baud rate divisor registers
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
#define DLL RBR
|
||||||
|
#define DLM IER
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Alternate function registers
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
#define AFR ISR
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Line control Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char LCR; /* 0x03 */
|
||||||
|
#define LCR_WL5 0x00 /* Word length 5 */
|
||||||
|
#define LCR_WL6 0x01 /* Word length 6 */
|
||||||
|
#define LCR_WL7 0x02 /* Word length 7 */
|
||||||
|
#define LCR_WL8 0x03 /* Word length 8 */
|
||||||
|
|
||||||
|
#define LCR_SB1 0x00 /* 1 stop bits */
|
||||||
|
#define LCR_SB1_5 0x04 /* 1.5 stop bits , only valid with 5 bit words*/
|
||||||
|
#define LCR_SB1_5 0x04 /* 2 stop bits */
|
||||||
|
|
||||||
|
#define LCR_PN 0x00 /* Parity NONE */
|
||||||
|
#define LCR_PE 0x0C /* Parity EVEN */
|
||||||
|
#define LCR_PO 0x08 /* Parity ODD */
|
||||||
|
#define LCR_PM 0x28 /* Forced "mark" parity */
|
||||||
|
#define LCR_PS 0x38 /* Forced "space" parity */
|
||||||
|
|
||||||
|
#define LCR_DL 0x80 /* Enable baudrate latch */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Modem control Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char MCR; /* 0x04 */
|
||||||
|
#define MCR_DTR 0x01
|
||||||
|
#define MCR_RTS 0x02
|
||||||
|
#define MCR_INT 0x08 /* Enable interrupts */
|
||||||
|
#define MCR_LOOP 0x10 /* Loopback mode */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Line status Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char LSR; /* 0x05 */
|
||||||
|
#define LSR_RSR 0x01
|
||||||
|
#define LSR_OE 0x02
|
||||||
|
#define LSR_PE 0x04
|
||||||
|
#define LSR_FE 0x08
|
||||||
|
#define LSR_BI 0x10
|
||||||
|
#define LSR_THE 0x20
|
||||||
|
#define LSR_TEMT 0x40
|
||||||
|
#define LSR_FIE 0x80
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Modem status Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char MSR; /* 0x06 */
|
||||||
|
#define MSR_DCTS 0x01
|
||||||
|
#define MSR_DDSR 0x02
|
||||||
|
#define MSR_TERI 0x04
|
||||||
|
#define MSR_DDCD 0x08
|
||||||
|
#define MSR_CTS 0x10
|
||||||
|
#define MSR_DSR 0x20
|
||||||
|
#define MSR_RI 0x40
|
||||||
|
#define MSR_CD 0x80
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Scratch pad Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char SCR; /* 0x07 */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define USE_UART 0 /* 0=UART0 1=UART1 */
|
||||||
|
#define UART_INTERNAL_CLOCK_DIVISOR 16
|
||||||
|
|
||||||
|
typedef volatile struct async *pasync;
|
||||||
|
static const pasync port = (pasync)(0xEF600300 + (USE_UART*0x100)); /* 0xEF600300 - port A, 0xEF600400 - port B */
|
||||||
|
|
||||||
|
static void *spittyp; /* handle for termios */
|
||||||
|
int ppc403_spi_interrupt = 0; /* do not use interrupts... */
|
||||||
|
|
||||||
|
|
||||||
|
int round(double x)
|
||||||
|
{
|
||||||
|
return (int)((int)((x-(int)x)*1000)>500 ? x+1 : x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spiBaudSet(unsigned32 baudrate)
|
||||||
|
{
|
||||||
|
unsigned32 tmp;
|
||||||
|
|
||||||
|
tmp = round( (double)rtems_cpu_configuration_get_serial_per_sec() / (baudrate * 16) );
|
||||||
|
|
||||||
|
port->LCR = port->LCR | LCR_DL;
|
||||||
|
|
||||||
|
port->DLL = tmp & 0xff;
|
||||||
|
port->DLM = tmp >> 8;
|
||||||
|
|
||||||
|
port->LCR = port->LCR & ~LCR_DL;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Hardware-dependent portion of tcsetattr().
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
spiSetAttributes (int minor, const struct termios *t)
|
||||||
|
{
|
||||||
|
int baud;
|
||||||
|
|
||||||
|
/* FIXME: check c_cflag & CRTSCTS for hardware flowcontrol */
|
||||||
|
/* FIXME: check and IMPLEMENT XON/XOFF */
|
||||||
|
switch (t->c_cflag & CBAUD) {
|
||||||
|
default: baud = -1; break;
|
||||||
|
case B50: baud = 50; break;
|
||||||
|
case B75: baud = 75; break;
|
||||||
|
case B110: baud = 110; break;
|
||||||
|
case B134: baud = 134; break;
|
||||||
|
case B150: baud = 150; break;
|
||||||
|
case B200: baud = 200; break;
|
||||||
|
case B300: baud = 300; break;
|
||||||
|
case B600: baud = 600; break;
|
||||||
|
case B1200: baud = 1200; break;
|
||||||
|
case B1800: baud = 1800; break;
|
||||||
|
case B2400: baud = 2400; break;
|
||||||
|
case B4800: baud = 4800; break;
|
||||||
|
case B9600: baud = 9600; break;
|
||||||
|
case B19200: baud = 19200; break;
|
||||||
|
case B38400: baud = 38400; break;
|
||||||
|
case B57600: baud = 57600; break;
|
||||||
|
case B115200: baud = 115200; break;
|
||||||
|
case B230400: baud = 230400; break;
|
||||||
|
case B460800: baud = 460800; break;
|
||||||
|
}
|
||||||
|
if (baud > 0) {
|
||||||
|
spiBaudSet(baud);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spiPollRead (int minor)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Wait for character */
|
||||||
|
while ((port->LSR & LSR_RSR)==0);;
|
||||||
|
|
||||||
|
return port->RBR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
spiPollWrite(int minor,const char *buf,int len)
|
||||||
|
{
|
||||||
|
|
||||||
|
while (len-- > 0) {
|
||||||
|
while (!(port->LSR & LSR_THE));;
|
||||||
|
port->THR = *buf++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enable/disable RTS line to start/stop remote transmitter
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
spiStartRemoteTx (int minor)
|
||||||
|
{
|
||||||
|
/* Not implemented !
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
|
rtems_interrupt_disable (level);
|
||||||
|
port->SPCTL |= CRRts; activate RTS
|
||||||
|
rtems_interrupt_enable (level);
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spiStopRemoteTx (int minor)
|
||||||
|
{
|
||||||
|
/* Not implemented !
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
|
rtems_interrupt_disable (level);
|
||||||
|
port->SPCTL &= ~CRRts; deactivate RTS
|
||||||
|
rtems_interrupt_enable (level);
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InterruptWrite (int minor, const char *buf, int len)
|
||||||
|
{
|
||||||
|
port->IER |= IER_XMT; /* always enable tx interrupt */
|
||||||
|
port->THR = *buf; /* write char to send */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtems_isr serial_ISR(rtems_vector_number v)
|
||||||
|
{
|
||||||
|
unsigned char _isr;
|
||||||
|
char ch;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
_isr=port->ISR & 0x0E;
|
||||||
|
|
||||||
|
if ((_isr == ISR_Rx) || (_isr==ISR_RxTO)) {
|
||||||
|
ch = port->RBR;
|
||||||
|
rtems_termios_enqueue_raw_characters (spittyp,&ch,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isr == ISR_Tx) {
|
||||||
|
res = rtems_termios_dequeue_characters (spittyp,1);
|
||||||
|
if (res==0) {
|
||||||
|
port->IER &= ~IER_XMT;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* deinit SPI
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
spiDeInit(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* disable interrupts for serial port
|
||||||
|
* set it to state to work with polling boot monitor, if any...
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* set up baud rate to original state */
|
||||||
|
spiBaudSet(rtems_cpu_configuration_get_serial_rate());
|
||||||
|
|
||||||
|
port->IER = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* init SPI
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_status_code
|
||||||
|
spiInitialize(void)
|
||||||
|
{
|
||||||
|
register unsigned tmp;
|
||||||
|
rtems_isr_entry previous_isr; /* this is a dummy */
|
||||||
|
unsigned char _ier;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the serial port
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select clock source and set uart internal clock divisor
|
||||||
|
*/
|
||||||
|
|
||||||
|
asm volatile ("mfdcr %0, 0x0b1" : "=r" (tmp)); /* CPC_CR0 0x0b1 */
|
||||||
|
|
||||||
|
/* UART0 bit 24 0x80, UART1 bit 25 0x40 */
|
||||||
|
tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? (USE_UART ? 0x40 : 0x80) : 0);
|
||||||
|
|
||||||
|
tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? 0: ((UART_INTERNAL_CLOCK_DIVISOR -1) << 1));
|
||||||
|
|
||||||
|
asm volatile ("mtdcr 0x0b1, %0" : "=r" (tmp) : "0" (tmp)); /* CPC_CR0 0x0b1*/
|
||||||
|
|
||||||
|
/* Disable port interrupts while changing hardware */
|
||||||
|
_ier = port->IER;
|
||||||
|
port->IER = 0;
|
||||||
|
|
||||||
|
/* set up port control: 8 bit,1 stop,no parity */
|
||||||
|
port->LCR = LCR_WL8 | LCR_SB1 | LCR_PN;
|
||||||
|
|
||||||
|
/* set up baud rate */
|
||||||
|
spiBaudSet(rtems_cpu_configuration_get_serial_rate());
|
||||||
|
|
||||||
|
if (ppc403_spi_interrupt) {
|
||||||
|
|
||||||
|
/* add rx/tx isr to vector table */
|
||||||
|
if (USE_UART==0)
|
||||||
|
ictrl_set_vector(serial_ISR,PPC_IRQ_EXT_UART0,&previous_isr);
|
||||||
|
else
|
||||||
|
ictrl_set_vector(serial_ISR,PPC_IRQ_EXT_UART1,&previous_isr);
|
||||||
|
|
||||||
|
/* Enable and clear FIFO */
|
||||||
|
port->FCR = FCR_FE | FCR_CRF | FCR_CTF | FCR_RT8;
|
||||||
|
|
||||||
|
/* Enable recive interrupts, don't enable TxInt yet */
|
||||||
|
port->IER=IER_RCV;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
port->IER=_ier;
|
||||||
|
}
|
||||||
|
|
||||||
|
atexit(spiDeInit);
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
***************
|
||||||
|
* BOILERPLATE *
|
||||||
|
***************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* console_initialize
|
||||||
|
*
|
||||||
|
* This routine initializes the console IO driver.
|
||||||
|
*
|
||||||
|
* Input parameters: NONE
|
||||||
|
*
|
||||||
|
* Output parameters: NONE
|
||||||
|
*
|
||||||
|
* Return values:
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver console_initialize(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up TERMIOS
|
||||||
|
*/
|
||||||
|
rtems_termios_initialize ();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do device-specific initialization
|
||||||
|
*/
|
||||||
|
spiInitialize ();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register the device
|
||||||
|
*/
|
||||||
|
status = rtems_io_register_name ("/dev/console", major, 0);
|
||||||
|
if (status != RTEMS_SUCCESSFUL)
|
||||||
|
rtems_fatal_error_occurred (status);
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open entry point
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver console_open(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc;
|
||||||
|
static const rtems_termios_callbacks intrCallbacks = {
|
||||||
|
NULL, /* firstOpen */
|
||||||
|
NULL, /* lastClose */
|
||||||
|
NULL, /* pollRead */
|
||||||
|
InterruptWrite, /* write */
|
||||||
|
spiSetAttributes, /* setAttributes */
|
||||||
|
spiStopRemoteTx, /* stopRemoteTx */
|
||||||
|
spiStartRemoteTx, /* startRemoteTx */
|
||||||
|
1 /* outputUsesInterrupts */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const rtems_termios_callbacks pollCallbacks = {
|
||||||
|
NULL, /* firstOpen */
|
||||||
|
NULL, /* lastClose */
|
||||||
|
spiPollRead, /* pollRead */
|
||||||
|
spiPollWrite, /* write */
|
||||||
|
spiSetAttributes, /* setAttributes */
|
||||||
|
spiStopRemoteTx, /* stopRemoteTx */
|
||||||
|
spiStartRemoteTx, /* startRemoteTx */
|
||||||
|
0 /* outputUsesInterrupts */
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ppc403_spi_interrupt) {
|
||||||
|
rtems_libio_open_close_args_t *args = arg;
|
||||||
|
sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
|
||||||
|
spittyp = args->iop->data1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
|
||||||
|
}
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close entry point
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver console_close(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rtems_termios_close (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read bytes from the serial port. We only have stdin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver console_read(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rtems_termios_read (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write bytes to the serial port. Stdout and stderr are the same.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver console_write(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rtems_termios_write (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IO Control entry point
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver console_control(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rtems_termios_ioctl (arg);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -18,6 +18,8 @@
|
|||||||
* IMD makes no representations about the suitability
|
* IMD makes no representations about the suitability
|
||||||
* of this software for any purpose.
|
* of this software for any purpose.
|
||||||
*
|
*
|
||||||
|
* Modifications for PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ictrl.h"
|
#include "ictrl.h"
|
||||||
@@ -41,6 +43,47 @@ rtems_isr_entry ictrl_vector_table[PPC_IRQ_EXT_MAX];
|
|||||||
/*
|
/*
|
||||||
* clear bits in EXISR that have a bit set in mask
|
* clear bits in EXISR that have a bit set in mask
|
||||||
*/
|
*/
|
||||||
|
#if defined(ppc405)
|
||||||
|
RTEMS_INLINE_ROUTINE void
|
||||||
|
clr_exisr(unsigned32 mask)
|
||||||
|
{
|
||||||
|
asm volatile ("mtdcr 0xC0,%0"::"r" (mask));/*EXISR*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get value of EXISR
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE unsigned32
|
||||||
|
get_exisr(void)
|
||||||
|
{
|
||||||
|
unsigned32 val;
|
||||||
|
|
||||||
|
asm volatile ("mfdcr %0,0xC0":"=r" (val));/*EXISR*/
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get value of EXIER
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE unsigned32
|
||||||
|
get_exier(void)
|
||||||
|
{
|
||||||
|
unsigned32 val;
|
||||||
|
asm volatile ("mfdcr %0,0xC2":"=r" (val));/*EXIER*/
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set value of EXIER
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void
|
||||||
|
set_exier(unsigned32 val)
|
||||||
|
{
|
||||||
|
asm volatile ("mtdcr 0xC2,%0"::"r" (val));/*EXIER*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* not ppc405 */
|
||||||
|
|
||||||
RTEMS_INLINE_ROUTINE void
|
RTEMS_INLINE_ROUTINE void
|
||||||
clr_exisr(unsigned32 mask)
|
clr_exisr(unsigned32 mask)
|
||||||
{
|
{
|
||||||
@@ -78,7 +121,7 @@ set_exier(unsigned32 val)
|
|||||||
{
|
{
|
||||||
asm volatile ("mtdcr 0x42,%0"::"r" (val));/*EXIER*/
|
asm volatile ("mtdcr 0x42,%0"::"r" (val));/*EXIER*/
|
||||||
}
|
}
|
||||||
|
#endif /* ppc405 */
|
||||||
/*
|
/*
|
||||||
* enable an external interrupt, make this interrupt consistent
|
* enable an external interrupt, make this interrupt consistent
|
||||||
*/
|
*/
|
||||||
@@ -191,7 +234,6 @@ ictrl_set_vector(rtems_isr_entry new_handler,
|
|||||||
/* check for valid vector range */
|
/* check for valid vector range */
|
||||||
if ((vector >= PPC_IRQ_EXT_BASE) &&
|
if ((vector >= PPC_IRQ_EXT_BASE) &&
|
||||||
(vector < PPC_IRQ_EXT_BASE + PPC_IRQ_EXT_MAX)) {
|
(vector < PPC_IRQ_EXT_BASE + PPC_IRQ_EXT_MAX)) {
|
||||||
|
|
||||||
/* return old handler entry */
|
/* return old handler entry */
|
||||||
*old_handler = ictrl_vector_table[vector - PPC_IRQ_EXT_BASE];
|
*old_handler = ictrl_vector_table[vector - PPC_IRQ_EXT_BASE];
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
* IMD makes no representations about the suitability
|
* IMD makes no representations about the suitability
|
||||||
* of this software for any purpose.
|
* of this software for any purpose.
|
||||||
*
|
*
|
||||||
|
* Modifications for PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -40,10 +42,19 @@ extern "C" {
|
|||||||
|
|
||||||
/* mask for external interrupt status in EXIER/EXISR register */
|
/* mask for external interrupt status in EXIER/EXISR register */
|
||||||
/* note: critical interrupt is in these registers aswell */
|
/* note: critical interrupt is in these registers aswell */
|
||||||
|
#ifndef ppc405
|
||||||
#define PPC_EXI_MASK 0x0FFFFFFF
|
#define PPC_EXI_MASK 0x0FFFFFFF
|
||||||
|
#else /* ppc405 */
|
||||||
|
#define PPC_EXI_MASK 0xFFFFFFFF
|
||||||
|
#endif /* ppc405 */
|
||||||
|
|
||||||
|
#ifndef ppc405
|
||||||
#define PPC_IRQ_EXT_SPIR (PPC_IRQ_EXT_BASE+4)
|
#define PPC_IRQ_EXT_SPIR (PPC_IRQ_EXT_BASE+4)
|
||||||
#define PPC_IRQ_EXT_SPIT (PPC_IRQ_EXT_BASE+5)
|
#define PPC_IRQ_EXT_SPIT (PPC_IRQ_EXT_BASE+5)
|
||||||
|
#else /* ppc405 */
|
||||||
|
#define PPC_IRQ_EXT_UART0 (PPC_IRQ_EXT_BASE+0)
|
||||||
|
#define PPC_IRQ_EXT_UART1 (PPC_IRQ_EXT_BASE+1)
|
||||||
|
#endif /* ppc405 */
|
||||||
#define PPC_IRQ_EXT_JTAGR (PPC_IRQ_EXT_BASE+6)
|
#define PPC_IRQ_EXT_JTAGR (PPC_IRQ_EXT_BASE+6)
|
||||||
#define PPC_IRQ_EXT_JTAGT (PPC_IRQ_EXT_BASE+7)
|
#define PPC_IRQ_EXT_JTAGT (PPC_IRQ_EXT_BASE+7)
|
||||||
#define PPC_IRQ_EXT_DMA0 (PPC_IRQ_EXT_BASE+8)
|
#define PPC_IRQ_EXT_DMA0 (PPC_IRQ_EXT_BASE+8)
|
||||||
|
|||||||
@@ -30,7 +30,10 @@
|
|||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
|
* Modifications for PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
@@ -45,7 +48,13 @@ static inline rtems_unsigned32 get_itimer(void)
|
|||||||
{
|
{
|
||||||
rtems_unsigned32 ret;
|
rtems_unsigned32 ret;
|
||||||
|
|
||||||
|
#ifndef ppc405
|
||||||
asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); /* TBLO */
|
asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); /* TBLO */
|
||||||
|
#else /* ppc405 */
|
||||||
|
/* asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); TBLO */
|
||||||
|
|
||||||
|
asm volatile ("mfspr %0, 0x10c" : "=r" ((ret))); /* 405GP TBL */
|
||||||
|
#endif /* ppc405 */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -54,10 +63,21 @@ void Timer_initialize()
|
|||||||
{
|
{
|
||||||
rtems_unsigned32 iocr;
|
rtems_unsigned32 iocr;
|
||||||
|
|
||||||
|
#ifndef ppc405
|
||||||
asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
|
asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
|
||||||
iocr &= ~4;
|
iocr &= ~4;
|
||||||
iocr |= 4; /* Select external timer clock */
|
iocr |= 4; /* Select external timer clock */
|
||||||
asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
|
asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
|
||||||
|
#else /* ppc405 */
|
||||||
|
asm volatile ("mfdcr %0, 0x0b2" : "=r" (iocr)); /*405GP CPC0_CR1 */
|
||||||
|
/* asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); IOCR */
|
||||||
|
|
||||||
|
/* iocr |= 0x800000; select external timer clock CETE*/
|
||||||
|
iocr &= ~0x800000; /* timer clocked from system clock CETE*/
|
||||||
|
|
||||||
|
asm volatile ("mtdcr 0x0b2, %0" : "=r" (iocr) : "0" (iocr)); /* 405GP CPC0_CR1 */
|
||||||
|
/* asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); IOCR */
|
||||||
|
#endif /* ppc405 */
|
||||||
|
|
||||||
Timer_starting = get_itimer();
|
Timer_starting = get_itimer();
|
||||||
}
|
}
|
||||||
|
|||||||
2
c/src/lib/libcpu/powerpc/ppc403/tty_drv/.cvsignore
Normal file
2
c/src/lib/libcpu/powerpc/ppc403/tty_drv/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
32
c/src/lib/libcpu/powerpc/ppc403/tty_drv/Makefile.am
Normal file
32
c/src/lib/libcpu/powerpc/ppc403/tty_drv/Makefile.am
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
##
|
||||||
|
## $Id$
|
||||||
|
##
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = foreign 1.4
|
||||||
|
|
||||||
|
PGM = $(ARCH)/tty_drv.rel
|
||||||
|
|
||||||
|
include_HEADERS = tty_drv.h
|
||||||
|
|
||||||
|
C_FILES = tty_drv.c
|
||||||
|
|
||||||
|
tty_drv_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||||
|
|
||||||
|
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): $(tty_drv_rel_OBJECTS)
|
||||||
|
$(make-rel)
|
||||||
|
|
||||||
|
all-local: $(ARCH) $(tty_drv_rel_OBJECTS) $(PGM)
|
||||||
|
|
||||||
|
.PRECIOUS: $(PGM)
|
||||||
|
|
||||||
|
EXTRA_DIST = tty_drv.c tty_drv.h
|
||||||
|
|
||||||
|
include $(top_srcdir)/../../../../../automake/local.am
|
||||||
557
c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.c
Normal file
557
c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.c
Normal file
@@ -0,0 +1,557 @@
|
|||||||
|
/*
|
||||||
|
* This file contains the PowerPC 405GP tty driver.
|
||||||
|
*
|
||||||
|
* Derived from /c/src/lib/libbsp/i386/shared/comm/tty_drv.c
|
||||||
|
*
|
||||||
|
* Modifications to PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NO_BSP_INIT
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <rtems/termiostypes.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/libio.h>
|
||||||
|
#include "../ictrl/ictrl.h"
|
||||||
|
#include <stdlib.h> /* for atexit() */
|
||||||
|
|
||||||
|
|
||||||
|
struct ttyasync {
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Data Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char RBR; /* 0x00 */
|
||||||
|
#define THR RBR
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Interrupt registers
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char IER; /* Interrupt Enable Register 0x01 */
|
||||||
|
#define IER_RCV 0x01
|
||||||
|
#define IER_XMT 0x02
|
||||||
|
#define IER_LS 0x04
|
||||||
|
#define IER_MS 0x08
|
||||||
|
|
||||||
|
unsigned char ISR; /* Interrupt Status Register 0x02 */
|
||||||
|
#define ISR_MS 0x00
|
||||||
|
#define ISR_nIP 0x01
|
||||||
|
#define ISR_Tx 0x02
|
||||||
|
#define ISR_Rx 0x04
|
||||||
|
#define ISR_LS 0x06
|
||||||
|
#define ISR_RxTO 0x0C
|
||||||
|
#define ISR_64BFIFO 0x20
|
||||||
|
#define ISR_FIFOworks 0x40
|
||||||
|
#define ISR_FIFOen 0x80
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| FIFO Control registers
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
#define FCR ISR
|
||||||
|
#define FCR_FE 0x01 /* FIFO enable */
|
||||||
|
#define FCR_CRF 0x02 /* Clear receive FIFO */
|
||||||
|
#define FCR_CTF 0x04 /* Clear transmit FIFO */
|
||||||
|
#define FCR_DMA 0x08 /* DMA mode select */
|
||||||
|
#define FCR_F64 0x20 /* Enable 64 byte fifo (16750+) */
|
||||||
|
#define FCR_RT14 0xC0 /* Set Rx trigger at 14 */
|
||||||
|
#define FCR_RT8 0x80 /* Set Rx trigger at 8 */
|
||||||
|
#define FCR_RT4 0x40 /* Set Rx trigger at 4 */
|
||||||
|
#define FCR_RT1 0x00 /* Set Rx trigger at 1 */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Baud rate divisor registers
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
#define DLL RBR
|
||||||
|
#define DLM IER
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Alternate function registers
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
#define AFR ISR
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Line control Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char LCR; /* 0x03 */
|
||||||
|
#define LCR_WL5 0x00 /* Word length 5 */
|
||||||
|
#define LCR_WL6 0x01 /* Word length 6 */
|
||||||
|
#define LCR_WL7 0x02 /* Word length 7 */
|
||||||
|
#define LCR_WL8 0x03 /* Word length 8 */
|
||||||
|
|
||||||
|
#define LCR_SB1 0x00 /* 1 stop bits */
|
||||||
|
#define LCR_SB1_5 0x04 /* 1.5 stop bits , only valid with 5 bit words*/
|
||||||
|
#define LCR_SB1_5 0x04 /* 2 stop bits */
|
||||||
|
|
||||||
|
#define LCR_PN 0x00 /* Parity NONE */
|
||||||
|
#define LCR_PE 0x0C /* Parity EVEN */
|
||||||
|
#define LCR_PO 0x08 /* Parity ODD */
|
||||||
|
#define LCR_PM 0x28 /* Forced "mark" parity */
|
||||||
|
#define LCR_PS 0x38 /* Forced "space" parity */
|
||||||
|
|
||||||
|
#define LCR_DL 0x80 /* Enable baudrate latch */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Modem control Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char MCR; /* 0x04 */
|
||||||
|
#define MCR_DTR 0x01
|
||||||
|
#define MCR_RTS 0x02
|
||||||
|
#define MCR_INT 0x08 /* Enable interrupts */
|
||||||
|
#define MCR_LOOP 0x10 /* Loopback mode */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Line status Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char LSR; /* 0x05 */
|
||||||
|
#define LSR_RSR 0x01
|
||||||
|
#define LSR_OE 0x02
|
||||||
|
#define LSR_PE 0x04
|
||||||
|
#define LSR_FE 0x08
|
||||||
|
#define LSR_BI 0x10
|
||||||
|
#define LSR_THE 0x20
|
||||||
|
#define LSR_TEMT 0x40
|
||||||
|
#define LSR_FIE 0x80
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Modem status Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char MSR; /* 0x06 */
|
||||||
|
#define MSR_DCTS 0x01
|
||||||
|
#define MSR_DDSR 0x02
|
||||||
|
#define MSR_TERI 0x04
|
||||||
|
#define MSR_DDCD 0x08
|
||||||
|
#define MSR_CTS 0x10
|
||||||
|
#define MSR_DSR 0x20
|
||||||
|
#define MSR_RI 0x40
|
||||||
|
#define MSR_CD 0x80
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------+
|
||||||
|
| Scratch pad Register.
|
||||||
|
+---------------------------------------------------------------------------*/
|
||||||
|
unsigned char SCR; /* 0x07 */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define TTY0_USE_UART 1 /* 0=UART0 1=UART1 */
|
||||||
|
#define TTY0_UART_INTERNAL_CLOCK_DIVISOR 16
|
||||||
|
#define TTY0_USE_INTERRUPT
|
||||||
|
|
||||||
|
|
||||||
|
typedef volatile struct ttyasync *tty0pasync;
|
||||||
|
static const tty0pasync tty0port = (tty0pasync)(0xEF600300 + (TTY0_USE_UART*0x100)); /* 0xEF600300 - port A, 0xEF600400 - port B */
|
||||||
|
|
||||||
|
static void *tty0ttyp; /* handle for termios */
|
||||||
|
|
||||||
|
|
||||||
|
int tty0_round(double x)
|
||||||
|
{
|
||||||
|
return (int)((int)((x-(int)x)*1000)>500 ? x+1 : x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty0BaudSet(unsigned32 baudrate)
|
||||||
|
{
|
||||||
|
unsigned32 tmp;
|
||||||
|
|
||||||
|
tmp = tty0_round( (double)rtems_cpu_configuration_get_serial_per_sec() / (baudrate * 16) );
|
||||||
|
|
||||||
|
tty0port->LCR = tty0port->LCR | LCR_DL;
|
||||||
|
|
||||||
|
tty0port->DLL = tmp & 0xff;
|
||||||
|
tty0port->DLM = tmp >> 8;
|
||||||
|
|
||||||
|
tty0port->LCR = tty0port->LCR & ~LCR_DL;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Hardware-dependent portion of tcsetattr().
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
tty0SetAttributes (int minor, const struct termios *t)
|
||||||
|
{
|
||||||
|
int baud;
|
||||||
|
|
||||||
|
/* FIXME: check c_cflag & CRTSCTS for hardware flowcontrol */
|
||||||
|
/* FIXME: check and IMPLEMENT XON/XOFF */
|
||||||
|
switch (t->c_cflag & CBAUD) {
|
||||||
|
default: baud = -1; break;
|
||||||
|
case B50: baud = 50; break;
|
||||||
|
case B75: baud = 75; break;
|
||||||
|
case B110: baud = 110; break;
|
||||||
|
case B134: baud = 134; break;
|
||||||
|
case B150: baud = 150; break;
|
||||||
|
case B200: baud = 200; break;
|
||||||
|
case B300: baud = 300; break;
|
||||||
|
case B600: baud = 600; break;
|
||||||
|
case B1200: baud = 1200; break;
|
||||||
|
case B1800: baud = 1800; break;
|
||||||
|
case B2400: baud = 2400; break;
|
||||||
|
case B4800: baud = 4800; break;
|
||||||
|
case B9600: baud = 9600; break;
|
||||||
|
case B19200: baud = 19200; break;
|
||||||
|
case B38400: baud = 38400; break;
|
||||||
|
case B57600: baud = 57600; break;
|
||||||
|
case B115200: baud = 115200; break;
|
||||||
|
case B230400: baud = 230400; break;
|
||||||
|
case B460800: baud = 460800; break;
|
||||||
|
}
|
||||||
|
if (baud > 0) {
|
||||||
|
tty0BaudSet(baud);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tty0PollRead (int minor)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Wait for character */
|
||||||
|
while ((tty0port->LSR & LSR_RSR)==0);;
|
||||||
|
|
||||||
|
return tty0port->RBR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
tty0PollWrite(int minor,const char *buf,int len)
|
||||||
|
{
|
||||||
|
|
||||||
|
while (len-- > 0) {
|
||||||
|
while (!(tty0port->LSR & LSR_THE));;
|
||||||
|
tty0port->THR = *buf++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================ Termios support =================*/
|
||||||
|
|
||||||
|
static int tty0InterruptWrite (int minor, const char *buf, int len)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(len <= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write character */
|
||||||
|
|
||||||
|
tty0port->THR = (*buf &0xff);
|
||||||
|
tty0port->IER |= IER_XMT; /* always enable tx interrupt */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtems_isr tty0serial_ISR(rtems_vector_number v)
|
||||||
|
{
|
||||||
|
char buf[128];
|
||||||
|
int off, ret, vect;
|
||||||
|
|
||||||
|
off = 0;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
vect = tty0port->ISR & 0x0f;
|
||||||
|
if(vect & 1)
|
||||||
|
{
|
||||||
|
/* no more interrupts */
|
||||||
|
if(off > 0) {
|
||||||
|
/* Update rx buffer */
|
||||||
|
rtems_termios_enqueue_raw_characters(tty0ttyp, buf, off );
|
||||||
|
|
||||||
|
tty0port->IER |= IER_RCV; /* always enable rx interrupt */
|
||||||
|
/*rtems_termios_rxirq_occured(tty0ttyp);*/
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vect = vect & 0xe; /*mask out all except interrupt pending*/
|
||||||
|
|
||||||
|
switch(vect)
|
||||||
|
{
|
||||||
|
|
||||||
|
case ISR_Tx :
|
||||||
|
/*
|
||||||
|
* TX holding empty: we have to disable these interrupts
|
||||||
|
* if there is nothing more to send.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If nothing else to send disable interrupts */
|
||||||
|
ret = rtems_termios_dequeue_characters(tty0ttyp, 1);
|
||||||
|
|
||||||
|
if ( ret == 0 ) {
|
||||||
|
tty0port->IER &= ~IER_XMT;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ISR_RxTO:
|
||||||
|
case ISR_Rx :
|
||||||
|
|
||||||
|
/* disable interrupts and notify termios */
|
||||||
|
tty0port->IER &= ~IER_RCV;
|
||||||
|
|
||||||
|
/* read all bytes in fifo*/
|
||||||
|
while (( off < sizeof(buf) ) && ( tty0port->LSR & LSR_RSR ))
|
||||||
|
{
|
||||||
|
buf[off++] = tty0port->RBR;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ISR_LS:
|
||||||
|
/* RX error: eat character */
|
||||||
|
/* printk("********* Error **********\n"); */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Should not happen */
|
||||||
|
/* printk("error vect=%x",vect); */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* deinit TTY0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tty0DeInit(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* disable interrupts for serial tty0port
|
||||||
|
* set it to state to work with polling boot monitor, if any...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* set up baud rate to original state */
|
||||||
|
tty0BaudSet(rtems_cpu_configuration_get_serial_rate());
|
||||||
|
|
||||||
|
tty0port->IER = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* init SPI
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_status_code
|
||||||
|
tty0Initialize(void)
|
||||||
|
{
|
||||||
|
register unsigned tmp;
|
||||||
|
rtems_isr_entry previous_isr; /* this is a dummy */
|
||||||
|
unsigned char _ier;
|
||||||
|
unsigned char _tmp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the serial tty0port
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select clock source and set uart internal clock divisor
|
||||||
|
*/
|
||||||
|
|
||||||
|
asm volatile ("mfdcr %0, 0x0b1" : "=r" (tmp)); /* CPC_CR0 0x0b1 */
|
||||||
|
|
||||||
|
/* UART0 bit 24 0x80, UART1 bit 25 0x40 */
|
||||||
|
tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? (TTY0_USE_UART ? 0x40 : 0x80) : 0);
|
||||||
|
|
||||||
|
tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? 0: ((TTY0_UART_INTERNAL_CLOCK_DIVISOR -1) << 1));
|
||||||
|
|
||||||
|
asm volatile ("mtdcr 0x0b1, %0" : "=r" (tmp) : "0" (tmp)); /* CPC_CR0 0x0b1*/
|
||||||
|
|
||||||
|
/* Disable tty0port interrupts while changing hardware */
|
||||||
|
_ier = tty0port->IER;
|
||||||
|
tty0port->IER = 0;
|
||||||
|
|
||||||
|
/* set up tty0port control: 8 bit,1 stop,no parity */
|
||||||
|
tty0port->LCR = LCR_WL8 | LCR_SB1 | LCR_PN;
|
||||||
|
|
||||||
|
/* set up baud rate */
|
||||||
|
tty0BaudSet(rtems_cpu_configuration_get_serial_rate());
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTY0_USE_INTERRUPT
|
||||||
|
|
||||||
|
/* add rx/tx isr to vector table */
|
||||||
|
|
||||||
|
if (TTY0_USE_UART==0)
|
||||||
|
ictrl_set_vector(tty0serial_ISR,PPC_IRQ_EXT_UART0,&previous_isr);
|
||||||
|
else
|
||||||
|
ictrl_set_vector(tty0serial_ISR,PPC_IRQ_EXT_UART1,&previous_isr);
|
||||||
|
|
||||||
|
/* Enable and clear FIFO */
|
||||||
|
tty0port->FCR = FCR_FE | FCR_CRF | FCR_CTF | FCR_RT14;
|
||||||
|
|
||||||
|
/* Read status to clear them */
|
||||||
|
_tmp = tty0port->LSR;
|
||||||
|
_tmp = tty0port->RBR;
|
||||||
|
_tmp = tty0port->MSR;
|
||||||
|
|
||||||
|
/* Enable recive interrupts, don't enable TxInt yet */
|
||||||
|
tty0port->IER=IER_RCV;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
tty0port->IER=_ier;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
atexit(tty0DeInit);
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
***************
|
||||||
|
* BOILERPLATE *
|
||||||
|
***************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* console_initialize
|
||||||
|
*
|
||||||
|
* This routine initializes the console IO driver.
|
||||||
|
*
|
||||||
|
* Input parameters: NONE
|
||||||
|
*
|
||||||
|
* Output parameters: NONE
|
||||||
|
*
|
||||||
|
* Return values:
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver tty0_initialize(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code status;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up TERMIOS
|
||||||
|
*/
|
||||||
|
rtems_termios_initialize ();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do device-specific initialization
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*tty0Initialize (); Moved this to open instead */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register the device
|
||||||
|
*/
|
||||||
|
status = rtems_io_register_name ("/dev/ttyS0", major, 0);
|
||||||
|
if (status != RTEMS_SUCCESSFUL)
|
||||||
|
rtems_fatal_error_occurred (status);
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open entry point
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver tty0_open(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc;
|
||||||
|
|
||||||
|
#ifdef TTY0_USE_INTERRUPT
|
||||||
|
|
||||||
|
static const rtems_termios_callbacks intrCallbacks = {
|
||||||
|
NULL, /* firstOpen */
|
||||||
|
NULL, /* lastClose */
|
||||||
|
NULL, /* pollRead */
|
||||||
|
tty0InterruptWrite, /* write */
|
||||||
|
tty0SetAttributes, /* setAttributes */
|
||||||
|
NULL, /* stopRemoteTx */
|
||||||
|
NULL, /* startRemoteTx */
|
||||||
|
TERMIOS_TASK_DRIVEN /* outputUsesInterrupts */
|
||||||
|
};
|
||||||
|
rtems_libio_open_close_args_t *args = arg;
|
||||||
|
|
||||||
|
tty0Initialize (); /* Initalize hardware */
|
||||||
|
|
||||||
|
sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
|
||||||
|
tty0ttyp = args->iop->data1;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static const rtems_termios_callbacks pollCallbacks = {
|
||||||
|
NULL, /* firstOpen */
|
||||||
|
NULL, /* lastClose */
|
||||||
|
tty0PollRead, /* pollRead */
|
||||||
|
tty0PollWrite, /* write */
|
||||||
|
tty0SetAttributes, /* setAttributes */
|
||||||
|
NULL, /* stopRemoteTx */
|
||||||
|
NULL, /* startRemoteTx */
|
||||||
|
0 /* outputUsesInterrupts */
|
||||||
|
};
|
||||||
|
|
||||||
|
tty0Initialize (); /* Initalize hardware */
|
||||||
|
|
||||||
|
sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close entry point
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver tty0_close(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rtems_termios_close (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read bytes from the serial port. We only have stdin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver tty0_read(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rtems_termios_read (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write bytes to the serial port. Stdout and stderr are the same.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver tty0_write(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rtems_termios_write (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IO Control entry point
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_device_driver tty0_control(
|
||||||
|
rtems_device_major_number major,
|
||||||
|
rtems_device_minor_number minor,
|
||||||
|
void * arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rtems_termios_ioctl (arg);
|
||||||
|
}
|
||||||
|
|
||||||
63
c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.h
Normal file
63
c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#ifdef ppc405
|
||||||
|
#ifndef __tty_drv__
|
||||||
|
#define __tty_drv__
|
||||||
|
|
||||||
|
/* functions */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ttyS1 entry points */
|
||||||
|
rtems_device_driver tty0_initialize(
|
||||||
|
rtems_device_major_number,
|
||||||
|
rtems_device_minor_number,
|
||||||
|
void *
|
||||||
|
);
|
||||||
|
|
||||||
|
rtems_device_driver tty0_open(
|
||||||
|
rtems_device_major_number,
|
||||||
|
rtems_device_minor_number,
|
||||||
|
void *
|
||||||
|
);
|
||||||
|
|
||||||
|
rtems_device_driver tty0_control(
|
||||||
|
rtems_device_major_number,
|
||||||
|
rtems_device_minor_number,
|
||||||
|
void *
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* tty1 & tty2 shared entry points */
|
||||||
|
rtems_device_driver tty0_close(
|
||||||
|
rtems_device_major_number,
|
||||||
|
rtems_device_minor_number,
|
||||||
|
void *
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
rtems_device_driver tty0_read(
|
||||||
|
rtems_device_major_number,
|
||||||
|
rtems_device_minor_number,
|
||||||
|
void *
|
||||||
|
);
|
||||||
|
|
||||||
|
rtems_device_driver tty0_write(
|
||||||
|
rtems_device_major_number,
|
||||||
|
rtems_device_minor_number,
|
||||||
|
void *
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#define TTY0_DRIVER_TABLE_ENTRY \
|
||||||
|
{ tty0_initialize, tty0_open, tty0_close, \
|
||||||
|
tty0_read, tty0_write, tty0_control }
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* end of include file */
|
||||||
|
|
||||||
|
#endif /* __tty_drv__ */
|
||||||
|
#endif /* ppc405 */
|
||||||
Reference in New Issue
Block a user