01-10-22 Andy Dachs <a.dachs@sstl.co.uk>

* mpc8260ads added as new BSP.  tm27 reported not to run
	at this time.
	* ChangeLog, Makefile.am, README, aclocal.m4, bsp_specs,
	clock/.cvsignore, clock/Makefile.am, clock/p_clock.c, configure.in,
	console/Makefile.am, console/console.c, include/Makefile.am,
	include/bsp.h, include/coverhd.h, irq/.cvsignore, irq/Makefile.am,
	irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c,
	network/Makefile.am, network/README, network/if_hdlcsubr.c,
	network/if_hdlcsubr.h, network/network.c, start/Makefile.am,
	start/start.S, startup/Makefile.am, startup/bspstart.c,
	startup/cpuinit.c, startup/linkcmds, startup/setvec.c, times,
	vectors/.cvsignore, vectors/Makefile.am, vectors/vectors.S,
	vectors/vectors.h, vectors/vectors_init.c, wrapup/Makefile.am:
	New files.
This commit is contained in:
Joel Sherrill
2001-10-22 14:46:02 +00:00
parent 2b93dac920
commit 5edbffe3f6
38 changed files with 6919 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
01-10-22 Andy Dachs <a.dachs@sstl.co.uk>
* mpc8260ads added as new BSP. tm27 reported not to run
at this time.
* ChangeLog, Makefile.am, README, aclocal.m4, bsp_specs,
clock/.cvsignore, clock/Makefile.am, clock/p_clock.c, configure.in,
console/Makefile.am, console/console.c, include/Makefile.am,
include/bsp.h, include/coverhd.h, irq/.cvsignore, irq/Makefile.am,
irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c,
network/Makefile.am, network/README, network/if_hdlcsubr.c,
network/if_hdlcsubr.h, network/network.c, start/Makefile.am,
start/start.S, startup/Makefile.am, startup/bspstart.c,
startup/cpuinit.c, startup/linkcmds, startup/setvec.c, times,
vectors/.cvsignore, vectors/Makefile.am, vectors/vectors.S,
vectors/vectors.h, vectors/vectors_init.c, wrapup/Makefile.am:
New files.

View File

@@ -0,0 +1,17 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I ../../../../../../aclocal
# wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories
SUBDIRS = clock console include vectors irq network start startup wrapup
include $(top_srcdir)/../../bsp.am
EXTRA_DIST = README bsp_specs times
include $(top_srcdir)/../../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,337 @@
#
# $Id$
#
BSP NAME: mpc8260ads
BOARD: Motorola MPC8260 ADS Evaluation board
BUS: N/A
CPU FAMILY: ppc
CPU: PowerPC MPC8260
COPROCESSORS: Hardware FPU (except on revision 2J24M)
MODE: 32 bit mode, I and D cache disabled
DEBUG MONITOR: None
PERIPHERALS
===========
TIMERS: Decrementer
RESOLUTION: 0.1 microsecond
SERIAL PORTS: 4 SCCs (SSC1 and 2 are connectd to RS232 drivers)
SCC3 is used in HDLC mode to transport IP frames.
SMCs, FCCs, SPI, I2C are unused.
REAL-TIME CLOCK:
DMA: Each serial port
VIDEO: none
SCSI: none
NETWORKING: IP over HDLC (8 Mbps) on SCC3 (MPC8260)
DRIVER INFORMATION
==================
CLOCK DRIVER: Decrementer
IOSUPP DRIVER: SCC1, SCC2
SHMSUPP: none
TIMER DRIVER: Timebase register (lower 32 bits only)
STDIO
=====
PORT: SCC2
ELECTRICAL: RS-232
BAUD: 9600
BITS PER CHARACTER: 8
PARITY: None
STOP BITS: 1
NOTES
=====
On-chip resources:
SCC1 console
SCC2 console
SCC3 network
SCC4
CLK1
CLK2
CLK3
CLK4
CLK5 network
CLK6
CLK7
CLK8
BRG1 console
BRG2 console
BRG3 console
BRG4 network
RTC
PIT
TB timer
DEC clock
SWT
*CS0 8M FLASH
*CS1 Config registers
*CS2 60X SDRAM
*CS3
*CS4 LCL SDRAM
*CS5 ATM
*CS6
*CS7
*CS8
*CS9
*CS10
*CS11
UPMA
UPMB
IRQ0
IRQ1
IRQ2
IRQ3
IRQ4
IRQ5
IRQ6
IRQ7
Board description
-----------------
Clock rate: 40MHz (board can run up 66MHz with alternate OSC)
Bus width: 32 bit Flash, 64 bit SDRAM
FLASH: 8M SIMM
RAM: 16M SDRAM DIMM
The board is marked with "Rev PILOT"
U17 is marked with "MPC8260ADS Pilot 00"
The processor is marked with "XPC8260ZU166 166/133/66 MHz"
Board Configuration:
--------------------
The evaluation board has a number of configurable options:
DIP switch settings used:
DS1: 1-"off", 2-"on", 3-"off", 4-"on", 5-"off", 6-"off", 7-"off", 8-"off"
DS2: all "on"
DS3: all "on"
A 40MHz oscillator is fitted to U16.
Board Connections:
------------------
Connect a serial terminal to PA3 (SCC2) configured for 9600,n,8,1 to
get console I/O. A 9way male-female straight-through cable is required to
connect to a PC.
If you require the network connections (see README in network directory)
you need to connect 3VTTL - RS422 level convertors to the CPM expansion
connector, P4. The signals, as numbered on the connector itself
(beware: the numbering on the PCB does not agree):
TX Data (SCC3 TXD) (output) Pin a25
TX Clock (BRG4O) (output) Pin a11
Rx Data (SCC3 RXD) (input) Pin c15
Rx Clock (CLK5) (input) Pin d28
Ground (GND) (n/a) Pin c1
Debugging/ Code loading:
------------------------
Tested using the Metrowerks debugger and Macraigor OCDemon (Raven).
The OCD connects via the parallel port and allows you to download code
to the board. It may be possible to use some other debugger if you
don't already have Metrowerks CodeWarrior.
Verification
-------------------------------
*** TESTING IN PROGRESS - DO NOT BELIEVE THESE RESULTS ***
Single processor tests: Passed
Multi-processort tests: not applicable
Timing tests:
Context Switch
context switch: self 9
context switch: to another task 10
context switch: no floating point contexts 23
fp context switch: restore 1st FP task 24
fp context switch: save initialized, restore initialized 11
fp context switch: save idle, restore initialized 11
fp context switch: save idle, restore idle 23
Task Manager
rtems_task_create 83
rtems_task_ident 84
rtems_task_start 30
rtems_task_restart: calling task 48
rtems_task_restart: suspended task -- returns to caller 36
rtems_task_restart: blocked task -- returns to caller 47
rtems_task_restart: ready task -- returns to caller 35
rtems_task_restart: suspended task -- preempts caller 56
rtems_task_restart: blocked task -- preempts caller 116
rtems_task_restart: ready task -- preempts caller 93
rtems_task_delete: calling task 102
rtems_task_delete: suspended task 74
rtems_task_delete: blocked task 76
rtems_task_delete: ready task 80
rtems_task_suspend: calling task 37
rtems_task_suspend: returns to caller 14
rtems_task_resume: task readied -- returns to caller 16
rtems_task_resume: task readied -- preempts caller 30
rtems_task_set_priority: obtain current priority 12
rtems_task_set_priority: returns to caller 23
rtems_task_set_priority: preempts caller 52
rtems_task_mode: obtain current mode 5
rtems_task_mode: no reschedule 6
rtems_task_mode: reschedule -- returns to caller 15
rtems_task_mode: reschedule -- preempts caller 43
rtems_task_get_note 13
rtems_task_set_note 12
rtems_task_wake_after: yield -- returns to caller 8
rtems_task_wake_after: yields -- preempts caller 30
rtems_task_wake_when: 49
Interrupt Manager
interrupt entry overhead: returns to nested interrupt 7
interrupt entry overhead: returns to interrupted task 31
interrupt entry overhead: returns to preempting task 14
interrupt exit overhead: returns to nested interrupt 10
interrupt exit overhead: returns to interrupted task 8
interrupt exit overhead: returns to preempting task 45
Clock Manager
rtems_clock_set 28
rtems_clock_get 0
rtems_clock_tick 36
Timer Manager
rtems_timer_create 11
rtems_timer_ident 82
rtems_timer_delete: inactive 14
rtems_timer_delete: active 16
rtems_timer_fire_after: inactive 20
rtems_timer_fire_after: active 22
rtems_timer_fire_when: inactive 24
rtems_timer_fire_when: active 24
rtems_timer_reset: inactive 18
rtems_timer_reset: active 21
rtems_timer_cancel: inactive 11
rtems_timer_cancel: active 12
Semaphore Manager
rtems_semaphore_create 56
rtems_semaphore_ident 94
rtems_semaphore_delete 34
rtems_semaphore_obtain: available 13
rtems_semaphore_obtain: not available -- NO_WAIT 13
rtems_semaphore_obtain: not available -- caller blocks 48
rtems_semaphore_release: no waiting tasks 16
rtems_semaphore_release: task readied -- returns to caller 36
rtems_semaphore_release: task readied -- preempts caller 36
Message Queue Manager
rtems_message_queue_create 110
rtems_message_queue_ident 82
rtems_message_queue_delete 43
rtems_message_queue_send: no waiting tasks 28
rtems_message_queue_send: task readied -- returns to caller 31
rtems_message_queue_send: task readied -- preempts caller 46
rtems_message_queue_urgent: no waiting tasks 28
rtems_message_queue_urgent: task readied -- returns to caller 31
rtems_message_queue_urgent: task readied -- preempts caller 46
rtems_message_queue_broadcast: no waiting tasks 22
rtems_message_queue_broadcast: task readied -- returns to caller 81
rtems_message_queue_broadcast: task readied -- preempts caller 75
rtems_message_queue_receive: available 26
rtems_message_queue_receive: not available -- NO_WAIT 15
rtems_message_queue_receive: not available -- caller blocks 48
rtems_message_queue_flush: no messages flushed 14
rtems_message_queue_flush: messages flushed 14
Event Manager
rtems_event_send: no task readied 12
rtems_event_send: task readied -- returns to caller 38
rtems_event_send: task readied -- preempts caller 21
rtems_event_receive: obtain current events 1
rtems_event_receive: available 19
rtems_event_receive: not available -- NO_WAIT 11
rtems_event_receive: not available -- caller blocks 36
Signal Manager
rtems_signal_catch: 31
rtems_signal_send: returns to caller 21
rtems_signal_send: signal to self 39
exit ASR overhead: returns to calling task 30
exit ASR overhead: returns to preempting task 33
Partition Manager
rtems_partition_create 59
rtems_partition_ident 82
rtems_partition_delete 20
rtems_partition_get_buffer: available 19
rtems_partition_get_buffer: not available 13
rtems_partition_return_buffer 20
Region Manager
rtems_region_create 37
rtems_region_ident 84
rtems_region_delete 20
rtems_region_get_segment: available 19
rtems_region_get_segment: not available -- NO_WAIT 23
rtems_region_get_segment: not available -- caller blocks 75
rtems_region_return_segment: no waiting tasks 21
rtems_region_return_segment: task readied -- returns to caller 55
rtems_region_return_segment: task readied -- preempts caller 82
Dual-Ported Memory Manager
rtems_port_create 23
rtems_port_ident 82
rtems_port_delete 21
rtems_port_internal_to_external 10
rtems_port_external_to_internal 11
IO Manager
rtems_io_initialize 1
rtems_io_open 1
rtems_io_close 1
rtems_io_read 1
rtems_io_write 1
rtems_io_control 1
Rate Monotonic Manager
rtems_rate_monotonic_create 43
rtems_rate_monotonic_ident 82
rtems_rate_monotonic_cancel 23
rtems_rate_monotonic_delete: active 28
rtems_rate_monotonic_delete: inactive 25
rtems_rate_monotonic_period: obtain status 17
rtems_rate_monotonic_period: initiate period -- returns to caller 32
rtems_rate_monotonic_period: conclude periods -- caller blocks 30
Network tests:
TCP throughput (as measured by ttcp):
Receive: 1324 kbytes/sec
Transmit: 1037 kbytes/sec

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
%rename cpp old_cpp
%rename lib old_lib
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*cpp:
%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
*lib:
%{!qrtems: %(old_lib)} %{qrtems: --start-group \
%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
-lc -lgcc --end-group \
%{!qnolinkcmds: -T linkcmds%s}}
*startfile:
%{!qrtems: %(old_startfile)} %{qrtems: ecrti%O%s \
%{!qrtems_debug: start.o%s} \
%{qrtems_debug: start_g.o%s}}
*endfile:
%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s}
*link:
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -N -u start -e start}

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,26 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@:@srcdir@/../../shared/clock
C_FILES = p_clock.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
all-local: $(ARCH) $(OBJS)
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,71 @@
/*
* Clock Tick interrupt conexion code.
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* Modified to support the MPC750.
* Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
*
* $Id$
*/
#include <bsp.h>
#include <bspIo.h>
#include <bsp/irq.h>
extern void clockOn(void*);
extern void clockOff (void*);
extern int clockIsOn(void*);
extern void Clock_isr();
static rtems_irq_connect_data clockIrqData = {BSP_PERIODIC_TIMER,
(rtems_irq_hdl)Clock_isr,
(rtems_irq_enable)clockOn,
(rtems_irq_disable)clockOff,
(rtems_irq_is_enabled)clockIsOn};
int BSP_get_clock_irq_level()
{
/*
* Caution : if you change this, you must change the
* definition of BSP_PERIODIC_TIMER accordingly
*/
return BSP_PERIODIC_TIMER;
}
int BSP_disconnect_clock_handler (void)
{
if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
printk("Unable to stop system clock\n");
rtems_fatal_error_occurred(1);
}
return BSP_remove_rtems_irq_handler (&clockIrqData);
}
int BSP_connect_clock_handler (rtems_irq_hdl hdl)
{
if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
printk("Unable to get system clock handler\n");
rtems_fatal_error_occurred(1);
}
if (!BSP_remove_rtems_irq_handler (&clockIrqData)) {
printk("Unable to remove current system clock handler\n");
rtems_fatal_error_occurred(1);
}
/*
* Reinit structure
*/
clockIrqData.name = BSP_PERIODIC_TIMER;
clockIrqData.hdl = (rtems_irq_hdl) hdl;
clockIrqData.on = (rtems_irq_enable)clockOn;
clockIrqData.off = (rtems_irq_enable)clockOff;
clockIrqData.isOn = (rtems_irq_is_enabled)clockIsOn;
return BSP_install_rtems_irq_handler (&clockIrqData);
}

View File

