* cpu.c, cpu_asm.S: Removed files.
	* nios2-context-initialize.c, nios2-context-switch.S,
	nios2-fatal-halt.c, nios2-initialize-vectors.c, nios2-initialize.c,
	nios2-isr-get-level.c, nios2-isr-install-raw-handler.c,
	nios2-isr-install-vector.c, nios2-isr-is-in-progress.c,
	nios2-isr-set-level.c, nios2-thread-dispatch-disabled.c,
	rtems/score/nios2-utility.h: New files.
	* Makefile.am, preinstall.am: Reflect changes above.
	* irq.c: Update due to API changes.
	* rtems/score/cpu.h: New functions _CPU_Initialize_vectors(),
	_CPU_ISR_Set_level(), and _CPU_Fatal_halt() (instead of macros).
	Support for external interrupt controller (EIC).  Documentation
	changes.
This commit is contained in:
Sebastian Huber
2011-09-01 15:52:12 +00:00
parent 84649da6ea
commit e2d0c6833e
19 changed files with 908 additions and 304 deletions

View File

@@ -1,3 +1,19 @@
2011-09-01 Sebastian Huber <sebastian.huber@embedded-brains.de>
* cpu.c, cpu_asm.S: Removed files.
* nios2-context-initialize.c, nios2-context-switch.S,
nios2-fatal-halt.c, nios2-initialize-vectors.c, nios2-initialize.c,
nios2-isr-get-level.c, nios2-isr-install-raw-handler.c,
nios2-isr-install-vector.c, nios2-isr-is-in-progress.c,
nios2-isr-set-level.c, nios2-thread-dispatch-disabled.c,
rtems/score/nios2-utility.h: New files.
* Makefile.am, preinstall.am: Reflect changes above.
* irq.c: Update due to API changes.
* rtems/score/cpu.h: New functions _CPU_Initialize_vectors(),
_CPU_ISR_Set_level(), and _CPU_Fatal_halt() (instead of macros).
Support for external interrupt controller (EIC). Documentation
changes.
2011-08-18 Chris Johns <chrisj@rtems.org>
* cpu.c: Fix the ISR get level for the IIC. Make

View File

@@ -8,19 +8,35 @@ CLEANFILES =
DISTCLEANFILES =
include_rtemsdir = $(includedir)/rtems
include_rtems_HEADERS = rtems/asm.h
include_rtems_scoredir = $(includedir)/rtems/score
include_rtems_score_HEADERS = rtems/score/cpu.h
include_rtems_score_HEADERS =
include_rtems_score_HEADERS += rtems/score/cpu.h
include_rtems_score_HEADERS += rtems/score/nios2.h
include_rtems_score_HEADERS += rtems/score/nios2-utility.h
include_rtems_score_HEADERS += rtems/score/cpu_asm.h
include_rtems_score_HEADERS += rtems/score/types.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c \
irq.c \
nios2-iic-low-level.S \
cpu_asm.S
libscorecpu_a_SOURCES =
libscorecpu_a_SOURCES += irq.c
libscorecpu_a_SOURCES += nios2-context-initialize.c
libscorecpu_a_SOURCES += nios2-context-switch.S
libscorecpu_a_SOURCES += nios2-fatal-halt.c
libscorecpu_a_SOURCES += nios2-iic-low-level.S
libscorecpu_a_SOURCES += nios2-initialize.c
libscorecpu_a_SOURCES += nios2-initialize-vectors.c
libscorecpu_a_SOURCES += nios2-isr-get-level.c
libscorecpu_a_SOURCES += nios2-isr-install-raw-handler.c
libscorecpu_a_SOURCES += nios2-isr-install-vector.c
libscorecpu_a_SOURCES += nios2-isr-is-in-progress.c
libscorecpu_a_SOURCES += nios2-isr-set-level.c
libscorecpu_a_SOURCES += nios2-thread-dispatch-disabled.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
all-local: $(PREINSTALL_FILES)

View File

