forked from Imagelibrary/rtems
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:
17
c/src/lib/libbsp/powerpc/mpc8260ads/ChangeLog
Normal file
17
c/src/lib/libbsp/powerpc/mpc8260ads/ChangeLog
Normal 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.
|
||||
|
||||
17
c/src/lib/libbsp/powerpc/mpc8260ads/Makefile.am
Normal file
17
c/src/lib/libbsp/powerpc/mpc8260ads/Makefile.am
Normal 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
|
||||
337
c/src/lib/libbsp/powerpc/mpc8260ads/README
Normal file
337
c/src/lib/libbsp/powerpc/mpc8260ads/README
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1041
c/src/lib/libbsp/powerpc/mpc8260ads/aclocal.m4
vendored
Normal file
1041
c/src/lib/libbsp/powerpc/mpc8260ads/aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
26
c/src/lib/libbsp/powerpc/mpc8260ads/bsp_specs
Normal file
26
c/src/lib/libbsp/powerpc/mpc8260ads/bsp_specs
Normal 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}
|
||||
|
||||
2
c/src/lib/libbsp/powerpc/mpc8260ads/clock/.cvsignore
Normal file
2
c/src/lib/libbsp/powerpc/mpc8260ads/clock/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
26
c/src/lib/libbsp/powerpc/mpc8260ads/clock/Makefile.am
Normal file
26
c/src/lib/libbsp/powerpc/mpc8260ads/clock/Makefile.am
Normal file
@@ -0,0 +1,26 @@
|
||||
##
|
||||
## $Id$
|
||||
##
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
VPATH = @srcdir@:@srcdir@/../../shared/clock
|
||||
|
||||
C_FILES = p_clock.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||
|
||||
OBJS = $(C_O_FILES)
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
include $(top_srcdir)/../../../../../../automake/lib.am
|
||||
|
||||
#
|
||||
# (OPTIONAL) Add local stuff here using +=
|
||||
#
|
||||
|
||||
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
|
||||
|
||||
all-local: $(ARCH) $(OBJS)
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
71
c/src/lib/libbsp/powerpc/mpc8260ads/clock/p_clock.c
Normal file
71
c/src/lib/libbsp/powerpc/mpc8260ads/clock/p_clock.c
Normal 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);
|
||||
}
|
||||
33
c/src/lib/libbsp/powerpc/mpc8260ads/console/Makefile.am
Normal file
33
c/src/lib/libbsp/powerpc/mpc8260ads/console/Makefile.am
Normal 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
|
||||
478
c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c
Normal file
478
c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c
Normal 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
|
||||
|
||||
}
|
||||
|
||||
31
c/src/lib/libbsp/powerpc/mpc8260ads/include/Makefile.am
Normal file
31
c/src/lib/libbsp/powerpc/mpc8260ads/include/Makefile.am
Normal 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
|
||||
157
c/src/lib/libbsp/powerpc/mpc8260ads/include/bsp.h
Normal file
157
c/src/lib/libbsp/powerpc/mpc8260ads/include/bsp.h
Normal 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 */
|
||||
114
c/src/lib/libbsp/powerpc/mpc8260ads/include/coverhd.h
Normal file
114
c/src/lib/libbsp/powerpc/mpc8260ads/include/coverhd.h
Normal 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 */
|
||||
2
c/src/lib/libbsp/powerpc/mpc8260ads/irq/.cvsignore
Normal file
2
c/src/lib/libbsp/powerpc/mpc8260ads/irq/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
46
c/src/lib/libbsp/powerpc/mpc8260ads/irq/Makefile.am
Normal file
46
c/src/lib/libbsp/powerpc/mpc8260ads/irq/Makefile.am
Normal file
@@ -0,0 +1,46 @@
|
||||
##
|
||||
## $Id$
|
||||
##
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
C_FILES = irq.c irq_init.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||
|
||||
H_FILES = irq.h
|
||||
|
||||
S_FILES = irq_asm.S
|
||||
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
|
||||
|
||||
OBJS = $(C_O_FILES) $(S_O_FILES)
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
include $(top_srcdir)/../../../../../../automake/lib.am
|
||||
|
||||
SORDID_HACK:
|
||||
rm -f $(PROJECT_INCLUDE)/bsp/irq.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp:
|
||||
$(mkinstalldirs) $@
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/%.h: %.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp \
|
||||
$(H_FILES:%.h=$(PROJECT_INCLUDE)/bsp/%.h)
|
||||
|
||||
#
|
||||
# (OPTIONAL) Add local stuff here using +=
|
||||
#
|
||||
|
||||
$(PGM): $(OBJS)
|
||||
$(make-rel)
|
||||
|
||||
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
|
||||
|
||||
all-local: SORDID_HACK $(PREINSTALL_FILES) $(ARCH) $(OBJS) $(PGM)
|
||||
|
||||
EXTRA_DIST = irq.c irq.h irq_asm.S irq_init.c
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
453
c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.c
Normal file
453
c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.c
Normal 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...
|
||||
*/
|
||||
}
|
||||
347
c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.h
Normal file
347
c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq.h
Normal 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
|
||||
339
c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_asm.S
Normal file
339
c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_asm.S
Normal 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
|
||||
|
||||
150
c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_init.c
Normal file
150
c/src/lib/libbsp/powerpc/mpc8260ads/irq/irq_init.c
Normal 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
|
||||
}
|
||||
|
||||
37
c/src/lib/libbsp/powerpc/mpc8260ads/network/Makefile.am
Normal file
37
c/src/lib/libbsp/powerpc/mpc8260ads/network/Makefile.am
Normal 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
|
||||
55
c/src/lib/libbsp/powerpc/mpc8260ads/network/README
Normal file
55
c/src/lib/libbsp/powerpc/mpc8260ads/network/README
Normal 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>.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
346
c/src/lib/libbsp/powerpc/mpc8260ads/network/if_hdlcsubr.c
Normal file
346
c/src/lib/libbsp/powerpc/mpc8260ads/network/if_hdlcsubr.c
Normal 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);
|
||||
}
|
||||
40
c/src/lib/libbsp/powerpc/mpc8260ads/network/if_hdlcsubr.h
Normal file
40
c/src/lib/libbsp/powerpc/mpc8260ads/network/if_hdlcsubr.h
Normal 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
|
||||
1016
c/src/lib/libbsp/powerpc/mpc8260ads/network/network.c
Normal file
1016
c/src/lib/libbsp/powerpc/mpc8260ads/network/network.c
Normal file
File diff suppressed because it is too large
Load Diff
33
c/src/lib/libbsp/powerpc/mpc8260ads/start/Makefile.am
Normal file
33
c/src/lib/libbsp/powerpc/mpc8260ads/start/Makefile.am
Normal 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
|
||||
191
c/src/lib/libbsp/powerpc/mpc8260ads/start/start.S
Normal file
191
c/src/lib/libbsp/powerpc/mpc8260ads/start/start.S
Normal 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 */
|
||||
|
||||
|
||||
|
||||
43
c/src/lib/libbsp/powerpc/mpc8260ads/startup/Makefile.am
Normal file
43
c/src/lib/libbsp/powerpc/mpc8260ads/startup/Makefile.am
Normal 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
|
||||
370
c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c
Normal file
370
c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c
Normal 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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
51
c/src/lib/libbsp/powerpc/mpc8260ads/startup/cpuinit.c
Normal file
51
c/src/lib/libbsp/powerpc/mpc8260ads/startup/cpuinit.c
Normal 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
|
||||
}
|
||||
285
c/src/lib/libbsp/powerpc/mpc8260ads/startup/linkcmds
Normal file
285
c/src/lib/libbsp/powerpc/mpc8260ads/startup/linkcmds
Normal 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) }
|
||||
}
|
||||
43
c/src/lib/libbsp/powerpc/mpc8260ads/startup/setvec.c
Normal file
43
c/src/lib/libbsp/powerpc/mpc8260ads/startup/setvec.c
Normal 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;
|
||||
}
|
||||
|
||||
196
c/src/lib/libbsp/powerpc/mpc8260ads/times
Normal file
196
c/src/lib/libbsp/powerpc/mpc8260ads/times
Normal 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
|
||||
2
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/.cvsignore
Normal file
2
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
40
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/Makefile.am
Normal file
40
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/Makefile.am
Normal file
@@ -0,0 +1,40 @@
|
||||
##
|
||||
## $Id$
|
||||
##
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
VPATH = @srcdir@:
|
||||
|
||||
C_FILES = vectors_init.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
|
||||
|
||||
H_FILES = vectors.h
|
||||
|
||||
S_FILES = vectors.S
|
||||
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
|
||||
|
||||
OBJS = $(S_O_FILES) $(C_O_FILES)
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
include $(top_srcdir)/../../../../../../automake/lib.am
|
||||
|
||||
#
|
||||
# (OPTIONAL) Add local stuff here using +=
|
||||
#
|
||||
|
||||
$(PGM): $(OBJS)
|
||||
$(make-rel)
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp:
|
||||
$(mkinstalldirs) $@
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/vectors.h: vectors.h
|
||||
$(INSTALL_DATA) $< $@
|
||||
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp $(PROJECT_INCLUDE)/bsp/vectors.h
|
||||
|
||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS)
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
145
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/vectors.S
Normal file
145
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/vectors.S
Normal 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
|
||||
144
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/vectors.h
Normal file
144
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/vectors.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* vectors.h Exception frame related contant and API.
|
||||
*
|
||||
* This include file describe the data structure and the functions implemented
|
||||
* by rtems to handle exceptions.
|
||||
*
|
||||
* CopyRight (C) 1999 valette@crf.canon.fr
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
#ifndef LIBBSP_POWERPC_MBX8XX_VECTORS_H
|
||||
#define LIBBSP_POWERPC_MBX8XX_VECTORS_H
|
||||
|
||||
/*
|
||||
* The callee (high level exception code written in C)
|
||||
* will store the Link Registers (return address) at entry r1 + 4 !!!.
|
||||
* So let room for it!!!.
|
||||
*/
|
||||
#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4
|
||||
#define SRR0_FRAME_OFFSET 8
|
||||
#define SRR1_FRAME_OFFSET 12
|
||||
#define EXCEPTION_NUMBER_OFFSET 16
|
||||
#define GPR0_OFFSET 20
|
||||
#define GPR1_OFFSET 24
|
||||
#define GPR2_OFFSET 28
|
||||
#define GPR3_OFFSET 32
|
||||
#define GPR4_OFFSET 36
|
||||
#define GPR5_OFFSET 40
|
||||
#define GPR6_OFFSET 44
|
||||
#define GPR7_OFFSET 48
|
||||
#define GPR8_OFFSET 52
|
||||
#define GPR9_OFFSET 56
|
||||
#define GPR10_OFFSET 60
|
||||
#define GPR11_OFFSET 64
|
||||
#define GPR12_OFFSET 68
|
||||
#define GPR13_OFFSET 72
|
||||
#define GPR14_OFFSET 76
|
||||
#define GPR15_OFFSET 80
|
||||
#define GPR16_OFFSET 84
|
||||
#define GPR17_OFFSET 88
|
||||
#define GPR18_OFFSET 92
|
||||
#define GPR19_OFFSET 96
|
||||
#define GPR20_OFFSET 100
|
||||
#define GPR21_OFFSET 104
|
||||
#define GPR22_OFFSET 108
|
||||
#define GPR23_OFFSET 112
|
||||
#define GPR24_OFFSET 116
|
||||
#define GPR25_OFFSET 120
|
||||
#define GPR26_OFFSET 124
|
||||
#define GPR27_OFFSET 128
|
||||
#define GPR28_OFFSET 132
|
||||
#define GPR29_OFFSET 136
|
||||
#define GPR30_OFFSET 140
|
||||
#define GPR31_OFFSET 144
|
||||
#define EXC_CR_OFFSET 148
|
||||
#define EXC_CTR_OFFSET 152
|
||||
#define EXC_XER_OFFSET 156
|
||||
#define EXC_LR_OFFSET 160
|
||||
#define EXC_DAR_OFFSET 164
|
||||
/*
|
||||
* maintain the EABI requested 8 bytes aligment
|
||||
* As SVR4 ABI requires 16, make it 16 (as some
|
||||
* exception may need more registers to be processed...)
|
||||
*/
|
||||
#define EXCEPTION_FRAME_END 176
|
||||
|
||||
#ifndef ASM
|
||||
/*
|
||||
* default raw exception handlers
|
||||
*/
|
||||
|
||||
extern void default_exception_vector_code_prolog();
|
||||
extern int default_exception_vector_code_prolog_size;
|
||||
|
||||
/* codemove is like memmove, but it also gets the cache line size
|
||||
* as 4th parameter to synchronize them. If this last parameter is
|
||||
* zero, it performs more or less like memmove. No copy is performed if
|
||||
* source and destination addresses are equal. However the caches
|
||||
* are synchronized. Note that the size is always rounded up to the
|
||||
* next mutiple of 4.
|
||||
*/
|
||||
extern void * codemove(void *, const void *, unsigned int, unsigned long);
|
||||
extern void initialize_exceptions();
|
||||
|
||||
typedef struct {
|
||||
unsigned EXC_SRR0;
|
||||
unsigned EXC_SRR1;
|
||||
unsigned _EXC_number;
|
||||
unsigned GPR0;
|
||||
unsigned GPR1;
|
||||
unsigned GPR2;
|
||||
unsigned GPR3;
|
||||
unsigned GPR4;
|
||||
unsigned GPR5;
|
||||
unsigned GPR6;
|
||||
unsigned GPR7;
|
||||
unsigned GPR8;
|
||||
unsigned GPR9;
|
||||
unsigned GPR10;
|
||||
unsigned GPR11;
|
||||
unsigned GPR12;
|
||||
unsigned GPR13;
|
||||
unsigned GPR14;
|
||||
unsigned GPR15;
|
||||
unsigned GPR16;
|
||||
unsigned GPR17;
|
||||
unsigned GPR18;
|
||||
unsigned GPR19;
|
||||
unsigned GPR20;
|
||||
unsigned GPR21;
|
||||
unsigned GPR22;
|
||||
unsigned GPR23;
|
||||
unsigned GPR24;
|
||||
unsigned GPR25;
|
||||
unsigned GPR26;
|
||||
unsigned GPR27;
|
||||
unsigned GPR28;
|
||||
unsigned GPR29;
|
||||
unsigned GPR30;
|
||||
unsigned GPR31;
|
||||
unsigned EXC_CR;
|
||||
unsigned EXC_CTR;
|
||||
unsigned EXC_XER;
|
||||
unsigned EXC_LR;
|
||||
unsigned EXC_MSR;
|
||||
unsigned EXC_DAR;
|
||||
}BSP_Exception_frame;
|
||||
|
||||
|
||||
typedef void (*exception_handler_t) (BSP_Exception_frame* excPtr);
|
||||
extern exception_handler_t globalExceptHdl;
|
||||
/*
|
||||
* Compatibility with pc386
|
||||
*/
|
||||
typedef BSP_Exception_frame CPU_Exception_frame;
|
||||
typedef exception_handler_t cpuExcHandlerType;
|
||||
|
||||
#endif /* ASM */
|
||||
|
||||
#endif /* LIBBSP_POWERPC_MCP750_VECTORS_H */
|
||||
151
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/vectors_init.c
Normal file
151
c/src/lib/libbsp/powerpc/mpc8260ads/vectors/vectors_init.c
Normal 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(); */
|
||||
|
||||
}
|
||||
44
c/src/lib/libbsp/powerpc/mpc8260ads/wrapup/Makefile.am
Normal file
44
c/src/lib/libbsp/powerpc/mpc8260ads/wrapup/Makefile.am
Normal 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
|
||||
Reference in New Issue
Block a user