@@ -0,0 +1,33 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/console.rel
C_FILES = console.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(OBJS)
$(make-rel)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
all-local: $(ARCH) $(OBJS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = console.c
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,478 @@
/*
* console.c
*
* This file contains the MBX8xx termios serial I/O package.
* Only asynchronous I/O is supported.
*
* The SCCs and SMCs are assigned as follows
*
* Channel Device Minor Note
* SMC1 /dev/tty0 0
* SMC2 /dev/tty1 1
* SCC1 2 N/A. Hardwired as ethernet port
* SCC2 /dev/tty2 3
* SCC3 /dev/tty3 4
* SCC4 /dev/tty4 5
*
* All ports support termios. The use of termios is recommended for real-time
* applications. Termios provides buffering and input processing. When not
* using termios, processing is limited to the substitution of LF for CR on
* input, and the output of a CR following the output of a LF character.
* Note that the terminal should not send CR/LF pairs when the return key
* is pressed, and that output lines are terminated with LF/CR, not CR/LF
* (although that would be easy to change).
*
* I/O may be interrupt-driven (recommended for real-time applications) or
* polled. Polled I/O may be performed by this device driver entirely, or
* in part by EPPCBug. With EPPCBug 1.1, polled I/O is limited to the
* EPPCBug debug console. This is a limitation of the firmware. Later
* firmware may be able to do I/O through any port. This code assumes
* that the EPPCBug console is the default: SMC1. If the console and
* printk ports are set to anything else with EPPCBug polled I/O, the
* system will hang. Only port SMC1 is usable with EPPCBug polled I/O.
*
* LIMITATIONS:
*
* It is not possible to use different I/O modes on the different ports. The
* exception is with printk. The printk port can use a different mode from
* the other ports. If this is done, it is important not to open the printk
* port from an RTEMS application.
*
* Currently, the I/O modes are determined at build time. It would be much
* better to have the mode selected at boot time based on parameters in
* NVRAM.
*
* Interrupt-driven I/O requires termios.
*
* TESTS:
*
* TO RUN THE TESTS, USE POLLED I/O WITHOUT TERMIOS SUPPORT. Some tests
* play with the interrupt masks and turn off I/O. Those tests will hang
* when interrupt-driven I/O is used. Other tests, such as cdtest, do I/O
* from the static constructors before the console is open. This test
* will not work with interrupt-driven I/O. Because of the buffering
* performed in termios, test output may not be in sequence.The tests
* should all be fixed to work with interrupt-driven I/O and to
* produce output in the expected sequence. Obviously, the termios test
* requires termios support in the driver.
*
* Set CONSOLE_MINOR to the appropriate device minor number in the
* config file. This allows the RTEMS application console to be different
* from the EPPBug debug console or the GDB port.
*
* This driver handles all five available serial ports: it distinguishes
* the sub-devices using minor device numbers. It is not possible to have
* other protocols running on the other ports when this driver is used as
* currently written.
*
* Based on code (alloc860.c in eth_comm port) by
* Jay Monkman (jmonkman@frasca.com),
* Copyright (C) 1998 by Frasca International, Inc.
*
* Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
* and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>.
* Copyright (c) 2000, National Research Council of Canada
*
* Modifications by Andy Dachs <iwe@fsmal.net> for MPC8260
* support.
*
* The SCCs and SMCs on the eval board are assigned as follows
*
* Channel Device Minor Termios
* SMC1 /dev/tty3 4 no
* SMC2 /dev/tty4 5 no
* SCC1 /dev/tty0 0 no
* SCC2 /dev/console 1 yes
* SCC3 /dev/tty1 2 no * USED FOR NETWORK I/F
* SCC4 /dev/tty2 3 no * USED FOR NETWORK I/F
*
*/
#include <stdarg.h>
#include <stdio.h>
#include <bsp.h> /* Must be before libio.h */
#include <bspIo.h>
#include <rtems/libio.h>
#include <termios.h>
static void _BSP_output_char( char c );
static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg);
static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg);
BSP_output_char_function_type BSP_output_char = _BSP_output_char;
/*
* do_poll_read
*
* Input characters through polled I/O. Returns has soon as a character has
* been received. Otherwise, if we wait for the number of requested characters,
* we could be here forever!
*
* CR is converted to LF on input. The terminal should not send a CR/LF pair
* when the return or enter key is pressed.
*
* Input parameters:
* major - ignored. Should be the major number for this driver.
* minor - selected channel.
* arg->buffer - where to put the received characters.
* arg->count - number of characters to receive before returning--Ignored.
*
* Output parameters:
* arg->bytes_moved - the number of characters read. Always 1.
*
* Return value: RTEMS_SUCCESSFUL
*
* CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
*/
static rtems_status_code do_poll_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_libio_rw_args_t *rw_args = arg;
int c;
#define BSP_READ m8xx_uart_pollRead
while( (c = BSP_READ(minor)) == -1 );
rw_args->buffer[0] = (unsigned8)c;
if( rw_args->buffer[0] == '\r' )
rw_args->buffer[0] = '\n';
rw_args->bytes_moved = 1;
return RTEMS_SUCCESSFUL;
}
/*
* do_poll_write
*
* Output characters through polled I/O. Returns only once every character has
* been sent.
*
* CR is transmitted AFTER a LF on output.
*
* Input parameters:
* major - ignored. Should be the major number for this driver.
* minor - selected channel
* arg->buffer - where to get the characters to transmit.
* arg->count - the number of characters to transmit before returning.
*
* Output parameters:
* arg->bytes_moved - the number of characters read
*
* Return value: RTEMS_SUCCESSFUL
*
* CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
*/
static rtems_status_code do_poll_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_libio_rw_args_t *rw_args = arg;
unsigned32 i;
char cr ='\r';
#define BSP_WRITE m8xx_uart_pollWrite
for( i = 0; i < rw_args->count; i++ ) {
BSP_WRITE(minor, &(rw_args->buffer[i]), 1);
if ( rw_args->buffer[i] == '\n' )
BSP_WRITE(minor, &cr, 1);
}
rw_args->bytes_moved = i;
return RTEMS_SUCCESSFUL;
}
/*
* Print functions prototyped in bspIo.h
*/
static void _BSP_output_char( char c )
{
char cr = '\r';
/*
* Can't rely on console_initialize having been called before this function
* is used, so it may fail unless output is done through EPPC-Bug.
*/
#define PRINTK_WRITE m8xx_uart_pollWrite
PRINTK_WRITE( PRINTK_MINOR, &c, 1 );
if( c == '\n' )
PRINTK_WRITE( PRINTK_MINOR, &cr, 1 );
}
/*
***************
* BOILERPLATE *
***************
*
* All these functions are prototyped in rtems/c/src/lib/include/console.h.
*/
/*
* Initialize and register the device
*/
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
rtems_device_minor_number console_minor;
/*
* Set up TERMIOS if needed
*/
console_minor = CONSOLE_MINOR;
#if UARTS_USE_TERMIOS == 1
rtems_termios_initialize ();
#else
rtems_termios_initialize ();
#endif /* UARTS_USE_TERMIOS */
/*
* Do common initialization.
*/
m8xx_uart_initialize();
/*
* Do device-specific initialization
*/
#if 0
m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty4 */
m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty5 */
#endif
m8xx_uart_scc_initialize(SCC1_MINOR); /* /dev/tty0 */
m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty1 */
#if 0 /* used as network connections */
m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty2 */
m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty3 */
#endif
/*
* Set up interrupts
*/
m8xx_uart_interrupts_initialize();
status = rtems_io_register_name ("/dev/tty0", major, SCC1_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
chmod("/dev/tty0",0660);
chown("/dev/tty0",2,0);
status = rtems_io_register_name ("/dev/tty1", major, SCC2_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
chmod("/dev/tty1",0660);
chown("/dev/tty1",2,0);
#if 0
status = rtems_io_register_name ("/dev/tty2", major, SCC3_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
status = rtems_io_register_name ("/dev/tty3", major, SCC4_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
status = rtems_io_register_name ("/dev/tty4", major, SMC1_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
status = rtems_io_register_name ("/dev/tty5", major, SMC2_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
#endif
/* Now register the RTEMS console */
status = rtems_io_register_name ("/dev/console", major, console_minor);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
chmod("/dev/console",0666);
chown("/dev/console",2,0);
return RTEMS_SUCCESSFUL;
}
/*
* Open the device
*/
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
/* Used to track termios private data for callbacks */
extern struct rtems_termios_tty *ttyp[];
rtems_libio_open_close_args_t *args = arg;
rtems_status_code sc;
static const rtems_termios_callbacks intrCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
NULL, /* pollRead */
m8xx_uart_write, /* write */
m8xx_uart_setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
1 /* outputUsesInterrupts */
};
static const rtems_termios_callbacks pollCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
m8xx_uart_pollRead, /* pollRead */
m8xx_uart_pollWrite, /* write */
m8xx_uart_setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
};
if ( minor > NUM_PORTS-1 )
return RTEMS_INVALID_NUMBER;
#if UARTS_USE_TERMIOS == 1
#if UARTS_IO_MODE == 1 /* RTEMS interrupt-driven I/O with termios */
sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */
#else /* RTEMS polled I/O with termios */
sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
#endif
#else /* UARTS_USE_TERMIOS != 1 */
/* no termios -- default to polled I/O */
sc = RTEMS_SUCCESSFUL;
#endif /* UARTS_USE_TERMIOS != 1 */
return sc;
}
/*
* Close the device
*/
rtems_device_driver console_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
if ( minor > NUM_PORTS-1 )
return RTEMS_INVALID_NUMBER;
#if UARTS_USE_TERMIOS == 1
return rtems_termios_close( arg );
#else
return RTEMS_SUCCESSFUL;
#endif
}
/*
* Read from the device
*/
rtems_device_driver console_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
if ( minor > NUM_PORTS-1 )
return RTEMS_INVALID_NUMBER;
#if UARTS_USE_TERMIOS == 1
return rtems_termios_read( arg );
#else
return do_poll_read( major, minor, arg );
#endif
}
/*
* Write to the device
*/
rtems_device_driver console_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
if ( minor > NUM_PORTS-1 )
return RTEMS_INVALID_NUMBER;
#if UARTS_USE_TERMIOS == 1
return rtems_termios_write( arg );
#else
/* no termios -- default to polled */
return do_poll_write( major, minor, arg );
#endif
}
/*
* Handle ioctl request.
*/
rtems_device_driver console_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
if ( minor > NUM_PORTS-1 )
return RTEMS_INVALID_NUMBER;
#if UARTS_USE_TERMIOS == 1
return rtems_termios_ioctl( arg );
#else
return RTEMS_SUCCESSFUL;
#endif
}
/*
* Support routine for console-generic
*/
int mbx8xx_console_get_configuration(void)
{
#if UARTS_IO_MODE == 1
return 0x02;
#else
return 0;
#endif
}

View File