@@ -1,139 +0,0 @@
/*
* NIOS2 CPU Dependent Source
*
* COPYRIGHT (c) 1989-2006
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/isr.h>
#include <rtems/score/wkspace.h>
#include <rtems/score/nios2.h>
/* _CPU_Initialize
*
* This routine performs processor dependent initialization.
*
* INPUT PARAMETERS: NONE
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_Initialize(void)
{
/*
* If there is not an easy way to initialize the FP context
* during Context_Initialize, then it is usually easier to
* save an "uninitialized" FP context here and copy it to
* the task's during Context_Initialize.
*/
/* FP context initialization support goes here */
}
/*
* _CPU_ISR_Get_level
*/
uint32_t _CPU_ISR_Get_level( void )
{
/* @todo Add EIC support. */
uint32_t status = __builtin_rdctl(0);
return status & 1 ? 0 : 1;
}
/*
* FIXME: Evaluate interrupt level.
*/
void _CPU_Context_Initialize(
Context_Control *the_context,
uint32_t *stack_base,
uint32_t size,
uint32_t new_level,
void *entry_point,
bool is_fp
)
{
uint32_t stack = (uint32_t)stack_base + size - 4;
the_context->fp = stack;
the_context->sp = stack;
the_context->ra = (intptr_t) entry_point;
/* @todo Add EIC support. */
the_context->status = new_level ? 0 : 1;
}
/*
* _CPU_ISR_install_raw_handler
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_ISR_install_raw_handler(
uint32_t vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
/*
* This is where we install the interrupt handler into the "raw" interrupt
* table used by the CPU to dispatch interrupt handlers.
*/
}
/*
* _CPU_ISR_install_vector
*
* This kernel routine installs the RTEMS handler for the
* specified vector.
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
*
* Output parameters: NONE
*
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_ISR_install_vector(
uint32_t vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
*old_handler = _ISR_Vector_table[ vector ];
/*
* If the interrupt vector table is a table of pointer to isr entry
* points, then we need to install the appropriate RTEMS interrupt
* handler for this vector number.
*/
_CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
/*
* We put the actual user ISR address in '_ISR_vector_table'. This will
* be used by the _ISR_Handler so the user gets control.
*/
_ISR_Vector_table[ vector ] = new_handler;
}

View File

@@ -1,83 +0,0 @@
/*
* $Id$
*
* This file contains all assembly code for the
* NIOS2 implementation of RTEMS.
*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* Derived from no_cpu/cpu_asm.S, copyright (c) 1989-1999,
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/asm.h>
#include <rtems/score/cpu_asm.h>
.set noat
/* ===================================================================== */
/*
* void _CPU_Context_switch( run_context, heir_context )
* void _CPU_Context_restore( run_context, heir_context )
*
* This routine performs a normal non-FP context switch.
*/
.globl _CPU_Context_switch
_CPU_Context_switch:
rdctl r6, status
stw r16, 0(r4)
stw r17, 4(r4)
stw r18, 8(r4)
stw r19, 12(r4)
stw r20, 16(r4)
stw r21, 20(r4)
stw r22, 24(r4)
stw r23, 28(r4)
stw fp, 32(r4)
stw sp, 36(r4)
stw ra, 40(r4)
/* r6 saved status */
stw r6, 44(r4)
_CPU_Context_switch_restore:
ldw r16, 0(r5)
ldw r17, 4(r5)
ldw r18, 8(r5)
ldw r19, 12(r5)
ldw r20, 16(r5)
ldw r21, 20(r5)
ldw r22, 24(r5)
ldw r23, 28(r5)
ldw fp, 32(r5)
ldw sp, 36(r5)
/* Disable interrupts */
wrctl status, r0
ldw ea, 40(r5)
ldw at, 44(r5)
wrctl estatus, at
eret
.globl _CPU_Context_restore
_CPU_Context_restore:
/* Copy first to second arg, then re-use 2nd half of Context_switch */
mov r5, r4
br _CPU_Context_switch_restore

View File

