Patch from John Cotton <john.cotton@nrc.ca>, Charles-Antoine Gauthier

<charles.gauthier@iit.nrc.ca>, and Darlene A. Stewart
<Darlene.Stewart@nrc.ca> to add support for a number of very
significant things:

  + BSPs for many variations on the Motorola MBX8xx board series
  + Cache Manager including initial support for m68040
    and PowerPC
  + Rework of mpc8xx libcpu code so all mpc8xx CPUs now use
    same code base.
  + Rework of eth_comm BSP to utiltize above.

John reports this works on the 821 and 860.
This commit is contained in:
Joel Sherrill
2000-06-12 21:34:51 +00:00
parent edc61d488b
commit 3ab61f0a35
43 changed files with 0 additions and 7762 deletions

View File

@@ -1,61 +0,0 @@
/*
* PowerPC Cache enable routines
*
* $Id$
*/
#include <rtems/system.h>
#define PPC_Get_HID0( _value ) \
do { \
_value = 0; /* to avoid warnings */ \
asm volatile( \
"mfspr %0, 0x3f0;" /* get HID0 */ \
"isync" \
: "=r" (_value) \
: "0" (_value) \
); \
} while (0)
#define PPC_Set_HID0( _value ) \
do { \
asm volatile( \
"isync;" \
"mtspr 0x3f0, %0;" /* load HID0 */ \
"isync" \
: "=r" (_value) \
: "0" (_value) \
); \
} while (0)
void powerpc_instruction_cache_enable ()
{
unsigned32 value;
/*
* Enable the instruction cache
*/
PPC_Get_HID0( value );
value |= 0x00008000; /* Set ICE bit */
PPC_Set_HID0( value );
}
void powerpc_data_cache_enable ()
{
unsigned32 value;
/*
* enable data cache
*/
PPC_Get_HID0( value );
value |= 0x00004000; /* set DCE bit */
PPC_Set_HID0( value );
}

View File

@@ -1,214 +0,0 @@
/*
* This file contains directives for the GNU linker which are specific
* to the Motorola MVME167 board. This linker script produces ELF
* executables.
*
* Copyright (c) 1999, National Research Council of Canada.
* Some of this material was copied from binutils-2.9.4 linker scripts,
* and is therefore likely to be copyrighted by the Free Software
* Foundation, even though explicit copyright notices did not appear in
* those files.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
/* These are not really needed here */
OUTPUT_FORMAT("elf32-m68k")
OUTPUT_ARCH(m68k)
ENTRY(_start)
/*
* Declare some sizes.
*/
_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0x10000;
_StackSize = DEFINED(_StackSize) ? _StackSize : 0x1000;
MEMORY
{
/* The location of RAM is the address space is configurable.
This is where we put one board. The base address should be
passed as a parameter when building multiprocessor images
where each board resides at a different address. */
ram : org = 0x00800000, l = 4M
rom : org = 0xFF800000, l = 4M
sram : org = 0xFFE00000, l = 128K
}
SECTIONS
{
/*
* We want the entry point to be the first thing in memory.
* Merge all read-only data into the .text section.
*/
.text 0x00800000 :
{
text_start = . ;
*(.text)
*(.text.*)
*(.stub)
/* C++ constructors/destructors */
*(.gnu.linkonce.t*)
/* Initialization and finalization code.
*
* Various files can provide initialization and finalization functions.
* crtbegin.o and crtend.o are two instances. The body of these functions
* are in .init and .fini sections. We accumulate the bodies here, and
* prepend function prologues from crti.o and function epilogues from
* crtn.o. crti.o must be linked first; crtn.o must be linked last.
* Because these are wildcards, it doesn't matter if the user does not
* actually link against crti.o and crtn.o; the linker won't look for a
* file to match a wildcard. The wildcard also means that it doesn't
* matter which directory crti.o and crtn.o are in.
*/
PROVIDE (_init = .);
*crti.o(.init)
*(.init)
*crtn.o(.init)
PROVIDE (_fini = .);
*crti.o(.fini)
*(.fini)
*crtn.o(.init)
. = ALIGN (16);
/* C++ constructors and destructors for static objects.
*
* gcc uses crtbegin.o to find the start of the constructors and
* destructors so we make sure it is first. Because this is a wildcard,
* it doesn't matter if the user does not actually link against
* crtbegin.o; the linker won't look for a file to match a wildcard. The
* wildcard also means that it doesn't matter which directory crtbegin.o
* is in. The constructor and destructor list are terminated in crtend.o.
* The same comments apply to it.
*/
PROVIDE (__CTOR_LIST__ = .);
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
PROVIDE (__CTOR_END__ = .);
PROVIDE (__DTOR_LIST__ = .);
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
PROVIDE (__DTOR_END__ = .);
. = ALIGN (16);
/* Exception frame info */
*(.eh_frame)
. = ALIGN (16);
/* Do we have any of these with egcs-1.x and higher? */
*(.gcc_exc)
. = ALIGN (16);
_rodata_start = . ;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
*(.rodata1)
_erodata = .;
_etext = .;
PROVIDE (etext = .);
} >ram =0x4e75
. = ALIGN (16);
.data :
{
data_start = .;
*(.data)
*(.data.*)
*(.data1)
*(.sdata)
*(.gnu.linkonce.d*)
*(.gcc_except_table)
. = ALIGN (16);
_edata = .;
PROVIDE (edata = .);
} >ram
.bss :
{
bss_start = .;
*(.dynbss)
*(.bss)
*(COMMON)
*(.sbss)
*(.scommon)
. = ALIGN (16);
_end = .;
PROVIDE (end = .);
} >ram
_HeapStart = .;
. += HeapSize; /* XXX -- Old gld can't handle this */
_HeapEnd = .;
_StackStart = .;
. += _StackSize; /* XXX -- Old gld can't handle this */
/* . += 0x10000; */ /* HeapSize for old gld */
/* . += 0x1000; */ /* _StackSize for old gld */
. = ALIGN (16);
_StackEnd = .;
stack_init = .;
clear_end = .;
_WorkspaceBase = .;
/* 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 . */
}

View File

@@ -1,117 +0,0 @@
/*
* MPC860 buffer descriptor allocation routines
*
* Modified from original code by Jay Monkman (jmonkman@frasca.com)
*
* Original was written by:
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* Saskatoon, Saskatchewan, CANADA
* eric@skatter.usask.ca
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <rtems/rtems/intr.h>
#include <rtems/error.h>
#include <mpc860.h>
#include <info.h>
/*
* Send a command to the CPM RISC processer
*/
void M860ExecuteRISC(rtems_unsigned16 command)
{
rtems_unsigned16 lvl;
rtems_interrupt_disable(lvl);
while (m860.cpcr & M860_CR_FLG) {
continue;
}
m860.cpcr = command | M860_CR_FLG;
rtems_interrupt_enable (lvl);
}
/*
* Allocation order:
* - Dual-Port RAM section 0
* - Dual-Port RAM section 1
* - Dual-Port RAM section 2
* - Dual-Port RAM section 3
* - Dual-Port RAM section 4
*/
static struct {
char *base;
unsigned int size;
unsigned int used;
} bdregions[] = {
{ (char *)&m860.dpram0[0], sizeof m860.dpram0, 0 },
{ (char *)&m860.dpram1[0], sizeof m860.dpram1, 0 },
{ (char *)&m860.dpram2[0], sizeof m860.dpram2, 0 },
{ (char *)&m860.dpram3[0], sizeof m860.dpram3, 0 },
{ (char *)&m860.dpram4[0], sizeof m860.dpram4, 0 },
};
void *
M860AllocateBufferDescriptors (int count)
{
unsigned int i;
ISR_Level level;
void *bdp = NULL;
unsigned int want = count * sizeof(m860BufferDescriptor_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_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 unsigned char *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_Enable(level);
if (bdp == NULL)
rtems_panic("Can't allocate %d buffer descriptor(s).\n", count);
return bdp;
}
void *
M860AllocateRiscTimers (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 M860AllocateBufferDescriptors (((count * 4) +
sizeof(m860BufferDescriptor_t) - 1) /
sizeof(m860BufferDescriptor_t));
}

View File

@@ -1,128 +0,0 @@
/*
* mmu.c - this file contains functions for initializing the MMU
*
* Written by Jay Monkman (jmonkman@frasca.com)
*
* $Id$
*/
#include <bsp.h>
#include <mpc860.h>
/* Macros for handling all the MMU SPRs */
#define PUT_MI_CTR(r) __asm__ volatile ("mtspr 0x310,%0\n" ::"r"(r))
#define GET_MI_CTR(r) __asm__ volatile ("mfspr %0,0x310\n" :"=r"(r))
#define PUT_MD_CTR(r) __asm__ volatile ("mtspr 0x318,%0\n" ::"r"(r))
#define GET_MD_CTR(r) __asm__ volatile ("mfspr %0,0x318\n" :"=r"(r))
#define PUT_M_CASID(r) __asm__ volatile ("mtspr 0x319,%0\n" ::"r"(r))
#define GET_M_CASID(r) __asm__ volatile ("mfspr %0,0x319\n" :"=r"(r))
#define PUT_MI_EPN(r) __asm__ volatile ("mtspr 0x313,%0\n" ::"r"(r))
#define GET_MI_EPN(r) __asm__ volatile ("mfspr %0,0x313\n" :"=r"(r))
#define PUT_MI_TWC(r) __asm__ volatile ("mtspr 0x315,%0\n" ::"r"(r))
#define GET_MI_TWC(r) __asm__ volatile ("mfspr %0,0x315\n" :"=r"(r))
#define PUT_MI_RPN(r) __asm__ volatile ("mtspr 0x316,%0\n" ::"r"(r))
#define GET_MI_RPN(r) __asm__ volatile ("mfspr %0,0x316\n" :"=r"(r))
#define PUT_MD_EPN(r) __asm__ volatile ("mtspr 0x313,%0\n" ::"r"(r))
#define GET_MD_EPN(r) __asm__ volatile ("mfspr %0,0x313\n" :"=r"(r))
#define PUT_M_TWB(r) __asm__ volatile ("mtspr 0x31c,%0\n" ::"r"(r))
#define GET_M_TWB(r) __asm__ volatile ("mfspr %0,0x31c\n" :"=r"(r))
#define PUT_MD_TWC(r) __asm__ volatile ("mtspr 0x31d,%0\n" ::"r"(r))
#define GET_MD_TWC(r) __asm__ volatile ("mfspr %0,0x31d\n" :"=r"(r))
#define PUT_MD_RPN(r) __asm__ volatile ("mtspr 0x31e,%0\n" ::"r"(r))
#define GET_MD_RPN(r) __asm__ volatile ("mfspr %0,0x31e\n" :"=r"(r))
#define PUT_MI_AP(r) __asm__ volatile ("mtspr 0x312,%0\n" ::"r"(r))
#define GET_MI_AP(r) __asm__ volatile ("mfspr %0,0x312\n" :"=r"(r))
#define PUT_MD_AP(r) __asm__ volatile ("mtspr 0x31a,%0\n" ::"r"(r))
#define GET_MD_AP(r) __asm__ volatile ("mfspr %0,0x31a\n" :"=r"(r))
#define PUT_M_TW(r) __asm__ volatile ("mtspr 0x31f,%0\n" ::"r"(r))
#define GET_M_TW(r) __asm__ volatile ("mfspr %0,0x31f\n" :"=r"(r))
#define PUT_MI_DCAM(r) __asm__ volatile ("mtspr 0x330,%0\n" ::"r"(r))
#define GET_MI_DCAM(r) __asm__ volatile ("mfspr %0,0x330\n" :"=r"(r))
#define PUT_MI_DRAM0(r) __asm__ volatile ("mtspr 0x331,%0\n" ::"r"(r))
#define GET_MI_DRAM0(r) __asm__ volatile ("mfspr %0,0x331\n" :"=r"(r))
#define PUT_MI_DRAM1(r) __asm__ volatile ("mtspr 0x332,%0\n" ::"r"(r))
#define GET_MI_DRAM1(r) __asm__ volatile ("mfspr %0,0x332\n" :"=r"(r))
#define PUT_MD_DCAM(r) __asm__ volatile ("mtspr 0x338,%0\n" ::"r"(r))
#define GET_MD_DCAM(r) __asm__ volatile ("mfspr %0,0x338\n" :"=r"(r))
#define PUT_MD_DRAM0(r) __asm__ volatile ("mtspr 0x339,%0\n" ::"r"(r))
#define GET_MD_DRAM0(r) __asm__ volatile ("mfspr %0,0x339\n" :"=r"(r))
#define PUT_MD_DRAM1(r) __asm__ volatile ("mtspr 0x33a,%0\n" ::"r"(r))
#define GET_MD_DRAM1(r) __asm__ volatile ("mfspr %0,0x33a\n" :"=r"(r))
#define PUT_IC_CST(r) __asm__ volatile ("mtspr 0x230,%0\n" ::"r"(r))
#define GET_IC_CST(r) __asm__ volatile ("mfspr %0,0x230\n" :"=r"(r))
#define PUT_DC_CST(r) __asm__ volatile ("mtspr 0x238,%0\n" ::"r"(r))
#define GET_DC_CST(r) __asm__ volatile ("mfspr %0,0x238\n" :"=r"(r))
#define PUT_IC_ADR(r) __asm__ volatile ("mtspr 0x231,%0\n" ::"r"(r))
#define GET_IC_ADR(r) __asm__ volatile ("mfspr %0,0x231\n" :"=r"(r))
#define PUT_IC_DAT(r) __asm__ volatile ("mtspr 0x232,%0\n" ::"r"(r))
#define GET_IC_DAT(r) __asm__ volatile ("mfspr %0,0x232\n" :"=r"(r))
extern rtems_configuration_table BSP_Configuration;
void mmu_init(void)
{
register unsigned long t1, t2;
/* Let's clear MSR[IR] and MSR[DR] */
t2 = PPC_MSR_IR | PPC_MSR_DR;
__asm__ volatile (
"mfmsr %0\n"
"andc %0, %0, %1\n"
"mtmsr %0\n" :"=r"(t1), "=r"(t2):
"1"(t2));
/* Invalidate the TLBs */
__asm__ volatile ("tlbia\n"::);
__asm__ volatile ("isync\n"::);
/* make sure no TLB entries are reserved */
t1 = 0;
PUT_MI_CTR(t1);
t1 = M860_MD_CTR_TWAM; /* 4K pages */
/* PUT_MD_CTR(t1); */
t1 = M860_MI_EPN_VALID; /* make entry valid */
/* PUT_MD_EPN(t1); */
PUT_MI_EPN(t1);
t1 = M860_MI_TWC_PS8 | M860_MI_TWC_VALID; /* 8 MB pages, valid */
/* PUT_MD_TWC(t1); */
PUT_MI_TWC(t1);
t1 = M860_MD_RPN_CHANGE | M860_MD_RPN_F | M860_MD_RPN_16K |
M860_MD_RPN_SHARED | M860_MD_RPN_VALID;
/* PUT_MD_RPN(t1); */
PUT_MI_RPN(t1);
t1 = M860_MI_AP_Kp << 30;
PUT_MI_AP(t1);
/* PUT_MD_AP(t1); */
t1 = M860_CACHE_CMD_UNLOCK;
/* PUT_DC_CST(t1); */
PUT_IC_CST(t1);
t1 = M860_CACHE_CMD_INVALIDATE;
/* PUT_DC_CST(t1); */
PUT_IC_CST(t1);
t1 = M860_CACHE_CMD_ENABLE;
PUT_IC_CST(t1);
t1 = M860_CACHE_CMD_SFWT;
/* PUT_DC_CST(t1); */
t1 = M860_CACHE_CMD_ENABLE;
/* PUT_DC_CST(t1);*/
/* Let's set MSR[IR] */
t2 = PPC_MSR_IR;
__asm__ volatile (
"mfmsr %0\n"
"or %0, %0, %1\n"
"mtmsr %0\n" :"=r"(t1), "=r"(t2):
"1"(t2));
}

View File

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

View File

@@ -1,10 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = include console-generic clock timer vectors
include $(top_srcdir)/../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../automake/local.am

View File

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

View File

@@ -1,29 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/clock.rel
C_FILES = clock.c
clock_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(clock_rel_OBJECTS)
$(make-rel)
all-local: $(ARCH) $(clock_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = clock.c
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,178 +0,0 @@
/* clock.c
*
* This routine initializes the PIT on the MPC821.
* The tick frequency is specified by the bsp.
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copyright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <clockdrv.h>
#include <rtems/libio.h>
#include <stdlib.h> /* for atexit() */
#include <mpc821.h>
volatile rtems_unsigned32 Clock_driver_ticks;
extern volatile m821_t m821;
void Clock_exit( void );
/*
* These are set by clock driver during its init
*/
rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor;
/*
* ISR Handler
*/
rtems_isr Clock_isr(rtems_vector_number vector)
{
m821.piscr |= M821_PISCR_PS;
Clock_driver_ticks++;
rtems_clock_tick();
}
void Install_clock(rtems_isr_entry clock_isr)
{
rtems_isr_entry previous_isr;
rtems_unsigned32 pit_value;
Clock_driver_ticks = 0;
pit_value = rtems_configuration_get_microseconds_per_tick() /
rtems_cpu_configuration_get_clicks_per_usec();
if (pit_value == 0) {
pit_value = 0xffff;
} else {
pit_value--;
}
if (pit_value > 0xffff) { /* pit is only 16 bits long */
rtems_fatal_error_occurred(-1);
}
/*
* initialize the interval here
* First tick is set to right amount of time in the future
* Future ticks will be incremented over last value set
* in order to provide consistent clicks in the face of
* interrupt overhead
*/
rtems_interrupt_catch(clock_isr, PPC_IRQ_LVL0, &previous_isr);
m821.sccr &= ~(1<<24);
m821.pitc = pit_value;
/* set PIT irq level, enable PIT, PIT interrupts */
/* and clear int. status */
m821.piscr = M821_PISCR_PIRQ(0) |
M821_PISCR_PTE | M821_PISCR_PS | M821_PISCR_PIE;
m821.simask |= M821_SIMASK_LVM0;
atexit(Clock_exit);
}
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
{
rtems_isr_entry previous_isr;
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable(isrlevel);
rtems_interrupt_catch(new_clock_isr, PPC_IRQ_LVL0, &previous_isr);
rtems_interrupt_enable(isrlevel);
}
/*
* Called via atexit()
* Remove the clock interrupt handler by setting handler to NULL
*/
void
Clock_exit(void)
{
/* disable PIT and PIT interrupts */
m821.piscr &= ~(M821_PISCR_PTE | M821_PISCR_PIE);
(void) set_vector(0, PPC_IRQ_LVL0, 1);
}
rtems_device_driver Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
Install_clock( Clock_isr );
/*
* make major/minor avail to others such as shared memory driver
*/
rtems_clock_major = major;
rtems_clock_minor = minor;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
goto done;
/*
* This is hokey, but until we get a defined interface
* to do this, it will just be this simple...
*/
if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
Clock_isr(PPC_IRQ_LVL0);
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
ReInstall_clock(args->buffer);
}
done:
return RTEMS_SUCCESSFUL;
}