@@ -0,0 +1,31 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = bsp.h coverhd.h
BSP_H_FILES =
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/bsp:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/bsp.h: bsp.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/coverhd.h: coverhd.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(PROJECT_INCLUDE)/bsp \
$(PROJECT_INCLUDE)/bsp.h \
$(PROJECT_INCLUDE)/coverhd.h
all-local: $(PREINSTALL_FILES)
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,157 @@
/* bsp.h
*
* This include file contains all board IO definitions.
*
* XXX : put yours in here
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __NO_BSP_h
#define __NO_BSP_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <console.h>
#include <clockdrv.h>
#include <mpc8260.h>
#include <mpc8260/cpm.h>
#include <mpc8260/mmu.h>
#include <mpc8260/console.h>
#include <bsp/irq.h>
/*
* Board configuration registers
*/
typedef struct bcsr
{
rtems_unsigned32 bcsr0; /* Board Control and Status Register */
rtems_unsigned32 bcsr1;
rtems_unsigned32 bcsr2;
rtems_unsigned32 bcsr3;
} BCSR;
#define UART1_E 0x02000002 /* bit 6 of BCSR1 */
#define UART2_E 0x01000001 /* bit 7 of BCSR1 */
#define GP0_LED 0x02000002 /* bit 6 of BCSR0 */
#define GP1_LED 0x01000001 /* bit 7 of BCSR0 */
/*
* Network driver configuration
*/
struct rtems_bsdnet_ifconfig;
extern int rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config, int attaching);
#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_enet_driver_attach
/* miscellaneous stuff assumed to exist */
extern rtems_configuration_table BSP_Configuration;
/*
* We need to decide how much memory will be non-cacheable. This
* will mainly be memory that will be used in DMA (network and serial
* buffers).
*/
/*
#define NOCACHE_MEM_SIZE 512*1024
*/
/*
* Define the time limits for RTEMS Test Suite test durations.
* Long test and short test duration limits are provided. These
* values are in seconds and need to be converted to ticks for the
* application.
*
*/
#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
/*
* Stuff for Time Test 27
*/
#define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector( handler ) \
do { \
static rtems_irq_connect_data scIrqData = { \
PPC_IRQ_SCALL, \
(rtems_irq_hdl) handler, \
NULL, \
NULL, \
NULL \
}; \
BSP_install_rtems_irq_handler (&scIrqData); \
} while(0)
#define Cause_tm27_intr() asm volatile ("sc")
#define Clear_tm27_intr()
#define Lower_tm27_intr()
/* Constants */
/*
#define RAM_START 0
#define RAM_END 0x1000000
*/
/*
* Device Driver Table Entries
*/
/*
* NOTE: Use the standard Console driver entry
*/
/*
* NOTE: Use the standard Clock driver entry
*/
/*
* How many libio files we want
*/
#define BSP_LIBIO_MAX_FDS 20
/* functions */
void bsp_cleanup( void );
#if 0
void M8260ExecuteRISC( rtems_unsigned32 command );
void *M8260AllocateBufferDescriptors( int count );
void *M8260AllocateRiscTimers( int count );
extern char M8260DefaultWatchdogFeeder;
#endif
rtems_isr_entry set_vector( /* returns old vector */
rtems_isr_entry handler, /* isr routine */
rtems_vector_number vector, /* vector number */
int type /* RTEMS or RAW intr */
);
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,114 @@
/* coverhd.h
*
* This include file has defines to represent the overhead associated
* with calling a particular directive from C. These are used in the
* Timing Test Suite to ignore the overhead required to pass arguments
* to directives. On some CPUs and/or target boards, this overhead
* is significant and makes it difficult to distinguish internal
* RTEMS execution time from that used to call the directive.
* This file should be updated after running the C overhead timing
* test. Once this update has been performed, the RTEMS Time Test
* Suite should be rebuilt to account for these overhead times in the
* timing results.
*
* NOTE: If these are all zero, then the times reported include
* all calling overhead including passing of arguments.
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __COVERHD_h
#define __COVERHD_h
#ifdef __cplusplus
extern "C" {
#endif
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
#define CALLING_OVERHEAD_TASK_CREATE 0
#define CALLING_OVERHEAD_TASK_IDENT 0
#define CALLING_OVERHEAD_TASK_START 0
#define CALLING_OVERHEAD_TASK_RESTART 0
#define CALLING_OVERHEAD_TASK_DELETE 0
#define CALLING_OVERHEAD_TASK_SUSPEND 0
#define CALLING_OVERHEAD_TASK_RESUME 0
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
#define CALLING_OVERHEAD_TASK_MODE 0
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 2
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
#define CALLING_OVERHEAD_CLOCK_GET 2
#define CALLING_OVERHEAD_CLOCK_SET 2
#define CALLING_OVERHEAD_CLOCK_TICK 0
#define CALLING_OVERHEAD_TIMER_CREATE 0
#define CALLING_OVERHEAD_TIMER_IDENT 0
#define CALLING_OVERHEAD_TIMER_DELETE 0
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 2
#define CALLING_OVERHEAD_TIMER_RESET 0
#define CALLING_OVERHEAD_TIMER_CANCEL 0
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
#define CALLING_OVERHEAD_EVENT_SEND 0
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
#define CALLING_OVERHEAD_SIGNAL_SEND 0
#define CALLING_OVERHEAD_PARTITION_CREATE 0
#define CALLING_OVERHEAD_PARTITION_IDENT 0
#define CALLING_OVERHEAD_PARTITION_DELETE 0
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
#define CALLING_OVERHEAD_REGION_CREATE 0
#define CALLING_OVERHEAD_REGION_IDENT 0
#define CALLING_OVERHEAD_REGION_DELETE 0
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
#define CALLING_OVERHEAD_PORT_CREATE 0
#define CALLING_OVERHEAD_PORT_IDENT 0
#define CALLING_OVERHEAD_PORT_DELETE 0
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
#define CALLING_OVERHEAD_IO_INITIALIZE 0
#define CALLING_OVERHEAD_IO_OPEN 0
#define CALLING_OVERHEAD_IO_CLOSE 0
#define CALLING_OVERHEAD_IO_READ 0
#define CALLING_OVERHEAD_IO_WRITE 0
#define CALLING_OVERHEAD_IO_CONTROL 0
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,46 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
C_FILES = irq.c irq_init.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
H_FILES = irq.h
S_FILES = irq_asm.S
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
OBJS = $(C_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
include $(top_srcdir)/../../../../../../automake/lib.am
SORDID_HACK:
rm -f $(PROJECT_INCLUDE)/bsp/irq.h
$(PROJECT_INCLUDE)/bsp:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/bsp/%.h: %.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp \
$(H_FILES:%.h=$(PROJECT_INCLUDE)/bsp/%.h)
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(OBJS)
$(make-rel)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
all-local: SORDID_HACK $(PREINSTALL_FILES) $(ARCH) $(OBJS) $(PGM)
EXTRA_DIST = irq.c irq.h irq_asm.S irq_init.c
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,453 @@
/*
*
* This file contains the implementation of the function described in irq.h
*
* Copyright (C) 1998, 1999 valette@crf.canon.fr
*
* Modified for mpc8260 Andy Dachs <a.dachs@sstl.co.uk>
* Surrey Satellite Technology Limited, 2000
* Nested exception handlers not working yet.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp.h>
#include <bsp/irq.h>
#include <rtems/score/thread.h>
#include <rtems/score/apiext.h>
#include <libcpu/raw_exception.h>
#include <bsp/vectors.h>
#include <libcpu/cpu.h>
/*#include <bsp/8xx_immap.h>*/
#include <mpc8260.h>
/*#include <bsp/commproc.h>*/
/*
* default handler connected on each irq after bsp initialization
*/
static rtems_irq_connect_data default_rtems_entry;
/*
* location used to store initial tables used for interrupt
* management.
*/
static rtems_irq_global_settings* internal_config;
static rtems_irq_connect_data* rtems_hdl_tbl;
/*
* Check if symbolic IRQ name is an CPM IRQ
*/
static inline int is_cpm_irq(const rtems_irq_symbolic_name irqLine)
{
return (((int) irqLine <= BSP_CPM_IRQ_MAX_OFFSET) &
((int) irqLine >= BSP_CPM_IRQ_LOWEST_OFFSET)
);
}
/*
* Check if symbolic IRQ name is a Processor IRQ
*/
static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine)
{
return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
);
}
/*
* bit in the SIU mask registers (PPC bit numbering) that should
* be set to enable the relevant interrupt
*
*/
const static unsigned int SIU_MaskBit[BSP_CPM_IRQ_NUMBER] =
{
63, 48, 49, 50, /* err, i2c, spi, rtt */
51, 52, 53, 54, /* smc1, smc2, idma1, idma2 */
55, 56, 57, 63, /* idma3, idma4, sdma, - */
59, 60, 61, 62, /* tmr1, tmr2, tmr3, tmr4 */
29, 30, 63, 17, /* pit, tmcnt, -, irq1 */
18, 19, 20, 21, /* irq2, irq3, irq4, irq5 */
22, 23, 63, 63, /* irq6, irq7, -, - */
63, 63, 63, 63, /* -, -, -, - */
32, 33, 34, 35, /* fcc1, fcc2, fcc3, - */
36, 37, 38, 39, /* mcc1, mcc2, -, - */
40, 41, 42, 43, /* scc1, scc2, scc3, scc4 */
44, 45, 46, 47, /* -, -, -, - */
0, 1, 2, 3, /* pc0, pc1, pc2, pc3 */
4, 5, 6, 7, /* pc4, pc5, pc6, pc7 */
8, 9, 10, 11, /* pc8, pc9, pc10, pc11 */
12, 13, 14, 15 /* pc12, pc13, pc14, pc15 */
};
/*
* ------------------------ RTEMS Irq helper functions ----------------
*/
/*
* Caution : this function assumes the variable "internal_config"
* is already set and that the tables it contains are still valid
* and accessible.
*/
static void compute_SIU_IvectMask_from_prio ()
{
/*
* In theory this is feasible. No time to code it yet. See i386/shared/irq.c
* for an example based on 8259 controller mask. The actual masks defined
* correspond to the priorities defined for the SIU in irq_init.c.
*/
}
/*
* This function check that the value given for the irq line
* is valid.
*/
static int isValidInterrupt(int irq)
{
if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET) )
return 0;
return 1;
}
int BSP_irq_enable_at_cpm(const rtems_irq_symbolic_name irqLine)
{
int cpm_irq_index;
if (!is_cpm_irq(irqLine))
return 1;
cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
if( SIU_MaskBit[cpm_irq_index] < 32 )
m8260.simr_h |= (0x80000000 >> SIU_MaskBit[cpm_irq_index]);
else
m8260.simr_l |= (0x80000000 >> (SIU_MaskBit[cpm_irq_index]-32));
return 0;
}
int BSP_irq_disable_at_cpm(const rtems_irq_symbolic_name irqLine)
{
int cpm_irq_index;
if (!is_cpm_irq(irqLine))
return 1;
cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
if( SIU_MaskBit[cpm_irq_index] < 32 )
m8260.simr_h &= ~(0x80000000 >> SIU_MaskBit[cpm_irq_index]);
else
m8260.simr_l &= ~(0x80000000 >> (SIU_MaskBit[cpm_irq_index]-32));
return 0;
}
int BSP_irq_enabled_at_cpm(const rtems_irq_symbolic_name irqLine)
{
int cpm_irq_index;
if (!is_cpm_irq(irqLine))
return 0;
cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
if( SIU_MaskBit[cpm_irq_index] < 32 )
return m8260.simr_h & (0x80000000 >> SIU_MaskBit[cpm_irq_index]);
else
return m8260.simr_l & (0x80000000 >> (SIU_MaskBit[cpm_irq_index]-32));
}
/*
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
*/
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
unsigned int level;
if (!isValidInterrupt(irq->name)) {
printk( "not a valid intr\n" ) ;
return 0;
}
/*
* Check if default handler is actually connected. If not issue an error.
* You must first get the current handler via i386_get_current_idt_entry
* and then disconnect it using i386_delete_idt_entry.
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
printk( "Default handler not there\n" );
return 0;
}
_CPU_ISR_Disable(level);
/*
* store the data provided by user
*/
rtems_hdl_tbl[irq->name] = *irq;
if (is_cpm_irq(irq->name)) {
/*
* Enable interrupt at PIC level
*/
BSP_irq_enable_at_cpm (irq->name);
}
if (is_processor_irq(irq->name)) {
/*
* Should Enable exception at processor level but not needed. Will restore
* EE flags at the end of the routine anyway.
*/
}
/*
* Enable interrupt on device
*/
irq->on(irq);
_CPU_ISR_Enable(level);
/*
printk( "Enabled\n" );
*/
return 1;
}
int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
{
if (!isValidInterrupt(irq->name)) {
return 0;
}
*irq = rtems_hdl_tbl[irq->name];
return 1;
}
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
unsigned int level;
if (!isValidInterrupt(irq->name)) {
return 0;
}
/*
* Check if default handler is actually connected. If not issue an error.
* You must first get the current handler via i386_get_current_idt_entry
* and then disconnect it using i386_delete_idt_entry.
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
return 0;
}
_CPU_ISR_Disable(level);
if (is_cpm_irq(irq->name)) {
/*
* disable interrupt at PIC level
*/
BSP_irq_disable_at_cpm (irq->name);
}
if (is_processor_irq(irq->name)) {
/*
* disable exception at processor level
*/
}
/*
* Disable interrupt on device
*/
irq->off(irq);
/*
* restore the default irq value
*/
rtems_hdl_tbl[irq->name] = default_rtems_entry;
_CPU_ISR_Enable(level);
return 1;
}
/*
* ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
*/
int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
{
int i;
unsigned int level;
/*
* Store various code accelerators
*/
internal_config = config;
default_rtems_entry = config->defaultEntry;
rtems_hdl_tbl = config->irqHdlTbl;
_CPU_ISR_Disable(level);
/*
* start with CPM IRQ
*/
for (i=BSP_CPM_IRQ_LOWEST_OFFSET; i < BSP_CPM_IRQ_LOWEST_OFFSET + BSP_CPM_IRQ_NUMBER ; i++) {
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
BSP_irq_enable_at_cpm (i);
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
}
else {
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
BSP_irq_disable_at_cpm (i);
}
}
/*
* finish with Processor exceptions handled like IRQ
*/
for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER; i++) {
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
}
else {
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
}
}
_CPU_ISR_Enable(level);
return 1;
}
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
{
*config = internal_config;
return 0;
}
#ifdef DISPATCH_HANDLER_STAT
volatile unsigned int maxLoop = 0;
#endif
/*
* High level IRQ handler called from shared_raw_irq_code_entry
*/
void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
{
register unsigned int irq;
#if 0
register unsigned oldMask; /* old siu pic masks */
#endif
register unsigned msr;
register unsigned new_msr;
#ifdef DISPATCH_HANDLER_STAT
unsigned loopCounter;
#endif
/*
* Handle decrementer interrupt
*/
if (excNum == ASM_DEC_VECTOR) {
/*
_BSP_GPLED1_on();
*/
_CPU_MSR_GET(msr);
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
rtems_hdl_tbl[BSP_DECREMENTER].hdl();
_CPU_MSR_SET(msr);
/*
_BSP_GPLED1_off();
*/
return;
}
/*
* Handle external interrupt generated by SIU on PPC core
*/
#ifdef DISPATCH_HANDLER_STAT
loopCounter = 0;
#endif
while (1) {
if( ((m8260.sipnr_h & m8260.simr_h) | (m8260.sipnr_l & m8260.simr_l)) == 0 ) {
#ifdef DISPATCH_HANDLER_STAT
if (loopCounter > maxLoop) maxLoop = loopCounter;
#endif
break;
}
irq = (m8260.sivec >> 26) + BSP_CPM_IRQ_LOWEST_OFFSET;
/*
printk( "dispatching %d\n", irq );
*/
/* Clear pending register */
if( irq <= BSP_CPM_IRQ_MAX_OFFSET ) {
if( SIU_MaskBit[irq] < 32 )
m8260.sipnr_h = (0x80000000 >> SIU_MaskBit[irq]);
else
m8260.sipnr_l = (0x80000000 >> (SIU_MaskBit[irq]-32));
}
/*
_CPU_MSR_GET(msr);
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
*/
rtems_hdl_tbl[irq].hdl();
/*
_CPU_MSR_SET(msr);
*/
#if 0
ppc_cached_irq_mask |= (oldMask & ~(SIU_IvectMask[irq]));
((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
#endif
#ifdef DISPATCH_HANDLER_STAT
++ loopCounter;
#endif
}
}
void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
{
/*
* Process pending signals that have not already been
* processed by _Thread_Displatch. This happens quite
* unfrequently : the ISR must have posted an action
* to the current running thread.
*/
if ( _Thread_Do_post_task_switch_extension ||
_Thread_Executing->do_post_task_switch_extension ) {
_Thread_Executing->do_post_task_switch_extension = FALSE;
_API_extensions_Run_postswitch();
}
/*
* I plan to process other thread related events here.
* This will include DEBUG session requested from keyboard...
*/
}

View File

@@ -0,0 +1,347 @@
/* irq.h
*
* This include file describe the data structure and the functions implemented
* by rtems to write interrupt handlers.
*
* CopyRight (C) 1999 valette@crf.canon.fr
*
* This code is heavilly inspired by the public specification of STREAM V2
* that can be found at :
*
* <http://www.chorus.com/Documentation/index.html> by following
* the STREAM API Specification Document link.
*
* Modified for mpc8260 by Andy Dachs <a.dachs@sstl.co.uk>
* Surrey Satellite Technology Limited
* The interrupt handling on the mpc8260 seems quite different from
* the 860 (I don't know the 860 well). Although some interrupts
* are routed via the CPM irq and some are direct to the SIU they all
* appear logically the same. Therefore I removed the distinction
* between SIU and CPM interrupts.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef LIBBSP_POWERPC_MBX8XX_IRQ_IRQ_H
#define LIBBSP_POWERPC_MBX8XX_IRQ_IRQ_H
#define BSP_ASM_IRQ_VECTOR_BASE 0x0
#ifndef ASM
/*
extern volatile unsigned int ppc_cached_irq_mask;
*/
/*
* Symblolic IRQ names and related definitions.
*/
typedef enum {
/* Base vector for our SIU IRQ handlers. */
BSP_SIU_VECTOR_BASE = BSP_ASM_IRQ_VECTOR_BASE,
/*
* CPM IRQ handlers related definitions
* CAUTION : BSP_CPM_IRQ_LOWEST_OFFSET should be equal to OPENPIC_VEC_SOURCE
*/
BSP_CPM_IRQ_NUMBER = 64,
BSP_CPM_IRQ_LOWEST_OFFSET = BSP_SIU_VECTOR_BASE,
BSP_CPM_IRQ_MAX_OFFSET = BSP_CPM_IRQ_LOWEST_OFFSET + BSP_CPM_IRQ_NUMBER - 1,
/*
* PowerPc exceptions handled as interrupt where a rtems managed interrupt
* handler might be connected
*/
BSP_PROCESSOR_IRQ_NUMBER = 1,
BSP_PROCESSOR_IRQ_LOWEST_OFFSET = BSP_CPM_IRQ_MAX_OFFSET + 1,
BSP_PROCESSOR_IRQ_MAX_OFFSET = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1,
/*
* Summary
*/
BSP_IRQ_NUMBER = BSP_PROCESSOR_IRQ_MAX_OFFSET + 1,
BSP_LOWEST_OFFSET = BSP_CPM_IRQ_LOWEST_OFFSET,
BSP_MAX_OFFSET = BSP_PROCESSOR_IRQ_MAX_OFFSET,
/*
* Some SIU IRQ symbolic name definition. Please note that
* INT IRQ are defined but a single one will be used to
* redirect all CPM interrupt.
*
* On the mpc8260 all this seems to be transparent. Although the
* CPM, PIT and TMCNT interrupt may well be the only interrupts routed
* to the SIU at the hardware level all of them appear as CPM interupts
* to software apart from the registers for setting priority.
*
* The MPC8260 User Manual seems shot through with inconsistencies
* about this whole area.
*/
/*
* Some CPM IRQ symbolic name definition
*/
BSP_CPM_IRQ_ERROR = BSP_CPM_IRQ_LOWEST_OFFSET,
BSP_CPM_IRQ_I2C = BSP_CPM_IRQ_LOWEST_OFFSET + 1,
BSP_CPM_IRQ_SPI = BSP_CPM_IRQ_LOWEST_OFFSET + 2,
BSP_CPM_IRQ_RISC_TIMERS = BSP_CPM_IRQ_LOWEST_OFFSET + 3,
BSP_CPM_IRQ_SMC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 4,
BSP_CPM_IRQ_SMC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 5,
BSP_CPM_IRQ_IDMA1 = BSP_CPM_IRQ_LOWEST_OFFSET + 6,
BSP_CPM_IRQ_IDMA2 = BSP_CPM_IRQ_LOWEST_OFFSET + 7,
BSP_CPM_IRQ_IDMA3 = BSP_CPM_IRQ_LOWEST_OFFSET + 8,
BSP_CPM_IRQ_IDMA4 = BSP_CPM_IRQ_LOWEST_OFFSET + 9,
BSP_CPM_IRQ_SDMA = BSP_CPM_IRQ_LOWEST_OFFSET + 10,
BSP_CPM_IRQ_TIMER_1 = BSP_CPM_IRQ_LOWEST_OFFSET + 12,
BSP_CPM_IRQ_TIMER_2 = BSP_CPM_IRQ_LOWEST_OFFSET + 13,
BSP_CPM_IRQ_TIMER_3 = BSP_CPM_IRQ_LOWEST_OFFSET + 14,
BSP_CPM_IRQ_TIMER_4 = BSP_CPM_IRQ_LOWEST_OFFSET + 15,
BSP_CPM_IRQ_TMCNT = BSP_CPM_IRQ_LOWEST_OFFSET + 16,
BSP_CPM_IRQ_PIT = BSP_CPM_IRQ_LOWEST_OFFSET + 17,
BSP_CPM_IRQ_IRQ1 = BSP_CPM_IRQ_LOWEST_OFFSET + 19,
BSP_CPM_IRQ_IRQ2 = BSP_CPM_IRQ_LOWEST_OFFSET + 20,
BSP_CPM_IRQ_IRQ3 = BSP_CPM_IRQ_LOWEST_OFFSET + 21,
BSP_CPM_IRQ_IRQ4 = BSP_CPM_IRQ_LOWEST_OFFSET + 22,
BSP_CPM_IRQ_IRQ5 = BSP_CPM_IRQ_LOWEST_OFFSET + 23,
BSP_CPM_IRQ_IRQ6 = BSP_CPM_IRQ_LOWEST_OFFSET + 24,
BSP_CPM_IRQ_IRQ7 = BSP_CPM_IRQ_LOWEST_OFFSET + 25,
BSP_CPM_IRQ_FCC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 32,
BSP_CPM_IRQ_FCC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 33,
BSP_CPM_IRQ_FCC3 = BSP_CPM_IRQ_LOWEST_OFFSET + 34,
BSP_CPM_IRQ_MCC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 36,
BSP_CPM_IRQ_MCC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 37,
BSP_CPM_IRQ_SCC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 40,
BSP_CPM_IRQ_SCC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 41,
BSP_CPM_IRQ_SCC3 = BSP_CPM_IRQ_LOWEST_OFFSET + 42,
BSP_CPM_IRQ_SCC4 = BSP_CPM_IRQ_LOWEST_OFFSET + 43,
BSP_CPM_IRQ_PC15 = BSP_CPM_IRQ_LOWEST_OFFSET + 48,
BSP_CPM_IRQ_PC14 = BSP_CPM_IRQ_LOWEST_OFFSET + 49,
BSP_CPM_IRQ_PC13 = BSP_CPM_IRQ_LOWEST_OFFSET + 50,
BSP_CPM_IRQ_PC12 = BSP_CPM_IRQ_LOWEST_OFFSET + 51,
BSP_CPM_IRQ_PC11 = BSP_CPM_IRQ_LOWEST_OFFSET + 52,
BSP_CPM_IRQ_PC10 = BSP_CPM_IRQ_LOWEST_OFFSET + 53,
BSP_CPM_IRQ_PC9 = BSP_CPM_IRQ_LOWEST_OFFSET + 54,
BSP_CPM_IRQ_PC8 = BSP_CPM_IRQ_LOWEST_OFFSET + 55,
BSP_CPM_IRQ_PC7 = BSP_CPM_IRQ_LOWEST_OFFSET + 56,
BSP_CPM_IRQ_PC6 = BSP_CPM_IRQ_LOWEST_OFFSET + 57,
BSP_CPM_IRQ_PC5 = BSP_CPM_IRQ_LOWEST_OFFSET + 58,
BSP_CPM_IRQ_PC4 = BSP_CPM_IRQ_LOWEST_OFFSET + 59,
BSP_CPM_IRQ_PC3 = BSP_CPM_IRQ_LOWEST_OFFSET + 60,
BSP_CPM_IRQ_PC2 = BSP_CPM_IRQ_LOWEST_OFFSET + 61,
BSP_CPM_IRQ_PC1 = BSP_CPM_IRQ_LOWEST_OFFSET + 62,
BSP_CPM_IRQ_PC0 = BSP_CPM_IRQ_LOWEST_OFFSET + 63,
/*
* Some Processor exception handled as rtems IRQ symbolic name definition
*/
BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET,
BSP_PERIODIC_TIMER = BSP_DECREMENTER
}rtems_irq_symbolic_name;
#define CPM_INTERRUPT
/*
* Type definition for RTEMS managed interrupts
*/
typedef unsigned char rtems_irq_prio;
struct __rtems_irq_connect_data__; /* forward declaratiuon */
typedef void (*rtems_irq_hdl) (void);
typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
typedef struct __rtems_irq_connect_data__ {
/*
* IRQ line
*/
rtems_irq_symbolic_name name;
/*
* handler. See comment on handler properties below in function prototype.
*/
rtems_irq_hdl hdl;
/*
* function for enabling interrupts at device level (ONLY!).
* The BSP code will automatically enable it at SIU level and CPM level.
* RATIONALE : anyway such code has to exist in current driver code.
* It is usually called immediately AFTER connecting the interrupt handler.
* RTEMS may well need such a function when restoring normal interrupt
* processing after a debug session.
*
*/
rtems_irq_enable on;
/*
* function for disabling interrupts at device level (ONLY!).
* The code will disable it at SIU and CPM level. RATIONALE : anyway
* such code has to exist for clean shutdown. It is usually called
* BEFORE disconnecting the interrupt. RTEMS may well need such
* a function when disabling normal interrupt processing for
* a debug session. May well be a NOP function.
*/
rtems_irq_disable off;
/*
* function enabling to know what interrupt may currently occur
* if someone manipulates the i8259s interrupt mask without care...
*/
rtems_irq_is_enabled isOn;
} rtems_irq_connect_data;
typedef struct {
/*
* size of all the table fields (*Tbl) described below.
*/
unsigned int irqNb;
/*
* Default handler used when disconnecting interrupts.
*/
rtems_irq_connect_data defaultEntry;
/*
* Table containing initials/current value.
*/
rtems_irq_connect_data* irqHdlTbl;
/*
* actual value of BSP_SIU_IRQ_VECTOR_BASE...
*/
rtems_irq_symbolic_name irqBase;
/*
* software priorities associated with interrupts.
* if irqPrio [i] > intrPrio [j] it means that
* interrupt handler hdl connected for interrupt name i
* will not be interrupted by the handler connected for interrupt j
* The interrupt source will be physically masked at i8259 level.
*/
rtems_irq_prio* irqPrioTbl;
}rtems_irq_global_settings;
/*-------------------------------------------------------------------------+
| Function Prototypes.
+--------------------------------------------------------------------------*/
/*
* ------------------------ PPC CPM Mngt Routines -------
*/
/*
* function to disable a particular irq. After calling
* this function, even if the device asserts the interrupt line it will
* not be propagated further to the processor
*/
int BSP_irq_disable_at_cpm (const rtems_irq_symbolic_name irqLine);
/*
* function to enable a particular irq. After calling
* this function, if the device asserts the interrupt line it will
* be propagated further to the processor
*/
int BSP_irq_enable_at_cpm (const rtems_irq_symbolic_name irqLine);
/*
* function to acknoledge a particular irq. After calling
* this function, if a device asserts an enabled interrupt line it will
* be propagated further to the processor. Mainly usefull for people
* writting raw handlers as this is automagically done for rtems managed
* handlers.
*/
int BSP_irq_ack_at_cpm (const rtems_irq_symbolic_name irqLine);
/*
* function to check if a particular irq is enabled. After calling
*/
int BSP_irq_enabled_at_cpm (const rtems_irq_symbolic_name irqLine);
/*
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
*/
/*
* function to connect a particular irq handler. This hanlder will NOT be called
* directly as the result of the corresponding interrupt. Instead, a RTEMS
* irq prologue will be called that will :
*
* 1) save the C scratch registers,
* 2) switch to a interrupt stack if the interrupt is not nested,
* 4) modify them to disable the current interrupt at SIU level (and may
* be others depending on software priorities)
* 5) aknowledge the SIU',
* 6) demask the processor,
* 7) call the application handler
*
* As a result the hdl function provided
*
* a) can perfectly be written is C,
* b) may also well directly call the part of the RTEMS API that can be used
* from interrupt level,
* c) It only responsible for handling the jobs that need to be done at
* the device level including (aknowledging/re-enabling the interrupt at device,
* level, getting the data,...)
*
* When returning from the function, the following will be performed by
* the RTEMS irq epilogue :
*
* 1) masks the interrupts again,
* 2) restore the original SIU interrupt masks
* 3) switch back on the orinal stack if needed,
* 4) perform rescheduling when necessary,
* 5) restore the C scratch registers...
* 6) restore initial execution flow
*
*/
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
/*
* function to get the current RTEMS irq handler for ptr->name. It enables to
* define hanlder chain...
*/
int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
/*
* function to get disconnect the RTEMS irq handler for ptr->name.
* This function checks that the value given is the current one for safety reason.
* The user can use the previous function to get it.
*/
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
/*
* ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
*/
/*
* (Re) Initialize the RTEMS interrupt management.
*
* The result of calling this function will be the same as if each individual
* handler (config->irqHdlTbl[i].hdl) different from "config->defaultEntry.hdl"
* has been individualy connected via
* BSP_install_rtems_irq_handler(&config->irqHdlTbl[i])
* And each handler currently equal to config->defaultEntry.hdl
* has been previously disconnected via
* BSP_remove_rtems_irq_handler (&config->irqHdlTbl[i])
*
* This is to say that all information given will be used and not just
* only the space.
*
* CAUTION : the various table address contained in config will be used
* directly by the interrupt mangement code in order to save
* data size so they must stay valid after the call => they should
* not be modified or declared on a stack.
*/
int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config);
/*
* (Re) get info on current RTEMS interrupt management.
*/
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings**);
extern void BSP_rtems_irq_mng_init(unsigned cpuId);
#endif
#endif