@@ -21,6 +21,7 @@
#include <rtems/score/cpu.h>
#include <rtems/score/isr.h>
#include <rtems/score/thread.h>
#include <rtems/score/nios2-utility.h>
/*
* This routine provides the RTEMS interrupt management.
@@ -53,7 +54,7 @@ RTEMS_INLINE_ROUTINE void __IIC_Handler(void)
* this is the case.
*/
_CPU_read_ipending (active);
active = _Nios2_Get_ctlreg_ipending();
while (active)
{
@@ -77,7 +78,7 @@ RTEMS_INLINE_ROUTINE void __IIC_Handler(void)
++vector;
};
_CPU_read_ipending (active);
active = _Nios2_Get_ctlreg_ipending();
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2011 embedded brains GmbH
*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* COPYRIGHT (c) 1989-2006
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/cpu.h>
#include <string.h>
void _CPU_Context_Initialize(
Context_Control *context,
void *stack_area_begin,
size_t stack_area_size,
uint32_t new_level,
void (*entry_point)( void ),
bool is_fp
)
{
uint32_t stack = (uint32_t) stack_area_begin + stack_area_size - 4;
memset(context, 0, sizeof(*context));
context->fp = stack;
context->sp = stack;
context->ra = (uint32_t) entry_point;
/* @todo Add EIC support. */
context->status = new_level ? 0 : 1;
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2011 embedded brains GmbH
*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* Derived from no_cpu/cpu_asm.S, copyright (c) 1989-1999,
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/cpu.h>
#include <rtems/score/nios2-utility.h>
.extern _Nios2_Thread_dispatch_disabled
.globl _CPU_Context_switch
.globl _CPU_Context_restore
_CPU_Context_switch:
movhi r12, %hiadj(_Nios2_Thread_dispatch_disabled)
addi r12, r12, %lo(_Nios2_Thread_dispatch_disabled)
ldw r9, 0(r12)
rdctl r8, status
stw r16, NIOS2_CONTEXT_OFFSET_R16(r4)
stw r17, NIOS2_CONTEXT_OFFSET_R17(r4)
stw r18, NIOS2_CONTEXT_OFFSET_R18(r4)
stw r19, NIOS2_CONTEXT_OFFSET_R19(r4)
stw r20, NIOS2_CONTEXT_OFFSET_R20(r4)
stw r21, NIOS2_CONTEXT_OFFSET_R21(r4)
stw r22, NIOS2_CONTEXT_OFFSET_R22(r4)
stw r23, NIOS2_CONTEXT_OFFSET_R23(r4)
stw fp, NIOS2_CONTEXT_OFFSET_FP(r4)
stw r8, NIOS2_CONTEXT_OFFSET_STATUS(r4)
stw sp, NIOS2_CONTEXT_OFFSET_SP(r4)
stw ra, NIOS2_CONTEXT_OFFSET_RA(r4)
stw r9, NIOS2_CONTEXT_OFFSET_TDD(r4)
restore:
ldw r10, NIOS2_CONTEXT_OFFSET_TDD(r5)
ldw r16, NIOS2_CONTEXT_OFFSET_R16(r5)
ldw r17, NIOS2_CONTEXT_OFFSET_R17(r5)
ldw r18, NIOS2_CONTEXT_OFFSET_R18(r5)
ldw r19, NIOS2_CONTEXT_OFFSET_R19(r5)
ldw r20, NIOS2_CONTEXT_OFFSET_R20(r5)
ldw r21, NIOS2_CONTEXT_OFFSET_R21(r5)
ldw r22, NIOS2_CONTEXT_OFFSET_R22(r5)
ldw r23, NIOS2_CONTEXT_OFFSET_R23(r5)
ldw fp, NIOS2_CONTEXT_OFFSET_FP(r5)
stw r10, 0(r12)
ldw r11, NIOS2_CONTEXT_OFFSET_STATUS(r5)
ldw sp, NIOS2_CONTEXT_OFFSET_SP(r5)
ldw ra, NIOS2_CONTEXT_OFFSET_RA(r5)
wrctl status, r11
ret
_CPU_Context_restore:
mov r5, r4
br restore

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2011 embedded brains GmbH
*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* COPYRIGHT (c) 1989-2004.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems/score/cpu.h>
void _CPU_Fatal_halt( uint32_t _error )
{
/* write 0 to status register (disable interrupts) */
__builtin_wrctl( 0, 0 );
/* write error code to ET register */
__asm__ volatile ("mov et, %z0" : : "rM" (_error));
while (1);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2011 embedded brains GmbH
*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* COPYRIGHT (c) 1989-2006
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/isr.h>
#include <string.h>
void _CPU_Initialize_vectors( void )
{
memset(_ISR_Vector_table, 0, sizeof(ISR_Handler_entry) * ISR_NUMBER_OF_VECTORS);
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* COPYRIGHT (c) 1989-2006
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/cpu.h>
void _CPU_Initialize( void )
{
/* Nothing to do */
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2011 embedded brains GmbH
*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* COPYRIGHT (c) 1989-2006
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/cpu.h>
#include <rtems/score/interr.h>
#include <rtems/score/nios2-utility.h>
uint32_t _CPU_ISR_Get_level( void )
{
uint32_t status = _Nios2_Get_ctlreg_status();
uint32_t level = 0;
switch ( _Nios2_Get_ISR_status_mask() ) {
case NIOS2_ISR_STATUS_MASK_IIC:
level = (status & NIOS2_STATUS_PIE) == 0;
break;
case NIOS2_ISR_STATUS_MASK_EIC_IL:
level = (status & NIOS2_STATUS_IL_MASK) >> NIOS2_STATUS_IL_OFFSET;
break;
case NIOS2_ISR_STATUS_MASK_EIC_RSIE:
level = (status & NIOS2_STATUS_RSIE) == 0;
break;
default:
/* FIXME */
_Internal_error_Occurred( INTERNAL_ERROR_CORE, false, 0xdeadbeef );
break;
}
return level;
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* COPYRIGHT (c) 1989-2006
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/cpu.h>
/*
* _CPU_ISR_install_raw_handler
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_ISR_install_raw_handler(
uint32_t vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
/*
* This is where we install the interrupt handler into the "raw" interrupt
* table used by the CPU to dispatch interrupt handlers.
*/
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* COPYRIGHT (c) 1989-2006
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/isr.h>
/*
* _CPU_ISR_install_vector
*
* This kernel routine installs the RTEMS handler for the
* specified vector.
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
*
* Output parameters: NONE
*
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_ISR_install_vector(
uint32_t vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
*old_handler = _ISR_Vector_table[ vector ];
/*
* If the interrupt vector table is a table of pointer to isr entry
* points, then we need to install the appropriate RTEMS interrupt
* handler for this vector number.
*/
_CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
/*
* We put the actual user ISR address in '_ISR_vector_table'. This will
* be used by the _ISR_Handler so the user gets control.
*/
_ISR_Vector_table[ vector ] = new_handler;
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2011 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/isr.h>
#include <rtems/score/nios2-utility.h>
bool _ISR_Is_in_progress( void )
{
if ( _Nios2_Has_internal_interrupt_controller() ) {
return _ISR_Nest_level != 0;
} else {
uint32_t status = _Nios2_Get_ctlreg_status();
return (status & NIOS2_STATUS_IH) != 0;
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2011 embedded brains GmbH
*
* Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
*
* COPYRIGHT (c) 1989-2006
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/cpu.h>
#include <rtems/score/interr.h>
#include <rtems/score/nios2-utility.h>
void _CPU_ISR_Set_level( uint32_t new_level )
{
uint32_t status = _Nios2_Get_ctlreg_status();
switch ( _Nios2_Get_ISR_status_mask() ) {
case NIOS2_ISR_STATUS_MASK_IIC:
if ( new_level == 0 ) {
status |= NIOS2_STATUS_PIE;
} else {
status &= ~NIOS2_STATUS_PIE;
}
break;
case NIOS2_ISR_STATUS_MASK_EIC_IL:
status &= ~NIOS2_STATUS_IL_MASK;
status |= (new_level << NIOS2_STATUS_IL_OFFSET) & NIOS2_STATUS_IL_MASK;
break;
case NIOS2_ISR_STATUS_MASK_EIC_RSIE:
if ( new_level == 0 ) {
status |= NIOS2_STATUS_RSIE;
} else {
status &= ~NIOS2_STATUS_RSIE;
}
break;
default:
/* FIXME */
_Internal_error_Occurred( INTERNAL_ERROR_CORE, false, 0xdeadbeef );
break;
}
_Nios2_Set_ctlreg_status( status );
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2011 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/nios2-utility.h>
#define NIOS2_ASSERT_OFFSET(field, off) \
RTEMS_STATIC_ASSERT( \
RTEMS_offsetof(Context_Control, field) \
== NIOS2_CONTEXT_OFFSET_ ## off, \
nios2_context_offset_ ## field \
)
NIOS2_ASSERT_OFFSET(r16, R16);
NIOS2_ASSERT_OFFSET(r17, R17);
NIOS2_ASSERT_OFFSET(r18, R18);
NIOS2_ASSERT_OFFSET(r19, R19);
NIOS2_ASSERT_OFFSET(r20, R20);
NIOS2_ASSERT_OFFSET(r21, R21);
NIOS2_ASSERT_OFFSET(r22, R22);
NIOS2_ASSERT_OFFSET(r23, R23);
NIOS2_ASSERT_OFFSET(fp, FP);
NIOS2_ASSERT_OFFSET(status, STATUS);
NIOS2_ASSERT_OFFSET(sp, SP);
NIOS2_ASSERT_OFFSET(ra, RA);
NIOS2_ASSERT_OFFSET(thread_dispatch_disabled, TDD);
uint32_t _Nios2_Thread_dispatch_disabled;

View File

@@ -35,6 +35,10 @@ $(PROJECT_INCLUDE)/rtems/score/nios2.h: rtems/score/nios2.h $(PROJECT_INCLUDE)/r
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/nios2.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/nios2.h
$(PROJECT_INCLUDE)/rtems/score/nios2-utility.h: rtems/score/nios2-utility.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/nios2-utility.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/nios2-utility.h
$(PROJECT_INCLUDE)/rtems/score/cpu_asm.h: rtems/score/cpu_asm.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpu_asm.h

View File

@@ -41,7 +41,7 @@ extern "C" {
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
#define CPU_PROVIDES_ISR_IS_IN_PROGRESS TRUE
#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
@@ -86,9 +86,20 @@ extern "C" {
#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
#define CPU_STACK_ALIGNMENT CPU_ALIGNMENT
/*
* Alignment value according to "Nios II Processor Reference" chapter 7
* "Application Binary Interface" section "Stacks".
*/
#define CPU_STACK_ALIGNMENT 4
#define CPU_MODES_INTERRUPT_MASK 0x1
/*
* A Nios II configuration with an external interrupt controller (EIC) supports
* up to 64 interrupt levels. A Nios II configuration with an internal
* interrupt controller (IIC) has only two interrupt levels (enabled and
* disabled). The _CPU_ISR_Get_level() and _CPU_ISR_Set_level() functions will
* take care about configuration specific mappings.
*/
#define CPU_MODES_INTERRUPT_MASK 0x3f
#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
@@ -106,6 +117,11 @@ extern "C" {
*
* There is no need to save the global pointer (gp) since it is a system wide
* constant and set-up with the C runtime environment.
*
* The @a thread_dispatch_disabled field is used for the external interrupt
* controller (EIC) support.
*
* @see _Nios2_Thread_dispatch_disabled
*/
typedef struct {
uint32_t r16;
@@ -117,9 +133,10 @@ typedef struct {
uint32_t r22;
uint32_t r23;
uint32_t fp;
uint32_t status;
uint32_t sp;
uint32_t ra;
uint32_t status;
uint32_t thread_dispatch_disabled;
} Context_Control;
#define _CPU_Context_Get_SP( _context ) \
@@ -182,118 +199,123 @@ typedef struct {
uint32_t ipending;
} CPU_Exception_frame;
#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
#define _CPU_Initialize_vectors() \
memset(_ISR_Vector_table, 0, sizeof(ISR_Handler_entry) * ISR_NUMBER_OF_VECTORS)
#else
#define _CPU_Initialize_vectors()
#endif
void _CPU_Initialize_vectors( void );
/**
* @brief Read the ienable register.
*/
#define _CPU_read_ienable( value ) \
do { value = __builtin_rdctl(3); } while (0)
/**
* @brief Write the ienable register.
*/
#define _CPU_write_ienable( value ) \
do { __builtin_wrctl(3, value); } while (0)
/**
* @brief Read the ipending register.
*/
#define _CPU_read_ipending( value ) \
do { value = __builtin_rdctl(4); } while (0)
/**
* Disable all interrupts for a critical section. The previous
* level is returned in _level.
* @brief Macro to disable interrupts.
*
* The processor status before disabling the interrupts will be stored in
* @a _isr_cookie. This value will be used in _CPU_ISR_Flash() and
* _CPU_ISR_Enable().
*
* The global symbol _Nios2_ISR_Status_mask will be used to clear the bits in
* the status register representing the interrupt level. The global symbol
* _Nios2_ISR_Status_bits will be used to set the bits representing an
* interrupt level that disables interrupts. Both global symbols must be
* provided by the board support package.
*
* In case the Nios II uses the internal interrupt controller (IIC), then only
* the PIE status bit is used.
*
* In case the Nios II uses the external interrupt controller (EIC), then the
* RSIE status bit or the IL status field is used depending on the interrupt
* handling variant and the shadow register usage.
*/
#define _CPU_ISR_Disable( _isr_cookie ) \
do { \
_isr_cookie = __builtin_rdctl( 0 ); \
__builtin_wrctl( 0, 0 ); \
int _tmp; \
__asm__ volatile ( \
"rdctl %0, status\n" \
"movhi %1, %%hiadj(_Nios2_ISR_Status_mask)\n" \
"addi %1, %1, %%lo(_Nios2_ISR_Status_mask)\n" \
"and %1, %0, %1\n" \
"ori %1, %1, %%lo(_Nios2_ISR_Status_bits)\n" \
"wrctl status, %1" \
: "=&r" (_isr_cookie), "=&r" (_tmp) \
); \
} while ( 0 )
/**
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
* This indicates the end of a critical section. The parameter
* _level is not modified.
* @brief Macro to restore the processor status.
*
* The @a _isr_cookie must contain the processor status returned by
* _CPU_ISR_Disable(). The value is not modified.
*/
#define _CPU_ISR_Enable( _isr_cookie ) \
do { \
__builtin_wrctl( 0, (int) _isr_cookie ); \
} while ( 0 )
__builtin_wrctl( 0, (int) _isr_cookie )
/**
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long critical
* sections into two or more parts. The parameter _level is not
* modified.
* @brief Macro to restore the processor status and disable the interrupts
* again.
*
* The @a _isr_cookie must contain the processor status returned by
* _CPU_ISR_Disable(). The value is not modified.
*
* This flash code is optimal for all Nios II configurations. The rdctl does
* not flush the pipeline and has only a late result penalty. The wrctl on the
* other hand leads to a pipeline flush.
*/
#define _CPU_ISR_Flash( _isr_cookie ) \
do { \
int _status = __builtin_rdctl( 0 ); \
__builtin_wrctl( 0, (int) _isr_cookie ); \
__builtin_wrctl( 0, 0 ); \
__builtin_wrctl( 0, _status ); \
} while ( 0 )
/**
* Map interrupt level in task mode onto the hardware that the CPU
* actually provides. Currently, interrupt levels which do not
* map onto the CPU in a straight fashion are undefined.
* @brief Sets the interrupt level for the executing thread.
*
* The valid values of @a new_level depend on the Nios II configuration. A
* value of zero represents enabled interrupts in all configurations.
*
* @see _CPU_ISR_Get_level()
*/
#define _CPU_ISR_Set_level( new_level ) \
_CPU_ISR_Enable( new_level == 0 ? 1 : 0 );
void _CPU_ISR_Set_level( uint32_t new_level );
/**
* @brief Obtain the Current Interrupt Disable Level
* @brief Returns the interrupt level of the executing thread.
*
* This method is invoked to return the current interrupt disable level.
*
* @return This method returns the current interrupt disable level.
* @retval 0 Interrupts are enabled.
* @retval otherwise The value depends on the Nios II configuration. In case
* of an internal interrupt controller (IIC) the only valid value is one which
* indicates disabled interrupts. In case of an external interrupt controller
* (EIC) there are two possibilities. Firstly if the RSIE status bit is used
* to disable interrupts, then one is the only valid value indicating disabled
* interrupts. Secondly if the IL status field is used to disable interrupts,
* then this value will be returned. Interrupts are disabled at the maximum
* level specified by the _Nios2_ISR_Status_bits.
*/
uint32_t _CPU_ISR_Get_level( void );
/**
* Initialize the context to a state suitable for starting a
* task after a context restore operation. Generally, this
* involves:
*
* @brief Initializes the CPU context.
*
* The following steps are performed:
* - setting a starting address
* - preparing the stack
* - preparing the stack and frame pointers
* - setting the proper interrupt level in the context
* - initializing the floating point context
*
* @param[in] the_context points to the context area
* @param[in] stack_base is the low address of the allocated stack area
* @param[in] size is the size of the stack area in bytes
* @param[in] context points to the context area
* @param[in] stack_area_begin is the low address of the allocated stack area
* @param[in] stack_area_size is the size of the stack area in bytes
* @param[in] new_level is the interrupt level for the task
* @param[in] entry_point is the task's entry point
* @param[in] is_fp is set to TRUE if the task is a floating point task
*
* @note Implemented as a subroutine for the NIOS2 port.
* @param[in] is_fp is set to @c true if the task is a floating point task
*/
void _CPU_Context_Initialize(
Context_Control *the_context,
uint32_t *stack_base,
uint32_t size,
uint32_t new_level,
void *entry_point,
bool is_fp
Context_Control *context,
void *stack_area_begin,
size_t stack_area_size,
uint32_t new_level,
void (*entry_point)( void ),
bool is_fp
);
#define _CPU_Context_Restart_self( _the_context ) \
_CPU_Context_restore( (_the_context) );
#define _CPU_Fatal_halt( _error ) \
do { \
__builtin_wrctl(0, 0); /* write 0 to status register (disable interrupts) */ \
__asm volatile ("mov et, %z0" : : "rM" (_error)); /* write error code to ET register */ \
for (;;); \
} while ( 0 )
void _CPU_Fatal_halt( uint32_t _error ) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
void _CPU_Initialize( void );

View File

@@ -0,0 +1,300 @@
/*
* Copyright (c) 2011 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _RTEMS_SCORE_NIOS2_UTILITY_H
#define _RTEMS_SCORE_NIOS2_UTILITY_H
#define NIOS2_CTLREG_INDEX_STATUS 0
#define NIOS2_CTLREG_INDEX_ESTATUS 1
#define NIOS2_CTLREG_INDEX_BSTATUS 2
#define NIOS2_CTLREG_INDEX_IENABLE 3
#define NIOS2_CTLREG_INDEX_IPENDING 4
#define NIOS2_CTLREG_INDEX_CPUID 5
#define NIOS2_CTLREG_INDEX_EXCEPTION 7
#define NIOS2_CTLREG_INDEX_PTEADDR 8
#define NIOS2_CTLREG_INDEX_TLBACC 9
#define NIOS2_CTLREG_INDEX_TLBMISC 10
#define NIOS2_CTLREG_INDEX_BADADDR 12
#define NIOS2_CTLREG_INDEX_CONFIG 13
#define NIOS2_CTLREG_INDEX_MPUBASE 14
#define NIOS2_CTLREG_INDEX_MPUACC 15
#define NIOS2_CONTEXT_OFFSET_R16 0
#define NIOS2_CONTEXT_OFFSET_R17 4
#define NIOS2_CONTEXT_OFFSET_R18 8
#define NIOS2_CONTEXT_OFFSET_R19 12
#define NIOS2_CONTEXT_OFFSET_R20 16
#define NIOS2_CONTEXT_OFFSET_R21 20
#define NIOS2_CONTEXT_OFFSET_R22 24
#define NIOS2_CONTEXT_OFFSET_R23 28
#define NIOS2_CONTEXT_OFFSET_FP 32
#define NIOS2_CONTEXT_OFFSET_STATUS 36
#define NIOS2_CONTEXT_OFFSET_SP 40
#define NIOS2_CONTEXT_OFFSET_RA 44
#define NIOS2_CONTEXT_OFFSET_TDD 48
#define NIOS2_ISR_STATUS_MASK_IIC 0xfffffffe
#define NIOS2_ISR_STATUS_BITS_IIC 0x00000000
#define NIOS2_ISR_STATUS_MASK_EIC_IL 0xfffffc0f
#define NIOS2_ISR_STATUS_BITS_EIC_IL 0x000003f0
#define NIOS2_ISR_STATUS_MASK_EIC_RSIE 0xf7ffffff
#define NIOS2_ISR_STATUS_BITS_EIC_RSIE 0x00000000
#define NIOS2_STATUS_RSIE (1 << 23)
#define NIOS2_STATUS_NMI (1 << 22)
#define NIOS2_STATUS_PRS_OFFSET 16
#define NIOS2_STATUS_PRS_MASK (0x3f << NIOS2_STATUS_PRS_OFFSET)
#define NIOS2_STATUS_CRS_OFFSET 10
#define NIOS2_STATUS_CRS_MASK (0x3f << NIOS2_STATUS_CRS_OFFSET)
#define NIOS2_STATUS_IL_OFFSET 4
#define NIOS2_STATUS_IL_MASK (0x3f << NIOS2_STATUS_IL_OFFSET)
#define NIOS2_STATUS_IH (1 << 3)
#define NIOS2_STATUS_EH (1 << 2)
#define NIOS2_STATUS_U (1 << 1)
#define NIOS2_STATUS_PIE (1 << 0)
#define NIOS2_EXCEPTION_CAUSE_OFFSET 2
#define NIOS2_EXCEPTION_CAUSE_MASK (0x1f << NIOS2_EXCEPTION_CAUSE_OFFSET)
#define NIOS2_PTEADDR_PTBASE_OFFSET 22
#define NIOS2_PTEADDR_PTBASE_MASK (0x3ff << NIOS2_PTEADDR_PTBASE_OFFSET)
#define NIOS2_PTEADDR_VPN_OFFSET 2
#define NIOS2_PTEADDR_VPN_MASK (0xfffff << NIOS2_PTEADDR_VPN_OFFSET)
#define NIOS2_TLBACC_IG_OFFSET 25
#define NIOS2_TLBACC_IG_MASK (0x3ff << NIOS2_TLBACC_IG_OFFSET)
#define NIOS2_TLBACC_C (1 << 24)
#define NIOS2_TLBACC_R (1 << 23)
#define NIOS2_TLBACC_W (1 << 22)
#define NIOS2_TLBACC_X (1 << 21)
#define NIOS2_TLBACC_G (1 << 20)
#define NIOS2_TLBACC_PFN_OFFSET 2
#define NIOS2_TLBACC_PFN_MASK (0xfffff << NIOS2_TLBACC_PFN_OFFSET)
#define NIOS2_TLBMISC_WAY_OFFSET 20
#define NIOS2_TLBMISC_WAY_MASK (0xf << NIOS2_TLBMISC_WAY_OFFSET)
#define NIOS2_TLBMISC_RD (1 << 19)
#define NIOS2_TLBMISC_WE (1 << 18)
#define NIOS2_TLBMISC_PID_OFFSET 5
#define NIOS2_TLBMISC_PID_MASK (0x3fff << NIOS2_TLBMISC_PID_OFFSET)
#define NIOS2_TLBMISC_DBL (1 << 3)
#define NIOS2_TLBMISC_BAD (1 << 2)
#define NIOS2_TLBMISC_PERM (1 << 1)
#define NIOS2_TLBMISC_D (1 << 0)
#define NIOS2_CONFIG_ANI (1 << 1)
#define NIOS2_CONFIG_PE (1 << 0)
#define NIOS2_MPUBASE_BASE_OFFSET 5
#define NIOS2_MPUBASE_BASE_MASK (0x1ffffff << NIOS2_MPUBASE_BASE_OFFSET)
#define NIOS2_MPUBASE_INDEX_OFFSET 1
#define NIOS2_MPUBASE_INDEX_MASK (0x1f << NIOS2_MPUBASE_INDEX_OFFSET)
#define NIOS2_MPUBASE_D (1 << 0)
#define NIOS2_MPUACC_MASK_OFFSET 6
#define NIOS2_MPUACC_MASK_MASK (0x1ffffff << NIOS2_MPUACC_MASK_OFFSET)
#define NIOS2_MPUACC_LIMIT_OFFSET 6
#define NIOS2_MPUACC_LIMIT_MASK (0x3ffffff << NIOS2_MPUACC_LIMIT_OFFSET)
#define NIOS2_MPUACC_C (1 << 5)
#define NIOS2_MPUACC_PERM_OFFSET 2
#define NIOS2_MPUACC_PERM_MASK (0x7 << NIOS2_MPUACC_PERM_OFFSET)
#define NIOS2_MPUACC_RD (1 << 1)
#define NIOS2_MPUACC_WR (1 << 0)
#ifndef ASM
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @brief Nios II specific thread dispatch disabled indicator.
*
* This global variable is used by the interrupt dispatch support for the
* external interrupt controller (EIC) with shadow registers. This makes it
* possible to do the thread dispatch after an interrupt without disabled
* interrupts and thus probably reduce the maximum interrupt latency. Its
* purpose is to prevent unbounded stack usage of the interrupted thread.
*/
extern uint32_t _Nios2_Thread_dispatch_disabled;
/**
* @brief This global symbol specifies the status register mask used to disable
* interrupts.
*
* The board support package must provide a global symbol with this name to
* specifiy the status register mask used in _CPU_ISR_Disable().
*/
extern char _Nios2_ISR_Status_mask [];
/**
* @brief This symbol specifies the status register bits used to disable
* interrupts.
*
* The board support package must provide a global symbol with this name to
* specifiy the status register bits used in _CPU_ISR_Disable().
*/
extern char _Nios2_ISR_Status_bits [];
static inline uint32_t _Nios2_Get_ctlreg_status( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_STATUS );
}
static inline void _Nios2_Set_ctlreg_status( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_STATUS, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_estatus( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_ESTATUS );
}
static inline void _Nios2_Set_ctlreg_estatus( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_ESTATUS, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_bstatus( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_BSTATUS );
}
static inline void _Nios2_Set_ctlreg_bstatus( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_BSTATUS, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_ienable( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_IENABLE );
}
static inline void _Nios2_Set_ctlreg_ienable( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_IENABLE, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_ipending( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_IPENDING );
}
static inline uint32_t _Nios2_Get_ctlreg_cpuid( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_CPUID );
}
static inline uint32_t _Nios2_Get_ctlreg_exception( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_EXCEPTION );
}
static inline uint32_t _Nios2_Get_ctlreg_pteaddr( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_PTEADDR );
}
static inline void _Nios2_Set_ctlreg_pteaddr( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_PTEADDR, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_tlbacc( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_TLBACC );
}
static inline void _Nios2_Set_ctlreg_tlbacc( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_TLBACC, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_tlbmisc( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_TLBMISC );
}
static inline void _Nios2_Set_ctlreg_tlbmisc( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_TLBMISC, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_badaddr( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_BADADDR );
}
static inline uint32_t _Nios2_Get_ctlreg_config( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_CONFIG );
}
static inline void _Nios2_Set_ctlreg_config( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_CONFIG, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_mpubase( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_MPUBASE );
}
static inline void _Nios2_Set_ctlreg_mpubase( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_MPUBASE, (int) value );
}
static inline uint32_t _Nios2_Get_ctlreg_mpuacc( void )
{
return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_MPUACC );
}
static inline void _Nios2_Set_ctlreg_mpuacc( uint32_t value )
{
__builtin_wrctl( NIOS2_CTLREG_INDEX_MPUACC, (int) value );
}
static inline uint32_t _Nios2_Get_ISR_status_mask( void )
{
return (uint32_t) &_Nios2_ISR_Status_mask [0];
}
static inline uint32_t _Nios2_Get_ISR_status_bits( void )
{
return (uint32_t) &_Nios2_ISR_Status_bits [0];
}
static inline bool _Nios2_Has_internal_interrupt_controller( void )
{
uint32_t isr_status_mask = _Nios2_Get_ISR_status_mask();
return isr_status_mask == NIOS2_ISR_STATUS_MASK_IIC;
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !ASM */
#endif /* _RTEMS_SCORE_NIOS2_UTILITY_H */