mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-28 07:20:16 +00:00
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:
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 . */
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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)
|
||||
*
|
||||
*/
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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)
|
||||
*
|
||||
*/
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user