View File

@@ -0,0 +1,339 @@
/*
* This file contains the assembly code for the PowerPC
* IRQ veneers for RTEMS.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* Modified to support the MCP750.
* Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
*
*
* $Id$
*/
#include <bsp/vectors.h>
#include <libcpu/cpu.h>
#include <libcpu/raw_exception.h>
#include <rtems/score/cpuopts.h> /* for PPC_HAS_FPU */
#include "asm.h"
#define SYNC \
sync; \
isync
.text
.p2align 5
PUBLIC_VAR(decrementer_exception_vector_prolog_code)
SYM (decrementer_exception_vector_prolog_code):
/*
* let room for exception frame
*/
stwu r1, - (EXCEPTION_FRAME_END)(r1)
stw r4, GPR4_OFFSET(r1)
li r4, ASM_DEC_VECTOR
ba shared_raw_irq_code_entry
PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
PUBLIC_VAR(external_exception_vector_prolog_code)
SYM (external_exception_vector_prolog_code):
/*
* let room for exception frame
*/
stwu r1, - (EXCEPTION_FRAME_END)(r1)
stw r4, GPR4_OFFSET(r1)
li r4, ASM_EXT_VECTOR
ba shared_raw_irq_code_entry
PUBLIC_VAR (external_exception_vector_prolog_code_size)
external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
PUBLIC_VAR(shared_raw_irq_code_entry)
PUBLIC_VAR(C_dispatch_irq_handler)
.p2align 5
SYM (shared_raw_irq_code_entry):
/*
* Entry conditions :
* Registers already saved : R1, R4
* R1 : points to a location with enough room for the
* interrupt frame
* R4 : vector number
*/
/*
* Save SRR0/SRR1 As soon As possible as it is the minimal needed
* to reenable exception processing
*/
stw r0, GPR0_OFFSET(r1)
stw r2, GPR2_OFFSET(r1)
stw r3, GPR3_OFFSET(r1)
mfsrr0 r0
mfsrr1 r2
mfmsr r3
stw r0, SRR0_FRAME_OFFSET(r1)
stw r2, SRR1_FRAME_OFFSET(r1)
/*
* Enable data and instruction address translation, exception recovery
*
* also, on CPUs with FP, enable FP so that FP context can be
* saved and restored (using FP instructions)
*/
#if (PPC_HAS_FPU == 0)
ori r3, r3, MSR_RI /*| MSR_IR | MSR_DR*/
#else
ori r3, r3, MSR_RI | /*MSR_IR | MSR_DR |*/ MSR_FP
#endif
mtmsr r3
SYNC
/*
* Push C scratch registers on the current stack. It may
* actually be the thread stack or the interrupt stack.
* Anyway we have to make it in order to be able to call C/C++
* functions. Depending on the nesting interrupt level, we will
* switch to the right stack later.
*/
stw r5, GPR5_OFFSET(r1)
stw r6, GPR6_OFFSET(r1)
stw r7, GPR7_OFFSET(r1)
stw r8, GPR8_OFFSET(r1)
stw r9, GPR9_OFFSET(r1)
stw r10, GPR10_OFFSET(r1)
stw r11, GPR11_OFFSET(r1)
stw r12, GPR12_OFFSET(r1)
stw r13, GPR13_OFFSET(r1)
mfcr r5
mfctr r6
mfxer r7
mflr r8
stw r5, EXC_CR_OFFSET(r1)
stw r6, EXC_CTR_OFFSET(r1)
stw r7, EXC_XER_OFFSET(r1)
stw r8, EXC_LR_OFFSET(r1)
/*
* Add some non volatile registers to store information
* that will be used when returning from C handler
*/
stw r14, GPR14_OFFSET(r1)
stw r15, GPR15_OFFSET(r1)
/*
* save current stack pointer location in R14
*/
addi r14, r1, 0
/*
* store part of _Thread_Dispatch_disable_level address in R15
*/
addis r15,0, _Thread_Dispatch_disable_level@ha
/*
* Get current nesting level in R2
*/
mfspr r2, SPRG0
/*
* Check if stack switch is necessary
*/
cmpwi r2,0
bne nested
mfspr r1, SPRG1
nested:
/*
* Start Incrementing nesting level in R2
*/
addi r2,r2,1
/*
* Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
*/
lwz r6,_Thread_Dispatch_disable_level@l(r15)
/*
* store new nesting level in SPRG0
*/
mtspr SPRG0, r2
addi r6, r6, 1
mfmsr r5
/*
* store new _Thread_Dispatch_disable_level value
*/
stw r6, _Thread_Dispatch_disable_level@l(r15)
/*
* We are now running on the interrupt stack. External and decrementer
* exceptions are still disabled. I see no purpose trying to optimize
* further assembler code.
*/
/*
* Call C exception handler for decrementer Interrupt frame is passed just
* in case...
*/
addi r3, r14, 0x8
bl C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
/*
* start decrementing nesting level. Note : do not test result against 0
* value as an easy exit condition because if interrupt nesting level > 1
* then _Thread_Dispatch_disable_level > 1
*/
mfspr r2, SPRG0
/*
* start decrementing _Thread_Dispatch_disable_level
*/
lwz r3,_Thread_Dispatch_disable_level@l(r15)
addi r2, r2, -1 /* Continue decrementing nesting level */
addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */
mtspr SPRG0, r2 /* End decrementing nesting level */
stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
cmpwi r3, 0
/*
* switch back to original stack (done here just optimize registers
* contention. Could have been done before...)
*/
addi r1, r14, 0
bne easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
/*
* Here we are running again on the thread system stack.
* We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
* Interrupt are still disabled. Time to check if scheduler request to
* do something with the current thread...
*/
addis r4, 0, _Context_Switch_necessary@ha
lwz r5, _Context_Switch_necessary@l(r4)
cmpwi r5, 0
bne switch
addis r6, 0, _ISR_Signals_to_thread_executing@ha
lwz r7, _ISR_Signals_to_thread_executing@l(r6)
cmpwi r7, 0
li r8, 0
beq easy_exit
stw r8, _ISR_Signals_to_thread_executing@l(r6)
/*
* going to call _ThreadProcessSignalsFromIrq
* Push a complete exception like frame...
*/
stmw r16, GPR16_OFFSET(r1)
addi r3, r1, 0x8
/*
* compute SP at exception entry
*/
addi r2, r1, EXCEPTION_FRAME_END
/*
* store it at the right place
*/
stw r2, GPR1_OFFSET(r1)
/*
* Call High Level signal handling code
*/
bl _ThreadProcessSignalsFromIrq
/*
* start restoring exception like frame
*/
lwz r31, EXC_CTR_OFFSET(r1)
lwz r30, EXC_XER_OFFSET(r1)
lwz r29, EXC_CR_OFFSET(r1)
lwz r28, EXC_LR_OFFSET(r1)
mtctr r31
mtxer r30
mtcr r29
mtlr r28
lmw r4, GPR4_OFFSET(r1)
lwz r2, GPR2_OFFSET(r1)
lwz r0, GPR0_OFFSET(r1)
/*
* Disable data and instruction translation. Make path non recoverable...
*/
mfmsr r3
xori r3, r3, MSR_RI /*| MSR_IR | MSR_DR*/
mtmsr r3
SYNC
/*
* Restore rfi related settings
*/
lwz r3, SRR1_FRAME_OFFSET(r1)
mtsrr1 r3
lwz r3, SRR0_FRAME_OFFSET(r1)
mtsrr0 r3
lwz r3, GPR3_OFFSET(r1)
addi r1,r1, EXCEPTION_FRAME_END
SYNC
rfi
switch:
bl SYM (_Thread_Dispatch)
easy_exit:
/*
* start restoring interrupt frame
*/
lwz r3, EXC_CTR_OFFSET(r1)
lwz r4, EXC_XER_OFFSET(r1)
lwz r5, EXC_CR_OFFSET(r1)
lwz r6, EXC_LR_OFFSET(r1)
mtctr r3
mtxer r4
mtcr r5
mtlr r6
lwz r15, GPR15_OFFSET(r1)
lwz r14, GPR14_OFFSET(r1)
lwz r13, GPR13_OFFSET(r1)
lwz r12, GPR12_OFFSET(r1)
lwz r11, GPR11_OFFSET(r1)
lwz r10, GPR10_OFFSET(r1)
lwz r9, GPR9_OFFSET(r1)
lwz r8, GPR8_OFFSET(r1)
lwz r7, GPR7_OFFSET(r1)
lwz r6, GPR6_OFFSET(r1)
lwz r5, GPR5_OFFSET(r1)
/*
* Disable nested exception processing, data and instruction
* translation.
*/
mfmsr r3
xori r3, r3, MSR_RI /*| MSR_IR | MSR_DR*/
mtmsr r3
SYNC
/*
* Restore rfi related settings
*/
lwz r4, SRR1_FRAME_OFFSET(r1)
lwz r2, SRR0_FRAME_OFFSET(r1)
lwz r3, GPR3_OFFSET(r1)
lwz r0, GPR0_OFFSET(r1)
mtsrr1 r4
mtsrr0 r2
lwz r4, GPR4_OFFSET(r1)
lwz r2, GPR2_OFFSET(r1)
addi r1,r1, EXCEPTION_FRAME_END
SYNC
rfi