View File

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

View File

@@ -1,29 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/console-generic.rel
C_FILES = console-generic.c
console_generic_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(console_generic_rel_OBJECTS)
$(make-rel)
all-local: $(ARCH) $(console_generic_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = console-generic.c
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,834 +0,0 @@
/*
* General Serial I/O functions.
*
* This file contains the functions for performing serial I/O.
* The actual system calls (console_*) should be in the BSP part
* of the source tree. That way different BSPs can use whichever
* SMCs and SCCs they want. Originally, all the stuff was in
* this file, and it caused problems with one BSP using SCC2
* as /dev/console, others using SMC1 for /dev/console, etc.
*
* On-chip resources used:
* resource minor note
* SMC1 0
* SMC2 1
* SCC1 2 (shared with ethernet driver)
* SCC2 3
* BRG1
* BRG2
* BRG3
* BRG4
* Author: Jay Monkman (jmonkman@frasca.com)
* Copyright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libbsp/m68k/gen360/console/console.c:
*
* Author:
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* Saskatoon, Saskatchewan, CANADA
* eric@skatter.usask.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.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems/libio.h>
#include <mpc821.h>
#include <mpc821/console.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#define NIFACES 4 /* number of console devices (serial ports) */
static Buf_t *rxBufList[NIFACES];
static Buf_t *rxBufListTail[NIFACES];
/*
* Interrupt-driven input buffer
*/
#define RXBUFSIZE 16
/*
* I/O buffers and pointers to buffer descriptors
*/
static volatile char txBuf[NIFACES];
static volatile m821BufferDescriptor_t *RxBd[NIFACES], *TxBd[NIFACES];
/*
* Device-specific routines
*/
static int m821_get_brg_cd(int);
unsigned char m821_get_brg_clk(int);
unsigned char m821_get_brg_clk(int);
/*
* Compute baud-rate-generator configuration register value
*/
static int
m821_get_brg_cd (int baud)
{
int divisor;
int div16 = 0;
divisor = ((rtems_cpu_configuration_get_clock_speed() / 16) +
(baud / 2)) / baud;
if (divisor > 4096) {
div16 = 1;
divisor = (divisor + 8) / 16;
}
return M821_BRG_EN | M821_BRG_EXTC_BRGCLK |
((divisor - 1) << 1) | div16;
}
/* this function will fail if more that 4 baud rates have been selected */
/* at any time since the OS started. It needs to be fixed. FIXME */
unsigned char m821_get_brg_clk(int baud)
{
static int brg_spd[4];
static char brg_used[4];
int i;
/* first try to find a BRG that is already at the right speed */
for (i=0; i<4; i++) {
if (brg_spd[i] == baud) {
break;
}
}
if (i==4) { /* I guess we didn't find one */
for (i=0; i<4; i++) {
if (brg_used[i] == 0) {
break;
}
}
}
if (i != 4) {
brg_used[i]++;
brg_spd[i]=baud;
switch (i) {
case 0:
m821.brgc1 = M821_BRG_RST;
m821.brgc1 = m821_get_brg_cd(baud);
break;
case 1:
m821.brgc2 = M821_BRG_RST;
m821.brgc2 = m821_get_brg_cd(baud);
break;
case 2:
m821.brgc3 = M821_BRG_RST;
m821.brgc3 = m821_get_brg_cd(baud);
break;
case 3:
m821.brgc4 = M821_BRG_RST;
m821.brgc4 = m821_get_brg_cd(baud);
break;
}
return i;
}
else
return 0xff;
}
/*
* Hardware-dependent portion of tcsetattr().
*/
int
m821_smc_set_attributes (int minor, const struct termios *t)
{
/*
* minor must be 0 or 1
*/
int baud;
int brg;
switch (t->c_cflag & CBAUD) {
default: baud = -1; break;
case B50: baud = 50; break;
case B75: baud = 75; break;
case B110: baud = 110; break;
case B134: baud = 134; break;
case B150: baud = 150; break;
case B200: baud = 200; break;
case B300: baud = 300; break;
case B600: baud = 600; break;
case B1200: baud = 1200; break;
case B1800: baud = 1800; break;
case B2400: baud = 2400; break;
case B4800: baud = 4800; break;
case B9600: baud = 9600; break;
case B19200: baud = 19200; break;
case B38400: baud = 38400; break;
case B57600: baud = 57600; break;
case B115200: baud = 115200; break;
case B230400: baud = 230400; break;
case B460800: baud = 460800; break;
}
if (baud > 0) {
brg = m821_get_brg_clk(baud); /* 4 BRGs, 4 serial ports - hopefully */
/* at least 2 ports will be the same */
m821.simode |= brg << (12 + ((minor) * 16));
}
return 0;
}
int
m821_scc_set_attributes (int minor, const struct termios *t)
{
/*
* minor must be 2, or 3
*/
int baud;
int brg;
switch (t->c_cflag & CBAUD) {
default: baud = -1; break;
case B50: baud = 50; break;
case B75: baud = 75; break;
case B110: baud = 110; break;
case B134: baud = 134; break;
case B150: baud = 150; break;
case B200: baud = 200; break;
case B300: baud = 300; break;
case B600: baud = 600; break;
case B1200: baud = 1200; break;
case B1800: baud = 1800; break;
case B2400: baud = 2400; break;
case B4800: baud = 4800; break;
case B9600: baud = 9600; break;
case B19200: baud = 19200; break;
case B38400: baud = 38400; break;
case B57600: baud = 57600; break;
case B115200: baud = 115200; break;
case B230400: baud = 230400; break;
case B460800: baud = 460800; break;
}
if (baud > 0) {
brg = m821_get_brg_clk(baud); /* 4 BRGs, 5 serial ports - hopefully */
/* at least 2 ports will be the same */
m821.sicr |= (brg << (3 + ((minor-2) * 8))) |
(brg << ((minor-2) * 8));
}
return 0;
}
void
m821_scc_initialize (int port) /* port is the SCC # (i.e. 1, 2, 3 or 4) */
{
unsigned char brg;
volatile m821SCCparms_t *sccparms;
volatile m821SCCRegisters_t *sccregs;
/*
* Allocate buffer descriptors
*/
RxBd[port+1] = M821AllocateBufferDescriptors(1);
TxBd[port+1] = M821AllocateBufferDescriptors(1);
/*
* Configure ports A and B to enable TXDx and RXDx pins
*/
m821.papar |= (0xC << ((port-2) * 2));
m821.padir &= ~(0xC << ((port-2) * 2));
m821.pbdir |= (0x04 << (port-2));
m821.paodr &= ~(0x8 << ((port-2) * 2));
m821.pbdat &= ~(0x04 << (port-2));
/* SCC2 is the only one with handshaking lines */
/*
if (port == 2) {
m821.pcpar |= (0x02);
m821.pcpar &= ~(0xc0);
m821.pcdir &= ~(0xc2);
m821.pcso |= (0xc0);
}
*/
brg = m821_get_brg_clk(9600); /* 4 BRGs, 5 serial ports - hopefully */
/* at least 2 ports will be the same */
/*
* Set up SDMA
*/
m821.sdcr = 0x01; /* as recommended p 16-80, sec 16.10.2.1 MPC821UM/AD */
m821.sicr &= ~(0xff << ((port-1) * 8));
m821.sicr |= (brg << (3 + ((port-1) * 8))) | (brg << ((port-1) * 8));
/*
* Set up SCC1 parameter RAM common to all protocols
*/
if (port == 1) {
sccparms = (m821SCCparms_t*)&m821.scc1p;
sccregs = &m821.scc1;
}
else if (port == 2) {
sccparms = &m821.scc2p;
sccregs = &m821.scc2;
}
sccparms->rbase = (char *)RxBd[port+1] - (char *)&m821;
sccparms->tbase = (char *)TxBd[port+1] - (char *)&m821;
if (port == 1)
M821ExecuteRISC (M821_CR_OP_INIT_RX_TX | M821_CR_CHAN_SCC1);
else if (port == 2)
M821ExecuteRISC (M821_CR_OP_INIT_RX_TX | M821_CR_CHAN_SCC2);
sccparms->rfcr = M821_RFCR_MOT | M821_RFCR_DMA_SPACE(0);
sccparms->tfcr = M821_TFCR_MOT | M821_TFCR_DMA_SPACE(0);
sccparms->mrblr = RXBUFSIZE;
sccparms->un.uart.max_idl = 10;
sccparms->un.uart.brklen = 0;
sccparms->un.uart.brkec = 0;
sccparms->un.uart.brkcr = 1;
sccparms->un.uart.parec = 0;
sccparms->un.uart.frmec = 0;
sccparms->un.uart.nosec = 0;
sccparms->un.uart.uaddr[0] = 0;
sccparms->un.uart.uaddr[1] = 0;
sccparms->un.uart.toseq = 0;
sccparms->un.uart.character[0] = 0x8000;
sccparms->un.uart.character[1] = 0x8000;
sccparms->un.uart.character[2] = 0x8000;
sccparms->un.uart.character[3] = 0x8000;
sccparms->un.uart.character[4] = 0x8000;
sccparms->un.uart.character[5] = 0x8000;
sccparms->un.uart.character[6] = 0x8000;
sccparms->un.uart.character[7] = 0x8000;
sccparms->un.uart.rccm = 0xc0ff;
/*
* Set up the Receive Buffer Descriptor
*/
RxBd[port+1]->status = M821_BD_EMPTY | M821_BD_WRAP |
M821_BD_INTERRUPT;
RxBd[port+1]->length = 0;
RxBd[port+1]->buffer = malloc(RXBUFSIZE);
/*
* Setup the Transmit Buffer Descriptor
*/
TxBd[port+1]->status = M821_BD_WRAP;
/*
* Set up SCCx general and protocol-specific mode registers
*/
sccregs->scce = 0xffff;
sccregs->sccm = 0x0000;
sccregs->gsmr_h = 0x00000020;
sccregs->gsmr_l = 0x00028004;
sccregs->psmr = 0x3000;
sccregs->gsmr_l = 0x00028034;
}
void
m821_smc_initialize (int port) /* port is the SMC number (i.e. 1 or 2) */
{
unsigned char brg;
/*
* Allocate buffer descriptors
*/
RxBd[port-1] = M821AllocateBufferDescriptors (1);
TxBd[port-1] = M821AllocateBufferDescriptors (1);
/*
* Configure port B pins to enable SMTXDx and SMRXDx pins
*/
m821.pbpar |= (0xC0 << ((port-1) * 4));
m821.pbdir &= ~(0xC0 << ((port-1) * 4));
m821.pbdir |= (0x01 << (port-1));
m821.pbodr &= ~(0xC0 << ((port-1) * 4));
m821.pbdat &= ~(0x01 << (port-1));
/*
* Set up BRG1 (9,600 baud)
*/
brg = m821_get_brg_clk(9600); /* 4 BRGs, 5 serial ports - hopefully */
/* at least 2 ports will be the same */
/*
* Put SMC in NMSI mode, connect SMC to BRG
*/
m860.simode &= ~(0x7000 << ((port-1) * 16));
m860.simode |= brg << (12 + ((port-1) * 16));
/*
* Set up SMC1 parameter RAM common to all protocols
*/
if (port == 1) {
m821.smc1p.rbase = (char *)RxBd[port-1] - (char *)&m821;
m821.smc1p.tbase = (char *)TxBd[port-1] - (char *)&m821;
m821.smc1p.rfcr = M821_RFCR_MOT | M821_RFCR_DMA_SPACE(0);
m821.smc1p.tfcr = M821_TFCR_MOT | M821_TFCR_DMA_SPACE(0);
m821.smc1p.mrblr = RXBUFSIZE;
/*
* Set up SMC1 parameter RAM UART-specific parameters
*/
m821.smc1p.un.uart.max_idl = 10;
m821.smc1p.un.uart.brklen = 0;
m821.smc1p.un.uart.brkec = 0;
m821.smc1p.un.uart.brkcr = 0;
}
else {
m821.smc2p.rbase = (char *)RxBd[port-1] - (char *)&m821;
m821.smc2p.tbase = (char *)TxBd[port-1] - (char *)&m821;
m821.smc2p.rfcr = M821_RFCR_MOT | M821_RFCR_DMA_SPACE(0);
m821.smc2p.tfcr = M821_TFCR_MOT | M821_TFCR_DMA_SPACE(0);
m821.smc2p.mrblr = RXBUFSIZE;
/*
* Set up SMC2 parameter RAM UART-specific parameters
*/
m821.smc2p.un.uart.max_idl = 10;
m821.smc2p.un.uart.brklen = 0;
m821.smc2p.un.uart.brkec = 0;
m821.smc2p.un.uart.brkcr = 0;
}
/*
* Set up the Receive Buffer Descriptor
*/
RxBd[port-1]->status = M821_BD_EMPTY | M821_BD_WRAP |
M821_BD_INTERRUPT;
RxBd[port-1]->length = 0;
RxBd[port-1]->buffer = malloc(RXBUFSIZE);
/*
* Setup the Transmit Buffer Descriptor
*/
TxBd[port-1]->status = M821_BD_WRAP;
/*
* Set up SMCx general and protocol-specific mode registers
*/
if (port == 1) {
m821.smc1.smce = ~0; /* Clear any pending events */
m821.smc1.smcm = 0; /* Mask all interrupt/event sources */
m821.smc1.smcmr = M821_SMCMR_CLEN(9) | M821_SMCMR_SM_UART;
/*
* Send "Init parameters" command
*/
M821ExecuteRISC (M821_CR_OP_INIT_RX_TX | M821_CR_CHAN_SMC1);
/*
* Enable receiver and transmitter
*/
m821.smc1.smcmr |= M821_SMCMR_TEN | M821_SMCMR_REN;
}
else {
m821.smc2.smce = ~0; /* Clear any pending events */
m821.smc2.smcm = 0; /* Mask all interrupt/event sources */
m821.smc2.smcmr = M821_SMCMR_CLEN(9) | M821_SMCMR_SM_UART;
/*
* Send "Init parameters" command
*/
M821ExecuteRISC (M821_CR_OP_INIT_RX_TX | M821_CR_CHAN_SMC2);
/*
* Enable receiver and transmitter
*/
m821.smc2.smcmr |= M821_SMCMR_TEN | M821_SMCMR_REN;
}
}
int
m821_char_poll_read (int minor)
{
unsigned char c;
rtems_unsigned32 level;
_CPU_ISR_Disable(level);
if (RxBd[minor]->status & M821_BD_EMPTY) {
_CPU_ISR_Enable(level);
return -1;
}
c = ((char *)RxBd[minor]->buffer)[0];
RxBd[minor]->status = M821_BD_EMPTY | M821_BD_WRAP;
_CPU_ISR_Enable(level);
return c;
}
int
m821_char_poll_write (int minor, const char *buf, int len)
{
while (len--) {
while (TxBd[minor]->status & M821_BD_READY)
continue;
txBuf[minor] = *buf++;
TxBd[minor]->buffer = &txBuf[minor];
TxBd[minor]->length = 1;
TxBd[minor]->status = M821_BD_READY | M821_BD_WRAP;
}
return 0;
}
/*
* Interrupt handler
*/
rtems_isr
m821_scc1_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if ((m821.scc1.sccm & 0x1) && (m821.scc1.scce & 0x1)) {
m821.scc1.scce = 0x1;
/* m821.scc1.sccm &= ~0x1;*/
while ((RxBd[SCC1_MINOR]->status & M821_BD_EMPTY) == 0) {
rxBufListTail[SCC1_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SCC1_MINOR]->next) {
rxBufListTail[SCC1_MINOR] = rxBufListTail[SCC1_MINOR]->next;
rxBufListTail[SCC1_MINOR]->buf = RxBd[SCC1_MINOR]->buffer;
rxBufListTail[SCC1_MINOR]->len = RxBd[SCC1_MINOR]->length;
rxBufListTail[SCC1_MINOR]->pos = 0;
rxBufListTail[SCC1_MINOR]->next = 0;
RxBd[SCC1_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SCC1_MINOR]->status = M821_BD_EMPTY | M821_BD_WRAP |
M821_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m821.smc1.smce & 0x2) {
m821.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m821.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
}
rtems_isr
m821_scc2_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if ((m821.scc2.sccm & 0x1) && (m821.scc2.scce & 0x1)) {
m821.scc2.scce = 0x1;
/* m821.scc2.sccm &= ~0x1;*/
while ((RxBd[SCC2_MINOR]->status & M821_BD_EMPTY) == 0) {
rxBufListTail[SCC2_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SCC2_MINOR]->next) {
rxBufListTail[SCC2_MINOR] = rxBufListTail[SCC2_MINOR]->next;
rxBufListTail[SCC2_MINOR]->buf = RxBd[SCC2_MINOR]->buffer;
rxBufListTail[SCC2_MINOR]->len = RxBd[SCC2_MINOR]->length;
rxBufListTail[SCC2_MINOR]->pos = 0;
rxBufListTail[SCC2_MINOR]->next = 0;
RxBd[SCC2_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SCC2_MINOR]->status = M821_BD_EMPTY | M821_BD_WRAP |
M821_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m821.smc1.smce & 0x2) {
m821.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m821.cisr = 1UL << 29; /* Clear SCC2 interrupt-in-service bit */
}
rtems_isr
m821_smc1_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if (m821.smc1.smce & 0x1) {
m821.smc1.smce = 0x1;
/* m821.scc2.sccm &= ~0x1;*/
while ((RxBd[SMC1_MINOR]->status & M821_BD_EMPTY) == 0) {
rxBufListTail[SMC1_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SMC1_MINOR]->next) {
rxBufListTail[SMC1_MINOR] = rxBufListTail[SMC1_MINOR]->next;
rxBufListTail[SMC1_MINOR]->buf = RxBd[SMC1_MINOR]->buffer;
rxBufListTail[SMC1_MINOR]->len = RxBd[SMC1_MINOR]->length;
rxBufListTail[SMC1_MINOR]->pos = 0;
rxBufListTail[SMC1_MINOR]->next = 0;
RxBd[SMC1_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SMC1_MINOR]->status = M821_BD_EMPTY | M821_BD_WRAP |
M821_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m821.smc1.smce & 0x2) {
m821.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m821.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */
}
rtems_isr
m821_smc2_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if (m821.smc2.smce & 0x1) {
m821.smc2.smce = 0x1;
while ((RxBd[SMC2_MINOR]->status & M821_BD_EMPTY) == 0) {
rxBufListTail[SMC2_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SMC2_MINOR]->next) {
rxBufListTail[SMC2_MINOR] = rxBufListTail[SMC2_MINOR]->next;
rxBufListTail[SMC2_MINOR]->buf = RxBd[SMC2_MINOR]->buffer;
rxBufListTail[SMC2_MINOR]->len = RxBd[SMC2_MINOR]->length;
rxBufListTail[SMC2_MINOR]->pos = 0;
rxBufListTail[SMC2_MINOR]->next = 0;
RxBd[SMC2_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SMC2_MINOR]->status = M821_BD_EMPTY | M821_BD_WRAP |
M821_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m821.smc1.smce & 0x2) {
m821.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m821.cisr = 1UL << 3; /* Clear SMC2 interrupt-in-service bit */
}
int
m821_buf_poll_read (int minor, char **buf)
{
int len;
if (RxBd[minor]->status & M821_BD_EMPTY)
return -1;
RxBd[minor]->buffer = malloc(RXBUFSIZE); /* I hope this succeeds ... */
len = RxBd[minor]->length;
RxBd[minor]->status = M821_BD_EMPTY | M821_BD_WRAP;
return len;
}
int
m821_buf_poll_write (int minor, char *buf, int len)
{
static char *last_buf[6];
while (TxBd[minor]->status & M821_BD_READY)
continue;
if (last_buf[minor])
free(last_buf[minor]);
last_buf[minor] = buf;
TxBd[minor]->buffer = buf;
TxBd[minor]->length = len;
TxBd[minor]->status = M821_BD_READY | M821_BD_WRAP;
return 0;
}
void m821_console_initialize(void)
{
int i;
for (i=0; i < NIFACES; i++) {
rxBufList[i] = malloc(sizeof(Buf_t));
rxBufListTail[i] = rxBufList[i];
rxBufList[i]->buf = 0;
rxBufList[i]->len = 0;
rxBufList[i]->pos = 0;
rxBufList[i]->next = 0;
}
}
rtems_device_driver m821_console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_libio_rw_args_t *rw_args;
char *buffer;
int maximum;
int count;
Buf_t *tmp_buf;
rtems_unsigned32 level;
/*
* Set up interrupts
* FIXME: DANGER: WARNING:
* CICR and SIMASK must be set in any module that uses
* the CPM. Currently those are console-generic.c and
* network.c. If the registers are not set the same
* in both places, strange things may happen.
* If they are only set in one place, then an application
* that used the other module won't work correctly.
* Put this comment in each module that sets these 2 registers
*/
m821.cicr = 0x00e43e80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
m821.simask |= M821_SIMASK_LVM1;
rw_args = (rtems_libio_rw_args_t *) arg;
buffer = rw_args->buffer;
maximum = rw_args->count;
count = 0;
while (count == 0) {
if (rxBufList[minor]->len) {
while ((count < maximum) &&
(rxBufList[minor]->pos < rxBufList[minor]->len)) {
buffer[count++] = rxBufList[minor]->buf[rxBufList[minor]->pos++];
}
_CPU_ISR_Disable(level);
if (rxBufList[minor]->pos == rxBufList[minor]->len) {
if (rxBufList[minor]->next) {
tmp_buf=rxBufList[minor]->next;
free (rxBufList[minor]->buf);
free (rxBufList[minor]);
rxBufList[minor]=tmp_buf;
}
else {
free(rxBufList[minor]->buf);
rxBufList[minor]->buf=0;
rxBufList[minor]->len=0;
rxBufList[minor]->pos=0;
}
}
_CPU_ISR_Enable(level);
}
else
if(rxBufList[minor]->next && !rxBufList[minor]->len) {
tmp_buf = rxBufList[minor];
rxBufList[minor] = rxBufList[minor]->next;
free(tmp_buf);
}
/* sleep(1);*/
}
rw_args->bytes_moved = count;
return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
}
rtems_device_driver m821_console_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
int count;
int maximum;
rtems_libio_rw_args_t *rw_args;
char *in_buffer;
char *out_buffer;
int n;
/*
* Set up interrupts
* FIXME: DANGER: WARNING:
* CICR and SIMASK must be set in any module that uses
* the CPM. Currently those are console-generic.c and
* network.c. If the registers are not set the same
* in both places, strange things may happen.
* If they are only set in one place, then an application
* that used the other module won't work correctly.
* Put this comment in each module that sets these 2 registers
*/
/* m821.cicr = 0x00e43e80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
/* m821.simask |= M821_SIMASK_LVM1; */
rw_args = (rtems_libio_rw_args_t *) arg;
in_buffer = rw_args->buffer;
maximum = rw_args->count;
out_buffer = malloc(maximum*2); /* This is wasteful, but it won't */
/* be too small */
if (!out_buffer) {
rw_args->bytes_moved = 0;
return RTEMS_NO_MEMORY;
}
n=0;
for (count = 0; count < maximum; count++) {
if ( in_buffer[ count ] == '\n') {
out_buffer[count + n] = '\r';
n++;
}
out_buffer[count + n] = in_buffer[count];
}
m821_buf_poll_write(minor, out_buffer, maximum+n);
rw_args->bytes_moved = maximum;
return RTEMS_SUCCESSFUL;
}
/*
* How to use the console.
* In your BSP, have the following functions:
*
* rtems_device_driver console_initialize(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_open(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_close(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_read(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_write(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_control(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
*
*/

View File

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

View File

@@ -1,21 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = console.h mpc821.h
noinst_HEADERS = $(H_FILES)
TMPINSTALL_FILES += $(PROJECT_INCLUDE)/mpc821 \
$(H_FILES:%=$(PROJECT_INCLUDE)/mpc821/%)
$(PROJECT_INCLUDE)/mpc821:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/mpc821/%.h: %.h
$(INSTALL_DATA) $< $@
all-local: $(TMPINSTALL_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,44 +0,0 @@
/*
* $Id$
*/
#ifndef _M821_CONSOLE_H_
#define _M821_CONSOLE_H_
#include <rtems/libio.h>
int m821_smc_set_attributes(int, const struct termios*);
int m821_scc_set_attributes(int, const struct termios*);
void m821_scc_initialize(int);
void m821_smc_initialize(int);
int m821_char_poll_read(int);
int m821_char_poll_write(int, const char*, int);
rtems_isr m821_scc1_console_interrupt_handler(rtems_vector_number);
rtems_isr m821_scc2_console_interrupt_handler(rtems_vector_number);
rtems_isr m821_smc1_console_interrupt_handler(rtems_vector_number);
rtems_isr m821_smc2_console_interrupt_handler(rtems_vector_number);
int m821_buf_poll_read(int, char**);
int m821_buf_poll_write(int, char*, int);
void m821_console_initialize(void);
rtems_device_driver m821_console_read(rtems_device_major_number,
rtems_device_minor_number,
void*);
rtems_device_driver m821_console_write(rtems_device_major_number,
rtems_device_minor_number,
void*);
typedef struct Buf_t_ {
struct Buf_t_ *next;
volatile char *buf;
volatile int len;
int pos;
} Buf_t;
#define SMC1_MINOR 0
#define SMC2_MINOR 1
#define SCC1_MINOR 2
#define SCC2_MINOR 3
#endif

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,29 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/timer.rel
C_FILES = timer.c
timer_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(timer_rel_OBJECTS)
$(make-rel)
all-local: $(ARCH) $(timer_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = timer.c
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,100 +0,0 @@
/* timer.c
*
* This file manages the interval timer on the PowerPC MPC821.
* NOTE: This is not the PIT, but rather the RTEMS interval
* timer
* We shall use the bottom 32 bits of the timebase register,
*
* The following was in the 403 version of this file. I don't
* know what it means. JTM 5/19/98
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copywright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/timer/timer.c:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/lib/libcpu/hppa1_1/timer/timer.c:
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <mpc821.h>
static volatile rtems_unsigned32 Timer_starting;
static rtems_boolean Timer_driver_Find_average_overhead;
/*
* This is so small that this code will be reproduced where needed.
*/
static inline rtems_unsigned32 get_itimer(void)
{
rtems_unsigned32 ret;
asm volatile ("mftb %0" : "=r" ((ret))); /* TBLO */
return ret;
}
void Timer_initialize(void)
{
/* set interrupt level and enable timebase. This should never */
/* generate an interrupt however. */
m821.tbscr |= M821_TBSCR_TBIRQ(4) | M821_TBSCR_TBE;
Timer_starting = get_itimer();
}
int Read_timer(void)
{
rtems_unsigned32 clicks;
rtems_unsigned32 total;
clicks = get_itimer();
total = clicks - Timer_starting;
if ( Timer_driver_Find_average_overhead == 1 )
return total; /* in XXX microsecond units */
else {
if ( total < rtems_cpu_configuration_get_timer_least_valid() ) {
return 0; /* below timer resolution */
}
return (total - rtems_cpu_configuration_get_timer_average_overhead());
}
}
rtems_status_code Empty_function(void)
{
return RTEMS_SUCCESSFUL;
}
void Set_find_average_overhead(rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
}

View File

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

View File

@@ -1,32 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@:@srcdir@/../../ppc403/vectors
## FIXME
PGM = ${ARCH}/vectors.rel
## Assembly sources
S_FILES = vectors.S align_h.S
vectors_rel_OBJECTS = $(S_FILES:%.S=${ARCH}/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(vectors_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = vectors.S README
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,20 +0,0 @@
#
# $Id$
#
The location of the vectors file object is critical.
From the comments at the head of vectors.s:
The issue with this file is getting it loaded at the right place.
The first vector MUST be at address 0x????0100.
How this is achieved is dependant on the tool chain.
...
The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
offset from 0x????0000 to the first location in the file. This
will be either 0x0000 or 0xfff0.
The eth_comm BSP defines PPC_VECTOR_FILE_BASE to be 0x00000000

View File

@@ -1,952 +0,0 @@
/* vectors.s 1.1 - 95/12/04
*
* This file contains the assembly code for the PowerPC MPC821
* interrupt veneers for RTEMS.
*
* Author: Jay Monkman (jmonkman@frasca.com)
*
* Copyright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/vectors/vectors.s:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
*/
/*
* The issue with this file is getting it loaded at the right place.
* The first vector MUST be at address 0x????0100.
* How this is achieved is dependant on the tool chain.
*
* However the basic mechanism for ELF assemblers is to create a
* section called ".vectors", which will be loaded to an address
* between 0x????0000 and 0x????0100 (inclusive) via a link script.
*
* The basic mechanism for XCOFF assemblers is to place it in the
* normal text section, and arrange for this file to be located
* at an appropriate position on the linker command line.
*
* The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
* offset from 0x????0000 to the first location in the file. This
* will be either 0x0000 or 0xfff0.
*
* $Id$
*/
#include "asm.h"
#include <mpc821.h>
#ifndef PPC_VECTOR_FILE_BASE
#error "PPC_VECTOR_FILE_BASE is not defined."
#endif
/* Where this file will be loaded */
.set file_base, PPC_VECTOR_FILE_BASE
/* Offset to store reg 0 */
.set IP_LINK, 0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
.set IP_0, (IP_LINK + 56)
#else
.set IP_0, (IP_LINK + 8)
#endif
.set IP_2, (IP_0 + 4)
.set IP_3, (IP_2 + 4)
.set IP_4, (IP_3 + 4)
.set IP_5, (IP_4 + 4)
.set IP_6, (IP_5 + 4)
.set IP_7, (IP_6 + 4)
.set IP_8, (IP_7 + 4)
.set IP_9, (IP_8 + 4)
.set IP_10, (IP_9 + 4)
.set IP_11, (IP_10 + 4)
.set IP_12, (IP_11 + 4)
.set IP_13, (IP_12 + 4)
.set IP_28, (IP_13 + 4)
.set IP_29, (IP_28 + 4)
.set IP_30, (IP_29 + 4)
.set IP_31, (IP_30 + 4)
.set IP_CR, (IP_31 + 4)
.set IP_CTR, (IP_CR + 4)
.set IP_XER, (IP_CTR + 4)
.set IP_LR, (IP_XER + 4)
.set IP_PC, (IP_LR + 4)
.set IP_MSR, (IP_PC + 4)
.set IP_END, (IP_MSR + 16)
/* Vector offsets */
.set begin_vector, 0x0000
.set reset_vector, 0x0100
.set mach_vector, 0x0200
.set dsi_vector, 0x0300
.set isi_vector, 0x0400
.set ext_vector, 0x0500
.set align_vector, 0x0600
.set prog_vector, 0x0700
.set float_vector, 0x0800
.set dec_vector, 0x0900
.set sys_vector, 0x0C00
.set trace_vector, 0x0d00
.set syscall_vector, 0x0c00
.set fpassist_vector, 0x0e00
.set software_vector, 0x1000
.set itlbm_vector, 0x1100
.set dtlbm_vector, 0x1200
.set itlbe_vector, 0x1300
.set dtlbe_vector, 0x1400
.set databkpt_vector, 0x1c00
.set insbkpt_vector, 0x1d00
.set perbkpt_vector, 0x1e00
.set dev_vector, 0x1f00
.set siu_vector, 0x2000
.set cpm_vector, 0x2400
/* Go to the right section */
#if PPC_ASM == PPC_ASM_ELF
.section .vectors,"awx",@progbits
#elif PPC_ASM == PPC_ASM_XCOFF
.csect .text[PR]
#endif
PUBLIC_VAR (__vectors)
SYM (__vectors):
/* Critical error handling */
.org reset_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_SYSTEM_RESET
b PROC (_ISR_Handler)
/* Machine check exception */
.org mach_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_MCHECK
b PROC (_ISR_Handler)
/* Protection exception */
.org dsi_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_PROTECT
b PROC (_ISR_Handler)
/* Instruction Storage exception */
.org isi_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_ISI
b PROC (_ISR_Handler)
/* External interrupt */
/* When an external interrupt occurs, we must find out what caused it */
/* before calling the RTEMS handler. First we use SIVEC to decide */
/* what signalled the interrupt to the SIU. */
.org ext_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
stw r9, IP_9(r1) /* r9 will be restored in the next level */
stw r10, IP_10(r1)
lis r9, m821@ha
addi r9, r9, m821@l
lbz r10, 0x1c(r9) /* SIVEC */
rlwinm r10, r10, 4, 0, 27 /* each psuedo vector will have */
/* room for 16 instructions */
addis r10, r10, siu_vectors@ha
addi r10, r10, siu_vectors@l
mflr r0
mtlr r10
lwz r10, IP_10(r1)
blr
/* Align exception */
.org align_vector - file_base
.extern align_h
b align_h
/* Program exception */
.org prog_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_PROGRAM
b PROC (_ISR_Handler)
/* Float exception */
.org float_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_NOFP
b PROC (_ISR_Handler)
/* Decrementer exception */
.org dec_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_PROGRAM
b PROC (_ISR_Handler)
/* System call */
.org sys_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_SCALL
b PROC (_ISR_Handler)
/* Trace interrupt */
.org trace_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_TRACE
b PROC (_ISR_Handler)
.org itlbm_vector - file_base
itlbm_vectors:
mfspr r2, 784 /* MI_CTR */
mfspr r3, 792 /* MD_CTR */
mfspr r4, 787 /* MI_EPN */
mfspr r5, 789 /* MI_TWC */
mfspr r6, 797 /* MD_TWC */
mfspr r7, 789 /* MI_TWC */
mfspr r8, 790 /* MI_RPN */
mfspr r9, 798 /* MD_RPN */
mfspr r10, 796 /* M_TWB */
mfspr r11, 793 /* M_CASID */
mfspr r12, 786 /* MI_AP */
mfspr r13, 794 /* MD_AP */
mfspr r14, 799 /* M_TW */
mfspr r15, 816 /* MI_CAM */
mfspr r16, 817 /* MI_RAM0 */
mfspr r17, 818 /* MI_RAM1 */
mfspr r18, 824 /* MD_CAM */
mfspr r19, 825 /* M_RAM0 */
mfspr r20, 826 /* M_RAM1 */
.long 0
.org dtlbm_vector - file_base
dtlbm_vectors:
mfspr r1, 0x1a
mfspr r2, 784 /* MI_CTR */
mfspr r3, 792 /* MD_CTR */
lis r3, 0x400
mtspr 792, r3
mfspr r4, 787 /* MI_EPN */
mfspr r5, 789 /* MI_TWC */
mfspr r6, 797 /* MD_TWC */
mfspr r7, 789 /* MI_TWC */
mfspr r8, 790 /* MI_RPN */
mfspr r9, 798 /* MD_RPN */
mfspr r10, 796 /* M_TWB */
mfspr r11, 793 /* M_CASID */
mfspr r12, 786 /* MI_AP */
mfspr r13, 794 /* MD_AP */
mfspr r14, 799 /* M_TW */
mfspr r15, 816 /* MI_CAM */
mfspr r16, 817 /* MI_RAM0 */
mfspr r17, 818 /* MI_RAM1 */
mtspr 824, r18
mfspr r18, 824 /* MD_CAM */
mfspr r19, 825 /* M_RAM0 */
mfspr r20, 826 /* M_RAM1 */
.long 0
.org itlbe_vector - file_base
itlbe_vectors:
mfspr r2, 784 /* MI_CTR */
mfspr r3, 792 /* MD_CTR */
mfspr r4, 787 /* MI_EPN */
mfspr r5, 789 /* MI_TWC */
mfspr r6, 797 /* MD_TWC */
mfspr r7, 789 /* MI_TWC */
mfspr r8, 790 /* MI_RPN */
mfspr r9, 798 /* MD_RPN */
mfspr r10, 796 /* M_TWB */
mfspr r11, 793 /* M_CASID */
mfspr r12, 786 /* MI_AP */
mfspr r13, 794 /* MD_AP */
mfspr r14, 799 /* M_TW */
mfspr r15, 816 /* MI_CAM */
mfspr r16, 817 /* MI_RAM0 */
mfspr r17, 818 /* MI_RAM1 */
mfspr r18, 824 /* MD_CAM */
mfspr r19, 825 /* M_RAM0 */
mfspr r20, 826 /* M_RAM1 */
.long 0
.org dtlbe_vector - file_base
dtlbe_vectors:
mfspr r2, 784 /* MI_CTR */
mfspr r3, 792 /* MD_CTR */
mfspr r4, 787 /* MI_EPN */
mfspr r5, 789 /* MI_TWC */
mfspr r6, 797 /* MD_TWC */
mfspr r7, 789 /* MI_TWC */
mfspr r8, 790 /* MI_RPN */
mfspr r9, 798 /* MD_RPN */
mfspr r10, 796 /* M_TWB */
mfspr r11, 793 /* M_CASID */
mfspr r12, 786 /* MI_AP */
mfspr r13, 794 /* MD_AP */
mfspr r14, 799 /* M_TW */
mfspr r15, 816 /* MI_CAM */
mfspr r16, 817 /* MI_RAM0 */
mfspr r17, 818 /* MI_RAM1 */
mfspr r18, 824 /* MD_CAM */
mfspr r19, 825 /* M_RAM0 */
mfspr r20, 826 /* M_RAM1 */
.long 0
/* Now we look at what signaled the interrupt to the SIU. */
/* I needed to do this in order to decode the CPM interrupts before */
/* calling _ISR_Handler */
/* *IRQ0 */
.org siu_vector - file_base
siu_vectors:
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ0
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 0 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL0
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ1
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* This is probably not the "correct" way to do this. I need to have a
* way of calling _ISR_Handler for the CPM interrupts and this is the
* simplest way I can think of. Since I have the CPM interrupt mapped
* to the SIU interrupt level 1 on the eth-comm board, I put it here.
* It would probably be ok if I moved this directory to under libbsp
* instead of libcpu. For now, deal with it.
*/
/* Level 1 - CPM */
/* Now we need to get the CPM interrupt vector */
/* Registers: */
/* R0 - has stored value of LR */
/* R9 - pointer to m821 struct */
/* R10 has already been saved and restored */
li r10, 1
sth r10, 0x930(r9) /* CIVR */
lbz r10, 0x930(r9) /* if we use this as an offset into a */
rlwinm r10, r10, 1, 0, 31 /* table, each entry will have room */
/* 4 instructions. */
addis r10, r10, cpm_vectors@ha
addi r10, r10, cpm_vectors@l
mtlr r10
lwz r10, IP_10(r1)
blr
nop
nop
nop
nop
nop
nop
nop
#if 0
/* Level 1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL1
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
#endif
/* *IRQ2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ2
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL2
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ3 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ3
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 3 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL3
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ4
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL4
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ5 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ5
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 5 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL5
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ6 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ6
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 6 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL6
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ7 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ7
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 7 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL7
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* .org cpm_vector - file_base*/
cpm_vectors:
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RESERVED_0
.long 0
/* PC4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC4
b PROC (_ISR_Handler)
/* PC5 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC5
b PROC (_ISR_Handler)
/* SMC2 / PIP */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SMC2
b PROC (_ISR_Handler)
/* SMC1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SMC1
b PROC (_ISR_Handler)
/* SPI */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SPI
b PROC (_ISR_Handler)
/* PC6 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC6
b PROC (_ISR_Handler)
/* Timer 4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_TIMER4
b PROC (_ISR_Handler)
/* Reserved - we should never see this */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RESERVED_8
.long 0
/* PC7 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC7
b PROC (_ISR_Handler)
/* PC8 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC8
b PROC (_ISR_Handler)
/* PC9 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC9
b PROC (_ISR_Handler)
/* Timer 3 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_TIMER3
b PROC (_ISR_Handler)
/* Reserved - we should never get here */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RESERVED_D
.long 0
/* PC10 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC10
b PROC (_ISR_Handler)
/* PC11 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC11
b PROC (_ISR_Handler)
/* I2C */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_I2C
b PROC (_ISR_Handler)
/* RISC Timer Table */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RISC_TIMER
b PROC (_ISR_Handler)
/* Timer 2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_TIMER2
b PROC (_ISR_Handler)
/* Reserved - we should never get here */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RESERVED_13
.long 0
/* IDMA2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_IDMA2
b PROC (_ISR_Handler)
/* IDMA1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_IDMA1
b PROC (_ISR_Handler)
/* SDMA Channel Bus Error */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SDMA_ERROR
b PROC (_ISR_Handler)
/* PC12 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC12
b PROC (_ISR_Handler)
/* PC13 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC13
b PROC (_ISR_Handler)
/* Timer 1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_TIMER1
b PROC (_ISR_Handler)
/* PC14 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC14
b PROC (_ISR_Handler)
/* SCC4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SCC4
b PROC (_ISR_Handler)
/* SCC3 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SCC3
b PROC (_ISR_Handler)
/* SCC2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SCC2
b PROC (_ISR_Handler)
/* SCC1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SCC1
b PROC (_ISR_Handler)
/* PC15 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC15
b PROC (_ISR_Handler)

View File

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

View File

@@ -1,10 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = include console-generic clock timer vectors
include $(top_srcdir)/../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,19 +0,0 @@
#
# $Id$
#
Various non BSP dependant support routines.
clock - Uses the MPC860 PITPIT (Programmable interval timer) to
generate RTEMS clock ticks.
console_generic - Uses the MPC860 SCCs and SMCs to to serial I/O
include - console.h: function declarations for console related functions
timer - Uses the MPC860 timebase register for timing
tests. It only uses the lower 32 bits
vectors - MPC860 specific vector entry points.
Includes CPU dependant, application independant
handlers: alignment.

View File

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

View File

@@ -1,29 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/clock.rel
C_FILES = clock.c
clock_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(clock_rel_OBJECTS)
$(make-rel)
all-local: $(ARCH) $(clock_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = clock.c
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,179 +0,0 @@
/* clock.c
*
* This routine initializes the PIT on the MPC860.
* The tick frequency is specified by the bsp.
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copyright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <clockdrv.h>
#include <rtems/libio.h>
#include <stdlib.h> /* for atexit() */
#include <mpc860.h>
volatile rtems_unsigned32 Clock_driver_ticks;
extern volatile m860_t m860;
void Clock_exit( void );
/*
* These are set by clock driver during its init
*/
rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor;
/*
* ISR Handler
*/
rtems_isr Clock_isr(rtems_vector_number vector)
{
m860.piscr |= M860_PISCR_PS;
Clock_driver_ticks++;
rtems_clock_tick();
}
void Install_clock(rtems_isr_entry clock_isr)
{
rtems_isr_entry previous_isr;
rtems_unsigned32 pit_value;
Clock_driver_ticks = 0;
pit_value = rtems_configuration_get_microseconds_per_tick() /
rtems_cpu_configuration_get_clicks_per_usec();
if (pit_value == 0) {
pit_value = 0xffff;
} else {
pit_value--;
}
if (pit_value > 0xffff) { /* pit is only 16 bits long */
rtems_fatal_error_occurred(-1);
}
/*
* initialize the interval here
* First tick is set to right amount of time in the future
* Future ticks will be incremented over last value set
* in order to provide consistent clicks in the face of
* interrupt overhead
*/
rtems_interrupt_catch(clock_isr, PPC_IRQ_LVL0, &previous_isr);
m860.sccr &= ~(1<<24);
m860.pitc = pit_value;
/* set PIT irq level, enable PIT, PIT interrupts */
/* and clear int. status */
m860.piscr = M860_PISCR_PIRQ(0) |
M860_PISCR_PTE | M860_PISCR_PS | M860_PISCR_PIE;
m860.simask |= M860_SIMASK_LVM0;
atexit(Clock_exit);
}
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
{
rtems_isr_entry previous_isr;
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable(isrlevel);
rtems_interrupt_catch(new_clock_isr, PPC_IRQ_LVL0, &previous_isr);
rtems_interrupt_enable(isrlevel);
}
/*
* Called via atexit()
* Remove the clock interrupt handler by setting handler to NULL
*/
void
Clock_exit(void)
{
/* disable PIT and PIT interrupts */
m860.piscr &= ~(M860_PISCR_PTE | M860_PISCR_PIE);
(void) set_vector(0, PPC_IRQ_LVL0, 1);
}
rtems_device_driver Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
Install_clock( Clock_isr );
/*
* make major/minor avail to others such as shared memory driver
*/
rtems_clock_major = major;
rtems_clock_minor = minor;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
goto done;
/*
* This is hokey, but until we get a defined interface
* to do this, it will just be this simple...
*/
if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
Clock_isr(PPC_IRQ_LVL0);
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
ReInstall_clock(args->buffer);
}
done:
return RTEMS_SUCCESSFUL;
}

View File

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

View File

@@ -1,29 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/console-generic.rel
C_FILES = console-generic.c
console_generic_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(console_generic_rel_OBJECTS)
$(make-rel)
all-local: $(ARCH) $(console_generic_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = console-generic.c
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,929 +0,0 @@
/*
* General Serial I/O functions.
*
* This file contains the functions for performing serial I/O.
* The actual system calls (console_*) should be in the BSP part
* of the source tree. That way different BSPs can use whichever
* SMCs and SCCs they want. Originally, all the stuff was in
* this file, and it caused problems with one BSP using SCC2
* as /dev/console, others using SMC1 for /dev/console, etc.
*
* On-chip resources used:
* resource minor note
* SMC1 0
* SMC2 1
* SCC1 2 (shared with ethernet driver)
* SCC2 3
* SCC3 4
* SCC4 5
* BRG1
* BRG2
* BRG3
* BRG4
* Author: Jay Monkman (jmonkman@frasca.com)
* Copyright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libbsp/m68k/gen360/console/console.c:
*
* Author:
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* Saskatoon, Saskatchewan, CANADA
* eric@skatter.usask.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.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <rtems/libio.h>
#include <mpc860.h>
#include <mpc860/console.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#define NIFACES 6 /* number of console devices (serial ports) */
static Buf_t *rxBufList[NIFACES];
static Buf_t *rxBufListTail[NIFACES];
/*
* Interrupt-driven input buffer
*/
#define RXBUFSIZE 16
/*
* I/O buffers and pointers to buffer descriptors
*/
static volatile char txBuf[NIFACES];
static volatile m860BufferDescriptor_t *RxBd[NIFACES], *TxBd[NIFACES];
/*
* Device-specific routines
*/
static int m860_get_brg_cd(int);
unsigned char m860_get_brg_clk(int);
unsigned char m860_get_brg_clk(int);
/*
* Compute baud-rate-generator configuration register value
*/
static int
m860_get_brg_cd (int baud)
{
int divisor;
int div16 = 0;
divisor = ((rtems_cpu_configuration_get_clock_speed() / 16) +
(baud / 2)) / baud;
if (divisor > 4096) {
div16 = 1;
divisor = (divisor + 8) / 16;
}
return M860_BRG_EN | M860_BRG_EXTC_BRGCLK |
((divisor - 1) << 1) | div16;
}
/* this function will fail if more that 4 baud rates have been selected */
/* at any time since the OS started. It needs to be fixed. FIXME */
unsigned char m860_get_brg_clk(int baud)
{
static int brg_spd[4];
static char brg_used[4];
int i;
/* first try to find a BRG that is already at the right speed */
for (i=0; i<4; i++) {
if (brg_spd[i] == baud) {
break;
}
}
if (i==4) { /* I guess we didn't find one */
for (i=0; i<4; i++) {
if (brg_used[i] == 0) {
break;
}
}
}
if (i != 4) {
brg_used[i]++;
brg_spd[i]=baud;
switch (i) {
case 0:
m860.brgc1 = M860_BRG_RST;
m860.brgc1 = m860_get_brg_cd(baud);
break;
case 1:
m860.brgc2 = M860_BRG_RST;
m860.brgc2 = m860_get_brg_cd(baud);
break;
case 2:
m860.brgc3 = M860_BRG_RST;
m860.brgc3 = m860_get_brg_cd(baud);
break;
case 3:
m860.brgc4 = M860_BRG_RST;
m860.brgc4 = m860_get_brg_cd(baud);
break;
}
return i;
}
else
return 0xff;
}
/*
* Hardware-dependent portion of tcsetattr().
*/
int
m860_smc_set_attributes (int minor, const struct termios *t)
{
/*
* minor must be 0 or 1
*/
int baud;
int brg;
switch (t->c_cflag & CBAUD) {
default: baud = -1; break;
case B50: baud = 50; break;
case B75: baud = 75; break;
case B110: baud = 110; break;
case B134: baud = 134; break;
case B150: baud = 150; break;
case B200: baud = 200; break;
case B300: baud = 300; break;
case B600: baud = 600; break;
case B1200: baud = 1200; break;
case B1800: baud = 1800; break;
case B2400: baud = 2400; break;
case B4800: baud = 4800; break;
case B9600: baud = 9600; break;
case B19200: baud = 19200; break;
case B38400: baud = 38400; break;
case B57600: baud = 57600; break;
case B115200: baud = 115200; break;
case B230400: baud = 230400; break;
case B460800: baud = 460800; break;
}
if (baud > 0) {
brg = m860_get_brg_clk(baud); /* 4 BRGs, 6 serial ports - hopefully */
/* at least 2 ports will be the same */
m860.simode |= brg << (12 + ((minor) * 16));
}
return 0;
}
int
m860_scc_set_attributes (int minor, const struct termios *t)
{
/*
* minor must be 2, 3, 4 or 5
*/
int baud;
int brg;
switch (t->c_cflag & CBAUD) {
default: baud = -1; break;
case B50: baud = 50; break;
case B75: baud = 75; break;
case B110: baud = 110; break;
case B134: baud = 134; break;
case B150: baud = 150; break;
case B200: baud = 200; break;
case B300: baud = 300; break;
case B600: baud = 600; break;
case B1200: baud = 1200; break;
case B1800: baud = 1800; break;
case B2400: baud = 2400; break;
case B4800: baud = 4800; break;
case B9600: baud = 9600; break;
case B19200: baud = 19200; break;
case B38400: baud = 38400; break;
case B57600: baud = 57600; break;
case B115200: baud = 115200; break;
case B230400: baud = 230400; break;
case B460800: baud = 460800; break;
}
if (baud > 0) {
brg = m860_get_brg_clk(baud); /* 4 BRGs, 5 serial ports - hopefully */
/* at least 2 ports will be the same */
m860.sicr |= (brg << (3 + ((minor-2) * 8))) |
(brg << ((minor-2) * 8));
}
return 0;
}
void
m860_scc_initialize (int port) /* port is the SCC # (i.e. 1, 2, 3 or 4) */
{
unsigned char brg;
volatile m860SCCparms_t *sccparms;
volatile m860SCCRegisters_t *sccregs;
/*
* Allocate buffer descriptors
*/
RxBd[port+1] = M860AllocateBufferDescriptors(1);
TxBd[port+1] = M860AllocateBufferDescriptors(1);
/*
* Configure ports A and B to enable TXDx and RXDx pins
*/
m860.papar |= (0xC << ((port-2) * 2));
m860.padir &= ~(0xC << ((port-2) * 2));
m860.pbdir |= (0x04 << (port-2));
m860.paodr &= ~(0x8 << ((port-2) * 2));
m860.pbdat &= ~(0x04 << (port-2));
/* SCC2 is the only one with handshaking lines */
/*
if (port == 2) {
m860.pcpar |= (0x02);
m860.pcpar &= ~(0xc0);
m860.pcdir &= ~(0xc2);
m860.pcso |= (0xc0);
}
*/
brg = m860_get_brg_clk(9600); /* 4 BRGs, 5 serial ports - hopefully */
/* at least 2 ports will be the same */
/*
* Set up SDMA
*/
m860.sdcr = 0x01; /* as recommended p 16-80, sec 16.10.2.1 MPC860UM/AD */
m860.sicr &= ~(0xff << ((port-1) * 8));
m860.sicr |= (brg << (3 + ((port-1) * 8))) | (brg << ((port-1) * 8));
/*
* Set up SMC1 parameter RAM common to all protocols
*/
if (port == 1) {
sccparms = (m860SCCparms_t*)&m860.scc1p;
sccregs = &m860.scc1;
}
else if (port == 2) {
sccparms = &m860.scc2p;
sccregs = &m860.scc2;
}
else if (port == 3) {
sccparms = &m860.scc3p;
sccregs = &m860.scc3;
}
else {
sccparms = &m860.scc4p;
sccregs = &m860.scc4;
}
sccparms->rbase = (char *)RxBd[port+1] - (char *)&m860;
sccparms->tbase = (char *)TxBd[port+1] - (char *)&m860;
if (port == 1)
M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC1);
else if (port == 2)
M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC2);
else if (port == 3)
M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC3);
else if (port == 4)
M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC4);
sccparms->rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
sccparms->tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
sccparms->mrblr = RXBUFSIZE;
sccparms->un.uart.max_idl = 10;
sccparms->un.uart.brklen = 0;
sccparms->un.uart.brkec = 0;
sccparms->un.uart.brkcr = 1;
sccparms->un.uart.parec = 0;
sccparms->un.uart.frmec = 0;
sccparms->un.uart.nosec = 0;
sccparms->un.uart.uaddr[0] = 0;
sccparms->un.uart.uaddr[1] = 0;
sccparms->un.uart.toseq = 0;
sccparms->un.uart.character[0] = 0x8000;
sccparms->un.uart.character[1] = 0x8000;
sccparms->un.uart.character[2] = 0x8000;
sccparms->un.uart.character[3] = 0x8000;
sccparms->un.uart.character[4] = 0x8000;
sccparms->un.uart.character[5] = 0x8000;
sccparms->un.uart.character[6] = 0x8000;
sccparms->un.uart.character[7] = 0x8000;
sccparms->un.uart.rccm = 0xc0ff;
/*
* Set up the Receive Buffer Descriptor
*/
RxBd[port+1]->status = M860_BD_EMPTY | M860_BD_WRAP |
M860_BD_INTERRUPT;
RxBd[port+1]->length = 0;
RxBd[port+1]->buffer = malloc(RXBUFSIZE);
/*
* Setup the Transmit Buffer Descriptor
*/
TxBd[port+1]->status = M860_BD_WRAP;
/*
* Set up SCCx general and protocol-specific mode registers
*/
sccregs->scce = 0xffff;
sccregs->sccm = 0x0000;
sccregs->gsmr_h = 0x00000020;
sccregs->gsmr_l = 0x00028004;
sccregs->psmr = 0x3000;
sccregs->gsmr_l = 0x00028034;
}
void
m860_smc_initialize (int port) /* port is the SMC number (i.e. 1 or 2) */
{
unsigned char brg;
/*
* Allocate buffer descriptors
*/
RxBd[port-1] = M860AllocateBufferDescriptors (1);
TxBd[port-1] = M860AllocateBufferDescriptors (1);
/*
* Configure port B pins to enable SMTXDx and SMRXDx pins
*/
m860.pbpar |= (0xC0 << ((port-1) * 4));
m860.pbdir &= ~(0xC0 << ((port-1) * 4));
m860.pbdir |= (0x01 << (port-1));
m860.pbodr &= ~(0xC0 << ((port-1) * 4));
m860.pbdat &= ~(0x01 << (port-1));
/*
* Set up BRG1 (9,600 baud)
*/
brg = m860_get_brg_clk(9600); /* 4 BRGs, 5 serial ports - hopefully */
/* at least 2 ports will be the same */
/*
* Put SMC in NMSI mode, connect SMC to BRG
*/
m860.simode &= ~(0x7000 << ((port-1) * 16));
m860.simode |= brg << (12 + ((port-1) * 16));
/*
* Set up SMC1 parameter RAM common to all protocols
*/
if (port == 1) {
m860.smc1p.rbase = (char *)RxBd[port-1] - (char *)&m860;
m860.smc1p.tbase = (char *)TxBd[port-1] - (char *)&m860;
m860.smc1p.rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
m860.smc1p.tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
m860.smc1p.mrblr = RXBUFSIZE;
/*
* Set up SMC1 parameter RAM UART-specific parameters
*/
m860.smc1p.un.uart.max_idl = 10;
m860.smc1p.un.uart.brklen = 0;
m860.smc1p.un.uart.brkec = 0;
m860.smc1p.un.uart.brkcr = 0;
}
else {
m860.smc2p.rbase = (char *)RxBd[port-1] - (char *)&m860;
m860.smc2p.tbase = (char *)TxBd[port-1] - (char *)&m860;
m860.smc2p.rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
m860.smc2p.tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
m860.smc2p.mrblr = RXBUFSIZE;
/*
* Set up SMC2 parameter RAM UART-specific parameters
*/
m860.smc2p.un.uart.max_idl = 10;
m860.smc2p.un.uart.brklen = 0;
m860.smc2p.un.uart.brkec = 0;
m860.smc2p.un.uart.brkcr = 0;
}
/*
* Set up the Receive Buffer Descriptor
*/
RxBd[port-1]->status = M860_BD_EMPTY | M860_BD_WRAP |
M860_BD_INTERRUPT;
RxBd[port-1]->length = 0;
RxBd[port-1]->buffer = malloc(RXBUFSIZE);
/*
* Setup the Transmit Buffer Descriptor
*/
TxBd[port-1]->status = M860_BD_WRAP;
/*
* Set up SMCx general and protocol-specific mode registers
*/
if (port == 1) {
m860.smc1.smce = ~0; /* Clear any pending events */
m860.smc1.smcm = 0; /* Mask all interrupt/event sources */
m860.smc1.smcmr = M860_SMCMR_CLEN(9) | M860_SMCMR_SM_UART;
/*
* Send "Init parameters" command
*/
M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SMC1);
/*
* Enable receiver and transmitter
*/
m860.smc1.smcmr |= M860_SMCMR_TEN | M860_SMCMR_REN;
}
else {
m860.smc2.smce = ~0; /* Clear any pending events */
m860.smc2.smcm = 0; /* Mask all interrupt/event sources */
m860.smc2.smcmr = M860_SMCMR_CLEN(9) | M860_SMCMR_SM_UART;
/*
* Send "Init parameters" command
*/
M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SMC2);
/*
* Enable receiver and transmitter
*/
m860.smc2.smcmr |= M860_SMCMR_TEN | M860_SMCMR_REN;
}
}
int
m860_char_poll_read (int minor)
{
unsigned char c;
rtems_unsigned32 level;
_CPU_ISR_Disable(level);
if (RxBd[minor]->status & M860_BD_EMPTY) {
_CPU_ISR_Enable(level);
return -1;
}
c = ((char *)RxBd[minor]->buffer)[0];
RxBd[minor]->status = M860_BD_EMPTY | M860_BD_WRAP;
_CPU_ISR_Enable(level);
return c;
}
int
m860_char_poll_write (int minor, const char *buf, int len)
{
while (len--) {
while (TxBd[minor]->status & M860_BD_READY)
continue;
txBuf[minor] = *buf++;
TxBd[minor]->buffer = &txBuf[minor];
TxBd[minor]->length = 1;
TxBd[minor]->status = M860_BD_READY | M860_BD_WRAP;
}
return 0;
}
/*
* Interrupt handler
*/
rtems_isr
m860_scc1_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if ((m860.scc1.sccm & 0x1) && (m860.scc1.scce & 0x1)) {
m860.scc1.scce = 0x1;
/* m860.scc1.sccm &= ~0x1;*/
while ((RxBd[SCC1_MINOR]->status & M860_BD_EMPTY) == 0) {
rxBufListTail[SCC1_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SCC1_MINOR]->next) {
rxBufListTail[SCC1_MINOR] = rxBufListTail[SCC1_MINOR]->next;
rxBufListTail[SCC1_MINOR]->buf = RxBd[SCC1_MINOR]->buffer;
rxBufListTail[SCC1_MINOR]->len = RxBd[SCC1_MINOR]->length;
rxBufListTail[SCC1_MINOR]->pos = 0;
rxBufListTail[SCC1_MINOR]->next = 0;
RxBd[SCC1_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SCC1_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP |
M860_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m860.smc1.smce & 0x2) {
m860.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m860.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
}
rtems_isr
m860_scc2_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if ((m860.scc2.sccm & 0x1) && (m860.scc2.scce & 0x1)) {
m860.scc2.scce = 0x1;
/* m860.scc2.sccm &= ~0x1;*/
while ((RxBd[SCC2_MINOR]->status & M860_BD_EMPTY) == 0) {
rxBufListTail[SCC2_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SCC2_MINOR]->next) {
rxBufListTail[SCC2_MINOR] = rxBufListTail[SCC2_MINOR]->next;
rxBufListTail[SCC2_MINOR]->buf = RxBd[SCC2_MINOR]->buffer;
rxBufListTail[SCC2_MINOR]->len = RxBd[SCC2_MINOR]->length;
rxBufListTail[SCC2_MINOR]->pos = 0;
rxBufListTail[SCC2_MINOR]->next = 0;
RxBd[SCC2_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SCC2_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP |
M860_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m860.smc1.smce & 0x2) {
m860.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m860.cisr = 1UL << 29; /* Clear SCC2 interrupt-in-service bit */
}
rtems_isr
m860_scc3_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if ((m860.scc3.sccm & 0x1) && (m860.scc3.scce & 0x1)) {
m860.scc3.scce = 0x1;
/* m860.scc3.sccm &= ~0x1;*/
while ((RxBd[SCC3_MINOR]->status & M860_BD_EMPTY) == 0) {
rxBufListTail[SCC3_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SCC3_MINOR]->next) {
rxBufListTail[SCC3_MINOR] = rxBufListTail[SCC3_MINOR]->next;
rxBufListTail[SCC3_MINOR]->buf = RxBd[SCC3_MINOR]->buffer;
rxBufListTail[SCC3_MINOR]->len = RxBd[SCC3_MINOR]->length;
rxBufListTail[SCC3_MINOR]->pos = 0;
rxBufListTail[SCC3_MINOR]->next = 0;
RxBd[SCC3_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SCC3_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP |
M860_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m860.smc1.smce & 0x2) {
m860.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m860.cisr = 1UL << 28; /* Clear SCC3 interrupt-in-service bit */
}
rtems_isr
m860_scc4_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if ((m860.scc4.sccm & 0x1) && (m860.scc4.scce & 0x1)) {
m860.scc4.scce = 0x1;
/* m860.scc4.sccm &= ~0x1;*/
while ((RxBd[SCC4_MINOR]->status & M860_BD_EMPTY) == 0) {
rxBufListTail[SCC4_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SCC4_MINOR]->next) {
rxBufListTail[SCC4_MINOR] = rxBufListTail[SCC4_MINOR]->next;
rxBufListTail[SCC4_MINOR]->buf = RxBd[SCC4_MINOR]->buffer;
rxBufListTail[SCC4_MINOR]->len = RxBd[SCC4_MINOR]->length;
rxBufListTail[SCC4_MINOR]->pos = 0;
rxBufListTail[SCC4_MINOR]->next = 0;
RxBd[SCC4_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SCC4_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP |
M860_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m860.smc1.smce & 0x2) {
m860.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m860.cisr = 1UL << 27; /* Clear SCC4 interrupt-in-service bit */
}
rtems_isr
m860_smc1_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if (m860.smc1.smce & 0x1) {
m860.smc1.smce = 0x1;
/* m860.scc2.sccm &= ~0x1;*/
while ((RxBd[SMC1_MINOR]->status & M860_BD_EMPTY) == 0) {
rxBufListTail[SMC1_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SMC1_MINOR]->next) {
rxBufListTail[SMC1_MINOR] = rxBufListTail[SMC1_MINOR]->next;
rxBufListTail[SMC1_MINOR]->buf = RxBd[SMC1_MINOR]->buffer;
rxBufListTail[SMC1_MINOR]->len = RxBd[SMC1_MINOR]->length;
rxBufListTail[SMC1_MINOR]->pos = 0;
rxBufListTail[SMC1_MINOR]->next = 0;
RxBd[SMC1_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SMC1_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP |
M860_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m860.smc1.smce & 0x2) {
m860.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m860.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */
}
rtems_isr
m860_smc2_console_interrupt_handler (rtems_vector_number v)
{
/*
* Buffer received?
*/
if (m860.smc2.smce & 0x1) {
m860.smc2.smce = 0x1;
while ((RxBd[SMC2_MINOR]->status & M860_BD_EMPTY) == 0) {
rxBufListTail[SMC2_MINOR]->next = malloc(sizeof(Buf_t));
if (rxBufListTail[SMC2_MINOR]->next) {
rxBufListTail[SMC2_MINOR] = rxBufListTail[SMC2_MINOR]->next;
rxBufListTail[SMC2_MINOR]->buf = RxBd[SMC2_MINOR]->buffer;
rxBufListTail[SMC2_MINOR]->len = RxBd[SMC2_MINOR]->length;
rxBufListTail[SMC2_MINOR]->pos = 0;
rxBufListTail[SMC2_MINOR]->next = 0;
RxBd[SMC2_MINOR]->buffer = malloc(RXBUFSIZE);
}
RxBd[SMC2_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP |
M860_BD_INTERRUPT;
}
}
/*
* Buffer transmitted?
*/
#if 0
if (m860.smc1.smce & 0x2) {
m860.smc1.smce = 0x2;
if ((smcTxBd->status & M360_BD_READY) == 0)
rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
}
#endif
m860.cisr = 1UL << 3; /* Clear SMC2 interrupt-in-service bit */
}
int
m860_buf_poll_read (int minor, char **buf)
{
int len;
if (RxBd[minor]->status & M860_BD_EMPTY)
return -1;
RxBd[minor]->buffer = malloc(RXBUFSIZE); /* I hope this succeeds ... */
len = RxBd[minor]->length;
RxBd[minor]->status = M860_BD_EMPTY | M860_BD_WRAP;
return len;
}
int
m860_buf_poll_write (int minor, char *buf, int len)
{
static char *last_buf[6];
while (TxBd[minor]->status & M860_BD_READY)
continue;
if (last_buf[minor])
free(last_buf[minor]);
last_buf[minor] = buf;
TxBd[minor]->buffer = buf;
TxBd[minor]->length = len;
TxBd[minor]->status = M860_BD_READY | M860_BD_WRAP;
return 0;
}
void m860_console_initialize(void)
{
int i;
for (i=0; i < NIFACES; i++) {
rxBufList[i] = malloc(sizeof(Buf_t));
rxBufListTail[i] = rxBufList[i];
rxBufList[i]->buf = 0;
rxBufList[i]->len = 0;
rxBufList[i]->pos = 0;
rxBufList[i]->next = 0;
}
}
rtems_device_driver m860_console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_libio_rw_args_t *rw_args;
char *buffer;
int maximum;
int count;
Buf_t *tmp_buf;
rtems_unsigned32 level;
/*
* Set up interrupts
* FIXME: DANGER: WARNING:
* CICR and SIMASK must be set in any module that uses
* the CPM. Currently those are console-generic.c and
* network.c. If the registers are not set the same
* in both places, strange things may happen.
* If they are only set in one place, then an application
* that used the other module won't work correctly.
* Put this comment in each module that sets these 2 registers
*/
m860.cicr = 0x00e43e80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
m860.simask |= M860_SIMASK_LVM1;
rw_args = (rtems_libio_rw_args_t *) arg;
buffer = rw_args->buffer;
maximum = rw_args->count;
count = 0;
while (count == 0) {
if (rxBufList[minor]->len) {
while ((count < maximum) &&
(rxBufList[minor]->pos < rxBufList[minor]->len)) {
buffer[count++] = rxBufList[minor]->buf[rxBufList[minor]->pos++];
}
_CPU_ISR_Disable(level);
if (rxBufList[minor]->pos == rxBufList[minor]->len) {
if (rxBufList[minor]->next) {
tmp_buf=rxBufList[minor]->next;
free ((void *) rxBufList[minor]->buf);
free ((void *) rxBufList[minor]);
rxBufList[minor]=tmp_buf;
}
else {
free(rxBufList[minor]->buf);
rxBufList[minor]->buf=0;
rxBufList[minor]->len=0;
rxBufList[minor]->pos=0;
}
}
_CPU_ISR_Enable(level);
}
else
if(rxBufList[minor]->next && !rxBufList[minor]->len) {
tmp_buf = rxBufList[minor];
rxBufList[minor] = rxBufList[minor]->next;
free(tmp_buf);
}
/* sleep(1);*/
}
rw_args->bytes_moved = count;
return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
}
rtems_device_driver m860_console_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
int count;
int maximum;
rtems_libio_rw_args_t *rw_args;
char *in_buffer;
char *out_buffer;
int n;
/*
* Set up interrupts
* FIXME: DANGER: WARNING:
* CICR and SIMASK must be set in any module that uses
* the CPM. Currently those are console-generic.c and
* network.c. If the registers are not set the same
* in both places, strange things may happen.
* If they are only set in one place, then an application
* that used the other module won't work correctly.
* Put this comment in each module that sets these 2 registers
*/
#if 0
m860.cicr = 0x00e43e80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
m860.simask |= M860_SIMASK_LVM1;
#endif
rw_args = (rtems_libio_rw_args_t *) arg;
in_buffer = rw_args->buffer;
maximum = rw_args->count;
out_buffer = malloc(maximum*2); /* This is wasteful, but it won't */
/* be too small */
if (!out_buffer) {
rw_args->bytes_moved = 0;
return RTEMS_NO_MEMORY;
}
n=0;
for (count = 0; count < maximum; count++) {
if ( in_buffer[ count ] == '\n') {
out_buffer[count + n] = '\r';
n++;
}
out_buffer[count + n] = in_buffer[count];
}
m860_buf_poll_write(minor, out_buffer, maximum+n);
rw_args->bytes_moved = maximum;
return RTEMS_SUCCESSFUL;
}
/*
* How to use the console.
* In your BSP, have the following functions:
*
* rtems_device_driver console_initialize(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_open(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_close(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_read(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_write(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
* rtems_device_driver console_control(rtems_device_major_number major,
* rtems_device_minor_number minor,
* void *arg)
*
*/

View File

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

View File

@@ -1,27 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = mpc860.h
MPC860_H_FILES = console.h
noinst_HEADERS = $(H_FILES) $(MPC860_H_FILES)
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc860 \
$(H_FILES:%.h=$(PROJECT_INCLUDE)/%.h) \
$(MPC860_H_FILES:%.h=$(PROJECT_INCLUDE)/mpc860/%.h)
$(PROJECT_INCLUDE)/mpc860:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/mpc860/%.h: %.h
$(INSTALL_DATA) $< $@
all-local: $(PREINSTALL_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,48 +0,0 @@
/*
* $Id$
*/
#ifndef _M860_CONSOLE_H_
#define _M860_CONSOLE_H_
#include <rtems/libio.h>
int m860_smc_set_attributes(int, const struct termios*);
int m860_scc_set_attributes(int, const struct termios*);
void m860_scc_initialize(int);
void m860_smc_initialize(int);
int m860_char_poll_read(int);
int m860_char_poll_write(int, const char*, int);
rtems_isr m860_scc1_console_interrupt_handler(rtems_vector_number);
rtems_isr m860_scc2_console_interrupt_handler(rtems_vector_number);
rtems_isr m860_scc3_console_interrupt_handler(rtems_vector_number);
rtems_isr m860_scc4_console_interrupt_handler(rtems_vector_number);
rtems_isr m860_smc1_console_interrupt_handler(rtems_vector_number);
rtems_isr m860_smc2_console_interrupt_handler(rtems_vector_number);
int m860_buf_poll_read(int, char**);
int m860_buf_poll_write(int, char*, int);
void m860_console_initialize(void);
rtems_device_driver m860_console_read(rtems_device_major_number,
rtems_device_minor_number,
void*);
rtems_device_driver m860_console_write(rtems_device_major_number,
rtems_device_minor_number,
void*);
typedef struct Buf_t_ {
struct Buf_t_ *next;
volatile char *buf;
volatile int len;
int pos;
} Buf_t;
#define SMC1_MINOR 0
#define SMC2_MINOR 1
#define SCC1_MINOR 2
#define SCC2_MINOR 3
#define SCC3_MINOR 4
#define SCC4_MINOR 5
#endif

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,29 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/timer.rel
C_FILES = timer.c
timer_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(timer_rel_OBJECTS)
$(make-rel)
all-local: $(ARCH) $(timer_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = timer.c
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,100 +0,0 @@
/* timer.c
*
* This file manages the interval timer on the PowerPC MPC860.
* NOTE: This is not the PIT, but rather the RTEMS interval
* timer
* We shall use the bottom 32 bits of the timebase register,
*
* The following was in the 403 version of this file. I don't
* know what it means. JTM 5/19/98
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copywright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/timer/timer.c:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/lib/libcpu/hppa1_1/timer/timer.c:
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <mpc860.h>
static volatile rtems_unsigned32 Timer_starting;
static rtems_boolean Timer_driver_Find_average_overhead;
/*
* This is so small that this code will be reproduced where needed.
*/
static inline rtems_unsigned32 get_itimer(void)
{
rtems_unsigned32 ret;
asm volatile ("mftb %0" : "=r" ((ret))); /* TBLO */
return ret;
}
void Timer_initialize(void)
{
/* set interrupt level and enable timebase. This should never */
/* generate an interrupt however. */
m860.tbscr |= M860_TBSCR_TBIRQ(4) | M860_TBSCR_TBE;
Timer_starting = get_itimer();
}
int Read_timer(void)
{
rtems_unsigned32 clicks;
rtems_unsigned32 total;
clicks = get_itimer();
total = clicks - Timer_starting;
if ( Timer_driver_Find_average_overhead == 1 )
return total; /* in XXX microsecond units */
else {
if ( total < rtems_cpu_configuration_get_timer_least_valid() ) {
return 0; /* below timer resolution */
}
return (total - rtems_cpu_configuration_get_timer_average_overhead());
}
}
rtems_status_code Empty_function(void)
{
return RTEMS_SUCCESSFUL;
}
void Set_find_average_overhead(rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
}

View File

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

View File

@@ -1,32 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@:@srcdir@/../../ppc403/vectors
## FIXME
PGM = ${ARCH}/vectors.rel
## Assembly sources
S_FILES = vectors.S align_h.S
vectors_rel_OBJECTS = $(S_FILES:%.S=${ARCH}/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(vectors_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = vectors.S README
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -1,20 +0,0 @@
#
# $Id$
#
The location of the vectors file object is critical.
From the comments at the head of vectors.s:
The issue with this file is getting it loaded at the right place.
The first vector MUST be at address 0x????0100.
How this is achieved is dependant on the tool chain.
...
The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
offset from 0x????0000 to the first location in the file. This
will be either 0x0000 or 0xfff0.
The eth_comm BSP defines PPC_VECTOR_FILE_BASE to be 0x00000000

View File

@@ -1,952 +0,0 @@
/* vectors.s 1.1 - 95/12/04
*
* This file contains the assembly code for the PowerPC MPC860
* interrupt veneers for RTEMS.
*
* Author: Jay Monkman (jmonkman@frasca.com)
*
* Copyright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/vectors/vectors.s:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
*/
/*
* The issue with this file is getting it loaded at the right place.
* The first vector MUST be at address 0x????0100.
* How this is achieved is dependant on the tool chain.
*
* However the basic mechanism for ELF assemblers is to create a
* section called ".vectors", which will be loaded to an address
* between 0x????0000 and 0x????0100 (inclusive) via a link script.
*
* The basic mechanism for XCOFF assemblers is to place it in the
* normal text section, and arrange for this file to be located
* at an appropriate position on the linker command line.
*
* The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
* offset from 0x????0000 to the first location in the file. This
* will be either 0x0000 or 0xfff0.
*
* $Id$
*/
#include "asm.h"
#include <mpc860.h>
#ifndef PPC_VECTOR_FILE_BASE
#error "PPC_VECTOR_FILE_BASE is not defined."
#endif
/* Where this file will be loaded */
.set file_base, PPC_VECTOR_FILE_BASE
/* Offset to store reg 0 */
.set IP_LINK, 0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
.set IP_0, (IP_LINK + 56)
#else
.set IP_0, (IP_LINK + 8)
#endif
.set IP_2, (IP_0 + 4)
.set IP_3, (IP_2 + 4)
.set IP_4, (IP_3 + 4)
.set IP_5, (IP_4 + 4)
.set IP_6, (IP_5 + 4)
.set IP_7, (IP_6 + 4)
.set IP_8, (IP_7 + 4)
.set IP_9, (IP_8 + 4)
.set IP_10, (IP_9 + 4)
.set IP_11, (IP_10 + 4)
.set IP_12, (IP_11 + 4)
.set IP_13, (IP_12 + 4)
.set IP_28, (IP_13 + 4)
.set IP_29, (IP_28 + 4)
.set IP_30, (IP_29 + 4)
.set IP_31, (IP_30 + 4)
.set IP_CR, (IP_31 + 4)
.set IP_CTR, (IP_CR + 4)
.set IP_XER, (IP_CTR + 4)
.set IP_LR, (IP_XER + 4)
.set IP_PC, (IP_LR + 4)
.set IP_MSR, (IP_PC + 4)
.set IP_END, (IP_MSR + 16)
/* Vector offsets */
.set begin_vector, 0x0000
.set reset_vector, 0x0100
.set mach_vector, 0x0200
.set dsi_vector, 0x0300
.set isi_vector, 0x0400
.set ext_vector, 0x0500
.set align_vector, 0x0600
.set prog_vector, 0x0700
.set float_vector, 0x0800
.set dec_vector, 0x0900
.set sys_vector, 0x0C00
.set trace_vector, 0x0d00
.set syscall_vector, 0x0c00
.set fpassist_vector, 0x0e00
.set software_vector, 0x1000
.set itlbm_vector, 0x1100
.set dtlbm_vector, 0x1200
.set itlbe_vector, 0x1300
.set dtlbe_vector, 0x1400
.set databkpt_vector, 0x1c00
.set insbkpt_vector, 0x1d00
.set perbkpt_vector, 0x1e00
.set dev_vector, 0x1f00
.set siu_vector, 0x2000
.set cpm_vector, 0x2400
/* Go to the right section */
#if PPC_ASM == PPC_ASM_ELF
.section .vectors,"awx",@progbits
#elif PPC_ASM == PPC_ASM_XCOFF
.csect .text[PR]
#endif
PUBLIC_VAR (__vectors)
SYM (__vectors):
/* Critical error handling */
.org reset_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_SYSTEM_RESET
b PROC (_ISR_Handler)
/* Machine check exception */
.org mach_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_MCHECK
b PROC (_ISR_Handler)
/* Protection exception */
.org dsi_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_PROTECT
b PROC (_ISR_Handler)
/* Instruction Storage exception */
.org isi_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_ISI
b PROC (_ISR_Handler)
/* External interrupt */
/* When an external interrupt occurs, we must find out what caused it */
/* before calling the RTEMS handler. First we use SIVEC to decide */
/* what signalled the interrupt to the SIU. */
.org ext_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
stw r9, IP_9(r1) /* r9 will be restored in the next level */
stw r10, IP_10(r1)
lis r9, m860@ha
addi r9, r9, m860@l
lbz r10, 0x1c(r9) /* SIVEC */
rlwinm r10, r10, 4, 0, 27 /* each psuedo vector will have */
/* room for 16 instructions */
addis r10, r10, siu_vectors@ha
addi r10, r10, siu_vectors@l
mflr r0
mtlr r10
lwz r10, IP_10(r1)
blr
/* Align exception */
.org align_vector - file_base
.extern align_h
b align_h
/* Program exception */
.org prog_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_PROGRAM
b PROC (_ISR_Handler)
/* Float exception */
.org float_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_NOFP
b PROC (_ISR_Handler)
/* Decrementer exception */
.org dec_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_PROGRAM
b PROC (_ISR_Handler)
/* System call */
.org sys_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_SCALL
b PROC (_ISR_Handler)
/* Trace interrupt */
.org trace_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
#else
stwu r1, -(20*4 + IP_END)(r1)
#endif
#else
stwu r1, -(IP_END)(r1)
#endif
stw r0, IP_0(r1)
li r0, PPC_IRQ_TRACE
b PROC (_ISR_Handler)
.org itlbm_vector - file_base
itlbm_vectors:
mfspr r2, 784 /* MI_CTR */
mfspr r3, 792 /* MD_CTR */
mfspr r4, 787 /* MI_EPN */
mfspr r5, 789 /* MI_TWC */
mfspr r6, 797 /* MD_TWC */
mfspr r7, 789 /* MI_TWC */
mfspr r8, 790 /* MI_RPN */
mfspr r9, 798 /* MD_RPN */
mfspr r10, 796 /* M_TWB */
mfspr r11, 793 /* M_CASID */
mfspr r12, 786 /* MI_AP */
mfspr r13, 794 /* MD_AP */
mfspr r14, 799 /* M_TW */
mfspr r15, 816 /* MI_CAM */
mfspr r16, 817 /* MI_RAM0 */
mfspr r17, 818 /* MI_RAM1 */
mfspr r18, 824 /* MD_CAM */
mfspr r19, 825 /* M_RAM0 */
mfspr r20, 826 /* M_RAM1 */
.long 0
.org dtlbm_vector - file_base
dtlbm_vectors:
mfspr r1, 0x1a
mfspr r2, 784 /* MI_CTR */
mfspr r3, 792 /* MD_CTR */
lis r3, 0x400
mtspr 792, r3
mfspr r4, 787 /* MI_EPN */
mfspr r5, 789 /* MI_TWC */
mfspr r6, 797 /* MD_TWC */
mfspr r7, 789 /* MI_TWC */
mfspr r8, 790 /* MI_RPN */
mfspr r9, 798 /* MD_RPN */
mfspr r10, 796 /* M_TWB */
mfspr r11, 793 /* M_CASID */
mfspr r12, 786 /* MI_AP */
mfspr r13, 794 /* MD_AP */
mfspr r14, 799 /* M_TW */
mfspr r15, 816 /* MI_CAM */
mfspr r16, 817 /* MI_RAM0 */
mfspr r17, 818 /* MI_RAM1 */
mtspr 824, r18
mfspr r18, 824 /* MD_CAM */
mfspr r19, 825 /* M_RAM0 */
mfspr r20, 826 /* M_RAM1 */
.long 0
.org itlbe_vector - file_base
itlbe_vectors:
mfspr r2, 784 /* MI_CTR */
mfspr r3, 792 /* MD_CTR */
mfspr r4, 787 /* MI_EPN */
mfspr r5, 789 /* MI_TWC */
mfspr r6, 797 /* MD_TWC */
mfspr r7, 789 /* MI_TWC */
mfspr r8, 790 /* MI_RPN */
mfspr r9, 798 /* MD_RPN */
mfspr r10, 796 /* M_TWB */
mfspr r11, 793 /* M_CASID */
mfspr r12, 786 /* MI_AP */
mfspr r13, 794 /* MD_AP */
mfspr r14, 799 /* M_TW */
mfspr r15, 816 /* MI_CAM */
mfspr r16, 817 /* MI_RAM0 */
mfspr r17, 818 /* MI_RAM1 */
mfspr r18, 824 /* MD_CAM */
mfspr r19, 825 /* M_RAM0 */
mfspr r20, 826 /* M_RAM1 */
.long 0
.org dtlbe_vector - file_base
dtlbe_vectors:
mfspr r2, 784 /* MI_CTR */
mfspr r3, 792 /* MD_CTR */
mfspr r4, 787 /* MI_EPN */
mfspr r5, 789 /* MI_TWC */
mfspr r6, 797 /* MD_TWC */
mfspr r7, 789 /* MI_TWC */
mfspr r8, 790 /* MI_RPN */
mfspr r9, 798 /* MD_RPN */
mfspr r10, 796 /* M_TWB */
mfspr r11, 793 /* M_CASID */
mfspr r12, 786 /* MI_AP */
mfspr r13, 794 /* MD_AP */
mfspr r14, 799 /* M_TW */
mfspr r15, 816 /* MI_CAM */
mfspr r16, 817 /* MI_RAM0 */
mfspr r17, 818 /* MI_RAM1 */
mfspr r18, 824 /* MD_CAM */
mfspr r19, 825 /* M_RAM0 */
mfspr r20, 826 /* M_RAM1 */
.long 0
/* Now we look at what signaled the interrupt to the SIU. */
/* I needed to do this in order to decode the CPM interrupts before */
/* calling _ISR_Handler */
/* *IRQ0 */
.org siu_vector - file_base
siu_vectors:
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ0
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 0 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL0
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ1
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* This is probably not the "correct" way to do this. I need to have a
* way of calling _ISR_Handler for the CPM interrupts and this is the
* simplest way I can think of. Since I have the CPM interrupt mapped
* to the SIU interrupt level 1 on the eth-comm board, I put it here.
* It would probably be ok if I moved this directory to under libbsp
* instead of libcpu. For now, deal with it.
*/
/* Level 1 - CPM */
/* Now we need to get the CPM interrupt vector */
/* Registers: */
/* R0 - has stored value of LR */
/* R9 - pointer to m860 struct */
/* R10 has already been saved and restored */
li r10, 1
sth r10, 0x930(r9) /* CIVR */
lbz r10, 0x930(r9) /* if we use this as an offset into a */
rlwinm r10, r10, 1, 0, 31 /* table, each entry will have room */
/* 4 instructions. */
addis r10, r10, cpm_vectors@ha
addi r10, r10, cpm_vectors@l
mtlr r10
lwz r10, IP_10(r1)
blr
nop
nop
nop
nop
nop
nop
nop
#if 0
/* Level 1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL1
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
#endif
/* *IRQ2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ2
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL2
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ3 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ3
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 3 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL3
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ4
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL4
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ5 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ5
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 5 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL5
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ6 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ6
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 6 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL6
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* *IRQ7 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_IRQ7
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Level 7 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_LVL7
b PROC (_ISR_Handler)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* .org cpm_vector - file_base*/
cpm_vectors:
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RESERVED_0
.long 0
/* PC4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC4
b PROC (_ISR_Handler)
/* PC5 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC5
b PROC (_ISR_Handler)
/* SMC2 / PIP */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SMC2
b PROC (_ISR_Handler)
/* SMC1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SMC1
b PROC (_ISR_Handler)
/* SPI */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SPI
b PROC (_ISR_Handler)
/* PC6 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC6
b PROC (_ISR_Handler)
/* Timer 4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_TIMER4
b PROC (_ISR_Handler)
/* Reserved - we should never see this */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RESERVED_8
.long 0
/* PC7 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC7
b PROC (_ISR_Handler)
/* PC8 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC8
b PROC (_ISR_Handler)
/* PC9 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC9
b PROC (_ISR_Handler)
/* Timer 3 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_TIMER3
b PROC (_ISR_Handler)
/* Reserved - we should never get here */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RESERVED_D
.long 0
/* PC10 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC10
b PROC (_ISR_Handler)
/* PC11 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC11
b PROC (_ISR_Handler)
/* I2C */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_I2C
b PROC (_ISR_Handler)
/* RISC Timer Table */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RISC_TIMER
b PROC (_ISR_Handler)
/* Timer 2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_TIMER2
b PROC (_ISR_Handler)
/* Reserved - we should never get here */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_RESERVED_13
.long 0
/* IDMA2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_IDMA2
b PROC (_ISR_Handler)
/* IDMA1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_IDMA1
b PROC (_ISR_Handler)
/* SDMA Channel Bus Error */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SDMA_ERROR
b PROC (_ISR_Handler)
/* PC12 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC12
b PROC (_ISR_Handler)
/* PC13 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC13
b PROC (_ISR_Handler)
/* Timer 1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_TIMER1
b PROC (_ISR_Handler)
/* PC14 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC14
b PROC (_ISR_Handler)
/* SCC4 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SCC4
b PROC (_ISR_Handler)
/* SCC3 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SCC3
b PROC (_ISR_Handler)
/* SCC2 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SCC2
b PROC (_ISR_Handler)
/* SCC1 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_SCC1
b PROC (_ISR_Handler)
/* PC15 */
mtlr r0
lwz r9, IP_9(r1)
li r0, PPC_IRQ_CPM_PC15
b PROC (_ISR_Handler)