m68k/gen68360: Remove obsolete BSP family

Updates #5031
This commit is contained in:
Joel Sherrill
2025-02-05 15:13:29 -06:00
committed by Gedare Bloom
parent 552e481699
commit 7f86974bf3
28 changed files with 0 additions and 4193 deletions

View File

@@ -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

View File

@@ -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)
{
}

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -1 +0,0 @@
#include <bsp/irq-default.h>

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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));
}

View File

@@ -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);
}

View File

@@ -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) }
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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