View File

@@ -0,0 +1,150 @@
/* irq_init.c
*
* This file contains the implementation of rtems initialization
* related to interrupt handling.
*
* CopyRight (C) 2001 valette@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp/irq.h>
#include <bsp.h>
#include <bspIo.h>
#include <libcpu/raw_exception.h>
/*
#include <bsp/8xx_immap.h>
#include <bsp/mbx.h>
#include <bsp/commproc.h>
*/
extern unsigned int external_exception_vector_prolog_code_size;
extern void external_exception_vector_prolog_code();
extern unsigned int decrementer_exception_vector_prolog_code_size;
extern void decrementer_exception_vector_prolog_code();
extern void BSP_panic(char *s);
extern void _BSP_Fatal_error(unsigned int v);
/*
volatile unsigned int ppc_cached_irq_mask;
*/
/*
* default on/off function
*/
static void nop_func(){}
/*
* default isOn function
*/
static int not_connected() {return 0;}
/*
* default possible isOn function
*/
static int connected() {return 1;}
static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER];
static rtems_irq_global_settings initial_config;
static rtems_irq_connect_data defaultIrq = {
/* vectorIdex, hdl , on , off , isOn */
0, nop_func , nop_func , nop_func , not_connected
};
static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
/*
* actual priorities for interrupt :
*/
/*
* CPM Interrupts
*/
0, 45, 63, 44, 66, 68, 35, 39, 50, 62, 34, 0, 30, 40, 52, 58,
2, 3, 0, 5, 15, 16, 17, 18, 49, 51, 0, 0, 0, 0, 0, 0,
6, 7, 8, 0, 11, 12, 0, 0, 20, 21, 22, 23, 0, 0, 0, 0,
29, 31, 33, 37, 38, 41, 47, 48, 55, 56, 57, 60, 64, 65, 69, 70,
/*
* Processor exceptions handled as interrupts
*/
0
};
/*
* Initialize CPM interrupt management
*/
void
BSP_CPM_irq_init(void)
{
m8260.simr_l = 0;
m8260.simr_h = 0;
m8260.sipnr_l = 0xffffffff;
m8260.sipnr_h = 0xffffffff;
m8260.sicr = 0;
/*
* Initialize the interrupt priorities.
*/
m8260.siprr = 0x05309770; /* reset value */
m8260.scprr_h = 0x05309770; /* reset value */
m8260.scprr_l = 0x05309770; /* reset value */
}
void BSP_rtems_irq_mng_init(unsigned cpuId)
{
rtems_raw_except_connect_data vectorDesc;
int i;
BSP_CPM_irq_init();
/*
* Initialize Rtems management interrupt table
*/
/*
* re-init the rtemsIrq table
*/
for (i = 0; i < BSP_IRQ_NUMBER; i++) {
rtemsIrq[i] = defaultIrq;
rtemsIrq[i].name = i;
}
/*
* Init initial Interrupt management config
*/
initial_config.irqNb = BSP_IRQ_NUMBER;
initial_config.defaultEntry = defaultIrq;
initial_config.irqHdlTbl = rtemsIrq;
initial_config.irqBase = BSP_ASM_IRQ_VECTOR_BASE;
initial_config.irqPrioTbl = irqPrioTable;
if (!BSP_rtems_irq_mngt_set(&initial_config)) {
/*
* put something here that will show the failure...
*/
BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
}
/*
* We must connect the raw irq handler for the two
* expected interrupt sources : decrementer and external interrupts.
*/
vectorDesc.exceptIndex = ASM_DEC_VECTOR;
vectorDesc.hdl.vector = ASM_DEC_VECTOR;
vectorDesc.hdl.raw_hdl = decrementer_exception_vector_prolog_code;
vectorDesc.hdl.raw_hdl_size = (unsigned) &decrementer_exception_vector_prolog_code_size;
vectorDesc.on = nop_func;
vectorDesc.off = nop_func;
vectorDesc.isOn = connected;
if (!mpc8xx_set_exception (&vectorDesc)) {
BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
}
vectorDesc.exceptIndex = ASM_EXT_VECTOR;
vectorDesc.hdl.vector = ASM_EXT_VECTOR;
vectorDesc.hdl.raw_hdl = external_exception_vector_prolog_code;
vectorDesc.hdl.raw_hdl_size = (unsigned) &external_exception_vector_prolog_code_size;
if (!mpc8xx_set_exception (&vectorDesc)) {
BSP_panic("Unable to initialize RTEMS external raw exception\n");
}
#ifdef TRACE_IRQ_INIT
printk("RTEMS IRQ management is now operationnal\n");
#endif
}

View File

@@ -0,0 +1,37 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/network.rel
C_FILES = network.c if_hdlcsubr.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
AM_CPPFLAGS += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
$(PGM): $(OBJS)
$(make-rel)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
if HAS_NETWORKING
all-local: $(ARCH) $(OBJS) $(PGM)
endif
.PRECIOUS: $(PGM)
EXTRA_DIST = network.c
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,55 @@
Networking with HDLC
====================
Author: Andy Dachs <a.dachs@sstl.co.uk>
Date: 31st August 2001
Surrey Satellite Technology Limited
The network support in this BSP is not Ethernet support. The
"network" referred to here is a point to point HDLC communication link.
The ADS board does have a 10/100 ethernet port and it would be nice to
get support for that added.
My requirement is for a WAN so I need the ability to send IP frames over
HDLC. Ultimately this will end up as frame relay support but in the meantime
I'm simply wrapping up the IP packet inside an HDLC frame. There is no
addressing mechanism or mac address attached to the start of the frame.
This is what is physically transmitted:
<FLAG><IP Frame><CRC><FLAG>
The physical link consists of four lines,
TX DATA : Data transmitted
TX CLOCK: Clock for transmitted data. Data source provides clock.
RX DATA : Received data
RX CLOCK: Clock for received data. Data sink accepts clock.
To connect two entities you require a NULL modem arrangement, i.e. TX data
and Tx clock from one end go into RX data and Rx clock on the other end.
The MPC8260ADS side of the link is implemented using SCC3 in HDLC mode. The
TX clock is generated by BRG4. The RX clock in input to the board on the CLK5
input. I built a LVTTL to RS422 converter.
The other end of the link is a Windows NT PC with WANic400 synchronous
communication card. We bought the card from ImageStream
(http://www.imagestream.com/WANic400.html). You also need the NT
drivers and a cable. There are other distributors but I found these
guys helpful - and they also do Linux drivers.
The NT WANic driver has a number of modes, one of which is ethernet emulation.
This mode is what is needed to transport IP packets in HDLC frames.
In libnetworking/net you will find a file called if_hdlcsubr.c containing
the hdlc_input and hdlc_output routines required by network.c. This file was
created by taking out the addressing mechanisms from if_ethersubr.c in the
same directory. There are probably neater ways to do this <any
contributions welcome here>.

View File

@@ -0,0 +1,346 @@
/*
* Created from if_ethersubr.c by Andy Dachs <a.dachs@sstl.co.uk>
* Surrey Satellite Technology Limited (SSTL), 2001
* Modified (hacked) to support IP frames transmitted over HDLC. This
* all needs tidying up in future but it does actually work for point
* to point communications. I have an SDL WANic400 synchronous
* communications card that comes with Windows NT drivers. The drivers
* support a mode that they call "Ethernet Emulation". That simply
* puts the IP frame in an HDLC frame without any ethernet header. i.e.
* <HDLC Flag><IpFrame><CRC><HDLC Flag>. There is no addressing beyond
* the IP header information so is only suitable for point to point links
* with a single protocol. "At some point" I will add a Frame Relay header
* but at the moment I have difficulties getting the WANic card driver's
* Frame Relay driver to work.
*
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
* $Id$
*/
#include <sys/param.h>
/*#include <sys/systm.h>
#include <sys/kernel.h> */
#define KERNEL
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/netisr.h>
#include <net/route.h>
#include <net/if_llc.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/if_ether.h>
#include "if_hdlcsubr.h"
/*
u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
*/
#define senderr(e) { error = (e); goto bad;}
/*
* HDLC output routine.
* Just transmit the packet (hardware adds flags and CRC)
*/
int
hdlc_output(ifp, m0, dst, rt0)
register struct ifnet *ifp;
struct mbuf *m0;
struct sockaddr *dst;
struct rtentry *rt0;
{
short type;
int s, error = 0;
u_char edst[6];
register struct mbuf *m = m0;
register struct rtentry *rt;
struct mbuf *mcopy = (struct mbuf *)0;
/* register struct ether_header *eh; */
int off, len = m->m_pkthdr.len;
/* printk( "hdlc output" ); */
/* struct arpcom *ac = (struct arpcom *)ifp; */
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
senderr(ENETDOWN);
rt = rt0;
if (rt) {
if ((rt->rt_flags & RTF_UP) == 0) {
rt0 = rt = rtalloc1(dst, 1, 0UL);
if (rt0)
rt->rt_refcnt--;
else
senderr(EHOSTUNREACH);
}
if (rt->rt_flags & RTF_GATEWAY) {
if (rt->rt_gwroute == 0)
goto lookup;
if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
rtfree(rt); rt = rt0;
lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
0UL);
if ((rt = rt->rt_gwroute) == 0)
senderr(EHOSTUNREACH);
}
}
if (rt->rt_flags & RTF_REJECT)
if (rt->rt_rmx.rmx_expire == 0 ||
rtems_bsdnet_seconds_since_boot() < rt->rt_rmx.rmx_expire)
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
}
switch (dst->sa_family) {
case AF_INET:
#if 0
if (!arpresolve(ac, rt, m, dst, edst, rt0))
return (0); /* if not yet resolved */
#endif
/* If broadcasting on a simplex interface, loopback a copy */
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
mcopy = m_copy(m, 0, (int)M_COPYALL);
off = m->m_pkthdr.len - m->m_len;
type = htons(ETHERTYPE_IP);
break;
#if 0
case AF_UNSPEC:
eh = (struct ether_header *)dst->sa_data;
(void)memcpy(edst, eh->ether_dhost, sizeof (edst));
type = eh->ether_type;
break;
#endif
default:
printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
dst->sa_family);
senderr(EAFNOSUPPORT);
}
if (mcopy)
(void) looutput(ifp, mcopy, dst, rt);
#if 0
/*
* Add local net header. If no space in first mbuf,
* allocate another.
*/
M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
#endif
if (m == 0)
senderr(ENOBUFS);
#if 0
eh = mtod(m, struct ether_header *);
(void)memcpy(&eh->ether_type, &type,
sizeof(eh->ether_type));
(void)memcpy(eh->ether_dhost, edst, sizeof (edst));
(void)memcpy(eh->ether_shost, ac->ac_enaddr,
sizeof(eh->ether_shost));
#endif
s = splimp();
/*
* Queue message on interface, and start output if interface
* not yet active.
*/
if (IF_QFULL(&ifp->if_snd)) {
IF_DROP(&ifp->if_snd);
splx(s);
senderr(ENOBUFS);
}
IF_ENQUEUE(&ifp->if_snd, m);
if ((ifp->if_flags & IFF_OACTIVE) == 0)
(*ifp->if_start)(ifp);
splx(s);
ifp->if_obytes += len /*+ sizeof (struct ether_header)*/;
if (m->m_flags & M_MCAST)
ifp->if_omcasts++;
return (error);
bad:
if (m)
m_freem(m);
return (error);
}
/*
* Process a received Ethernet packet;
* the packet is in the mbuf chain m without
* the ether header, which is provided separately.
*/
void
hdlc_input(ifp, m)
struct ifnet *ifp;
struct mbuf *m;
{
register struct ifqueue *inq;
int s;
struct ether_header eh;
if ((ifp->if_flags & IFF_UP) == 0) {
m_freem(m);
return;
}
ifp->if_ibytes += m->m_pkthdr.len;
/*
if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
sizeof(etherbroadcastaddr)) == 0)
m->m_flags |= M_BCAST;
else if (eh->ether_dhost[0] & 1)
m->m_flags |= M_MCAST;
*/
if (m->m_flags & (M_BCAST|M_MCAST))
ifp->if_imcasts++;
/*
* RTEMS addition -- allow application to `tap into'
* the incoming packet stream.
*/
if (ifp->if_tap && (*ifp->if_tap)(ifp, &eh, m)) {
m_freem(m);
return;
}
schednetisr(NETISR_IP);
inq = &ipintrq;
s = splimp();
if (IF_QFULL(inq)) {
IF_DROP(inq);
m_freem(m);
} else
IF_ENQUEUE(inq, m);
splx(s);
}
/*
* Perform common duties while attaching to interface list
*/
void
hdlc_ifattach(ifp)
register struct ifnet *ifp;
{
register struct ifaddr *ifa;
register struct sockaddr_dl *sdl;
ifp->if_type = IFT_ETHER;
ifp->if_addrlen = 0;
ifp->if_hdrlen = 0;
ifp->if_mtu = 2048;
if (ifp->if_baudrate == 0)
ifp->if_baudrate = 8000000;
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
sdl->sdl_family == AF_LINK) {
sdl->sdl_type = IFT_ETHER;
sdl->sdl_alen = ifp->if_addrlen;
/*
bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
LLADDR(sdl), ifp->if_addrlen);
*/
break;
}
}
SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
int
hdlc_ioctl(struct ifnet *ifp, int command, caddr_t data)
{
struct ifaddr *ifa = (struct ifaddr *) data;
struct ifreq *ifr = (struct ifreq *) data;
int error = 0;
switch (command) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
switch (ifa->ifa_addr->sa_family) {
#if 0
#ifdef INET
case AF_INET:
ifp->if_init(ifp->if_softc); /* before arpwhohas */
arp_ifinit((struct arpcom *)ifp, ifa);
break;
#endif
#endif
default:
ifp->if_init(ifp->if_softc);
break;
}
break;
case SIOCGIFADDR:
{
struct sockaddr *sa;
sa = (struct sockaddr *) & ifr->ifr_data;
/*
bcopy(((struct arpcom *)ifp->if_softc)->ac_enaddr,
(caddr_t) sa->sa_data, ETHER_ADDR_LEN);
*/
}
break;
case SIOCSIFMTU:
/*
* Set the interface MTU.
*/
if (ifr->ifr_mtu > ETHERMTU) {
error = EINVAL;
} else {
ifp->if_mtu = ifr->ifr_mtu;
}
break;
}
return (error);
}

