forked from Imagelibrary/rtems
committed by
Gedare Bloom
parent
552e481699
commit
7f86974bf3
@@ -1,296 +0,0 @@
|
||||
gen68360
|
||||
========
|
||||
|
||||
This package requires a version of GCC that supports the `-mcpu32` option.
|
||||
|
||||
Copyright (c) 1996 Eric Norum <eric@norum.ca>
|
||||
|
||||
This board support package works with several different versions of
|
||||
MC68360 systems. See the conditional-compile tests in startup/init68360.c
|
||||
for examples.
|
||||
|
||||
Decisions made at compile time include:
|
||||
- If the CPU is a member of the 68040 family, the BSP is
|
||||
compiled for a generic 68040/68360 system as described
|
||||
in Chapter 9 of the MC68360 User's Manual. This version
|
||||
can be used with the Arnewsh SBC360 card.
|
||||
- If the preprocessor symbol M68360_ATLAS_HSB is defined,
|
||||
the BSP is compiled for an Atlas HSB card.
|
||||
- If the preprocessor symbol M68360_IMD_PGH is defined,
|
||||
the BSP is compiled for an IMD PGH360 card.
|
||||
- Otherwise, the BSP is compiled for a generic 68360 system
|
||||
as described in Chapter 9 of the MC68360 User's Manual. This
|
||||
version works with the Atlas ACE360 card.
|
||||
|
||||
```
|
||||
BSP NAME: gen68360 or gen68360_040
|
||||
BOARD: Generic 68360 as described in Motorola MC68360 User's Manual
|
||||
BOARD: Atlas Computer Equipment Inc. High Speed Bridge (HSB)
|
||||
BOARD: Atlas Computer Equipment Inc. Advanced Communication Engine (ACE)
|
||||
BOARD: Arnewsh SBC360 68040/68360 card
|
||||
BOARD: IMD PGH Board (custom)
|
||||
BUS: none
|
||||
CPU FAMILY: Motorola CPU32+, Motorola 68040
|
||||
COPROCESSORS: none
|
||||
MODE: not applicable
|
||||
|
||||
DEBUG MONITOR: none (Hardware provides BDM)
|
||||
```
|
||||
|
||||
PERIPHERALS
|
||||
-----------
|
||||
```
|
||||
TIMERS: PIT, Watchdog, 4 general purpose, 16 RISC
|
||||
RESOLUTION: one microsecond
|
||||
SERIAL PORTS: 4 SCC, 2 SMC, 1 SPI
|
||||
REAL-TIME CLOCK:
|
||||
DMA: Each serial port, 2 general purpose
|
||||
VIDEO: none
|
||||
SCSI: none
|
||||
NETWORKING: Ethernet on SCC1.
|
||||
```
|
||||
|
||||
DRIVER INFORMATION
|
||||
------------------
|
||||
```
|
||||
CLOCK DRIVER: Programmable Interval Timer
|
||||
IOSUPP DRIVER: Serial Management Controller 1
|
||||
SHMSUPP: none
|
||||
TIMER DRIVER: Timer 1
|
||||
```
|
||||
|
||||
STDIO
|
||||
-----
|
||||
```
|
||||
PORT: SMC1
|
||||
ELECTRICAL: EIA-232 (if board supplies level shifter)
|
||||
BAUD: 9600
|
||||
BITS PER CHARACTER: 8
|
||||
PARITY: None
|
||||
STOP BITS: 1
|
||||
```
|
||||
|
||||
Board description
|
||||
-----------------
|
||||
clock rate: 25 MHz
|
||||
bus width: 8-bit PROM/FLASH, 32-bit DRAM
|
||||
ROM: To 1 MByte, 180 nsec (3 wait states), chip select 0
|
||||
RAM: 4 or 16 MBytes of 60 nsec parity DRAM (1Mx36) to RAS1*/CAS1*
|
||||
|
||||
Board description (IMD PGH)
|
||||
---------------------------
|
||||
clock rate: 25 MHz
|
||||
bus width: 8-bit PROM/FLASH, 32-bit DRAM
|
||||
ROM: 512KByte, 180 nsec (3 wait states), chip select 0
|
||||
RAM: 16 MBytes of 60 nsec no-parity DRAM (1Mx32) to RAS1*/CAS1*
|
||||
|
||||
Host System
|
||||
-----------
|
||||
OPENSTEP 4.2 (Intel and Motorola), Solaris 2.5, Linux 2.0.29
|
||||
|
||||
Verification (Standalone 68360)
|
||||
-------------------------------
|
||||
```
|
||||
Single processor tests: Passed
|
||||
Multi-processort tests: not applicable
|
||||
Timing tests:
|
||||
Context Switch
|
||||
|
||||
context switch: self 10
|
||||
context switch: to another task 11
|
||||
context switch: no floating point contexts 38
|
||||
fp context switch: restore 1st FP task 39
|
||||
fp context switch: save initialized, restore initialized 14
|
||||
fp context switch: save idle, restore initialized 15
|
||||
fp context switch: save idle, restore idle 41
|
||||
|
||||
Task Manager
|
||||
|
||||
rtems_task_create 202
|
||||
rtems_task_ident 390
|
||||
rtems_task_start 71
|
||||
rtems_task_restart: calling task 99
|
||||
rtems_task_restart: suspended task -- returns to caller 86
|
||||
rtems_task_restart: blocked task -- returns to caller 116
|
||||
rtems_task_restart: ready task -- returns to caller 88
|
||||
rtems_task_restart: suspended task -- preempts caller 132
|
||||
rtems_task_restart: blocked task -- preempts caller 153
|
||||
rtems_task_restart: ready task -- preempts caller 149
|
||||
rtems_task_delete: calling task 236
|
||||
rtems_task_delete: suspended task 191
|
||||
rtems_task_delete: blocked task 195
|
||||
rtems_task_delete: ready task 198
|
||||
rtems_task_suspend: calling task 78
|
||||
rtems_task_suspend: returns to caller 36
|
||||
rtems_task_resume: task readied -- returns to caller 39
|
||||
rtems_task_resume: task readied -- preempts caller 67
|
||||
rtems_task_set_priority: obtain current priority 26
|
||||
rtems_task_set_priority: returns to caller 59
|
||||
rtems_task_set_priority: preempts caller 110
|
||||
rtems_task_mode: obtain current mode 13
|
||||
rtems_task_mode: no reschedule 15
|
||||
rtems_task_mode: reschedule -- returns to caller 20
|
||||
rtems_task_mode: reschedule -- preempts caller 67
|
||||
rtems_task_wake_after: yield -- returns to caller 16
|
||||
rtems_task_wake_after: yields -- preempts caller 65
|
||||
rtems_task_wake_when 116
|
||||
|
||||
Interrupt Manager
|
||||
|
||||
interrupt entry overhead: returns to nested interrupt 10
|
||||
interrupt entry overhead: returns to interrupted task 10
|
||||
interrupt entry overhead: returns to preempting task 10
|
||||
interrupt exit overhead: returns to nested interrupt 8
|
||||
interrupt exit overhead: returns to interrupted task 10
|
||||
interrupt exit overhead: returns to preempting task 59
|
||||
|
||||
Clock Manager
|
||||
|
||||
rtems_clock_set 73
|
||||
rtems_clock_get 1
|
||||
rtems_clock_tick 16
|
||||
|
||||
Timer Manager
|
||||
|
||||
rtems_timer_create 31
|
||||
rtems_timer_ident 380
|
||||
rtems_timer_delete: inactive 43
|
||||
rtems_timer_delete: active 46
|
||||
rtems_timer_fire_after: inactive 53
|
||||
rtems_timer_fire_after: active 56
|
||||
rtems_timer_fire_when: inactive 72
|
||||
rtems_timer_fire_when: active 72
|
||||
rtems_timer_reset: inactive 47
|
||||
rtems_timer_reset: active 51
|
||||
rtems_timer_cancel: inactive 25
|
||||
rtems_timer_cancel: active 28
|
||||
|
||||
Semaphore Manager
|
||||
|
||||
rtems_semaphore_create 59
|
||||
rtems_semaphore_ident 438
|
||||
rtems_semaphore_delete 57
|
||||
rtems_semaphore_obtain: available 31
|
||||
rtems_semaphore_obtain: not available -- NO_WAIT 31
|
||||
rtems_semaphore_obtain: not available -- caller blocks 108
|
||||
rtems_semaphore_release: no waiting tasks 40
|
||||
rtems_semaphore_release: task readied -- returns to caller 56
|
||||
rtems_semaphore_release: task readied -- preempts caller 83
|
||||
|
||||
Message Queue Manager
|
||||
|
||||
rtems_message_queue_create 241
|
||||
rtems_message_queue_ident 379
|
||||
rtems_message_queue_delete 75
|
||||
rtems_message_queue_send: no waiting tasks 72
|
||||
rtems_message_queue_send: task readied -- returns to caller 72
|
||||
rtems_message_queue_send: task readied -- preempts caller 99
|
||||
rtems_message_queue_urgent: no waiting tasks 72
|
||||
rtems_message_queue_urgent: task readied -- returns to caller 72
|
||||
rtems_message_queue_urgent: task readied -- preempts caller 99
|
||||
rtems_message_queue_broadcast: no waiting tasks 43
|
||||
rtems_message_queue_broadcast: task readied -- returns to caller 82
|
||||
rtems_message_queue_broadcast: task readied -- preempts caller 109
|
||||
rtems_message_queue_receive: available 52
|
||||
rtems_message_queue_receive: not available -- NO_WAIT 34
|
||||
rtems_message_queue_receive: not available -- caller blocks 111
|
||||
rtems_message_queue_flush: no messages flushed 25
|
||||
rtems_message_queue_flush: messages flushed 34
|
||||
|
||||
Event Manager
|
||||
|
||||
rtems_event_send: no task readied 22
|
||||
rtems_event_send: task readied -- returns to caller 50
|
||||
rtems_event_send: task readied -- preempts caller 80
|
||||
rtems_event_receive: obtain current events -1
|
||||
rtems_event_receive: available 26
|
||||
rtems_event_receive: not available -- NO_WAIT 22
|
||||
rtems_event_receive: not available -- caller blocks 89
|
||||
|
||||
Signal Manager
|
||||
|
||||
rtems_signal_catch 16
|
||||
rtems_signal_send: returns to caller 32
|
||||
rtems_signal_send: signal to self 51
|
||||
exit ASR overhead: returns to calling task 42
|
||||
exit ASR overhead: returns to preempting task 58
|
||||
|
||||
Partition Manager
|
||||
|
||||
rtems_partition_create 74
|
||||
rtems_partition_ident 379
|
||||
rtems_partition_delete 40
|
||||
rtems_partition_get_buffer: available 29
|
||||
rtems_partition_get_buffer: not available 27
|
||||
rtems_partition_return_buffer 34
|
||||
|
||||
Region Manager
|
||||
|
||||
rtems_region_create 63
|
||||
rtems_region_ident 388
|
||||
rtems_region_delete 40
|
||||
rtems_region_get_segment: available 43
|
||||
rtems_region_get_segment: not available -- NO_WAIT 40
|
||||
rtems_region_get_segment: not available -- caller blocks 120
|
||||
rtems_region_return_segment: no waiting tasks 48
|
||||
rtems_region_return_segment: task readied -- returns to caller 98
|
||||
rtems_region_return_segment: task readied -- preempts caller 125
|
||||
|
||||
Dual-Ported Memory Manager
|
||||
|
||||
rtems_port_create 38
|
||||
rtems_port_ident 380
|
||||
rtems_port_delete 40
|
||||
rtems_port_internal_to_external 22
|
||||
rtems_port_external_to_internal 22
|
||||
|
||||
IO Manager
|
||||
|
||||
rtems_io_initialize 4
|
||||
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 36
|
||||
rtems_rate_monotonic_ident 380
|
||||
rtems_rate_monotonic_cancel 34
|
||||
rtems_rate_monotonic_delete: active 51
|
||||
rtems_rate_monotonic_delete: inactive 47
|
||||
rtems_rate_monotonic_period: obtain status 27
|
||||
rtems_rate_monotonic_period: initiate period -- returns to caller 50
|
||||
rtems_rate_monotonic_period: conclude periods -- caller blocks 72
|
||||
|
||||
Network tests:
|
||||
TCP throughput (as measured by ttcp):
|
||||
Receive: 1081 kbytes/sec
|
||||
Transmit: 953 kbytes/sec
|
||||
```
|
||||
|
||||
Porting
|
||||
-------
|
||||
This board support package is written for a 68360 system similar to that
|
||||
described in chapter 9 of the Motorola MC68360 Quad Integrated Communication
|
||||
Processor Users' Manual. The salient features of this hardware are:
|
||||
|
||||
25 MHz external clock
|
||||
DRAM address multiplexing provided by 68360
|
||||
8-bit 180nsec PROM to CS0*
|
||||
4 MBytes of 60 nsec parity DRAM (1Mx36) to RAS1*/CAS1*
|
||||
Console serial port on SMC1
|
||||
Ethernet interface on SCC1
|
||||
|
||||
The board support package has been tested with:
|
||||
A home-built 68360 board
|
||||
An ACE360A and an HSB board produced by:
|
||||
Atlas Computer Equipment
|
||||
703 Colina Lane
|
||||
Santa Barbara, CA 93103
|
||||
A 68040/68360 board (SBC360) produced by:
|
||||
Arnewsh Inc.
|
||||
P.O. Box 270352
|
||||
Fort Collins, CO 80527-0352
|
||||
A custom 68360 board (PGH360) produced by IMD
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Use TIMER 1 and TIMER 2 for Timing Test Suite
|
||||
* The hardware on the MC68360 makes these routines very simple.
|
||||
*
|
||||
* NOTE: It is important that the timer start/stop overhead be
|
||||
* determined when porting or modifying this code.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Based on the `gen68302' board support package, and covered by the
|
||||
* original distribution terms.
|
||||
*
|
||||
* Copyright (c) 1996 Eric Norum <eric@norum.ca>
|
||||
*
|
||||
* 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.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/btimer.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/m68k/m68360.h>
|
||||
|
||||
void
|
||||
benchmark_timer_initialize (void)
|
||||
{
|
||||
/*
|
||||
* Reset timers 1 and 2
|
||||
*/
|
||||
m360.tgcr &= ~0x00FF;
|
||||
m360.tcn1 = 0;
|
||||
m360.tcn2 = 0;
|
||||
m360.ter1 = 0xFFFF;
|
||||
m360.ter2 = 0xFFFF;
|
||||
|
||||
/*
|
||||
* Cascade timers 1 and 2
|
||||
*/
|
||||
m360.tgcr |= 0x0080;
|
||||
|
||||
/*
|
||||
* Configure timers 1 and 2 to a single 32-bit, 1 MHz timer.
|
||||
* HARDWARE:
|
||||
* Change the `25' to match your processor clock
|
||||
*/
|
||||
m360.tmr2 = ((25-1) << 8) | 0x2;
|
||||
m360.tmr1 = 0;
|
||||
|
||||
/*
|
||||
* Start the timers
|
||||
*/
|
||||
m360.tgcr |= 0x0011;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return timer value in microsecond units
|
||||
*/
|
||||
uint32_t
|
||||
benchmark_timer_read (void)
|
||||
{
|
||||
unsigned short val;
|
||||
|
||||
val = m360.tcn1;
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
|
||||
{
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* This routine initializes the MC68360 Periodic Interval Timer
|
||||
*
|
||||
* The PIT has rather poor resolution, but it is easy to set up
|
||||
* and requires no housekeeping once it is going.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Eric Norum <eric@norum.ca>
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/m68k/m68360.h>
|
||||
|
||||
#define CLOCK_VECTOR 120
|
||||
#define CLOCK_IRQ_LEVEL 4
|
||||
|
||||
char M360DefaultWatchdogFeeder = 1;
|
||||
|
||||
/*
|
||||
* RTEMS and hardware have different notions of clock rate.
|
||||
*/
|
||||
static unsigned long rtems_nsec_per_tick;
|
||||
static unsigned long pit_nsec_per_tick;
|
||||
static unsigned long nsec;
|
||||
|
||||
/*
|
||||
* Periodic interval timer interrupt handler
|
||||
* See if it's really time for a `tick'
|
||||
* Perform a dummy read of DPRAM (work around bug in Rev. B of the 68360).
|
||||
* Feed the watchdog
|
||||
* Application code can override this by
|
||||
* setting M360DefaultWatchdogFeeder to zero.
|
||||
*/
|
||||
#define Clock_driver_support_at_tick(arg) \
|
||||
do { \
|
||||
nsec += pit_nsec_per_tick; \
|
||||
if (nsec >= rtems_nsec_per_tick) \
|
||||
return; \
|
||||
nsec -= rtems_nsec_per_tick; \
|
||||
m360.dpram0[0]; \
|
||||
if (M360DefaultWatchdogFeeder) { \
|
||||
m360.swsr = 0x55; \
|
||||
m360.swsr = 0xAA; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
/*
|
||||
* Attach clock interrupt handler
|
||||
*/
|
||||
#define Clock_driver_support_install_isr( _new ) \
|
||||
set_vector(_new, CLOCK_VECTOR, 1)
|
||||
|
||||
/*
|
||||
* Set up the clock hardware
|
||||
* The rate at which the periodic interval timer
|
||||
* can generate interrupts is almost certainly not
|
||||
* the same as desired by the BSP configuration.
|
||||
* Handle the difference by choosing the largest PIT
|
||||
* interval which is less than or equal to the RTEMS
|
||||
* interval and skipping some hardware interrupts.
|
||||
* To reduce the jitter in the calls to RTEMS the
|
||||
* hardware interrupt interval is never greater than
|
||||
* the maximum non-prescaled value from the PIT.
|
||||
*
|
||||
* For a 25 MHz external clock the basic clock rate is
|
||||
* 40 nsec * 128 * 4 = 20.48 usec/tick
|
||||
*/
|
||||
extern int m360_clock_rate;
|
||||
|
||||
#define Clock_driver_support_initialize_hardware() \
|
||||
do { \
|
||||
unsigned int divisor; \
|
||||
unsigned long nsec_per_chip_tick = 1000000000 / m360_clock_rate; \
|
||||
unsigned long nsec_per_pit_tick = 512 * nsec_per_chip_tick; \
|
||||
rtems_nsec_per_tick = rtems_configuration_get_microseconds_per_tick() * 1000; \
|
||||
divisor = rtems_nsec_per_tick / nsec_per_pit_tick; \
|
||||
if (divisor > 255) \
|
||||
divisor = 255; \
|
||||
else if (divisor == 0) \
|
||||
divisor = 1; \
|
||||
pit_nsec_per_tick = nsec_per_pit_tick * divisor; \
|
||||
m360.pitr &= ~0x1FF; \
|
||||
m360.picr = (CLOCK_IRQ_LEVEL << 8) | CLOCK_VECTOR; \
|
||||
m360.pitr |= divisor; \
|
||||
} while (0)
|
||||
|
||||
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
|
||||
|
||||
#include "../../../shared/dev/clock/clockimpl.h"
|
||||
@@ -1,15 +0,0 @@
|
||||
#
|
||||
# Config file for a "generic 68360" BSP
|
||||
|
||||
RTEMS_CPU=m68k
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/default.cfg
|
||||
|
||||
CPU_CFLAGS = -mcpu=cpu32
|
||||
|
||||
CFLAGS_OPTIMIZE_V = -O2 -g -fomit-frame-pointer
|
||||
|
||||
# FIXME: Disabled because linkcmds lacks proper KEEP() directives. See #2566.
|
||||
# The following two lines enable compiling and linking on per element.
|
||||
CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
|
||||
LDFLAGS = -Wl,--gc-sections
|
||||
@@ -1,16 +0,0 @@
|
||||
#
|
||||
# Configuration file for a 68040 using the 68360 in companion mode
|
||||
#
|
||||
|
||||
RTEMS_CPU=m68k
|
||||
|
||||
CPU_CFLAGS = -mcpu=68040
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/default.cfg
|
||||
|
||||
CFLAGS_OPTIMIZE_V = -O2 -g -fomit-frame-pointer
|
||||
|
||||
# FIXME: Disabled because linkcmds lacks proper KEEP() directives. See #2566.
|
||||
# The following two lines enable compiling and linking on per element.
|
||||
CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
|
||||
LDFLAGS = -Wl,--gc-sections
|
||||
@@ -1,15 +0,0 @@
|
||||
#
|
||||
# Config file for a "generic 68360" BSP
|
||||
|
||||
RTEMS_CPU=m68k
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/default.cfg
|
||||
|
||||
CPU_CFLAGS = -mcpu32
|
||||
|
||||
CFLAGS_OPTIMIZE_V = -O2 -g -fomit-frame-pointer
|
||||
|
||||
# FIXME: Disabled because linkcmds lacks proper KEEP() directives. See #2566.
|
||||
# The following two lines enable compiling and linking on per element.
|
||||
CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
|
||||
LDFLAGS = -Wl,--gc-sections
|
||||
@@ -1,385 +0,0 @@
|
||||
/*
|
||||
* SMC1 raw console serial I/O.
|
||||
*
|
||||
* This driver is an example of `POLLING' or `INTERRUPT' I/O.
|
||||
*
|
||||
* To run with interrupt-driven I/O, ensure m360_smc1_interrupt
|
||||
* is set before calling the initialization routine.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Eric Norum <eric@norum.ca>
|
||||
*
|
||||
* 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.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/console.h>
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <rtems/m68k/m68360.h>
|
||||
|
||||
/*
|
||||
* Declare clock speed -- may be overwritten by downloader or debugger
|
||||
*/
|
||||
int m360_clock_rate = 25000000;
|
||||
|
||||
/*
|
||||
* Interrupt-driven input buffer
|
||||
* Declare console baud rate -- may also be overwritten
|
||||
*/
|
||||
int console_baud_rate = 9600;
|
||||
|
||||
/*
|
||||
*/
|
||||
#define RXBUFSIZE 16
|
||||
|
||||
/*
|
||||
* Interrupt-driven callback
|
||||
*/
|
||||
static int m360_smc1_interrupt = 1;
|
||||
static void *smc1ttyp;
|
||||
|
||||
/*
|
||||
* I/O buffers and pointers to buffer descriptors
|
||||
*/
|
||||
static volatile char rxBuf[RXBUFSIZE];
|
||||
static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd;
|
||||
|
||||
/*
|
||||
* Device-specific routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* Compute baud-rate-generator configuration register value
|
||||
*/
|
||||
static int
|
||||
smc1BRGC (int baud)
|
||||
{
|
||||
int divisor;
|
||||
int div16 = 0;
|
||||
|
||||
divisor = ((m360_clock_rate / 16) + (baud / 2)) / baud;
|
||||
if (divisor > 4096) {
|
||||
div16 = 1;
|
||||
divisor = (divisor + 8) / 16;
|
||||
}
|
||||
return M360_BRG_EN | M360_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware-dependent portion of tcsetattr().
|
||||
*/
|
||||
static int
|
||||
smc1SetAttributes (int minor, const struct termios *t)
|
||||
{
|
||||
int baud;
|
||||
|
||||
baud = rtems_termios_baud_to_number(t->c_ospeed);
|
||||
if (baud > 0)
|
||||
m360.brgc1 = smc1BRGC (baud);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handler
|
||||
*/
|
||||
static rtems_isr
|
||||
smc1InterruptHandler (rtems_vector_number v)
|
||||
{
|
||||
/*
|
||||
* Buffer received?
|
||||
*/
|
||||
if (m360.smc1.smce & 0x1) {
|
||||
m360.smc1.smce = 0x1;
|
||||
while ((smcRxBd->status & M360_BD_EMPTY) == 0) {
|
||||
rtems_termios_enqueue_raw_characters (smc1ttyp,
|
||||
(char *)smcRxBd->buffer,
|
||||
smcRxBd->length);
|
||||
smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Buffer transmitted?
|
||||
*/
|
||||
if (m360.smc1.smce & 0x2) {
|
||||
m360.smc1.smce = 0x2;
|
||||
if ((smcTxBd->status & M360_BD_READY) == 0)
|
||||
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
|
||||
}
|
||||
m360.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */
|
||||
}
|
||||
|
||||
static int
|
||||
smc1Initialize (int major, int minor, void *arg)
|
||||
{
|
||||
/*
|
||||
* Allocate buffer descriptors
|
||||
*/
|
||||
smcRxBd = M360AllocateBufferDescriptors (1);
|
||||
smcTxBd = M360AllocateBufferDescriptors (1);
|
||||
|
||||
/*
|
||||
* Configure port B pins to enable SMTXD1 and SMRXD1 pins
|
||||
*/
|
||||
m360.pbpar |= 0xC0;
|
||||
m360.pbdir &= ~0xC0;
|
||||
m360.pbodr &= ~0xC0;
|
||||
|
||||
/*
|
||||
* Set up BRG1 (9,600 baud)
|
||||
*/
|
||||
m360.brgc1 = M360_BRG_RST;
|
||||
m360.brgc1 = smc1BRGC (console_baud_rate);
|
||||
|
||||
/*
|
||||
* Put SMC1 in NMSI mode, connect SMC1 to BRG1
|
||||
*/
|
||||
m360.simode |= M360_SI_SMC1_BRG1;
|
||||
|
||||
/*
|
||||
* Set up SMC1 parameter RAM common to all protocols
|
||||
*/
|
||||
m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360;
|
||||
m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360;
|
||||
m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
|
||||
m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE;
|
||||
if (m360_smc1_interrupt)
|
||||
m360.smc1p.mrblr = RXBUFSIZE;
|
||||
else
|
||||
m360.smc1p.mrblr = 1;
|
||||
|
||||
/*
|
||||
* Set up SMC1 parameter RAM UART-specific parameters
|
||||
*/
|
||||
m360.smc1p.un.uart.max_idl = 10;
|
||||
m360.smc1p.un.uart.brklen = 0;
|
||||
m360.smc1p.un.uart.brkec = 0;
|
||||
m360.smc1p.un.uart.brkcr = 0;
|
||||
|
||||
/*
|
||||
* Set up the Receive Buffer Descriptor
|
||||
*/
|
||||
smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
|
||||
smcRxBd->length = 0;
|
||||
smcRxBd->buffer = rxBuf;
|
||||
|
||||
/*
|
||||
* Setup the Transmit Buffer Descriptor
|
||||
*/
|
||||
smcTxBd->status = M360_BD_WRAP;
|
||||
|
||||
/*
|
||||
* Set up SMC1 general and protocol-specific mode registers
|
||||
*/
|
||||
m360.smc1.smce = ~0; /* Clear any pending events */
|
||||
m360.smc1.smcm = 0; /* Mask all interrupt/event sources */
|
||||
m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART;
|
||||
|
||||
/*
|
||||
* Send "Init parameters" command
|
||||
*/
|
||||
M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1);
|
||||
|
||||
/*
|
||||
* Enable receiver and transmitter
|
||||
*/
|
||||
m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN;
|
||||
|
||||
if (m360_smc1_interrupt) {
|
||||
rtems_isr_entry old_handler;
|
||||
|
||||
(void) rtems_interrupt_catch (smc1InterruptHandler,
|
||||
(m360.cicr & 0xE0) | 0x04,
|
||||
&old_handler);
|
||||
m360.smc1.smcm = 3; /* Enable SMC1 TX and RX interrupts */
|
||||
m360.cimr |= 1UL << 4; /* Enable SMC1 interrupts */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
smc1PollRead (int minor)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
if (smcRxBd->status & M360_BD_EMPTY)
|
||||
return -1;
|
||||
c = rxBuf[0];
|
||||
smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP;
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device-dependent write routine
|
||||
* Interrupt-driven devices:
|
||||
* Begin transmission of as many characters as possible (minimum is 1).
|
||||
* Polling devices:
|
||||
* Transmit all characters.
|
||||
*/
|
||||
static ssize_t
|
||||
smc1InterruptWrite (int minor, const char *buf, size_t len)
|
||||
{
|
||||
if (len > 0) {
|
||||
smcTxBd->buffer = (char *)buf;
|
||||
smcTxBd->length = len;
|
||||
smcTxBd->status = M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
smc1PollWrite (int minor, const char *buf, size_t len)
|
||||
{
|
||||
size_t retval = len;
|
||||
while (len--) {
|
||||
static char txBuf;
|
||||
while (smcTxBd->status & M360_BD_READY)
|
||||
continue;
|
||||
txBuf = *buf++;
|
||||
smcTxBd->buffer = &txBuf;
|
||||
smcTxBd->length = 1;
|
||||
smcTxBd->status = M360_BD_READY | M360_BD_WRAP;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
***************
|
||||
* BOILERPLATE *
|
||||
***************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Reserve resources consumed by this driver
|
||||
*
|
||||
* NOTE: This is in another file to reduce dependencies on the minimum size.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* Set up TERMIOS
|
||||
*/
|
||||
rtems_termios_initialize ();
|
||||
|
||||
/*
|
||||
* Register the device
|
||||
*/
|
||||
status = rtems_io_register_name ("/dev/console", major, 0);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred (status);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the device
|
||||
*/
|
||||
rtems_device_driver console_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
static const rtems_termios_callbacks intrCallbacks = {
|
||||
smc1Initialize, /* firstOpen */
|
||||
NULL, /* lastClose */
|
||||
NULL, /* pollRead */
|
||||
smc1InterruptWrite, /* write */
|
||||
smc1SetAttributes, /* setAttributes */
|
||||
NULL, /* stopRemoteTx */
|
||||
NULL, /* startRemoteTx */
|
||||
TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */
|
||||
};
|
||||
static const rtems_termios_callbacks pollCallbacks = {
|
||||
smc1Initialize, /* firstOpen */
|
||||
NULL, /* lastClose */
|
||||
smc1PollRead, /* pollRead */
|
||||
smc1PollWrite, /* write */
|
||||
smc1SetAttributes, /* setAttributes */
|
||||
NULL, /* stopRemoteTx */
|
||||
NULL, /* startRemoteTx */
|
||||
TERMIOS_POLLED /* outputUsesInterrupts */
|
||||
};
|
||||
|
||||
/*
|
||||
* Do generic termios initialization
|
||||
*/
|
||||
if (m360_smc1_interrupt) {
|
||||
rtems_libio_open_close_args_t *args = arg;
|
||||
|
||||
sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
|
||||
smc1ttyp = args->iop->data1;
|
||||
}
|
||||
else {
|
||||
sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the device
|
||||
*/
|
||||
rtems_device_driver console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_close (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the device
|
||||
*/
|
||||
rtems_device_driver console_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_read (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the device
|
||||
*/
|
||||
rtems_device_driver console_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_write (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle ioctl request.
|
||||
*/
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_ioctl (arg);
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSBSPsM68kGen68360
|
||||
*
|
||||
* @brief Board Support Package for `Generic' Motorola MC68360
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Eric Norum <eric@norum.ca>
|
||||
*
|
||||
* 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.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_M68K_GEN68360_BSP_H
|
||||
#define LIBBSP_M68K_GEN68360_BSP_H
|
||||
|
||||
/**
|
||||
* @defgroup RTEMSBSPsM68kGen68360 Motorola 68360
|
||||
*
|
||||
* @ingroup RTEMSBSPsM68k
|
||||
*
|
||||
* @brief Motorola 68360 Board Support Package.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <bspopts.h>
|
||||
#include <bsp/default-initial-extension.h>
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtems_bsdnet_ifconfig;
|
||||
extern int rtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config, int attaching);
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME "scc1"
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_scc1_driver_attach
|
||||
|
||||
extern rtems_isr_entry M68Kvec[]; /* vector table address */
|
||||
|
||||
/* functions */
|
||||
|
||||
void M360ExecuteRISC( uint16_t command );
|
||||
void *M360AllocateBufferDescriptors( int count );
|
||||
void *M360AllocateRiscTimers( int count );
|
||||
extern char M360DefaultWatchdogFeeder;
|
||||
|
||||
extern int m360_clock_rate; /* BRG clock rate, defined in console.c */
|
||||
|
||||
rtems_isr_entry set_vector(
|
||||
rtems_isr_entry handler,
|
||||
rtems_vector_number vector,
|
||||
int type
|
||||
);
|
||||
|
||||
/*
|
||||
* Definitions for Atlas Computer Equipment Inc. High Speed Bridge (HSB)
|
||||
*/
|
||||
#define ATLASHSB_ESR 0x20010000L
|
||||
#define ATLASHSB_USICR 0x20010001L
|
||||
#define ATLASHSB_DSRR 0x20010002L
|
||||
#define ATLASHSB_LED4 0x20010004L
|
||||
#define ATLASHSB_ROM_U6 0xFF080000L /* U6 flash ROM socket */
|
||||
|
||||
|
||||
/*
|
||||
* definitions for PGH360 board
|
||||
*/
|
||||
#if defined(PGH360)
|
||||
/*
|
||||
* logical SPI addresses of SPI slaves available
|
||||
*/
|
||||
#define PGH360_SPI_ADDR_EEPROM 0
|
||||
#define PGH360_SPI_ADDR_DISP4_DATA 1
|
||||
#define PGH360_SPI_ADDR_DISP4_CTRL 2
|
||||
|
||||
/*
|
||||
* Port B bit locations of SPI slave selects
|
||||
*/
|
||||
#define PGH360_PB_SPI_DISP4_RS_MSK (1<<15)
|
||||
#define PGH360_PB_SPI_DISP4_CE_MSK (1<<14)
|
||||
#define PGH360_PB_SPI_EEP_CE_MSK (1<< 0)
|
||||
#endif /* defined(PGH360) */
|
||||
|
||||
/*
|
||||
* Prototypes for BSP methods which cross file boundaries
|
||||
*/
|
||||
void _Init68360(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -1 +0,0 @@
|
||||
#include <bsp/irq-default.h>
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup m68k_tm27
|
||||
*
|
||||
* @brief Time Test 27
|
||||
*/
|
||||
|
||||
/*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_TMTEST27
|
||||
#error "This is an RTEMS internal file you must not include directly."
|
||||
#endif
|
||||
|
||||
#ifndef __tm27_h
|
||||
#define __tm27_h
|
||||
|
||||
/**
|
||||
* @defgroup m68k_tm27 Stuff for Time Test 27
|
||||
*
|
||||
* @ingroup RTEMSBSPsM68kGen68360
|
||||
*
|
||||
* @brief Don't bother with hardware -- just use a software-interrupt
|
||||
*/
|
||||
|
||||
#define MUST_WAIT_FOR_INTERRUPT 0
|
||||
|
||||
#define TM27_USE_VECTOR_HANDLER
|
||||
|
||||
#define Install_tm27_vector( handler ) set_vector( (handler), 34, 1 )
|
||||
|
||||
#define Cause_tm27_intr() asm volatile ("trap #2");
|
||||
|
||||
#define Clear_tm27_intr() /* empty */
|
||||
|
||||
#define Lower_tm27_intr() /* empty */
|
||||
|
||||
#endif
|
||||
@@ -1,847 +0,0 @@
|
||||
/*
|
||||
* This file contains the M360 SPI driver
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Embedded Brains GmbH. All rights reserved.
|
||||
*
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/m68k/m68360.h>
|
||||
#include <rtems/m68k/m360_spi.h>
|
||||
#include <rtems/error.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <errno.h>
|
||||
#include <rtems/libi2c.h>
|
||||
|
||||
#undef DEBUG
|
||||
static m360_spi_softc_t *m360_spi_softc_ptr;
|
||||
/*
|
||||
* this is a dummy receive buffer for sequences,
|
||||
* where only send data are available
|
||||
*/
|
||||
uint8_t m360_spi_dummy_rxbuf[2];
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static rtems_status_code m360_spi_baud_to_mode
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| determine proper divider value |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
uint32_t baudrate, /* desired baudrate */
|
||||
uint32_t *spimode /* result value */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| o = ok or error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
uint32_t divider;
|
||||
uint16_t tmpmode = 0;
|
||||
/*
|
||||
* determine clock divider and DIV16 bit
|
||||
*/
|
||||
divider = m360_clock_rate/baudrate;
|
||||
if (divider > 64) {
|
||||
tmpmode = M360_SPMODE_DIV16;
|
||||
divider /= 16;
|
||||
}
|
||||
if ((divider < 1) ||
|
||||
(divider > 64)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
else {
|
||||
tmpmode |= M360_SPMODE_PM(divider/4-1);
|
||||
}
|
||||
*spimode = tmpmode;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static rtems_status_code m360_spi_char_mode
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| determine proper value for character size |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
m360_spi_softc_t *softc_ptr, /* handle */
|
||||
uint32_t bits_per_char, /* bits per character */
|
||||
bool lsb_first, /* TRUE: send LSB first */
|
||||
uint16_t *spimode /* result value */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| o = ok or error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
uint16_t tmpmode;
|
||||
|
||||
/*
|
||||
* calculate data format
|
||||
*/
|
||||
if ((bits_per_char >= 4) &&
|
||||
(bits_per_char <= 16)) {
|
||||
tmpmode = M360_SPMODE_CLEN( bits_per_char-1);
|
||||
}
|
||||
else {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
*spimode = tmpmode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int m360_spi_wait
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| wait for spi to become idle |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
m360_spi_softc_t *softc_ptr /* handle */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| o = ok or error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
uint16_t act_status;
|
||||
rtems_status_code rc;
|
||||
uint32_t tout;
|
||||
|
||||
#if defined(DEBUG)
|
||||
printk("m360_spi_wait called... ");
|
||||
#endif
|
||||
if (softc_ptr->initialized) {
|
||||
/*
|
||||
* allow interrupts, when receiver is not empty
|
||||
*/
|
||||
m360.spim = (M360_SPIE_TXE | M360_SPIE_TXB |
|
||||
M360_SPIE_BSY | M360_SPIE_MME);
|
||||
|
||||
rc = rtems_semaphore_obtain(softc_ptr->irq_sema_id,
|
||||
RTEMS_WAIT,
|
||||
RTEMS_NO_TIMEOUT);
|
||||
if (rc != RTEMS_SUCCESSFUL) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tout = 0;
|
||||
do {
|
||||
if (tout++ > 1000000) {
|
||||
#if defined(DEBUG)
|
||||
printk("... exit with RTEMS_TIMEOUT\r\n");
|
||||
#endif
|
||||
return RTEMS_TIMEOUT;
|
||||
}
|
||||
/*
|
||||
* wait for SPI to terminate
|
||||
*/
|
||||
} while (!(m360.spie & M360_SPIE_TXB));
|
||||
}
|
||||
|
||||
act_status = m360.spie;
|
||||
if ((act_status & (M360_SPIE_TXE | M360_SPIE_TXB |
|
||||
M360_SPIE_BSY | M360_SPIE_MME))!= M360_SPIE_TXB) {
|
||||
#if defined(DEBUG)
|
||||
printk("... exit with RTEMS_IO_ERROR,"
|
||||
"act_status=0x%04x,mask=0x%04x,desired_status=0x%04x\r\n",
|
||||
act_status,status_mask,desired_status);
|
||||
#endif
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
#if defined(DEBUG)
|
||||
printk("... exit OK\r\n");
|
||||
#endif
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static rtems_isr m360_spi_irq_handler
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| handle interrupts |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_vector_number v /* vector number */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| <none> |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
m360_spi_softc_t *softc_ptr = m360_spi_softc_ptr;
|
||||
|
||||
/*
|
||||
* disable interrupt mask
|
||||
*/
|
||||
m360.spim = 0;
|
||||
if (softc_ptr->initialized) {
|
||||
rtems_semaphore_release(softc_ptr->irq_sema_id);
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static void m360_spi_install_irq_handler
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| (un-)install the interrupt handler |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
m360_spi_softc_t *softc_ptr, /* ptr to control structure */
|
||||
int install /* TRUE: install, FALSE: remove */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| <none> |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
rtems_status_code rc = RTEMS_SUCCESSFUL;
|
||||
|
||||
/*
|
||||
* (un-)install handler for SPI device
|
||||
*/
|
||||
if (install) {
|
||||
/*
|
||||
* create semaphore for IRQ synchronization
|
||||
*/
|
||||
rc = rtems_semaphore_create(rtems_build_name('s','p','i','s'),
|
||||
0,
|
||||
RTEMS_FIFO
|
||||
| RTEMS_SIMPLE_BINARY_SEMAPHORE,
|
||||
0,
|
||||
&softc_ptr->irq_sema_id);
|
||||
if (rc != RTEMS_SUCCESSFUL) {
|
||||
rtems_panic("SPI: cannot create semaphore");
|
||||
}
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
rc = rtems_interrupt_catch (m360_spi_irq_handler,
|
||||
(m360.cicr & 0xE0) | 0x05,
|
||||
&softc_ptr->old_handler);
|
||||
if (rc != RTEMS_SUCCESSFUL) {
|
||||
rtems_panic("SPI: cannot install IRQ handler");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* enable IRQ in CPIC
|
||||
*/
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
m360.cimr |= (1 << 5);
|
||||
}
|
||||
}
|
||||
else {
|
||||
rtems_isr_entry old_handler;
|
||||
/*
|
||||
* disable IRQ in CPIC
|
||||
*/
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
m360.cimr &= ~(1 << 5);
|
||||
}
|
||||
rc = rtems_interrupt_catch (softc_ptr->old_handler,
|
||||
(m360.cicr & 0xE0) | 0x05,
|
||||
&old_handler);
|
||||
if (rc != RTEMS_SUCCESSFUL) {
|
||||
rtems_panic("SPI: cannot uninstall IRQ handler");
|
||||
}
|
||||
/*
|
||||
* delete sync semaphore
|
||||
*/
|
||||
if (softc_ptr->irq_sema_id != 0) {
|
||||
rc = rtems_semaphore_delete(softc_ptr->irq_sema_id);
|
||||
if (rc != RTEMS_SUCCESSFUL) {
|
||||
rtems_panic("SPI: cannot delete semaphore");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_status_code m360_spi_init
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| initialize the driver |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh /* bus specifier structure */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| o = ok or error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc);
|
||||
rtems_status_code rc = RTEMS_SUCCESSFUL;
|
||||
|
||||
#if defined(DEBUG)
|
||||
printk("m360_spi_init called... ");
|
||||
#endif
|
||||
/*
|
||||
* init HW registers:
|
||||
*/
|
||||
/*
|
||||
* FIXME: set default mode in SPMODE
|
||||
*/
|
||||
|
||||
/*
|
||||
* allocate BDs (1x RX, 1x TX)
|
||||
*/
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
softc_ptr->rx_bd = M360AllocateBufferDescriptors (1);
|
||||
softc_ptr->tx_bd = M360AllocateBufferDescriptors (1);
|
||||
if ((softc_ptr->rx_bd == NULL) ||
|
||||
(softc_ptr->tx_bd == NULL)) {
|
||||
rc = RTEMS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* set parameter RAM
|
||||
*/
|
||||
m360.spip.rbase = (char *)softc_ptr->rx_bd - (char *)&m360;
|
||||
m360.spip.tbase = (char *)softc_ptr->tx_bd - (char *)&m360;
|
||||
m360.spip.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
|
||||
m360.spip.tfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
|
||||
m360.spip.mrblr = 2;
|
||||
|
||||
/*
|
||||
* issue "InitRxTx" Command to CP
|
||||
*/
|
||||
M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SPI);
|
||||
|
||||
/*
|
||||
* init interrupt stuff
|
||||
*/
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
m360_spi_install_irq_handler(softc_ptr,TRUE);
|
||||
}
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
/*
|
||||
* set up ports
|
||||
* LINE PAR DIR DAT
|
||||
* -----------------------
|
||||
* MOSI 1 1 x
|
||||
* MISO 1 1 x
|
||||
* CLK 1 1 x
|
||||
*/
|
||||
|
||||
/* set Port B Pin Assignment Register... */
|
||||
m360.pbpar =
|
||||
m360.pbpar
|
||||
| M360_PB_SPI_MISO_MSK
|
||||
| M360_PB_SPI_MOSI_MSK
|
||||
| M360_PB_SPI_CLK_MSK;
|
||||
|
||||
/* set Port B Data Direction Register... */
|
||||
m360.pbdir =
|
||||
m360.pbdir
|
||||
| M360_PB_SPI_MISO_MSK
|
||||
| M360_PB_SPI_MOSI_MSK
|
||||
| M360_PB_SPI_CLK_MSK;
|
||||
}
|
||||
/*
|
||||
* mark, that we have initialized
|
||||
*/
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
softc_ptr->initialized = TRUE;
|
||||
}
|
||||
#if defined(DEBUG)
|
||||
printk("... exit OK\r\n");
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int m360_spi_read_write_bytes
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| transmit/receive some bytes from SPI device |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
unsigned char *rbuf, /* buffer to store bytes */
|
||||
const unsigned char *tbuf, /* buffer to send bytes */
|
||||
int len /* number of bytes to transceive */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| number of bytes received or (negative) error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc);
|
||||
rtems_status_code rc = RTEMS_SUCCESSFUL;
|
||||
int bc = 0;
|
||||
|
||||
#if defined(DEBUG)
|
||||
printk("m360_spi_read_write_bytes called... ");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* prepare RxBD
|
||||
*/
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
if (rbuf == NULL) {
|
||||
/*
|
||||
* no Tx buffer: receive to dummy buffer
|
||||
*/
|
||||
m360.spip.mrblr = sizeof(m360_spi_dummy_rxbuf);
|
||||
softc_ptr->rx_bd->buffer = m360_spi_dummy_rxbuf;
|
||||
softc_ptr->rx_bd->length = 0;
|
||||
softc_ptr->rx_bd->status = (M360_BD_EMPTY | M360_BD_WRAP |
|
||||
M360_BD_CONTINUOUS);
|
||||
}
|
||||
else {
|
||||
m360.spip.mrblr = len;
|
||||
softc_ptr->rx_bd->buffer = rbuf;
|
||||
softc_ptr->rx_bd->length = 0;
|
||||
softc_ptr->rx_bd->status = (M360_BD_EMPTY | M360_BD_WRAP);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* prepare TxBD
|
||||
*/
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
if (tbuf == NULL) {
|
||||
/*
|
||||
* FIXME: no Tx buffer: transmit from dummy buffer
|
||||
*/
|
||||
softc_ptr->tx_bd->buffer = m360_spi_dummy_rxbuf;
|
||||
softc_ptr->tx_bd->length = len;
|
||||
softc_ptr->tx_bd->status = (M360_BD_READY | M360_BD_WRAP |
|
||||
M360_BD_CONTINUOUS);
|
||||
}
|
||||
else {
|
||||
softc_ptr->tx_bd->buffer = tbuf;
|
||||
softc_ptr->tx_bd->length = len;
|
||||
softc_ptr->tx_bd->status = (M360_BD_READY | M360_BD_WRAP);
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
/*
|
||||
* set START command
|
||||
*/
|
||||
m360.spcom = M360_SPCOM_STR;
|
||||
/*
|
||||
* wait for SPI to finish
|
||||
*/
|
||||
rc = m360_spi_wait(softc_ptr);
|
||||
}
|
||||
#if defined(DEBUG)
|
||||
printk("... exit OK, rc=%d\r\n",bc);
|
||||
#endif
|
||||
return (rc == RTEMS_SUCCESSFUL) ? bc : -rc;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int m360_spi_read_bytes
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| receive some bytes from SPI device |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
unsigned char *buf, /* buffer to store bytes */
|
||||
int len /* number of bytes to receive */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| number of bytes received or (negative) error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
return m360_spi_read_write_bytes(bh,buf,NULL,len);
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int m360_spi_write_bytes
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| send some bytes to SPI device |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
unsigned char *buf, /* buffer to send */
|
||||
int len /* number of bytes to send */
|
||||
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| number of bytes sent or (negative) error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
return m360_spi_read_write_bytes(bh,NULL,buf,len);
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_status_code m360_spi_set_tfr_mode
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| set SPI to desired baudrate/clock mode/character mode |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
const rtems_libi2c_tfr_mode_t *tfr_mode /* transfer mode info */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| rtems_status_code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc);
|
||||
uint32_t spimode_baud,spimode;
|
||||
rtems_status_code rc = RTEMS_SUCCESSFUL;
|
||||
/*
|
||||
* FIXME: set proper mode
|
||||
*/
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
rc = m360_spi_baud_to_mode(tfr_mode->baudrate,&spimode_baud);
|
||||
}
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
rc = m360_spi_char_mode(softc_ptr,
|
||||
tfr_mode->bits_per_char,
|
||||
tfr_mode->lsb_first,
|
||||
&spimode);
|
||||
}
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
spimode |= spimode_baud;
|
||||
spimode |= M360_SPMODE_MASTER; /* set master mode */
|
||||
if (!tfr_mode->lsb_first) {
|
||||
spimode |= M360_SPMODE_REV;
|
||||
}
|
||||
if (tfr_mode->clock_inv) {
|
||||
spimode |= M360_SPMODE_CI;
|
||||
}
|
||||
if (tfr_mode->clock_phs) {
|
||||
spimode |= M360_SPMODE_CP;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == RTEMS_SUCCESSFUL) {
|
||||
/*
|
||||
* disable SPI
|
||||
*/
|
||||
m360.spmode &= ~M360_SPMODE_EN;
|
||||
/*
|
||||
* set new mode and reenable SPI
|
||||
*/
|
||||
m360.spmode = spimode | M360_SPMODE_EN;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int m360_spi_ioctl
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| perform selected ioctl function for SPI |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
int cmd, /* ioctl command code */
|
||||
void *arg /* additional argument array */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| rtems_status_code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
int ret_val = -1;
|
||||
|
||||
switch(cmd) {
|
||||
case RTEMS_LIBI2C_IOCTL_SET_TFRMODE:
|
||||
ret_val =
|
||||
-m360_spi_set_tfr_mode(bh,
|
||||
(const rtems_libi2c_tfr_mode_t *)arg);
|
||||
break;
|
||||
case RTEMS_LIBI2C_IOCTL_READ_WRITE:
|
||||
ret_val =
|
||||
m360_spi_read_write_bytes(bh,
|
||||
((rtems_libi2c_read_write_t *)arg)->rd_buf,
|
||||
((rtems_libi2c_read_write_t *)arg)->wr_buf,
|
||||
((rtems_libi2c_read_write_t *)arg)->byte_cnt);
|
||||
break;
|
||||
default:
|
||||
ret_val = -RTEMS_NOT_DEFINED;
|
||||
break;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Board-specific adaptation functions |
|
||||
\*=========================================================================*/
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static rtems_status_code bsp_spi_sel_addr
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| address a slave device on the bus |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
uint32_t addr, /* address to send on bus */
|
||||
int rw /* 0=write,1=read */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| o = ok or error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
#if defined(PGH360)
|
||||
/*
|
||||
* select given device
|
||||
*/
|
||||
/*
|
||||
* GPIO1[24] is SPI_A0
|
||||
* GPIO1[25] is SPI_A1
|
||||
* GPIO1[26] is SPI_A2
|
||||
* set pins to address
|
||||
*/
|
||||
switch(addr) {
|
||||
case PGH360_SPI_ADDR_EEPROM:
|
||||
m360.pbdat &= ~PGH360_PB_SPI_EEP_CE_MSK;
|
||||
break;
|
||||
case PGH360_SPI_ADDR_DISP4_DATA:
|
||||
m360.pbdat = (m360.pbdat
|
||||
& ~(PGH360_PB_SPI_DISP4_CE_MSK |
|
||||
PGH360_PB_SPI_DISP4_RS_MSK));
|
||||
break;
|
||||
case PGH360_SPI_ADDR_DISP4_CTRL:
|
||||
m360.pbdat = (m360.pbdat
|
||||
& ~(PGH360_PB_SPI_DISP4_CE_MSK)
|
||||
| PGH360_PB_SPI_DISP4_RS_MSK);
|
||||
break;
|
||||
default:
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
#endif /* PGH360 */
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static rtems_status_code bsp_spi_send_start_dummy
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| dummy function, SPI has no start condition |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh /* bus specifier structure */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| o = ok or error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static rtems_status_code bsp_spi_send_stop
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| deselect SPI |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh /* bus specifier structure */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| o = ok or error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
printk("bsp_spi_send_stop called... ");
|
||||
#endif
|
||||
#if defined(PGH360)
|
||||
m360.pbdat = (m360.pbdat
|
||||
| PGH360_PB_SPI_DISP4_CE_MSK
|
||||
| PGH360_PB_SPI_EEP_CE_MSK);
|
||||
#endif
|
||||
#if defined(DEBUG)
|
||||
printk("... exit OK\r\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
| list of handlers |
|
||||
\*=========================================================================*/
|
||||
|
||||
rtems_libi2c_bus_ops_t bsp_spi_ops = {
|
||||
init: m360_spi_init,
|
||||
send_start: bsp_spi_send_start_dummy,
|
||||
send_stop: bsp_spi_send_stop,
|
||||
send_addr: bsp_spi_sel_addr,
|
||||
read_bytes: m360_spi_read_bytes,
|
||||
write_bytes: m360_spi_write_bytes,
|
||||
ioctl: m360_spi_ioctl
|
||||
};
|
||||
|
||||
static m360_spi_desc_t bsp_spi_bus_desc = {
|
||||
{/* public fields */
|
||||
ops: &bsp_spi_ops,
|
||||
size: sizeof(bsp_spi_bus_desc)
|
||||
},
|
||||
{ /* our private fields */
|
||||
initialized: FALSE
|
||||
}
|
||||
};
|
||||
|
||||
/*=========================================================================*\
|
||||
| initialization |
|
||||
\*=========================================================================*/
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_status_code bsp_register_spi
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| register SPI bus and devices |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void /* <none> */
|
||||
)
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| 0 or error code |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
int ret_code;
|
||||
int spi_busno;
|
||||
|
||||
/*
|
||||
* init I2C library (if not already done)
|
||||
*/
|
||||
rtems_libi2c_initialize ();
|
||||
|
||||
/*
|
||||
* init port pins used to address/select SPI devices
|
||||
*/
|
||||
|
||||
#if defined(PGH360)
|
||||
|
||||
/*
|
||||
* set up ports
|
||||
* LINE PAR DIR DAT
|
||||
* -----------------------
|
||||
* EEP_CE 0 1 act-high
|
||||
* DISP4_CS 0 1 act-high
|
||||
* DISP4_RS 0 1 active
|
||||
*/
|
||||
|
||||
/* set Port B Pin Assignment Register... */
|
||||
m360.pbpar =
|
||||
(m360.pbpar
|
||||
& ~(PGH360_PB_SPI_EEP_CE_MSK
|
||||
| PGH360_PB_SPI_DISP4_CE_MSK
|
||||
| PGH360_PB_SPI_DISP4_RS_MSK));
|
||||
|
||||
/* set Port B Data Direction Register... */
|
||||
m360.pbdir =
|
||||
m360.pbdir
|
||||
| PGH360_PB_SPI_EEP_CE_MSK
|
||||
| PGH360_PB_SPI_DISP4_CE_MSK
|
||||
| PGH360_PB_SPI_DISP4_RS_MSK;
|
||||
|
||||
/* set Port B Data Register to inactive CE state */
|
||||
m360.pbdat =
|
||||
m360.pbdat
|
||||
| PGH360_PB_SPI_DISP4_CE_MSK
|
||||
| PGH360_PB_SPI_DISP4_RS_MSK;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* register SPI bus
|
||||
*/
|
||||
ret_code = rtems_libi2c_register_bus("/dev/spi",
|
||||
&(bsp_spi_bus_desc.bus_desc));
|
||||
if (ret_code < 0) {
|
||||
return -ret_code;
|
||||
}
|
||||
spi_busno = ret_code;
|
||||
#if defined(PGH360)
|
||||
/*
|
||||
* register devices
|
||||
*/
|
||||
#if 0
|
||||
ret_code = rtems_libi2c_register_drv(RTEMS_BSP_SPI_FLASH_DEVICE_NAME,
|
||||
spi_flash_m25p40_rw_driver_descriptor,
|
||||
spi_busno,0x00);
|
||||
if (ret_code < 0) {
|
||||
return -ret_code;
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(PGH360) */
|
||||
/*
|
||||
* FIXME: further drivers, when available
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup m68k_m360spi
|
||||
*
|
||||
* @brief this file contains the MC68360 SPI driver declarations
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 embedded brains GmbH & Co. KG
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup m68k_m360spi M360_SPIDRV Support
|
||||
*
|
||||
* @ingroup RTEMSBSPsM68kGen68360
|
||||
*
|
||||
* @brief M360_SPIDRV Support Package
|
||||
*/
|
||||
|
||||
#ifndef _M360_SPIDRV_H
|
||||
#define _M360_SPIDRV_H
|
||||
|
||||
#include <rtems/m68k/m68360.h>
|
||||
#include <rtems/libi2c.h>
|
||||
#include <rtems/irq.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct m360_spi_softc {
|
||||
int initialized;
|
||||
rtems_id irq_sema_id;
|
||||
rtems_isr_entry old_handler;
|
||||
m360BufferDescriptor_t *rx_bd;
|
||||
m360BufferDescriptor_t *tx_bd;
|
||||
} m360_spi_softc_t ;
|
||||
|
||||
typedef struct {
|
||||
rtems_libi2c_bus_t bus_desc;
|
||||
m360_spi_softc_t softc;
|
||||
} m360_spi_desc_t;
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_status_code m360_spi_init
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| initialize the driver |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh /* bus specifier structure */
|
||||
);
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| o = ok or error code |
|
||||
\*=========================================================================*/
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int m360_spi_read_bytes
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| receive some bytes from SPI device |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
unsigned char *buf, /* buffer to store bytes */
|
||||
int len /* number of bytes to receive */
|
||||
);
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| number of bytes received or (negative) error code |
|
||||
\*=========================================================================*/
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int m360_spi_write_bytes
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| send some bytes to SPI device |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
unsigned char *buf, /* buffer to send */
|
||||
int len /* number of bytes to send */
|
||||
|
||||
);
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| number of bytes sent or (negative) error code |
|
||||
\*=========================================================================*/
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_status_code m360_spi_set_tfr_mode
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| set SPI to desired baudrate/clock mode/character mode |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
const rtems_libi2c_tfr_mode_t *tfr_mode /* transfer mode info */
|
||||
);
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| rtems_status_code |
|
||||
\*=========================================================================*/
|
||||
|
||||
/*=========================================================================*\
|
||||
| Function: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int m360_spi_ioctl
|
||||
(
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Purpose: |
|
||||
| perform selected ioctl function for SPI |
|
||||
+---------------------------------------------------------------------------+
|
||||
| Input Parameters: |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
rtems_libi2c_bus_t *bh, /* bus specifier structure */
|
||||
int cmd, /* ioctl command code */
|
||||
void *arg /* additional argument array */
|
||||
);
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Return Value: |
|
||||
| rtems_status_code |
|
||||
\*=========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _M360_SPIDRV_H */
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* MC68360 buffer descriptor allocation routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Eric Norum <eric@norum.ca>
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/m68k/m68360.h>
|
||||
#include <rtems/error.h>
|
||||
|
||||
/*
|
||||
* Allocation order:
|
||||
* - Dual-Port RAM section 1
|
||||
* - Dual-Port RAM section 3
|
||||
* - Dual-Port RAM section 0
|
||||
* - Dual-Port RAM section 2
|
||||
*/
|
||||
static struct {
|
||||
uint8_t *base;
|
||||
uint32_t size;
|
||||
uint32_t used;
|
||||
} bdregions[] = {
|
||||
{ (uint8_t *)&m360.dpram1[0], sizeof m360.dpram1, 0 },
|
||||
{ (uint8_t *)&m360.dpram3[0], sizeof m360.dpram3, 0 },
|
||||
{ (uint8_t *)&m360.dpram0[0], sizeof m360.dpram0, 0 },
|
||||
{ (uint8_t *)&m360.dpram2[0], sizeof m360.dpram2, 0 },
|
||||
};
|
||||
|
||||
/*
|
||||
* Send a command to the CPM RISC processer
|
||||
*/
|
||||
void *
|
||||
M360AllocateBufferDescriptors (int count)
|
||||
{
|
||||
unsigned int i;
|
||||
ISR_Level level;
|
||||
void *bdp = NULL;
|
||||
unsigned int want = count * sizeof(m360BufferDescriptor_t);
|
||||
|
||||
/*
|
||||
* Running with interrupts disabled is usually considered bad
|
||||
* form, but this routine is probably being run as part of an
|
||||
* initialization sequence so the effect shouldn't be too severe.
|
||||
*/
|
||||
_ISR_Local_disable (level);
|
||||
for (i = 0 ; i < sizeof(bdregions) / sizeof(bdregions[0]) ; i++) {
|
||||
/*
|
||||
* Verify that the region exists.
|
||||
* This test is necessary since some chips have
|
||||
* less dual-port RAM.
|
||||
*/
|
||||
if (bdregions[i].used == 0) {
|
||||
volatile uint8_t *cp = bdregions[i].base;
|
||||
*cp = 0xAA;
|
||||
if (*cp != 0xAA) {
|
||||
bdregions[i].used = bdregions[i].size;
|
||||
continue;
|
||||
}
|
||||
*cp = 0x55;
|
||||
if (*cp != 0x55) {
|
||||
bdregions[i].used = bdregions[i].size;
|
||||
continue;
|
||||
}
|
||||
*cp = 0x0;
|
||||
}
|
||||
if (bdregions[i].size - bdregions[i].used >= want) {
|
||||
bdp = bdregions[i].base + bdregions[i].used;
|
||||
bdregions[i].used += want;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ISR_Local_enable (level);
|
||||
if (bdp == NULL)
|
||||
rtems_panic ("Can't allocate %d buffer descriptor(s).\n", count);
|
||||
return bdp;
|
||||
}
|
||||
|
||||
void *
|
||||
M360AllocateRiscTimers (int count)
|
||||
{
|
||||
/*
|
||||
* Convert the count to the number of buffer descriptors
|
||||
* of equal or larger size. This ensures that all buffer
|
||||
* descriptors are allocated with appropriate alignment.
|
||||
*/
|
||||
return M360AllocateBufferDescriptors (((count * 4) +
|
||||
sizeof(m360BufferDescriptor_t) - 1) /
|
||||
sizeof(m360BufferDescriptor_t));
|
||||
}
|
||||
@@ -1,842 +0,0 @@
|
||||
/*
|
||||
* MC68360 support routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Eric Norum <eric@norum.ca>
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/m68k/m68360.h>
|
||||
|
||||
extern void _CopyDataClearBSSAndStart (unsigned long ramSize);
|
||||
extern void *RamBase;
|
||||
extern void *_RomBase; /* From linkcmds */
|
||||
|
||||
/*
|
||||
* Declare the m360 structure here for the benefit of the debugger
|
||||
*/
|
||||
|
||||
volatile m360_t m360;
|
||||
|
||||
/*
|
||||
* Send a command to the CPM RISC processer
|
||||
*/
|
||||
|
||||
void M360ExecuteRISC(uint16_t command)
|
||||
{
|
||||
uint16_t sr;
|
||||
|
||||
m68k_disable_interrupts (sr);
|
||||
while (m360.cr & M360_CR_FLG)
|
||||
continue;
|
||||
m360.cr = command | M360_CR_FLG;
|
||||
m68k_enable_interrupts (sr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize MC68360
|
||||
*/
|
||||
void _Init68360 (void)
|
||||
{
|
||||
int i;
|
||||
rtems_isr_entry *vbr;
|
||||
unsigned long ramSize;
|
||||
|
||||
#if (defined (__mc68040__))
|
||||
volatile unsigned long *RamBase_p;
|
||||
|
||||
RamBase_p = (volatile unsigned long *)&RamBase;
|
||||
|
||||
/*
|
||||
*******************************************
|
||||
* Motorola 68040 and companion-mode 68360 *
|
||||
*******************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 6: Is this a power-up reset?
|
||||
* For now we just ignore this and do *all* the steps
|
||||
* Someday we might want to:
|
||||
* if (Hard, Loss of Clock, Power-up)
|
||||
* Do all steps
|
||||
* else if (Double bus fault, watchdog or soft reset)
|
||||
* Skip to step 12
|
||||
* else (must be a reset command)
|
||||
* Skip to step 14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external 25 MHz oscillator.
|
||||
*/
|
||||
m360.clkocr = 0x83; /* No more writes, full-power CLKO2 */
|
||||
m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
|
||||
no LPSTOP slowdown, PLL X1 */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor for external cycles
|
||||
* 1024 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEC;
|
||||
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT standard M68000 family interrupt level encoding
|
||||
* CF1MODE=10 (BCLRO* output)
|
||||
* No RAS1* double drive
|
||||
* A31 - A28
|
||||
* AMUX output
|
||||
* CAS2* - CAS3*
|
||||
* CAS0* - CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
*/
|
||||
m360.pepar = 0x3440;
|
||||
|
||||
/*
|
||||
* Step 11: Remap Chip Select 0 (CS0*), set up GMR
|
||||
*/
|
||||
/*
|
||||
* 512 addresses per DRAM page (256K DRAM chips)
|
||||
* 70 nsec DRAM
|
||||
* 180 nsec ROM (3 wait states)
|
||||
*/
|
||||
m360.gmr = M360_GMR_RCNT(23) | M360_GMR_RFEN |
|
||||
M360_GMR_RCYC(0) | M360_GMR_PGS(1) |
|
||||
M360_GMR_DPS_32BIT | M360_GMR_NCS |
|
||||
M360_GMR_TSS40;
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_32BIT;
|
||||
|
||||
/*
|
||||
* Step 12: Initialize the system RAM
|
||||
*/
|
||||
/*
|
||||
* Set up option/base registers
|
||||
* 1M DRAM
|
||||
* 70 nsec DRAM
|
||||
* Enable burst mode
|
||||
* No parity checking
|
||||
* Wait for chips to power up
|
||||
* Perform 8 read cycles
|
||||
*/
|
||||
ramSize = 1 * 1024 * 1024;
|
||||
m360.memc[1].or = M360_MEMC_OR_TCYC(0) |
|
||||
M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_DRAM;
|
||||
m360.memc[1].br = (unsigned long)&RamBase |
|
||||
M360_MEMC_BR_BACK40 |
|
||||
M360_MEMC_BR_V;
|
||||
for (i = 0; i < 50000; i++)
|
||||
continue;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
unsigned long rambase_value;
|
||||
rambase_value = *RamBase_p;
|
||||
(void) rambase_value; /* avoid set but not used warning */
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Enable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Bus request MC68040 Arbitration ID 3
|
||||
* Bus asynchronous timing mode (work around bug in Rev. B)
|
||||
* Arbitration asynchronous timing mode
|
||||
* Disable timers during FREEZE
|
||||
* Disable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
* No show cycles
|
||||
* User/supervisor access
|
||||
* Bus clear in arbitration ID level 3
|
||||
* SIM60 interrupt sources higher priority than CPM
|
||||
*/
|
||||
m360.mcr = 0x6000EC3F;
|
||||
|
||||
#elif (defined (M68360_ATLAS_HSB))
|
||||
/*
|
||||
******************************************
|
||||
* Standalone Motorola 68360 -- ATLAS HSB *
|
||||
******************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 6: Is this a power-up reset?
|
||||
* For now we just ignore this and do *all* the steps
|
||||
* Someday we might want to:
|
||||
* if (Hard, Loss of Clock, Power-up)
|
||||
* Do all steps
|
||||
* else if (Double bus fault, watchdog or soft reset)
|
||||
* Skip to step 12
|
||||
* else (must be a CPU32+ reset command)
|
||||
* Skip to step 14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external 25 MHz oscillator.
|
||||
*/
|
||||
m360.clkocr = 0x8F; /* No more writes, no clock outputs */
|
||||
m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
|
||||
no LPSTOP slowdown, PLL X1 */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor for external cycles
|
||||
* 1024 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEC;
|
||||
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT not used (CPU32+ mode)
|
||||
* CF1MODE=00 (CONFIG1 input)
|
||||
* RAS1* double drive
|
||||
* WE0* - WE3*
|
||||
* OE* output
|
||||
* CAS2* - CAS3*
|
||||
* CAS0* - CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
* (static RAM, external address multiplexing, etc).
|
||||
*/
|
||||
m360.pepar = 0x0180;
|
||||
|
||||
/*
|
||||
* Step 11: Remap Chip Select 0 (CS0*), set up GMR
|
||||
*/
|
||||
m360.gmr = M360_GMR_RCNT(12) | M360_GMR_RFEN |
|
||||
M360_GMR_RCYC(0) | M360_GMR_PGS(1) |
|
||||
M360_GMR_DPS_32BIT | M360_GMR_DWQ |
|
||||
M360_GMR_GAMX;
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
|
||||
/*
|
||||
* Step 12: Initialize the system RAM
|
||||
*/
|
||||
ramSize = 2 * 1024 * 1024;
|
||||
/* first bank 1MByte DRAM */
|
||||
m360.memc[1].or = M360_MEMC_OR_TCYC(2) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_PGME | M360_MEMC_OR_DRAM;
|
||||
m360.memc[1].br = (unsigned long)&RamBase | M360_MEMC_BR_V;
|
||||
|
||||
/* second bank 1MByte DRAM */
|
||||
m360.memc[2].or = M360_MEMC_OR_TCYC(2) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_PGME | M360_MEMC_OR_DRAM;
|
||||
m360.memc[2].br = ((unsigned long)&RamBase + 0x100000) |
|
||||
M360_MEMC_BR_V;
|
||||
|
||||
/* flash rom socket U6 on CS5 */
|
||||
m360.memc[5].br = (unsigned long)ATLASHSB_ROM_U6 | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[5].or = M360_MEMC_OR_WAITS(2) | M360_MEMC_OR_512KB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
|
||||
/* CSRs on CS7 */
|
||||
m360.memc[7].or = M360_MEMC_OR_TCYC(4) | M360_MEMC_OR_64KB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
m360.memc[7].br = ATLASHSB_ESR | 0x01;
|
||||
for (i = 0; i < 50000; i++)
|
||||
continue;
|
||||
for (i = 0; i < 8; ++i)
|
||||
*((volatile unsigned long *)(unsigned long)&RamBase);
|
||||
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Enable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Disable timers during FREEZE
|
||||
* Enable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
*/
|
||||
|
||||
#elif defined(PGH360)
|
||||
/*
|
||||
* Step 6: Is this a power-up reset?
|
||||
* For now we just ignore this and do *all* the steps
|
||||
* Someday we might want to:
|
||||
* if (Hard, Loss of Clock, Power-up)
|
||||
* Do all steps
|
||||
* else if (Double bus fault, watchdog or soft reset)
|
||||
* Skip to step 12
|
||||
* else (must be a CPU32+ reset command)
|
||||
* Skip to step 14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external 25 MHz oscillator.
|
||||
*/
|
||||
m360.clkocr = 0x8e; /* No more writes, CLKO1=1/3, CLKO2=off */
|
||||
/*
|
||||
* adjust crystal to average between 4.19 MHz and 4.00 MHz
|
||||
* reprogram pll
|
||||
*/
|
||||
m360.pllcr = 0xA000+(24576000/((4000000+4194304)/2/128))-1;
|
||||
/* LPSTOP slowdown, PLL /128*??? */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* 128 sec. watchdog timeout
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor external
|
||||
* 128 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEF;
|
||||
/*
|
||||
* also initialize the SWP bit in PITR to 1
|
||||
*/
|
||||
m360.pitr |= 0x0200;
|
||||
/*
|
||||
* and trigger SWSR twice to ensure, that interval starts right now
|
||||
*/
|
||||
m360.swsr = 0x55;
|
||||
m360.swsr = 0xAA;
|
||||
m360.swsr = 0x55;
|
||||
m360.swsr = 0xAA;
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT not used (CPU32+ mode)
|
||||
* CF1MODE=00 (CONFIG1 input)
|
||||
* IPIPE1
|
||||
* WE0-3
|
||||
* OE* output
|
||||
* CAS2* / CAS3*
|
||||
* CAS0* / CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
* (static RAM, external address multiplexing, etc).
|
||||
*/
|
||||
m360.pepar = 0x0080;
|
||||
/*
|
||||
* Step 11: Remap Chip Select 0 (CS0*), set up GMR
|
||||
* no DRAM support
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
*/
|
||||
m360.gmr = M360_GMR_RCNT(23) | M360_GMR_RFEN | M360_GMR_RCYC(0) |
|
||||
M360_GMR_PGS(6) | M360_GMR_DPS_32BIT | M360_GMR_DWQ |
|
||||
M360_GMR_GAMX;
|
||||
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_512KB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
|
||||
/*
|
||||
* Step 12: Initialize the system RAM
|
||||
* Set up option/base registers
|
||||
* 16 MB DRAM
|
||||
* 1 wait state
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
* NOTE: no Page mode possible for EDO RAMs (?)
|
||||
*/
|
||||
ramSize = 16 * 1024 * 1024;
|
||||
m360.memc[7].or = M360_MEMC_OR_TCYC(1) | M360_MEMC_OR_16MB |
|
||||
M360_MEMC_OR_FCMC(0) | /* M360_MEMC_OR_PGME | */
|
||||
M360_MEMC_OR_32BIT | M360_MEMC_OR_DRAM;
|
||||
m360.memc[7].br = (unsigned long)&RamBase | M360_MEMC_BR_V;
|
||||
|
||||
/*
|
||||
* FIXME: here we should wait for 8 refresh cycles...
|
||||
*/
|
||||
/*
|
||||
* Step 12a: test the ram, if wanted
|
||||
* FIXME: when do we call this?
|
||||
* -> only during firmware execution
|
||||
* -> perform intesive test only on request
|
||||
* -> ensure, that results are stored properly
|
||||
*/
|
||||
#if 0 /* FIXME: activate RAM tests again */
|
||||
{
|
||||
void *ram_base, *ram_end, *code_loc;
|
||||
extern char ramtest_start,ramtest_end;
|
||||
ram_base = &ramtest_start;
|
||||
ram_end = &ramtest_end;
|
||||
code_loc = (void *)ramtest_exec;
|
||||
if ((ram_base < ram_end) &&
|
||||
!((ram_base <= code_loc) && (code_loc < ram_end))) {
|
||||
ramtest_exec(ram_base,ram_end);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Disable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Disable timers during FREEZE
|
||||
* Enable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
* No show cycles
|
||||
* User/supervisor access
|
||||
* Bus clear interupt service level 7
|
||||
* SIM60 interrupt sources higher priority than CPM
|
||||
*/
|
||||
m360.mcr = 0x4C7F;
|
||||
|
||||
#elif (defined (GEN68360_WITH_SRAM))
|
||||
/*
|
||||
***************************************************
|
||||
* Generic Standalone Motorola 68360 *
|
||||
* As described in MC68360 User's Manual *
|
||||
* But uses SRAM instead of DRAM *
|
||||
* CS0* - 512kx8 flash memory *
|
||||
* CS1* - 512kx32 static RAM *
|
||||
* CS2* - 512kx32 static RAM *
|
||||
***************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external oscillator which
|
||||
* oscillates at the system clock rate.
|
||||
*/
|
||||
m360.clkocr = 0x8F; /* No more writes, no clock outputs */
|
||||
m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
|
||||
no LPSTOP slowdown, PLL X1 */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor for external cycles
|
||||
* 1024 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEC;
|
||||
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT not used (CPU32+ mode)
|
||||
* CF1MODE=00 (CONFIG1 input)
|
||||
* IPIPE1*
|
||||
* WE0* - WE3*
|
||||
* OE* output
|
||||
* CAS2* - CAS3*
|
||||
* CAS0* - CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
* (static RAM, external address multiplexing, etc).
|
||||
*/
|
||||
m360.pepar = 0x0080;
|
||||
|
||||
/*
|
||||
* Step 11: Set up GMR
|
||||
*
|
||||
*/
|
||||
m360.gmr = 0x0;
|
||||
|
||||
/*
|
||||
* Step 11a: Remap 512Kx8 flash memory on CS0*
|
||||
* 2 wait states
|
||||
* Make it read-only for now
|
||||
*/
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(2) | M360_MEMC_OR_512KB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
/*
|
||||
* Step 12: Set up main memory
|
||||
* 512Kx32 SRAM on CS1*
|
||||
* 512Kx32 SRAM on CS2*
|
||||
* 0 wait states
|
||||
*/
|
||||
ramSize = 4 * 1024 * 1024;
|
||||
m360.memc[1].br = (unsigned long)&RamBase | M360_MEMC_BR_V;
|
||||
m360.memc[1].or = M360_MEMC_OR_WAITS(0) | M360_MEMC_OR_2MB |
|
||||
M360_MEMC_OR_32BIT;
|
||||
m360.memc[2].br = ((unsigned long)&RamBase + 0x200000) | M360_MEMC_BR_V;
|
||||
m360.memc[2].or = M360_MEMC_OR_WAITS(0) | M360_MEMC_OR_2MB |
|
||||
M360_MEMC_OR_32BIT;
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Enable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Disable timers during FREEZE
|
||||
* Enable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
* No show cycles
|
||||
* User/supervisor access
|
||||
* Bus clear interrupt service level 7
|
||||
* SIM60 interrupt sources higher priority than CPM
|
||||
*/
|
||||
m360.mcr = 0x4C7F;
|
||||
|
||||
#else
|
||||
volatile unsigned long *RamBase_p;
|
||||
|
||||
RamBase_p = (volatile unsigned long *)&RamBase;
|
||||
/*
|
||||
***************************************************
|
||||
* Generic Standalone Motorola 68360 *
|
||||
* As described in MC68360 User's Manual *
|
||||
* Atlas ACE360 *
|
||||
***************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 6: Is this a power-up reset?
|
||||
* For now we just ignore this and do *all* the steps
|
||||
* Someday we might want to:
|
||||
* if (Hard, Loss of Clock, Power-up)
|
||||
* Do all steps
|
||||
* else if (Double bus fault, watchdog or soft reset)
|
||||
* Skip to step 12
|
||||
* else (must be a CPU32+ reset command)
|
||||
* Skip to step 14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external 25 MHz oscillator.
|
||||
*/
|
||||
m360.clkocr = 0x8F; /* No more writes, no clock outputs */
|
||||
m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
|
||||
no LPSTOP slowdown, PLL X1 */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor for external cycles
|
||||
* 1024 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEC;
|
||||
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT not used (CPU32+ mode)
|
||||
* CF1MODE=00 (CONFIG1 input)
|
||||
* RAS1* double drive
|
||||
* WE0* - WE3*
|
||||
* OE* output
|
||||
* CAS2* - CAS3*
|
||||
* CAS0* - CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
* (static RAM, external address multiplexing, etc).
|
||||
*/
|
||||
m360.pepar = 0x0180;
|
||||
|
||||
/*
|
||||
* Step 11: Remap Chip Select 0 (CS0*), set up GMR
|
||||
* 32-bit DRAM
|
||||
* Internal DRAM address multiplexing
|
||||
* 60 nsec DRAM
|
||||
* 180 nsec ROM (3 wait states)
|
||||
* 15.36 usec DRAM refresh interval
|
||||
* The DRAM page size selection is not modified since this
|
||||
* startup code may be running in a bootstrap PROM or in
|
||||
* a program downloaded by the bootstrap PROM.
|
||||
*/
|
||||
m360.gmr = (m360.gmr & 0x001C0000) | M360_GMR_RCNT(23) |
|
||||
M360_GMR_RFEN | M360_GMR_RCYC(0) |
|
||||
M360_GMR_DPS_32BIT | M360_GMR_NCS |
|
||||
M360_GMR_GAMX;
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
|
||||
/*
|
||||
* Step 12: Initialize the system RAM
|
||||
* Do this only if the DRAM has not already been set up
|
||||
*/
|
||||
if ((m360.memc[1].br & M360_MEMC_BR_V) == 0) {
|
||||
/*
|
||||
* Set up GMR DRAM page size, option and base registers
|
||||
* Assume 16Mbytes of DRAM
|
||||
* 60 nsec DRAM
|
||||
*/
|
||||
m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(5);
|
||||
m360.memc[1].or = M360_MEMC_OR_TCYC(0) |
|
||||
M360_MEMC_OR_16MB |
|
||||
M360_MEMC_OR_DRAM;
|
||||
m360.memc[1].br = (unsigned long)&RamBase | M360_MEMC_BR_V;
|
||||
|
||||
/*
|
||||
* Wait for chips to power up
|
||||
* Perform 8 read cycles
|
||||
*/
|
||||
for (i = 0; i < 50000; i++)
|
||||
continue;
|
||||
for (i = 0; i < 8; ++i)
|
||||
*RamBase_p;
|
||||
|
||||
/*
|
||||
* Determine memory size (1, 4, or 16 Mbytes)
|
||||
* Set GMR DRAM page size appropriately.
|
||||
* The OR is left at 16 Mbytes. The bootstrap PROM places its
|
||||
* .data and .bss segments at the top of the 16 Mbyte space.
|
||||
* A 1 Mbyte or 4 Mbyte DRAM will show up several times in
|
||||
* the memory map, but will work with the same bootstrap PROM.
|
||||
*/
|
||||
*(volatile char *)&RamBase = 0;
|
||||
*((volatile char *)&RamBase+0x00C01800) = 1;
|
||||
if (*(volatile char *)&RamBase) {
|
||||
m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(1);
|
||||
}
|
||||
else {
|
||||
*((volatile char *)&RamBase+0x00801000) = 1;
|
||||
if (*(volatile char *)&RamBase) {
|
||||
m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(3);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable parity checking
|
||||
*/
|
||||
m360.memc[1].br |= M360_MEMC_BR_PAREN;
|
||||
}
|
||||
switch (m360.gmr & 0x001C0000) {
|
||||
default: ramSize = 4 * 1024 * 1024; break;
|
||||
case M360_GMR_PGS(1): ramSize = 1 * 1024 * 1024; break;
|
||||
case M360_GMR_PGS(3): ramSize = 4 * 1024 * 1024; break;
|
||||
case M360_GMR_PGS(5): ramSize = 16 * 1024 * 1024; break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Enable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Disable timers during FREEZE
|
||||
* Enable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
* No show cycles
|
||||
* User/supervisor access
|
||||
* Bus clear interrupt service level 7
|
||||
* SIM60 interrupt sources higher priority than CPM
|
||||
*/
|
||||
m360.mcr = 0x4C7F;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copy data, clear BSS, switch stacks and call main()
|
||||
* Must pass ramSize as argument since the data/bss segment
|
||||
* may be overwritten.
|
||||
*/
|
||||
_CopyDataClearBSSAndStart (ramSize);
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
/*
|
||||
* This file contains GNU linker directives for a generic MC68360 board.
|
||||
* Variations in memory size and allocation can be made by
|
||||
* overriding some values with linker command-line arguments.
|
||||
*
|
||||
* Saskatchewan Accelerator Laboratory
|
||||
* University of Saskatchewan
|
||||
* Saskatoon, Saskatchewan, CANADA
|
||||
* eric@skatter.usask.ca
|
||||
*/
|
||||
|
||||
/*
|
||||
* Declare some sizes.
|
||||
* A heap size of 0 means `use all available memory for the heap'.
|
||||
*/
|
||||
RamBase = DEFINED(RamBase) ? RamBase : 0x0;
|
||||
RamSize = DEFINED(RamSize) ? RamSize : 64M;
|
||||
RamEnd = RamBase + RamSize;
|
||||
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0;
|
||||
|
||||
/*
|
||||
* Declare on-board memory.
|
||||
*/
|
||||
MEMORY {
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 64M
|
||||
rom : ORIGIN = 0x0F000000, LENGTH = 1M
|
||||
dpram : ORIGIN = 0x0E000000, LENGTH = 8k
|
||||
}
|
||||
|
||||
ENTRY(start)
|
||||
STARTUP(start.o)
|
||||
|
||||
/*
|
||||
* Load objects
|
||||
*/
|
||||
SECTIONS {
|
||||
/*
|
||||
* Boot PROM
|
||||
*/
|
||||
rom : {
|
||||
_RomBase = .;
|
||||
} >rom
|
||||
|
||||
/*
|
||||
* Dynamic RAM
|
||||
*/
|
||||
ram : {
|
||||
RamBase = .;
|
||||
} >ram
|
||||
|
||||
/*
|
||||
* Text, data and bss segments
|
||||
*/
|
||||
.text : {
|
||||
*(.text*)
|
||||
|
||||
/*
|
||||
* C++ constructors/destructors
|
||||
*/
|
||||
*(.gnu.linkonce.t.*)
|
||||
|
||||
/*
|
||||
* Initialization and finalization code.
|
||||
*/
|
||||
PROVIDE (_init = .);
|
||||
*crti.o(.init)
|
||||
*(.init)
|
||||
*crtn.o(.init)
|
||||
PROVIDE (_fini = .);
|
||||
*crti.o(.fini)
|
||||
*(.fini)
|
||||
*crtn.o(.fini)
|
||||
|
||||
/*
|
||||
* Special FreeBSD sysctl sections.
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
__start_set_sysctl_set = .;
|
||||
*(set_sysctl_*);
|
||||
__stop_set_sysctl_set = ABSOLUTE(.);
|
||||
*(set_domain_*);
|
||||
*(set_pseudo_*);
|
||||
|
||||
/*
|
||||
* C++ constructors/destructors
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
*crtbegin.o(.ctors)
|
||||
*(.ctors)
|
||||
*crtend.o(.ctors)
|
||||
*crtbegin.o(.dtors)
|
||||
*(.dtors)
|
||||
*crtend.o(.dtors)
|
||||
|
||||
/*
|
||||
* Exception frame info
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
*(.eh_frame)
|
||||
|
||||
/*
|
||||
* Read-only data
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
_rodata_start = . ;
|
||||
*(.rodata*)
|
||||
KEEP (*(SORT(.rtemsroset.*)))
|
||||
*(.gnu.linkonce.r*)
|
||||
|
||||
. = ALIGN (16);
|
||||
PROVIDE (etext = .);
|
||||
} >ram
|
||||
|
||||
.tdata : {
|
||||
_TLS_Data_begin = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_TLS_Data_end = .;
|
||||
} >ram
|
||||
|
||||
.tbss : {
|
||||
_TLS_BSS_begin = .;
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
|
||||
_TLS_BSS_end = .;
|
||||
} >ram
|
||||
|
||||
_TLS_Data_size = _TLS_Data_end - _TLS_Data_begin;
|
||||
_TLS_Data_begin = _TLS_Data_size != 0 ? _TLS_Data_begin : _TLS_BSS_begin;
|
||||
_TLS_Data_end = _TLS_Data_size != 0 ? _TLS_Data_end : _TLS_BSS_begin;
|
||||
_TLS_BSS_size = _TLS_BSS_end - _TLS_BSS_begin;
|
||||
_TLS_Size = _TLS_BSS_end - _TLS_Data_begin;
|
||||
_TLS_Alignment = MAX (ALIGNOF (.tdata), ALIGNOF (.tbss));
|
||||
|
||||
.data : {
|
||||
_copy_start = .;
|
||||
*(.data*)
|
||||
KEEP (*(SORT(.rtemsrwset.*)))
|
||||
*(.gnu.linkonce.d*)
|
||||
*(.gcc_except_table*)
|
||||
*(.jcr)
|
||||
. = ALIGN (16);
|
||||
PROVIDE (edata = .);
|
||||
_copy_end = .;
|
||||
} >ram
|
||||
.bss : {
|
||||
M68Kvec = .;
|
||||
. += (256 * 4);
|
||||
_clear_start = .;
|
||||
*(.dynbss)
|
||||
*(.bss* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (16);
|
||||
PROVIDE (end = .);
|
||||
_clear_end = .;
|
||||
} >ram
|
||||
|
||||
.noinit (NOLOAD) : {
|
||||
*(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*)))
|
||||
} > ram
|
||||
|
||||
.rtemsstack (NOLOAD) : {
|
||||
*(SORT(.rtemsstack.*))
|
||||
WorkAreaBase = .;
|
||||
} >ram
|
||||
|
||||
/*
|
||||
* On-chip memory/peripherals
|
||||
*/
|
||||
dpram : {
|
||||
m360 = .;
|
||||
. += (8 * 1024);
|
||||
} >dpram
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* These must appear regardless of . */
|
||||
|
||||
/* Addition to let linker know about custom section for GDB pretty-printing support. */
|
||||
.debug_gdb_scripts 0 : { *(.debug_gdb_scripts) }
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* This file contains GNU linker directives for a generic MC68360 board.
|
||||
* Variations in memory size and allocation can be made by
|
||||
* overriding some values with linker command-line arguments.
|
||||
*
|
||||
* These linker directives are for producing a bootstrap PROM version.
|
||||
* The data segment is placed at the end of the text segment in the PROM.
|
||||
* The start-up code takes care of copying this region to RAM.
|
||||
*
|
||||
* Saskatchewan Accelerator Laboratory
|
||||
* University of Saskatchewan
|
||||
* Saskatoon, Saskatchewan, CANADA
|
||||
* eric@skatter.usask.ca
|
||||
*/
|
||||
|
||||
/*
|
||||
* Declare some sizes.
|
||||
* A heap size of 0 means `use all available memory for the heap'.
|
||||
*/
|
||||
RamBase = DEFINED(RamBase) ? RamBase : 0x0;
|
||||
RamSize = DEFINED(RamSize) ? RamSize : 64M;
|
||||
RamEnd = RamBase + RamSize;
|
||||
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0;
|
||||
|
||||
/*
|
||||
* Declare on-board memory.
|
||||
*/
|
||||
MEMORY {
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 64M
|
||||
myram : ORIGIN = 16M-400k, LENGTH = 400k
|
||||
rom : ORIGIN = 0x0F000000, LENGTH = 1M
|
||||
dpram : ORIGIN = 0x0E000000, LENGTH = 8k
|
||||
}
|
||||
|
||||
/*
|
||||
* Load objects
|
||||
*/
|
||||
SECTIONS {
|
||||
/*
|
||||
* Boot PROM
|
||||
*/
|
||||
rom : {
|
||||
_RomBase = .;
|
||||
} >rom
|
||||
|
||||
/*
|
||||
* Dynamic RAM
|
||||
*/
|
||||
ram : {
|
||||
RamBase = .;
|
||||
} >ram
|
||||
|
||||
/*
|
||||
* Text, data and bss segments
|
||||
*/
|
||||
.text : AT(0x0) {
|
||||
*(.text*)
|
||||
|
||||
/*
|
||||
* C++ constructors/destructors
|
||||
*/
|
||||
*(.gnu.linkonce.t.*)
|
||||
|
||||
/*
|
||||
* Initialization and finalization code.
|
||||
*/
|
||||
PROVIDE (_init = .);
|
||||
*crti.o(.init)
|
||||
*(.init)
|
||||
*crtn.o(.init)
|
||||
PROVIDE (_fini = .);
|
||||
*crti.o(.fini)
|
||||
*(.fini)
|
||||
*crtn.o(.fini)
|
||||
|
||||
/*
|
||||
* Special FreeBSD sysctl sections.
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
__start_set_sysctl_set = .;
|
||||
*(set_sysctl_*);
|
||||
__stop_set_sysctl_set = ABSOLUTE(.);
|
||||
*(set_domain_*);
|
||||
*(set_pseudo_*);
|
||||
|
||||
/*
|
||||
* C++ constructors/destructors
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
*crtbegin.o(.ctors)
|
||||
*(.ctors)
|
||||
*crtend.o(.ctors)
|
||||
*crtbegin.o(.dtors)
|
||||
*(.dtors)
|
||||
*crtend.o(.dtors)
|
||||
|
||||
/*
|
||||
* Exception frame info
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
*(.eh_frame)
|
||||
|
||||
/*
|
||||
* Read-only data
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
_rodata_start = . ;
|
||||
*(.rodata*)
|
||||
KEEP (*(SORT(.rtemsroset.*)))
|
||||
*(.gnu.linkonce.r*)
|
||||
|
||||
. = ALIGN (16);
|
||||
PROVIDE (etext = .);
|
||||
} >rom
|
||||
|
||||
.tdata : {
|
||||
_TLS_Data_begin = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_TLS_Data_end = .;
|
||||
} >rom
|
||||
|
||||
.tbss : {
|
||||
_TLS_BSS_begin = .;
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
|
||||
_TLS_BSS_end = .;
|
||||
} >rom
|
||||
|
||||
_TLS_Data_size = _TLS_Data_end - _TLS_Data_begin;
|
||||
_TLS_Data_begin = _TLS_Data_size != 0 ? _TLS_Data_begin : _TLS_BSS_begin;
|
||||
_TLS_Data_end = _TLS_Data_size != 0 ? _TLS_Data_end : _TLS_BSS_begin;
|
||||
_TLS_BSS_size = _TLS_BSS_end - _TLS_BSS_begin;
|
||||
_TLS_Size = _TLS_BSS_end - _TLS_Data_begin;
|
||||
_TLS_Alignment = MAX (ALIGNOF (.tdata), ALIGNOF (.tbss));
|
||||
|
||||
.data : AT(SIZEOF(.text)) {
|
||||
_copy_start = .;
|
||||
*(.data)
|
||||
KEEP (*(SORT(.rtemsrwset.*)))
|
||||
*(.gnu.linkonce.d*)
|
||||
*(.jcr)
|
||||
*(.gcc_except_table*)
|
||||
. = ALIGN (16);
|
||||
PROVIDE (edata = .);
|
||||
_copy_end = .;
|
||||
} >myram
|
||||
.bss : {
|
||||
M68Kvec = .;
|
||||
. += (256 * 4);
|
||||
_clear_start = .;
|
||||
*(.dynbss)
|
||||
*(.bss* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (16);
|
||||
PROVIDE (end = .);
|
||||
_clear_end = .;
|
||||
} >myram
|
||||
|
||||
.noinit (NOLOAD) : {
|
||||
*(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*)))
|
||||
} >mvram
|
||||
|
||||
.rtemsstack (NOLOAD) : {
|
||||
*(SORT(.rtemsstack.*))
|
||||
WorkAreaBase = .;
|
||||
} >myram
|
||||
|
||||
/*
|
||||
* On-chip memory/peripherals
|
||||
*/
|
||||
dpram : {
|
||||
m360 = .;
|
||||
. += (8 * 1024);
|
||||
} >dpram
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* This file contains GNU linker directives for a generic MC68360 board.
|
||||
* Variations in memory size and allocation can be made by
|
||||
* overriding some values with linker command-line arguments.
|
||||
*
|
||||
* These linker directives are for producing a PROM version.
|
||||
* The data segment is placed at the end of the text segment in the PROM.
|
||||
* The start-up code takes care of copying this region to RAM.
|
||||
*
|
||||
* Saskatchewan Accelerator Laboratory
|
||||
* University of Saskatchewan
|
||||
* Saskatoon, Saskatchewan, CANADA
|
||||
* eric@skatter.usask.ca
|
||||
*/
|
||||
|
||||
/*
|
||||
* Declare some sizes.
|
||||
* A heap size of 0 means `use all available memory for the heap'.
|
||||
*/
|
||||
RamBase = DEFINED(RamBase) ? RamBase : 0x0;
|
||||
RamSize = DEFINED(RamSize) ? RamSize : 64M;
|
||||
RamEnd = RamBase + RamSize;
|
||||
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0;
|
||||
|
||||
/*
|
||||
* Declare on-board memory.
|
||||
*/
|
||||
MEMORY {
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 64M
|
||||
rom : ORIGIN = 0x0F000000, LENGTH = 1M
|
||||
dpram : ORIGIN = 0x0E000000, LENGTH = 8k
|
||||
}
|
||||
|
||||
/*
|
||||
* Load objects
|
||||
*/
|
||||
SECTIONS {
|
||||
/*
|
||||
* Boot PROM
|
||||
*/
|
||||
rom : {
|
||||
_RomBase = .;
|
||||
} >rom
|
||||
|
||||
/*
|
||||
* Dynamic RAM
|
||||
*/
|
||||
ram : {
|
||||
RamBase = .;
|
||||
} >ram
|
||||
|
||||
/*
|
||||
* Text, data and bss segments
|
||||
*/
|
||||
.text : AT(0x0) {
|
||||
*(.text*)
|
||||
|
||||
/*
|
||||
* C++ constructors/destructors
|
||||
*/
|
||||
*(.gnu.linkonce.t.*)
|
||||
|
||||
/*
|
||||
* Initialization and finalization code.
|
||||
*/
|
||||
PROVIDE (_init = .);
|
||||
*crti.o(.init)
|
||||
*(.init)
|
||||
*crtn.o(.init)
|
||||
PROVIDE (_fini = .);
|
||||
*crti.o(.fini)
|
||||
*(.fini)
|
||||
*crtn.o(.fini)
|
||||
|
||||
/*
|
||||
* Special FreeBSD sysctl sections.
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
__start_set_sysctl_set = .;
|
||||
*(set_sysctl_*);
|
||||
__stop_set_sysctl_set = ABSOLUTE(.);
|
||||
*(set_domain_*);
|
||||
*(set_pseudo_*);
|
||||
|
||||
/*
|
||||
* C++ constructors/destructors
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
*crtbegin.o(.ctors)
|
||||
*(.ctors)
|
||||
*crtend.o(.ctors)
|
||||
*crtbegin.o(.dtors)
|
||||
*(.dtors)
|
||||
*crtend.o(.dtors)
|
||||
|
||||
/*
|
||||
* Exception frame info
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
*(.eh_frame)
|
||||
|
||||
/*
|
||||
* Read-only data
|
||||
*/
|
||||
. = ALIGN (16);
|
||||
_rodata_start = . ;
|
||||
*(.rodata*)
|
||||
KEEP (*(SORT(.rtemsroset.*)))
|
||||
*(.gnu.linkonce.r*)
|
||||
|
||||
. = ALIGN (16);
|
||||
PROVIDE (etext = .);
|
||||
} >rom
|
||||
|
||||
.tdata : {
|
||||
_TLS_Data_begin = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_TLS_Data_end = .;
|
||||
} >rom
|
||||
|
||||
.tbss : {
|
||||
_TLS_BSS_begin = .;
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
|
||||
_TLS_BSS_end = .;
|
||||
} >rom
|
||||
|
||||
_TLS_Data_size = _TLS_Data_end - _TLS_Data_begin;
|
||||
_TLS_Data_begin = _TLS_Data_size != 0 ? _TLS_Data_begin : _TLS_BSS_begin;
|
||||
_TLS_Data_end = _TLS_Data_size != 0 ? _TLS_Data_end : _TLS_BSS_begin;
|
||||
_TLS_BSS_size = _TLS_BSS_end - _TLS_BSS_begin;
|
||||
_TLS_Size = _TLS_BSS_end - _TLS_Data_begin;
|
||||
_TLS_Alignment = MAX (ALIGNOF (.tdata), ALIGNOF (.tbss));
|
||||
|
||||
.data : AT(SIZEOF(.text)) {
|
||||
_copy_start = .;
|
||||
*(.data)
|
||||
KEEP (*(SORT(.rtemsrwset.*)))
|
||||
*(.gnu.linkonce.d*)
|
||||
*(.jcr)
|
||||
*(.gcc_except_table*)
|
||||
. = ALIGN (16);
|
||||
PROVIDE (edata = .);
|
||||
_copy_end = .;
|
||||
} >ram
|
||||
.bss : {
|
||||
M68Kvec = .;
|
||||
. += (256 * 4);
|
||||
*(.dynbss)
|
||||
*(.bss* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (16);
|
||||
PROVIDE (end = .);
|
||||
_clear_end = .;
|
||||
} >ram
|
||||
|
||||
.noinit (NOLOAD) : {
|
||||
*(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*)))
|
||||
} > ram
|
||||
|
||||
.rtemsstack (NOLOAD) : {
|
||||
*(SORT(.rtemsstack.*))
|
||||
WorkAreaBase = .;
|
||||
} >ram
|
||||
|
||||
/*
|
||||
* On-chip memory/peripherals
|
||||
*/
|
||||
dpram : {
|
||||
m360 = .;
|
||||
. += (8 * 1024);
|
||||
} >dpram
|
||||
}
|
||||
@@ -1,413 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* This file contains the entry point for the application.
|
||||
* It jumps to the BSP which is responsible for performing
|
||||
* all initialization.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Eric Norum <eric@norum.ca>
|
||||
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/asm.h>
|
||||
|
||||
BEGIN_CODE
|
||||
/*
|
||||
* Step 1: Decide on Reset Stack Pointer and Initial Program Counter
|
||||
*/
|
||||
Entry:
|
||||
.long m360+1024 | 0: Initial SSP
|
||||
.long start | 1: Initial PC
|
||||
.long _uhoh | 2: Bus error
|
||||
.long _uhoh | 3: Address error
|
||||
.long _uhoh | 4: Illegal instruction
|
||||
.long _uhoh | 5: Zero division
|
||||
.long _uhoh | 6: CHK, CHK2 instruction
|
||||
.long _uhoh | 7: TRAPcc, TRAPV instructions
|
||||
.long _uhoh | 8: Privilege violation
|
||||
.long _uhoh | 9: Trace
|
||||
.long _uhoh | 10: Line 1010 emulator
|
||||
.long _uhoh | 11: Line 1111 emulator
|
||||
.long _uhoh | 12: Hardware breakpoint
|
||||
.long _uhoh | 13: Reserved for coprocessor violation
|
||||
.long _uhoh | 14: Format error
|
||||
.long _uhoh | 15: Uninitialized interrupt
|
||||
.long _uhoh | 16: Unassigned, reserved
|
||||
.long _uhoh | 17:
|
||||
.long _uhoh | 18:
|
||||
.long _uhoh | 19:
|
||||
.long _uhoh | 20:
|
||||
.long _uhoh | 21:
|
||||
.long _uhoh | 22:
|
||||
.long _uhoh | 23:
|
||||
.long _spuriousInterrupt | 24: Spurious interrupt
|
||||
.long _uhoh | 25: Level 1 interrupt autovector
|
||||
.long _uhoh | 26: Level 2 interrupt autovector
|
||||
.long _uhoh | 27: Level 3 interrupt autovector
|
||||
.long _uhoh | 28: Level 4 interrupt autovector
|
||||
.long _uhoh | 29: Level 5 interrupt autovector
|
||||
.long _uhoh | 30: Level 6 interrupt autovector
|
||||
.long _uhoh | 31: Level 7 interrupt autovector
|
||||
.long _uhoh | 32: Trap instruction (0-15)
|
||||
.long _uhoh | 33:
|
||||
.long _uhoh | 34:
|
||||
.long _uhoh | 35:
|
||||
.long _uhoh | 36:
|
||||
.long _uhoh | 37:
|
||||
.long _uhoh | 38:
|
||||
.long _uhoh | 39:
|
||||
.long _uhoh | 40:
|
||||
.long _uhoh | 41:
|
||||
.long _uhoh | 42:
|
||||
.long _uhoh | 43:
|
||||
.long _uhoh | 44:
|
||||
.long _uhoh | 45:
|
||||
.long _uhoh | 46:
|
||||
.long _uhoh | 47:
|
||||
.long _uhoh | 48: Reserved for coprocessor
|
||||
.long _uhoh | 49:
|
||||
.long _uhoh | 50:
|
||||
.long _uhoh | 51:
|
||||
.long _uhoh | 52:
|
||||
.long _uhoh | 53:
|
||||
.long _uhoh | 54:
|
||||
.long _uhoh | 55:
|
||||
.long _uhoh | 56:
|
||||
.long _uhoh | 57:
|
||||
.long _uhoh | 58:
|
||||
.long _uhoh | 59: Unassigned, reserved
|
||||
.long _uhoh | 60:
|
||||
.long _uhoh | 61:
|
||||
.long _uhoh | 62:
|
||||
.long _uhoh | 63:
|
||||
.long _uhoh | 64: User defined vectors (192)
|
||||
.long _uhoh | 65:
|
||||
.long _uhoh | 66:
|
||||
.long _uhoh | 67:
|
||||
.long _uhoh | 68:
|
||||
.long _uhoh | 69:
|
||||
.long _uhoh | 70:
|
||||
.long _uhoh | 71:
|
||||
.long _uhoh | 72:
|
||||
.long _uhoh | 73:
|
||||
.long _uhoh | 74:
|
||||
.long _uhoh | 75:
|
||||
.long _uhoh | 76:
|
||||
.long _uhoh | 77:
|
||||
.long _uhoh | 78:
|
||||
.long _uhoh | 79:
|
||||
.long _uhoh | 80:
|
||||
.long _uhoh | 81:
|
||||
.long _uhoh | 82:
|
||||
.long _uhoh | 83:
|
||||
.long _uhoh | 84:
|
||||
.long _uhoh | 85:
|
||||
.long _uhoh | 86:
|
||||
.long _uhoh | 87:
|
||||
.long _uhoh | 88:
|
||||
.long _uhoh | 89:
|
||||
.long _uhoh | 90:
|
||||
.long _uhoh | 91:
|
||||
.long _uhoh | 92:
|
||||
.long _uhoh | 93:
|
||||
.long _uhoh | 94:
|
||||
.long _uhoh | 95:
|
||||
.long _uhoh | 96:
|
||||
.long _uhoh | 97:
|
||||
.long _uhoh | 98:
|
||||
.long _uhoh | 99:
|
||||
.long _uhoh | 100:
|
||||
.long _uhoh | 101:
|
||||
.long _uhoh | 102:
|
||||
.long _uhoh | 103:
|
||||
.long _uhoh | 104:
|
||||
.long _uhoh | 105:
|
||||
.long _uhoh | 106:
|
||||
.long _uhoh | 107:
|
||||
.long _uhoh | 108:
|
||||
.long _uhoh | 109:
|
||||
.long _uhoh | 110:
|
||||
.long _uhoh | 111:
|
||||
.long _uhoh | 112:
|
||||
.long _uhoh | 113:
|
||||
.long _uhoh | 114:
|
||||
.long _uhoh | 115:
|
||||
.long _uhoh | 116:
|
||||
.long _uhoh | 117:
|
||||
.long _uhoh | 118:
|
||||
.long _uhoh | 119:
|
||||
.long _uhoh | 120:
|
||||
.long _uhoh | 121:
|
||||
.long _uhoh | 122:
|
||||
.long _uhoh | 123:
|
||||
.long _uhoh | 124:
|
||||
.long _uhoh | 125:
|
||||
.long _uhoh | 126:
|
||||
.long _uhoh | 127:
|
||||
.long _uhoh | 128:
|
||||
.long _uhoh | 129:
|
||||
.long _uhoh | 130:
|
||||
.long _uhoh | 131:
|
||||
.long _uhoh | 132:
|
||||
.long _uhoh | 133:
|
||||
.long _uhoh | 134:
|
||||
.long _uhoh | 135:
|
||||
.long _uhoh | 136:
|
||||
.long _uhoh | 137:
|
||||
.long _uhoh | 138:
|
||||
.long _uhoh | 139:
|
||||
.long _uhoh | 140:
|
||||
.long _uhoh | 141:
|
||||
.long _uhoh | 142:
|
||||
.long _uhoh | 143:
|
||||
.long _uhoh | 144:
|
||||
.long _uhoh | 145:
|
||||
.long _uhoh | 146:
|
||||
.long _uhoh | 147:
|
||||
.long _uhoh | 148:
|
||||
.long _uhoh | 149:
|
||||
.long _uhoh | 150:
|
||||
.long _uhoh | 151:
|
||||
.long _uhoh | 152:
|
||||
.long _uhoh | 153:
|
||||
.long _uhoh | 154:
|
||||
.long _uhoh | 155:
|
||||
.long _uhoh | 156:
|
||||
.long _uhoh | 157:
|
||||
.long _uhoh | 158:
|
||||
.long _uhoh | 159:
|
||||
.long _uhoh | 160:
|
||||
.long _uhoh | 161:
|
||||
.long _uhoh | 162:
|
||||
.long _uhoh | 163:
|
||||
.long _uhoh | 164:
|
||||
.long _uhoh | 165:
|
||||
.long _uhoh | 166:
|
||||
.long _uhoh | 167:
|
||||
.long _uhoh | 168:
|
||||
.long _uhoh | 169:
|
||||
.long _uhoh | 170:
|
||||
.long _uhoh | 171:
|
||||
.long _uhoh | 172:
|
||||
.long _uhoh | 173:
|
||||
.long _uhoh | 174:
|
||||
.long _uhoh | 175:
|
||||
.long _uhoh | 176:
|
||||
.long _uhoh | 177:
|
||||
.long _uhoh | 178:
|
||||
.long _uhoh | 179:
|
||||
.long _uhoh | 180:
|
||||
.long _uhoh | 181:
|
||||
.long _uhoh | 182:
|
||||
.long _uhoh | 183:
|
||||
.long _uhoh | 184:
|
||||
.long _uhoh | 185:
|
||||
.long _uhoh | 186:
|
||||
.long _uhoh | 187:
|
||||
.long _uhoh | 188:
|
||||
.long _uhoh | 189:
|
||||
.long _uhoh | 190:
|
||||
.long _uhoh | 191:
|
||||
.long _uhoh | 192:
|
||||
.long _uhoh | 193:
|
||||
.long _uhoh | 194:
|
||||
.long _uhoh | 195:
|
||||
.long _uhoh | 196:
|
||||
.long _uhoh | 197:
|
||||
.long _uhoh | 198:
|
||||
.long _uhoh | 199:
|
||||
.long _uhoh | 200:
|
||||
.long _uhoh | 201:
|
||||
.long _uhoh | 202:
|
||||
.long _uhoh | 203:
|
||||
.long _uhoh | 204:
|
||||
.long _uhoh | 205:
|
||||
.long _uhoh | 206:
|
||||
.long _uhoh | 207:
|
||||
.long _uhoh | 208:
|
||||
.long _uhoh | 209:
|
||||
.long _uhoh | 210:
|
||||
.long _uhoh | 211:
|
||||
.long _uhoh | 212:
|
||||
.long _uhoh | 213:
|
||||
.long _uhoh | 214:
|
||||
.long _uhoh | 215:
|
||||
.long _uhoh | 216:
|
||||
.long _uhoh | 217:
|
||||
.long _uhoh | 218:
|
||||
.long _uhoh | 219:
|
||||
.long _uhoh | 220:
|
||||
.long _uhoh | 221:
|
||||
.long _uhoh | 222:
|
||||
.long _uhoh | 223:
|
||||
.long _uhoh | 224:
|
||||
.long _uhoh | 225:
|
||||
.long _uhoh | 226:
|
||||
.long _uhoh | 227:
|
||||
.long _uhoh | 228:
|
||||
.long _uhoh | 229:
|
||||
.long _uhoh | 230:
|
||||
.long _uhoh | 231:
|
||||
.long _uhoh | 232:
|
||||
.long _uhoh | 233:
|
||||
.long _uhoh | 234:
|
||||
.long _uhoh | 235:
|
||||
.long _uhoh | 236:
|
||||
.long _uhoh | 237:
|
||||
.long _uhoh | 238:
|
||||
.long _uhoh | 239:
|
||||
.long _uhoh | 240:
|
||||
.long _uhoh | 241:
|
||||
.long _uhoh | 242:
|
||||
.long _uhoh | 243:
|
||||
.long _uhoh | 244:
|
||||
.long _uhoh | 245:
|
||||
.long _uhoh | 246:
|
||||
.long _uhoh | 247:
|
||||
.long _uhoh | 248:
|
||||
.long _uhoh | 249:
|
||||
.long _uhoh | 250:
|
||||
.long _uhoh | 251:
|
||||
.long _uhoh | 252:
|
||||
.long _uhoh | 253:
|
||||
.long _uhoh | 254:
|
||||
.long _uhoh | 255:
|
||||
|
||||
/*
|
||||
* Default trap handler
|
||||
* With an oscilloscope you can see AS* stop
|
||||
*/
|
||||
PUBLIC (_uhoh)
|
||||
_uhoh: nop | Leave spot for breakpoint
|
||||
stop #0x2700 | Stop with interrupts disabled
|
||||
bra.l _uhoh | Stuck forever
|
||||
|
||||
/*
|
||||
* Log, but otherwise ignore, spurious interrupts
|
||||
*/
|
||||
PUBLIC (_spuriousInterrupt)
|
||||
_spuriousInterrupt:
|
||||
addql #1,_M68kSpuriousInterruptCount
|
||||
rte
|
||||
|
||||
/*
|
||||
* Place the low-order 3 octets of the board's ethernet address at
|
||||
* a `well-known' fixed location relative to the startup location.
|
||||
*/
|
||||
.align 2
|
||||
.word 0 | Padding
|
||||
ethernet_address_buffer:
|
||||
.word 0x08F3 | Default address
|
||||
.word 0xDEAD
|
||||
.word 0xCAFE
|
||||
|
||||
/*
|
||||
* Initial PC
|
||||
*/
|
||||
.globl start
|
||||
start:
|
||||
/*
|
||||
* Step 2: Stay in Supervisor Mode
|
||||
*/
|
||||
#if ( M68K_HAS_SEPARATE_STACKS == 1 )
|
||||
oriw #0x3000,sr | Switch to Master Stack Pointer
|
||||
lea SYM(m360)+1024-64,a7 | Put stack in dual-port ram
|
||||
| a little below the interrupt stack
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Step 3: Write the VBR
|
||||
*/
|
||||
lea Entry,a0 | Get base of vector table
|
||||
movec a0,vbr | Set up the VBR
|
||||
|
||||
/*
|
||||
* Step 4: Write the MBAR
|
||||
*/
|
||||
movec dfc,d1 | Save destination register
|
||||
moveq #7,d0 | CPU-space funcction code
|
||||
movec d0,dfc | Set destination function code register
|
||||
movel #m360+0x101,d0 | MBAR value (mask CPU space accesses)
|
||||
movesl d0,0x3FF00 | Set MBAR
|
||||
movec d1,dfc | Restore destination register
|
||||
|
||||
/*
|
||||
* Step 5: Verify a dual-port RAM location
|
||||
*/
|
||||
lea m360,a0 | Point a0 to first DPRAM location
|
||||
moveb #0x33,d0 | Set the test value
|
||||
moveb d0,a0@ | Set the memory location
|
||||
cmpb a0@,d0 | Does it read back?
|
||||
bne _uhoh | If not, bad news!
|
||||
notb d0 | Flip bits
|
||||
moveb d0,a0@ | Set the memory location
|
||||
cmpb a0@,d0 | Does it read back?
|
||||
bne _uhoh | If not, bad news!
|
||||
|
||||
/*
|
||||
* Remaining steps are handled by C code
|
||||
*/
|
||||
jmp _Init68360 | Start C code (which never returns)
|
||||
|
||||
/*
|
||||
* Copy DATA segment, clear BSS segment, set up real stack, start C program.
|
||||
* Assume that DATA and BSS sizes are multiples of 4.
|
||||
*/
|
||||
PUBLIC (_CopyDataClearBSSAndStart)
|
||||
_CopyDataClearBSSAndStart:
|
||||
lea _copy_start,a0 | Get start of DATA in RAM
|
||||
lea etext,a2 | Get start of DATA in ROM
|
||||
cmpl a0,a2 | Are they the same?
|
||||
beq.s NOCOPY | Yes, no copy necessary
|
||||
lea _copy_end,a1 | Get end of DATA in RAM
|
||||
bra.s COPYLOOPTEST | Branch into copy loop
|
||||
COPYLOOP:
|
||||
movel a2@+,a0@+ | Copy word from ROM to RAM
|
||||
COPYLOOPTEST:
|
||||
cmpl a1,a0 | Done?
|
||||
bcs.s COPYLOOP | No, skip
|
||||
NOCOPY:
|
||||
|
||||
lea _clear_start,a0 | Get start of BSS
|
||||
lea _clear_end,a1 | Get end of BSS
|
||||
clrl d0 | Value to set
|
||||
bra.s ZEROLOOPTEST | Branch into clear loop
|
||||
ZEROLOOP:
|
||||
movel d0,a0@+ | Clear a word
|
||||
ZEROLOOPTEST:
|
||||
cmpl a1,a0 | Done?
|
||||
bcs.s ZEROLOOP | No, skip
|
||||
|
||||
movel #_ISR_Stack_area_end,a7 | set master stack pointer
|
||||
movel d0,a7@- | command line
|
||||
jsr boot_card | Call C main
|
||||
|
||||
PUBLIC (_mainDone)
|
||||
_mainDone:
|
||||
nop | Leave spot for breakpoint
|
||||
movew #1,a7 | Force a double bus error
|
||||
movel d0,a7@- | This should cause a RESET
|
||||
stop #0x2700 | Stop with interrupts disabled
|
||||
bra.l _mainDone | Stuck forever
|
||||
|
||||
.align 2
|
||||
END_CODE
|
||||
|
||||
BEGIN_DATA_DCL
|
||||
.align 2
|
||||
PUBLIC (environ)
|
||||
environ:
|
||||
.long 0
|
||||
PUBLIC (_M68kSpuriousInterruptCount)
|
||||
_M68kSpuriousInterruptCount:
|
||||
.long 0
|
||||
END_DATA_DCL
|
||||
|
||||
END
|
||||
Reference in New Issue
Block a user