View File

@@ -0,0 +1,40 @@
/*
* RTEMS/TCPIP driver for MPC8260 SCC HDLC networking
*
* Submitted by Andy Dachs <a.dachs@sstl.co.uk>
* (c) Surrey Satellite Technology Limited, 2001
*
* On the ADS board the ethernet interface is connected to FCC2
* but in my application I want TCP over HDLC (see README)
* so will use SCC3 as the network interface. I have other plans
* for the FCCs so am unlikely to add true ethernet support to
* this BSP. Contributions welcome!
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __IF_HDLCSUBR_H
#define __IF_HDLCSUBR_H
struct ifnet;
struct mbuf;
struct sockaddr;
struct rtentry;
void hdlc_ifattach __P((struct ifnet *));
void hdlc_input __P((struct ifnet *, struct mbuf *));
int hdlc_output __P((struct ifnet *,
struct mbuf *, struct sockaddr *, struct rtentry *));
int hdlc_ioctl __P((struct ifnet *, int , caddr_t ));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/start.o
S_FILES = start.S
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
OBJS = $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PROJECT_RELEASE)/lib/start$(LIB_VARIANT).o: $(PGM)
$(INSTALL_DATA) $< $@
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/start$(LIB_VARIANT).o
all-local: $(ARCH) $(OBJS) $(PGM) $(TMPINSTALL_FILES)
.PRECIOUS: $(PGM)
EXTRA_DIST = start.S
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,191 @@
/* start.S
*
* $Id$
*
* Modified for the Motorola PQII ADS board by
* Andy Dachs <a.dachs@sstl.co.uk> 23-11-00.
* Surrey Satellite Technology Limited
*
* I have a proprietary bootloader programmed into the flash
* on the board which initialises the SDRAM prior to calling
* this function.
*
* This file is based on the one by Jay Monkman (jmonkman@fracsa.com)
* which in turn was based on the dlentry.s file for the Papyrus BSP,
* written 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.
*
*/
#include "asm.h"
/*
* The initial stack is set to run BELOW the code base address.
* (between the vectors and text sections)
*
* The entry veneer has to clear the BSS and copy the read only
* version of the data segment to the correct location.
*/
.section ".entry" /* This might have to be the first thing in the
* text section. At one time, it had to be
* first, but I don't believe it is true
* any more. */
PUBLIC_VAR (start)
SYM(start):
bl .startup
base_addr:
/*
* Parameters from linker
*/
toc_pointer:
.long s.got
bss_length:
.long bss.size
bss_addr:
.long bss.start
PUBLIC_VAR (data_length )
data_length:
.long data.size
PUBLIC_VAR (data_addr )
data_addr:
.long data.start
PUBLIC_VAR (text_addr)
text_addr:
.long text.start
PUBLIC_VAR (text_length)
text_length:
.long text.size
/*
* Initialization code
*/
.startup:
/* Get start address */
mflr r1
/* --------------------------------------------------
* Clear MSR[EE] to disable interrupts
* Clear MSR[IP] bit to put vectors at 0x00000000
* Set MSR[FP] to enable FPU - not on my eval board!
* -------------------------------------------------- */
mfmsr r5
lis r13, 0xFFFF
ori r13, r13, 0x7FBF
and r5, r5, r13 /* Clear EE and IP */
#if 1
ori r5, r5, 0x2000 /* Enable FPU */
#endif
mtmsr r5
#ifdef ENABLE_CACHE
/* Enable caches */
mfspr r5, 1008
ori r5, r5, 0x8000
isync
mtspr 1008, r5
/* Leave D-cache disabled for now */
#if 0
ori r5, r5, 0x4000
sync
mtspr 1008, r5
#endif
#endif
/*--------------------------------------------------
* Set up the power management modes
* The 8260 has a dynamic power management mode that
* is automatically invoked if the unit is idle.
* We invoke the NAP mode in the RTEMS idle task.
*-------------------------------------------------- */
lis r13, 0x0050 /* set nap mode and DPM */
or r5, r5, r13
mtspr 1008, r5
/*--------------------------------------------------
*
*-------------------------------------------------- */
/* clear the bss section */
bl bssclr
/*
* C_setup.
*/
/* set toc */
lwz r2, toc_pointer-base_addr(r1)
/* Set up stack pointer = beginning of text section - 56 */
addi r1, r1, -56-4
/* clear argc and argv */
xor r3, r3, r3
xor r4, r4, r4
.extern SYM (boot_card)
bl SYM (boot_card) /* call the first C routine */
/* we don't expect to return from boot_card but if we do */
/* wait here for watchdog to kick us into hard reset */
twiddle:
b twiddle
/*
* bssclr - zero out bss
*/
bssclr:
lwz r4, bss_addr-base_addr(r1) /* Start of bss */
lwz r5, bss_length-base_addr(r1) /* Length of bss */
rlwinm. r5,r5,30,0x3FFFFFFF /* form length/4 */
beqlr /* no bss */
mtctr r5 /* set ctr reg */
xor r6,r6,r6 /* r6 = 0 */
clear_bss:
stswi r6,r4,0x4 /* store r6 */
addi r4,r4,0x4 /* update r2 */
bdnz clear_bss /* dec counter and loop */
blr /* return */

View File

@@ -0,0 +1,43 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@:@srcdir@/../../../shared
PGM = $(ARCH)/startup.rel
C_FILES = bspclean.c bsplibc.c bsppost.c bspstart.c bootcard.c \
main.c sbrk.c setvec.c gnatinstallhandler.c cpuinit.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
S_FILES =
S_O_FILES = $(S_FILES:%.s=$(ARCH)/%.o)
OBJS = $(C_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(OBJS)
$(make-rel)
$(PROJECT_RELEASE)/lib/linkcmds: linkcmds
$(INSTALL_DATA) $< $@
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/linkcmds
all-local: $(ARCH) $(OBJS) $(PGM) $(TMPINSTALL_FILES)
.PRECIOUS: $(PGM)
EXTRA_DIST = bspstart.c linkcmds setvec.c
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,370 @@
/* bsp_start()
*
* This routine starts the application. It includes application,
* board, and monitor specific initialization and configuration.
* The generic CPU dependent initialization has been performed
* before this routine is invoked.
*
* The MPC860 specific stuff was written by Jay Monkman (jmonkman@frasca.com)
*
* Modified for the MPC8260ADS board by Andy Dachs <a.dachs@sstl.co.uk>
* Surrey Satellite Technology Limited, 2001
* A 40MHz system clock is assumed.
* The PON. RST.CONF. Dip switches (DS1) are
* 1 - Off
* 2 - On
* 3 - Off
* 4 - On
* 5 - Off
* 6 - Off
* 7 - Off
* 8 - Off
* Dip switches on DS2 and DS3 are all set to ON
* The LEDs on the board are used to signal panic and fatal_error
* conditions.
* The mmu is unused at this time.
*
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp.h>
/*
#include <mmu.h>
*/
#include <mpc8260.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <rtems/score/thread.h>
#include <string.h>
#ifdef STACK_CHECKER_ON
#include <stackchk.h>
#endif
/*
* The original table from the application (in ROM) and our copy of it with
* some changes. Configuration is defined in <confdefs.h>. Make sure that
* our configuration tables are uninitialized so that they get allocated in
* the .bss section (RAM).
*/
extern rtems_configuration_table Configuration;
extern unsigned long intrStackPtr;
rtems_configuration_table BSP_Configuration;
rtems_cpu_table Cpu_table;
char *rtems_progname;
/*
* Use the shared implementations of the following routines.
* Look in rtems/c/src/lib/libbsp/shared/bsppost.c and
* rtems/c/src/lib/libbsp/shared/bsplibc.c.
*/
void bsp_postdriver_hook(void);
void bsp_libc_init( void *, unsigned32, int );
void BSP_panic(char *s)
{
_BSP_GPLED1_on();
printk("%s PANIC %s\n",_RTEMS_version, s);
__asm__ __volatile ("sc");
}
void _BSP_Fatal_error(unsigned int v)
{
_BSP_GPLED0_on();
_BSP_GPLED1_on();
printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
__asm__ __volatile ("sc");
}
void _BSP_GPLED0_on()
{
BCSR *csr;
csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
csr->bcsr0 &= ~GP0_LED; /* Turn on GP0 LED */
}
void _BSP_GPLED0_off()
{
BCSR *csr;
csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
csr->bcsr0 |= GP0_LED; /* Turn off GP0 LED */
}
void _BSP_GPLED1_on()
{
BCSR *csr;
csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
csr->bcsr0 &= ~GP1_LED; /* Turn on GP1 LED */
}
void _BSP_GPLED1_off()
{
BCSR *csr;
csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
csr->bcsr0 |= GP1_LED; /* Turn off GP1 LED */
}
void _BSP_Uart1_enable()
{
BCSR *csr;
csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
csr->bcsr1 &= ~UART1_E; /* Enable Uart1 */
}
void _BSP_Uart1_disable()
{
BCSR *csr;
csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
csr->bcsr1 |= UART1_E; /* Disable Uart1 */
}
void _BSP_Uart2_enable()
{
BCSR *csr;
csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
csr->bcsr1 &= ~UART2_E; /* Enable Uart2 */
}
void _BSP_Uart2_disable()
{
BCSR *csr;
csr = (BCSR *)(m8260.memc[1].br & 0xFFFF8000);
csr->bcsr1 |= UART2_E; /* Disable Uart2 */
}
extern void m8260_console_reserve_resources(rtems_configuration_table *);
/*
* Function: bsp_pretasking_hook
* Created: 95/03/10
*
* Description:
* BSP pretasking hook. Called just before drivers are initialized.
* Used to setup libc and install any BSP extensions.
*
* NOTES:
* Must not use libc (to do io) from here, since drivers are
* not yet initialized.
*
*/
void
bsp_pretasking_hook(void)
{
/*
* These are assigned addresses in the linkcmds file for the BSP. This
* approach is better than having these defined as manifest constants and
* compiled into the kernel, but it is still not ideal when dealing with
* multiprocessor configuration in which each board as a different memory
* map. A better place for defining these symbols might be the makefiles.
* Consideration should also be given to developing an approach in which
* the kernel and the application can be linked and burned into ROM
* independently of each other.
*/
extern unsigned char _HeapStart;
extern unsigned char _HeapEnd;
bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 );
#ifdef STACK_CHECKER_ON
/*
* Initialize the stack bounds checker
* We can either turn it on here or from the app.
*/
Stack_check_Initialize();
#endif
#ifdef RTEMS_DEBUG
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
#endif
}
void bsp_start(void)
{
extern void *_WorkspaceBase;
extern int _end;
rtems_unsigned32 heap_start;
rtems_unsigned32 ws_start;
ppc_cpu_id_t myCpu;
ppc_cpu_revision_t myCpuRevision;
register unsigned char* intrStack;
register unsigned int intrNestingLevel = 0;
/* Set MPC8260ADS board LEDS and Uart enable lines */
_BSP_GPLED0_off();
_BSP_GPLED1_off();
_BSP_Uart1_enable();
_BSP_Uart2_enable();
/*
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
* store the result in global variables so that it can be used latter...
*/
myCpu = get_ppc_cpu_type();
myCpuRevision = get_ppc_cpu_revision();
cpu_init();
/*
mmu_init();
*/
/*
* Initialize some SPRG registers related to irq handling
*/
intrStack = (((unsigned char*)&intrStackPtr) - CPU_MINIMUM_STACK_FRAME_SIZE);
asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack));
asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel));
/*
printk( "About to call initialize_exceptions\n" );
*/
/*
* Install our own set of exception vectors
*/
initialize_exceptions();
/*
mmu_init();
*/
/*
* Enable instruction and data caches. Do not force writethrough mode.
*/
#if INSTRUCTION_CACHE_ENABLE
rtems_cache_enable_instruction();
#endif
#if DATA_CACHE_ENABLE
rtems_cache_enable_data();
#endif
/*
* Allocate the memory for the RTEMS Work Space. This can come from
* a variety of places: hard coded address, malloc'ed from outside
* RTEMS world (e.g. simulator or primitive memory manager), or (as
* typically done by stock BSPs) by subtracting the required amount
* of work space from the last physical address on the CPU board.
*/
/*
* Need to "allocate" the memory for the RTEMS Workspace and
* tell the RTEMS configuration where it is. This memory is
* not malloc'ed. It is just "pulled from the air".
*/
BSP_Configuration.work_space_start = (void *)&_WorkspaceBase;
/*
BSP_Configuration.microseconds_per_tick = 1000;
*/
/*
* initialize the CPU table for this BSP
*/
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
Cpu_table.postdriver_hook = bsp_postdriver_hook;
if( Cpu_table.interrupt_stack_size < 4*1024 )
Cpu_table.interrupt_stack_size = 4 * 1024;
Cpu_table.clicks_per_usec = 10; /* for 40MHz extclk */
Cpu_table.serial_per_sec = 40000000;
Cpu_table.serial_external_clock = 0;
Cpu_table.serial_xon_xoff = 0;
Cpu_table.serial_cts_rts = 0;
Cpu_table.serial_rate = 9600;
Cpu_table.timer_average_overhead = 3;
Cpu_table.timer_least_valid = 3;
Cpu_table.clock_speed = 40000000;
#ifdef REV_0_2
/* set up some board specific registers */
m8260.siumcr &= 0xF3FFFFFF; /* set TBEN ** BUG FIX ** */
m8260.siumcr |= 0x08000000;
#endif
/* use BRG1 to generate 32kHz timebase */
/*
m8260.brgc1 = M8260_BRG_EN + (unsigned32)(((unsigned16)((40016384)/(32768)) - 1) << 1) + 0;
*/
/*
* Initalize RTEMS IRQ system
*/
BSP_rtems_irq_mng_init(0);
/*
* Call this in case we use TERMIOS for console I/O
*/
m8xx_uart_reserve_resources(&BSP_Configuration);
/*
rtems_termios_initialize();
*/
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Exit from bspstart\n");
#endif
}
/*
*
* _Thread_Idle_body
*
* Replaces the one in c/src/exec/score/src/threadidlebody.c
* The MSR[POW] bit is set to put the CPU into the low power mode
* defined in HID0. HID0 is set during starup in start.S.
*
*/
Thread _Thread_Idle_body(
unsigned32 ignored )
{
for( ; ; )
{
asm volatile(
"mfmsr 3; oris 3,3,4; sync; mtmsr 3; isync; ori 3,3,0; ori 3,3,0"
);
}
}

View File

@@ -0,0 +1,51 @@
/*
* cpuinit.c - this file contains functions for initializing the CPU
*
* Written by Jay Monkman (jmonkman@frasca.com)
*
* $Id$
*/
#include <bsp.h>
/* Macros for handling all the MMU SPRs */
#define PUT_IC_CST(r) __asm__ volatile ("mtspr 0x230,%0\n" ::"r"(r))
#define GET_IC_CST(r) __asm__ volatile ("mfspr %0,0x230\n" :"=r"(r))
#define PUT_DC_CST(r) __asm__ volatile ("mtspr 0x238,%0\n" ::"r"(r))
#define GET_DC_CST(r) __asm__ volatile ("mfspr %0,0x238\n" :"=r"(r))
void cpu_init(void)
{
/* BRGCLK is VCO_OUT/4 */
/*
m8260.sccr = 0;
*/
#if 0
register unsigned long t1, t2;
/* Let's clear MSR[IR] and MSR[DR] */
t2 = PPC_MSR_IR | PPC_MSR_DR;
__asm__ volatile (
"mfmsr %0\n"
"andc %0, %0, %1\n"
"mtmsr %0\n" :"=r"(t1), "=r"(t2):
"1"(t2));
t1 = M8xx_CACHE_CMD_UNLOCK;
/* PUT_DC_CST(t1); */
PUT_IC_CST(t1);
t1 = M8xx_CACHE_CMD_INVALIDATE;
/* PUT_DC_CST(t1); */
PUT_IC_CST(t1);
t1 = M8xx_CACHE_CMD_ENABLE;
PUT_IC_CST(t1);
t1 = M8xx_CACHE_CMD_SFWT;
/* PUT_DC_CST(t1); */
t1 = M8xx_CACHE_CMD_ENABLE;
/* PUT_DC_CST(t1);*/
#endif
}

View File

@@ -0,0 +1,285 @@
/*
* This file contains directives for the GNU linker which are specific
* to the MPC8260ADS Board
*
* $Id$
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
"elf32-powerpc")
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/usr/local/rtems/powerpc-rtems/lib);
ENTRY(start)
/*
* Declare some sizes.
* XXX: The assignment of ". += XyzSize;" fails in older gld's if the
* number used there is not constant. If this happens to you, edit
* the lines marked XXX below to use a constant value.
*/
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x400000; /* 4M Heap */
StackSize = DEFINED(StackSize) ? StackSize : 0x8000;
WorkSpaceSize = DEFINED(WorkSpaceSize) ? WorkSpaceSize : 0x80000; /* 512k */
RamDiskSize = DEFINED(RamDiskSize) ? RamDiskSize : 0x0800000; /* 8M ram disk */
MEMORY
{
ram : org = 0x0, l = 16M
dpram : org = 0x04700000, l = 128K
flash : org = 0xff800000, l = 8M
}
SECTIONS
{
/*
* The stack will live in this area - between the vectors and
* the text section.
*/
.text 0x10000:
{
_textbase = .;
text.start = .;
/* Entry point is the .entry section */
*(.entry)
*(.entry2)
/* Actual Code */
*(.text)
*(.text.*)
*(.rodata)
*(.rodata1)
/* C++ constructors/destructors */
*(.gnu.linkonce.t*)
/* Initialization and finalization code.
*
* Various files can provide initialization and finalization functions.
* The bodies of these functions are in .init and .fini sections. We
* accumulate the bodies here, and prepend function prologues from
* ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
* first; ecrtn.o must be linked last. Because these are wildcards, it
* doesn't matter if the user does not actually link against ecrti.o and
* ecrtn.o; the linker won't look for a file to match a wildcard. The
* wildcard also means that it doesn't matter which directory ecrti.o
* and ecrtn.o are in.
*/
PROVIDE (_init = .);
*ecrti.o(.init)
*(.init)
*ecrtn.o(.init)
PROVIDE (_fini = .);
*ecrti.o(.fini)
*(.fini)
*ecrtn.o(.init)
/*
* C++ constructors and destructors for static objects.
* PowerPC EABI does not use crtstuff yet, so we build "old-style"
* constructor and destructor lists that begin with the list lenght
* end terminate with a NULL entry.
*/
PROVIDE (__CTOR_LIST__ = .);
/* LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) */
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
LONG(0)
PROVIDE (__CTOR_END__ = .);
PROVIDE (__DTOR_LIST__ = .);
/* LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) */
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
LONG(0)
PROVIDE (__DTOR_END__ = .);
/* Exception frame info */
*(.eh_frame)
/* Miscellaneous read-only data */
_rodata_start = . ;
*(.gnu.linkonce.r*)
*(.lit)
*(.shdata)
*(.rodata)
*(.rodata1)
*(.descriptors)
*(rom_ver)
_erodata = .;
/* Various possible names for the end of the .text section */
etext = ALIGN(0x10);
_etext = .;
_endtext = .;
text.end = .;
PROVIDE (etext = .);
PROVIDE (__etext = .);
} > ram
PROVIDE (__EXCEPT_START__ = .);
.gcc_except_table : { *(.gcc_except_table) } >RAM
PROVIDE (__EXCEPT_END__ = .);
__GOT_START__ = .;
.got :
{
s.got = .;
*(.got.plt) *(.got)
} > ram
__GOT_END__ = .;
.got1 : { *(.got1) } >ram
PROVIDE (__GOT2_START__ = .);
PROVIDE (_GOT2_START_ = .);
.got2 : { *(.got2) } >ram
PROVIDE (__GOT2_END__ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (__FIXUP_START__ = .);
PROVIDE (_FIXUP_START_ = .);
.fixup : { *(.fixup) } >ram
PROVIDE (_FIXUP_END_ = .);
PROVIDE (__FIXUP_END__ = .);
PROVIDE (__SDATA2_START__ = .);
.sdata2 : { *(.sdata2) } >ram
.sbss2 : { *(.sbss2) } >ram
PROVIDE (__SBSS2_END__ = .);
.sbss2 : { *(.sbss2) } >ram
PROVIDE (__SBSS2_END__ = .);
__SBSS_START__ = .;
.bss :
{
bss.start = .;
*(.bss) *(.sbss) *(COMMON)
. = ALIGN(4);
bss.end = .;
} > ram
__SBSS_END__ = .;
/* R/W Data */
.data ( . ) :
{
. = ALIGN (4);
data.start = .;
*(.data)
*(.data1)
*(.gnu.linkonce.d.*)
PROVIDE (__SDATA_START__ = .);
*(.sdata)
data.end = .;
} > ram
data.size = data.end - data.start;
bss.size = bss.end - bss.start;
text.size = text.end - text.start;
PROVIDE(_end = data.end);
.gzipmalloc : {
. = ALIGN (16);
_startmalloc = .;
} >ram
/*
* Interrupt stack setup
*/
IntrStack_start = ALIGN(0x10);
. += 0x4000;
intrStack = .;
PROVIDE(intrStackPtr = intrStack);
_HeapStart = .;
__HeapStart = .;
. += HeapSize;
_HeapEnd = .;
__HeapEnd = .;
clear_end = .;
_WorkspaceBase = .;
__WorkspaceBase = .;
. += WorkSpaceSize;
_RamDiskBase = .;
__RamDiskBase = .;
. += RamDiskSize;
_RamDiskEnd = .;
__RamDiskEnd = .;
PROVIDE( _RamDiskSize = _RamDiskEnd - _RamDiskBase );
/* Sections for compressed .text and .data */
/* after the .datarom section is an int specifying */
/* the length of the following compressed image */
/* Executes once then could get overwritten */
.textrom 0x100000 :
{
*(.textrom)
_endloader = .;
} > ram
.datarom :
{
_dr_start = .;
*(.datarom)
_dr_end = .;
} > ram
dr_len = _dr_end - _dr_start;
.dpram :
{
m8260 = .;
_m8260 = .;
. += (128 * 1024);
} > dpram
/* the reset vector is at 0xfff00000 which is */
/* located at offset 0x400000 from the base */
/* of flash */
.bootrom 0xFFF00000 :
{
*(.bootrom)
_endboot = .;
} > flash
.line 0 : { *(.line) }
.debug 0 : { *(.debug) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_aregion 0 : { *(.debug_aregion) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
}

View File

@@ -0,0 +1,43 @@
/* set_vector
*
* This routine installs an interrupt vector on the target Board/CPU.
* This routine is allowed to be as board dependent as necessary.
*
* INPUT:
* handler - interrupt handler entry point
* vector - vector number
* type - 0 indicates raw hardware connect
* 1 indicates RTEMS interrupt connect
*
* RETURNS:
* address of previous interrupt handler
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
rtems_isr_entry set_vector( /* returns old vector */
rtems_isr_entry handler, /* isr routine */
rtems_vector_number vector, /* vector number */
int type /* RTEMS or RAW intr */
)
{
rtems_isr_entry previous_isr;
if (type) {
rtems_interrupt_catch(handler, vector, (rtems_isr_entry *) &previous_isr );
} else {
/* XXX: install non-RTEMS ISR as "raw" interupt */
}
return previous_isr;
}

View File

@@ -0,0 +1,196 @@
#
# Timing Test Suite Results for the mpc8260ads BSP
#
#
# $Id$
#
# Testing not complete.
# DO NOT BELIEVE THESE RESULTS
Board: mpc8260ads
CPU: Motorola MPC8260
Clock Speed: 40 Mhz
Memory Configuration: SDRAM, no caches
Wait States:
Times Reported in: cycles, microseconds, etc
Timer Source: Time Base register
Column X:
Column Y:
# DESCRIPTION A B
== ================================================================= ==== ====
1 rtems_semaphore_create 56
rtems_semaphore_delete 35
rtems_semaphore_obtain: available 13
rtems_semaphore_obtain: not available -- NO_WAIT 13
rtems_semaphore_release: no waiting tasks 16
2 rtems_semaphore_obtain: not available -- caller blocks 48
3 rtems_semaphore_release: task readied -- preempts caller 36
4 rtems_task_restart: blocked task -- preempts caller 117
rtems_task_restart: ready task -- preempts caller 94
rtems_semaphore_release: task readied -- returns to caller 22
rtems_task_create 83
rtems_task_start 30
rtems_task_restart: suspended task -- returns to caller 36
rtems_task_delete: suspended task 74
rtems_task_restart: ready task -- returns to caller 35
rtems_task_restart: blocked task -- returns to caller 47
rtems_task_delete: blocked task 76
5 rtems_task_suspend: calling task 37
rtems_task_resume: task readied -- preempts caller 31
6 rtems_task_restart: calling task 48
rtems_task_suspend: returns to caller 14
rtems_task_resume: task readied -- returns to caller 16
rtems_task_delete: ready task 80
7 rtems_task_restart: suspended task -- preempts caller 56
8 rtems_task_set_priority: obtain current priority 12
rtems_task_set_priority: returns to caller 23
rtems_task_mode: obtain current mode 5
rtems_task_mode: no reschedule 7
rtems_task_mode: reschedule -- returns to caller 14
rtems_task_mode: reschedule -- preempts caller 43
rtems_task_set_note 13
rtems_task_get_note 12
rtems_clock_set 28
rtems_clock_get 0
9 rtems_message_queue_create 110
rtems_message_queue_send: no waiting tasks 28
rtems_message_queue_urgent: no waiting tasks 28
rtems_message_queue_receive: available 26
rtems_message_queue_flush: no messages flushed 13
rtems_message_queue_flush: messages flushed 14
rtems_message_queue_delete 45
10 rtems_message_queue_receive: not available -- NO_WAIT 15
rtems_message_queue_receive: not available -- caller blocks 48
11 rtems_message_queue_send: task readied -- preempts caller 46
12 rtems_message_queue_send: task readied -- returns to caller 31
13 rtems_message_queue_urgent: task readied -- preempts caller 46
14 rtems_message_queue_urgent: task readied -- returns to caller 31
15 rtems_event_receive: obtain current events 1
rtems_event_receive: not available -- NO_WAIT 11
rtems_event_receive: not available -- caller blocks 36
rtems_event_send: no task readied 12
rtems_event_receive: available 19
rtems_event_send: task readied -- returns to caller 21
16 rtems_event_send: task readied -- preempts caller 38
17 rtems_task_set_priority: preempts caller 51
18 rtems_task_delete: calling task 102
19 rtems_signal_catch 31
rtems_signal_send: returns to caller 21
rtems_signal_send: signal to self 39
exit ASR overhead: returns to calling task 30
exit ASR overhead: returns to preempting task 33
20 rtems_partition_create 59
rtems_region_create 37
rtems_partition_get_buffer: available 19
rtems_partition_get_buffer: not available 12
rtems_partition_return_buffer 21
rtems_partition_delete 20
rtems_region_get_segment: available 20
rtems_region_get_segment: not available -- NO_WAIT 24
rtems_region_return_segment: no waiting tasks 21
rtems_region_get_segment: not available -- caller blocks 76
rtems_region_return_segment: task readied -- preempts caller 82
rtems_region_return_segment: task readied -- returns to caller 55
rtems_region_delete 20
rtems_io_initialize 1
rtems_io_open 1
rtems_io_close 1
rtems_io_read 1
rtems_io_write 1
rtems_io_control 1
21 rtems_task_ident 84
rtems_message_queue_ident 82
rtems_semaphore_ident 94
rtems_partition_ident 82
rtems_region_ident 84
rtems_port_ident 82
rtems_timer_ident 82
rtems_rate_monotonic_ident 82
22 rtems_message_queue_broadcast: task readied -- returns to caller 81
rtems_message_queue_broadcast: no waiting tasks 22
rtems_message_queue_broadcast: task readied -- preempts caller 76
23 rtems_timer_create 11
rtems_timer_fire_after: inactive 20
rtems_timer_fire_after: active 22
rtems_timer_cancel: active 12
rtems_timer_cancel: inactive 11
rtems_timer_reset: inactive 18
rtems_timer_reset: active 21
rtems_timer_fire_when: inactive 24
rtems_timer_fire_when: active 24
rtems_timer_delete: active 16
rtems_timer_delete: inactive 14
rtems_task_wake_when 49
24 rtems_task_wake_after: yield -- returns to caller 8
rtems_task_wake_after: yields -- preempts caller 30
25 rtems_clock_tick 35
26 _ISR_Disable 24
_ISR_Flash 0
_ISR_Enable 1
_Thread_Disable_dispatch 1
_Thread_Enable_dispatch 7
_Thread_Set_state 7
_Thread_Disptach (NO FP) 31
context switch: no floating point contexts 22
context switch: self 9
context switch: to another task 10
fp context switch: restore 1st FP task 24
fp context switch: save idle, restore initialized 10
fp context switch: save idle, restore idle 23
fp context switch: save initialized, restore initialized 10
_Thread_Resume 11
_Thread_Unblock 6
_Thread_Ready 10
_Thread_Get 3
_Semaphore_Get 2
_Thread_Get: invalid id 0
27 interrupt entry overhead: returns to interrupted task 14
interrupt exit overhead: returns to interrupted task 26
interrupt entry overhead: returns to nested interrupt 7
interrupt exit overhead: returns to nested interrupt 10
interrupt entry overhead: returns to preempting task 14
interrupt exit overhead: returns to preempting task 45
28 rtems_port_create 23
rtems_port_external_to_internal 10
rtems_port_internal_to_external 10
rtems_port_delete 21
29 rtems_rate_monotonic_create 43
rtems_rate_monotonic_period: initiate period -- returns to caller 32
rtems_rate_monotonic_period: obtain status 17
rtems_rate_monotonic_cancel 22
rtems_rate_monotonic_delete: inactive 25
rtems_rate_monotonic_delete: active 28
rtems_rate_monotonic_period: conclude periods -- caller blocks 30

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,40 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@:
C_FILES = vectors_init.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
H_FILES = vectors.h
S_FILES = vectors.S
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
OBJS = $(S_O_FILES) $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(OBJS)
$(make-rel)
$(PROJECT_INCLUDE)/bsp:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/bsp/vectors.h: vectors.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp $(PROJECT_INCLUDE)/bsp/vectors.h
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS)
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,145 @@
/*
* (c) 1999, Eric Valette valette@crf.canon.fr
*
*
* This file contains the assembly code for the PowerPC
* exception veneers for RTEMS.
*
* $Id$
*/
#include <bsp/vectors.h>
#include <libcpu/cpu.h>
#include <rtems/score/targopts.h>
#include "asm.h"
#define SYNC \
sync; \
isync
.text
.p2align 5
PUBLIC_VAR(default_exception_vector_code_prolog)
SYM (default_exception_vector_code_prolog):
/*
* let room for exception frame
*/
stwu r1, - (EXCEPTION_FRAME_END)(r1)
stw r3, GPR3_OFFSET(r1)
stw r2, GPR2_OFFSET(r1)
mflr r2
stw r2, EXC_LR_OFFSET(r1)
bl 0f
0: /*
* r3 = exception vector entry point
* (256 * vector number) + few instructions
*/
mflr r3
/*
* r3 = r3 >> 8 = vector
*/
srwi r3,r3,8
ba push_normalized_frame
PUBLIC_VAR (default_exception_vector_code_prolog_size)
default_exception_vector_code_prolog_size= . - default_exception_vector_code_prolog
.p2align 5
PUBLIC_VAR (push_normalized_frame)
SYM (push_normalized_frame):
stw r3, EXCEPTION_NUMBER_OFFSET(r1)
stw r0, GPR0_OFFSET(r1)
mfsrr0 r2
stw r2, SRR0_FRAME_OFFSET(r1)
mfsrr1 r3
stw r3, SRR1_FRAME_OFFSET(r1)
/*
* Save general purpose registers
* Already saved in prolog : R1, R2, R3, LR.
* Saved a few line above : R0
*
* Manual says that "stmw" instruction may be slower than
* series of individual "stw" but who cares about performance
* for the DEFAULT exception handler?
*/
stmw r4, GPR4_OFFSET(r1) /* save R4->R31 */
mfcr r31
stw r31, EXC_CR_OFFSET(r1)
mfctr r30
stw r30, EXC_CTR_OFFSET(r1)
mfxer r28
stw r28, EXC_XER_OFFSET(r1)
/*
* compute SP at exception entry
*/
addi r2, r1, EXCEPTION_FRAME_END
/*
* store it at the right place
*/
stw r2, GPR1_OFFSET(r1)
/*
* Enable data and instruction address translation, exception nesting
*/
mfmsr r3
ori r3,r3, MSR_RI /*| MSR_IR | MSR_DR*/
mtmsr r3
SYNC
/*
* Call C exception handler
*/
/*
* store the execption frame address in r3 (first param)
*/
addi r3, r1, 0x8
/*
* globalExceptHdl(r3)
*/
addis r4, 0, globalExceptHdl@ha
lwz r5, globalExceptHdl@l(r4)
mtlr r5
blrl
/*
* Restore registers status
*/
lwz r31, EXC_CR_OFFSET(r1)
mtcr r31
lwz r30, EXC_CTR_OFFSET(r1)
mtctr r30
lwz r29, EXC_LR_OFFSET(r1)
mtlr r29
lwz r28, EXC_XER_OFFSET(r1)
mtxer r28
lmw r4, GPR4_OFFSET(r1)
lwz r2, GPR2_OFFSET(r1)
lwz r0, GPR0_OFFSET(r1)
/*
* Disable data and instruction translation. Make path non recoverable...
*/
mfmsr r3
xori r3, r3, MSR_RI /*| MSR_IR | MSR_DR*/
mtmsr r3
SYNC
/*
* Restore rfi related settings
*/
lwz r3, SRR1_FRAME_OFFSET(r1)
mtsrr1 r3
lwz r3, SRR0_FRAME_OFFSET(r1)
mtsrr0 r3
lwz r3, GPR3_OFFSET(r1)
addi r1,r1, EXCEPTION_FRAME_END
SYNC
rfi

View File

@@ -0,0 +1,144 @@
/*
* vectors.h Exception frame related contant and API.
*
* This include file describe the data structure and the functions implemented
* by rtems to handle exceptions.
*
* CopyRight (C) 1999 valette@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef LIBBSP_POWERPC_MBX8XX_VECTORS_H
#define LIBBSP_POWERPC_MBX8XX_VECTORS_H
/*
* The callee (high level exception code written in C)
* will store the Link Registers (return address) at entry r1 + 4 !!!.
* So let room for it!!!.
*/
#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4
#define SRR0_FRAME_OFFSET 8
#define SRR1_FRAME_OFFSET 12
#define EXCEPTION_NUMBER_OFFSET 16
#define GPR0_OFFSET 20
#define GPR1_OFFSET 24
#define GPR2_OFFSET 28
#define GPR3_OFFSET 32
#define GPR4_OFFSET 36
#define GPR5_OFFSET 40
#define GPR6_OFFSET 44
#define GPR7_OFFSET 48
#define GPR8_OFFSET 52
#define GPR9_OFFSET 56
#define GPR10_OFFSET 60
#define GPR11_OFFSET 64
#define GPR12_OFFSET 68
#define GPR13_OFFSET 72
#define GPR14_OFFSET 76
#define GPR15_OFFSET 80
#define GPR16_OFFSET 84
#define GPR17_OFFSET 88
#define GPR18_OFFSET 92
#define GPR19_OFFSET 96
#define GPR20_OFFSET 100
#define GPR21_OFFSET 104
#define GPR22_OFFSET 108
#define GPR23_OFFSET 112
#define GPR24_OFFSET 116
#define GPR25_OFFSET 120
#define GPR26_OFFSET 124
#define GPR27_OFFSET 128
#define GPR28_OFFSET 132
#define GPR29_OFFSET 136
#define GPR30_OFFSET 140
#define GPR31_OFFSET 144
#define EXC_CR_OFFSET 148
#define EXC_CTR_OFFSET 152
#define EXC_XER_OFFSET 156
#define EXC_LR_OFFSET 160
#define EXC_DAR_OFFSET 164
/*
* maintain the EABI requested 8 bytes aligment
* As SVR4 ABI requires 16, make it 16 (as some
* exception may need more registers to be processed...)
*/
#define EXCEPTION_FRAME_END 176
#ifndef ASM
/*
* default raw exception handlers
*/
extern void default_exception_vector_code_prolog();
extern int default_exception_vector_code_prolog_size;
/* codemove is like memmove, but it also gets the cache line size
* as 4th parameter to synchronize them. If this last parameter is
* zero, it performs more or less like memmove. No copy is performed if
* source and destination addresses are equal. However the caches
* are synchronized. Note that the size is always rounded up to the
* next mutiple of 4.
*/
extern void * codemove(void *, const void *, unsigned int, unsigned long);
extern void initialize_exceptions();
typedef struct {
unsigned EXC_SRR0;
unsigned EXC_SRR1;
unsigned _EXC_number;
unsigned GPR0;
unsigned GPR1;
unsigned GPR2;
unsigned GPR3;
unsigned GPR4;
unsigned GPR5;
unsigned GPR6;
unsigned GPR7;
unsigned GPR8;
unsigned GPR9;
unsigned GPR10;
unsigned GPR11;
unsigned GPR12;
unsigned GPR13;
unsigned GPR14;
unsigned GPR15;
unsigned GPR16;
unsigned GPR17;
unsigned GPR18;
unsigned GPR19;
unsigned GPR20;
unsigned GPR21;
unsigned GPR22;
unsigned GPR23;
unsigned GPR24;
unsigned GPR25;
unsigned GPR26;
unsigned GPR27;
unsigned GPR28;
unsigned GPR29;
unsigned GPR30;
unsigned GPR31;
unsigned EXC_CR;
unsigned EXC_CTR;
unsigned EXC_XER;
unsigned EXC_LR;
unsigned EXC_MSR;
unsigned EXC_DAR;
}BSP_Exception_frame;
typedef void (*exception_handler_t) (BSP_Exception_frame* excPtr);
extern exception_handler_t globalExceptHdl;
/*
* Compatibility with pc386
*/
typedef BSP_Exception_frame CPU_Exception_frame;
typedef exception_handler_t cpuExcHandlerType;
#endif /* ASM */
#endif /* LIBBSP_POWERPC_MCP750_VECTORS_H */

View File

@@ -0,0 +1,151 @@
/*
* vectors_init.c Exception hanlding initialisation (and generic handler).
*
* This include file describe the data structure and the functions implemented
* by rtems to handle exceptions.
*
* CopyRight (C) 1999 valette@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp/vectors.h>
#include <libcpu/raw_exception.h>
#include <bsp.h>
static rtems_raw_except_global_settings exception_config;
static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1];
exception_handler_t globalExceptHdl;
void C_exception_handler(BSP_Exception_frame* excPtr)
{
int recoverable = 0;
printk("exception handler called for exception %d\n", excPtr->_EXC_number);
printk("\t Next PC or Address of fault = %x\n", excPtr->EXC_SRR0);
printk("\t Saved MSR = %x\n", excPtr->EXC_SRR1);
printk("\t R0 = %x\n", excPtr->GPR0);
printk("\t R1 = %x\n", excPtr->GPR1);
printk("\t R2 = %x\n", excPtr->GPR2);
printk("\t R3 = %x\n", excPtr->GPR3);
printk("\t R4 = %x\n", excPtr->GPR4);
printk("\t R5 = %x\n", excPtr->GPR5);
printk("\t R6 = %x\n", excPtr->GPR6);
printk("\t R7 = %x\n", excPtr->GPR7);
printk("\t R8 = %x\n", excPtr->GPR8);
printk("\t R9 = %x\n", excPtr->GPR9);
printk("\t R10 = %x\n", excPtr->GPR10);
printk("\t R11 = %x\n", excPtr->GPR11);
printk("\t R12 = %x\n", excPtr->GPR12);
printk("\t R13 = %x\n", excPtr->GPR13);
printk("\t R14 = %x\n", excPtr->GPR14);
printk("\t R15 = %x\n", excPtr->GPR15);
printk("\t R16 = %x\n", excPtr->GPR16);
printk("\t R17 = %x\n", excPtr->GPR17);
printk("\t R18 = %x\n", excPtr->GPR18);
printk("\t R19 = %x\n", excPtr->GPR19);
printk("\t R20 = %x\n", excPtr->GPR20);
printk("\t R21 = %x\n", excPtr->GPR21);
printk("\t R22 = %x\n", excPtr->GPR22);
printk("\t R23 = %x\n", excPtr->GPR23);
printk("\t R24 = %x\n", excPtr->GPR24);
printk("\t R25 = %x\n", excPtr->GPR25);
printk("\t R26 = %x\n", excPtr->GPR26);
printk("\t R27 = %x\n", excPtr->GPR27);
printk("\t R28 = %x\n", excPtr->GPR28);
printk("\t R29 = %x\n", excPtr->GPR29);
printk("\t R30 = %x\n", excPtr->GPR30);
printk("\t R31 = %x\n", excPtr->GPR31);
printk("\t CR = %x\n", excPtr->EXC_CR);
printk("\t CTR = %x\n", excPtr->EXC_CTR);
printk("\t XER = %x\n", excPtr->EXC_XER);
printk("\t LR = %x\n", excPtr->EXC_LR);
printk("\t MSR = %x\n", excPtr->EXC_MSR);
if (excPtr->_EXC_number == ASM_DEC_VECTOR)
recoverable = 1;
if (excPtr->_EXC_number == ASM_SYS_VECTOR)
#ifdef TEST_RAW_EXCEPTION_CODE
recoverable = 1;
#else
recoverable = 0;
#endif
if (!recoverable) {
printk("unrecoverable exception!!! Push reset button\n");
while(1);
}
}
void nop_except_enable(const rtems_raw_except_connect_data* ptr)
{
}
int except_always_enabled(const rtems_raw_except_connect_data* ptr)
{
return 1;
}
void initialize_exceptions()
{
int i;
/*
* Initialize pointer used by low level execption handling
*/
globalExceptHdl = C_exception_handler;
/*
* Put default_exception_vector_code_prolog at relevant exception
* code entry addresses
*/
exception_config.exceptSize = LAST_VALID_EXC + 1;
exception_config.rawExceptHdlTbl = &exception_table[0];
exception_config.defaultRawEntry.exceptIndex = 0;
exception_config.defaultRawEntry.hdl.vector = 0;
exception_config.defaultRawEntry.hdl.raw_hdl = default_exception_vector_code_prolog;
/*
* Note that next line the '&' before default_exception_vector_code_prolog_size
* is not a bug as it is defined a .set directly in asm...
*/
exception_config.defaultRawEntry.hdl.raw_hdl_size = (unsigned) &default_exception_vector_code_prolog_size;
/*
_BSP_GPLED0_off();
_BSP_GPLED1_on();
*/
for (i=0; i <= exception_config.exceptSize; i++) {
/*
printk("installing exception number %d\n", i);
*/
if (!mpc8xx_vector_is_valid (i)) {
continue;
}
exception_table[i].exceptIndex = i;
exception_table[i].hdl = exception_config.defaultRawEntry.hdl;
exception_table[i].hdl.vector = i;
exception_table[i].on = nop_except_enable;
exception_table[i].off = nop_except_enable;
exception_table[i].isOn = except_always_enabled;
}
/* _BSP_GPLED0_on(); */
if (!mpc8xx_init_exceptions(&exception_config)) {
/*
* At this stage we may not call BSP_Panic because it uses exceptions!!!
*/
printk("Exception handling initialization failed\n");
printk("System locked\n"); while(1);
}
else {
#if 0
printk("Exception handling initialization done\n");
#endif
}
/* _BSP_GPLED1_off(); */
}

View File

@@ -0,0 +1,44 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
# We only build the networking device driver if HAS_NETWORKING was defined
if HAS_NETWORKING
NETWORKING = network
endif
BSP_PIECES = clock irq start startup console vectors $(NETWORKING)
# pieces to pick up out of libcpu/ppc
# CPU_PIECES = mpc8xx/clock mpc8xx/console-generic mpc8xx/cpm \
# mpc8xx/mmu mpc8xx/timer mpc8xx/vectors
# bummer; have to use $foreach since % pattern subst rules only replace 1x
OBJS = $(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.o)) \
$(wildcard ../../../../libcpu/$(RTEMS_CPU)/shared/*/$(ARCH)/*.o) \
$(wildcard ../../../../libcpu/powerpc/new_exception_processing/$(ARCH)/*.rel) \
$(wildcard ../../../../libcpu/$(RTEMS_CPU)/mpc8260/*/$(ARCH)/*.o)
LIB = $(ARCH)/libbsp.a
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 +=
#
$(LIB): $(OBJS)
$(make-library)
$(PROJECT_RELEASE)/lib/libbsp$(LIB_VARIANT).a: $(LIB)
$(INSTALL_DATA) $< $@
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/libbsp$(LIB_VARIANT).a
all-local: $(ARCH) $(OBJS) $(LIB) $(TMPINSTALL_FILES)
.PRECIOUS: $(LIB)
include $(top_srcdir)/../../../../../../automake/local.am