MISOC LM32: Add arch/src/lm32 directory

This commit is contained in:
Ramtin Amin
2016-11-01 11:35:27 -06:00
committed by Gregory Nutt
parent 62b394d06f
commit 000e10470c
25 changed files with 3037 additions and 6 deletions
+1 -3
View File
@@ -3,6 +3,7 @@
#
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
# Ramtin Amin <keytwo@gmail.com>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -43,7 +44,6 @@ ifeq ($(CONFIG_WINDOWS_NATIVE),y)
NUTTX = "$(TOPDIR)\nuttx$(EXEEXT)"
INCLUDES += -I "$(ARCH_SRCDIR)\chip"
INCLUDES += -I "$(ARCH_SRCDIR)\common"
INCLUDES += -I "$(ARCH_SRCDIR)\generated"
INCLUDES += -I "$(ARCH_SRCDIR)\$(ARCH_SUBDIR)"
INCLUDES += -I "$(TOPDIR)\sched"
else
@@ -52,14 +52,12 @@ ifeq ($(WINTOOL),y)
NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}"
INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}"
INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}"
INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/generated}"
INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}"
INCLUDES += -I "${shell cygpath -w $(TOPDIR)/sched}"
else
NUTTX = "$(TOPDIR)/nuttx$(EXEEXT)"
INCLUDES += -I "$(ARCH_SRCDIR)/chip"
INCLUDES += -I "$(ARCH_SRCDIR)/common"
INCLUDES += -I "$(ARCH_SRCDIR)/generated"
INCLUDES += -I "$(ARCH_SRCDIR)/$(ARCH_SUBDIR)"
INCLUDES += -I "$(TOPDIR)/sched"
endif
+20
View File
@@ -0,0 +1,20 @@
#include <arch/board/generated/csr.h>
void uart_isr();
void uart_isr()
{
}
void isr(void);
void isr(void)
{
unsigned int irqs;
irqs = irq_pending() & irq_getmask();
if (irqs & (1 << UART_INTERRUPT))
{
uart_isr();
}
}
+141
View File
@@ -0,0 +1,141 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#ifdef CONFIG_SERIAL_TERMIOS
# include <termios.h>
#endif
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/serial/serial.h>
#include <arch/board/board.h>
#include <arch/board/generated/csr.h>
#include "hw/flags.h"
#include "misoc_irqasm.h"
#include "misoc_uart.h"
#include "lm32.h"
/* Buffer sizes must be a power of 2 so that modulos can be computed
* with logical AND.
*/
#define UART_RINGBUFFER_SIZE_RX 128
#define UART_RINGBUFFER_MASK_RX (UART_RINGBUFFER_SIZE_RX-1)
static char rx_buf[UART_RINGBUFFER_SIZE_RX];
static volatile unsigned int rx_produce;
static unsigned int rx_consume;
#define UART_RINGBUFFER_SIZE_TX 128
#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1)
static char tx_buf[UART_RINGBUFFER_SIZE_TX];
static unsigned int tx_produce;
static volatile unsigned int tx_consume;
static int uart_interrupt(int irq, void *context);
static int uart_interrupt(int irq, void *context)
{
unsigned int stat, rx_produce_next;
stat = uart_ev_pending_read();
if(stat & UART_EV_RX) {
while(!uart_rxempty_read()) {
rx_produce_next = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
if(rx_produce_next != rx_consume) {
rx_buf[rx_produce] = uart_rxtx_read();
rx_produce = rx_produce_next;
}
uart_ev_pending_write(UART_EV_RX);
}
}
if(stat & UART_EV_TX) {
uart_ev_pending_write(UART_EV_TX);
while((tx_consume != tx_produce) && !uart_txfull_read()) {
uart_rxtx_write(tx_buf[tx_consume]);
tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
}
}
return OK;
}
/* Do not use in interrupt handlers! */
char uart_read(void)
{
char c;
if(irq_getie()) {
while(rx_consume == rx_produce);
} else if (rx_consume == rx_produce) {
return 0;
}
c = rx_buf[rx_consume];
rx_consume = (rx_consume + 1) & UART_RINGBUFFER_MASK_RX;
return c;
}
int uart_read_nonblock(void)
{
return (rx_consume != rx_produce);
}
int up_putc(int ch)
{
unsigned int oldmask;
unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX;
if(irq_getie()) {
while(tx_produce_next == tx_consume);
} else if(tx_produce_next == tx_consume) {
return ch;
}
oldmask = irq_getmask();
irq_setmask(oldmask & ~(1 << UART_INTERRUPT));
if((tx_consume != tx_produce) || uart_txfull_read()) {
tx_buf[tx_produce] = ch;
tx_produce = tx_produce_next;
} else {
uart_rxtx_write(ch);
}
irq_setmask(oldmask);
return ch;
}
void uart_init(void)
{
rx_produce = 0;
rx_consume = 0;
tx_produce = 0;
tx_consume = 0;
uart_ev_pending_write(uart_ev_pending_read());
uart_ev_enable_write(UART_EV_TX | UART_EV_RX);
irq_setmask(irq_getmask() | (1 << UART_INTERRUPT));
irq_attach(1 << UART_INTERRUPT, uart_interrupt);
}
void uart_sync(void)
{
while(tx_consume != tx_produce);
}
+49
View File
@@ -0,0 +1,49 @@
############################################################################
# arch/misoc/src/Makefile
#
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
# Ramtin Amin <keytwo@gmail.com>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
HEAD_ASRC = lm32_vectors.S
CMN_ASRCS =
CMN_CSRCS = misoc_uart.c
CHIP_ASRCS = lm32_start.S lm32_syscall.S
CHIP_CSRCS = lm32_allocateheap.c lm32_assert.c lm32_blocktask.c
CHIP_CSRCS += lm32_copystate.c lm32_createstack.c lm32_doirq.c lm32_dumpstate.c
CHIP_CSRCS += lm32_dumpstate.c lm32_exit.c lm32_idle.c lm32_initialize.c
CHIP_CSRCS += lm32_initialstate.c lm32_interruptcontext.c lm32_irq.c
CHIP_CSRCS += lm32_releasepending.c lm32_releasestack.c lm32_stackframe.c
CHIP_CSRCS += lm32_swint.c lm32_unblocktask.c
+1 -2
View File
@@ -1,5 +1,5 @@
/****************************************************************************
* arch/misoc/src/common/lm32.h
* arch/misoc/src/lm32/lm32.h
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@@ -144,7 +144,6 @@ void lm32_irq_initialize(void);
/* System timer *************************************************************/
void lm32_timer_initialize(void);
int lm32_timerisr(int irq, void *context);
/* Software interrupts ******************************************************/
+1 -1
View File
@@ -1,5 +1,5 @@
/****************************************************************************
* arch/misoc/src/common/lm32_allocateheap.c
* arch/misoc/src/lm32/lm32_allocateheap.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
+162
View File
@@ -0,0 +1,162 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_assert.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <nuttx/usb/usbdev_trace.h>
#include <arch/board/board.h>
#include "sched/sched.h"
#include "lm32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* USB trace dumping */
#ifndef CONFIG_USBDEV_TRACE
# undef CONFIG_ARCH_USBDUMP
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: _up_assert
****************************************************************************/
static void _up_assert(int errorcode) noreturn_function;
static void _up_assert(int errorcode)
{
/* Are we in an interrupt handler or the idle task? */
if (g_current_regs || this_task()->pid == 0)
{
(void)up_irq_save();
for (; ; )
{
#ifdef CONFIG_ARCH_LEDS
board_autoled_on(LED_PANIC);
up_mdelay(250);
board_autoled_off(LED_PANIC);
up_mdelay(250);
#endif
}
}
else
{
exit(errorcode);
}
}
/****************************************************************************
* Name: assert_tracecallback
****************************************************************************/
#ifdef CONFIG_ARCH_USBDUMP
static int usbtrace_syslog(FAR const char *fmt, ...)
{
va_list ap;
int ret;
/* Let vsyslog do the real work */
va_start(ap, fmt);
ret = vsyslog(LOG_EMERG, fmt, ap);
va_end(ap);
return ret;
}
static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg)
{
usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value);
return 0;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_assert
****************************************************************************/
void up_assert(const uint8_t *filename, int lineno)
{
#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_DEBUG_ALERT)
struct tcb_s *rtcb = this_task();
#endif
board_autoled_on(LED_ASSERTION);
#if CONFIG_TASK_NAME_SIZE > 0
_alert("Assertion failed at file:%s line: %d task: %s\n",
filename, lineno, rtcb->name);
#else
_alert("Assertion failed at file:%s line: %d\n",
filename, lineno);
#endif
lm32_dumpstate();
#ifdef CONFIG_ARCH_USBDUMP
/* Dump USB trace data */
(void)usbtrace_enumerate(assert_tracecallback, NULL);
#endif
#ifdef CONFIG_BOARD_CRASHDUMP
board_crashdump(up_getsp(), this_task(), filename, lineno);
#endif
_up_assert(EXIT_FAILURE);
}
+180
View File
@@ -0,0 +1,180 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_blocktask.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <sched.h>
#include <syscall.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include "sched/sched.h"
#include "group/group.h"
#include "lm32.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_block_task
*
* Description:
* The currently executing task at the head of
* the ready to run list must be stopped. Save its context
* and move it to the inactive list specified by task_state.
*
* Inputs:
* tcb: Refers to a task in the ready-to-run list (normally
* the task at the head of the list). It most be
* stopped, its context saved and moved into one of the
* waiting task lists. It it was the task at the head
* of the ready-to-run list, then a context to the new
* ready to run task must be performed.
* task_state: Specifies which waiting task list should be
* hold the blocked task TCB.
*
****************************************************************************/
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
{
struct tcb_s *rtcb = this_task();
bool switch_needed;
/* Verify that the context switch can be performed */
ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
/* Remove the tcb task from the ready-to-run list. If we
* are blocking the task at the head of the task list (the
* most likely case), then a context switch to the next
* ready-to-run task is needed. In this case, it should
* also be true that rtcb == tcb.
*/
switch_needed = sched_removereadytorun(tcb);
/* Add the task to the specified blocked task list */
sched_addblocked(tcb, (tstate_t)task_state);
/* If there are any pending tasks, then add them to the ready-to-run
* task list now
*/
if (g_pendingtasks.head)
{
switch_needed |= sched_mergepending();
}
/* Now, perform the context switch if one is needed */
if (switch_needed)
{
/* Update scheduler parameters */
sched_suspend_scheduler(rtcb);
/* Are we in an interrupt handler? */
if (g_current_regs)
{
/* Yes, then we have to do things differently.
* Just copy the g_current_regs into the OLD rtcb.
*/
up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Reset scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
up_restorestate(rtcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */
else
{
/* Get the context of the task at the head of the ready to
* run list.
*/
struct tcb_s *nexttcb = this_task();
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
(void)group_addrenv(nexttcb);
#endif
/* Reset scheduler parameters */
sched_resume_scheduler(nexttcb);
/* Then switch contexts */
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
* normal sense. When it does return, it is because the blocked
* task is again ready to run and has execution priority.
*/
}
}
}
+87
View File
@@ -0,0 +1,87 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_copystate.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <arch/irq.h>
#include "lm32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lm32_copystate
****************************************************************************/
/* A little faster than most memcpy's */
void lm32_copystate(uint32_t *dest, uint32_t *src)
{
int i;
/* In the LM32 model, the state is copied from the stack to the TCB,
* but only a reference is passed to get the state from the TCB. So the
* following check avoids copying the TCB save area onto itself:
*/
if (src != dest)
{
for (i = 0; i < XCPTCONTEXT_REGS; i++)
{
*dest++ = *src++;
}
}
}
+214
View File
@@ -0,0 +1,214 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_createstack.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/kmalloc.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "lm32.h"
/****************************************************************************
* Pre-processor Macros
****************************************************************************/
/* LM32 requires at least a 4-byte stack alignment. For floating point use,
* however, the stack must be aligned to 8-byte addresses.
*/
#ifdef CONFIG_LIBC_FLOATINGPOINT
# define STACK_ALIGNMENT 8
#else
# define STACK_ALIGNMENT 4
#endif
/* Stack alignment macros */
#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_create_stack
*
* Description:
* Allocate a stack for a new thread and setup up stack-related information
* in the TCB.
*
* The following TCB fields must be initialized by this function:
*
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
* the stack pointer.
*
* Inputs:
* - tcb: The TCB of new task
* - stack_size: The requested stack size. At least this much
* must be allocated.
* - ttype: The thread type. This may be one of following (defined in
* include/nuttx/sched.h):
*
* TCB_FLAG_TTYPE_TASK Normal user task
* TCB_FLAG_TTYPE_PTHREAD User pthread
* TCB_FLAG_TTYPE_KERNEL Kernel thread
*
* This thread type is normally available in the flags field of the TCB,
* however, there are certain contexts where the TCB may not be fully
* initialized when up_create_stack is called.
*
* If CONFIG_BUILD_KERNEL is defined, then this thread type may affect
* how the stack is allocated. For example, kernel thread stacks should
* be allocated from protected kernel memory. Stacks for user tasks and
* threads must come from memory that is accessible to user code.
*
****************************************************************************/
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
/* Is there already a stack allocated of a different size? Because of
* alignment issues, stack_size might erroneously appear to be of a
* different size. Fortunately, this is not a critical operation.
*/
if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
{
/* Yes.. Release the old stack */
up_release_stack(tcb, ttype);
}
/* Do we need to allocate a new stack? */
if (!tcb->stack_alloc_ptr)
{
/* Allocate the stack. If DEBUG is enabled (but not stack debug),
* then create a zeroed stack to make stack dumps easier to trace.
*/
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
/* Use the kernel allocator if this is a kernel thread */
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
}
#ifdef CONFIG_DEBUG_FEATURES
/* Was the allocation successful? */
if (!tcb->stack_alloc_ptr)
{
serr("ERROR: Failed to allocate stack, size %d\n", stack_size);
}
#endif
}
/* Did we successfully allocate a stack? */
if (tcb->stack_alloc_ptr)
{
size_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
*/
#ifdef CONFIG_STACK_COLORATION
memset(tcb->stack_alloc_ptr, 0xaa, stack_size);
#endif
/* LM32 uses a push-down stack: the stack grows toward lower
* addresses in memory. The stack pointer register points to the
* lowest, valid working address (the "top" of the stack). Items on
* the stack are referenced as positive word offsets from sp.
*/
top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
/* The LM32 stack must be aligned at word (4 byte) boundaries; for
* floating point use, the stack must be aligned to 8-byte addresses.
* If necessary top_of_stack must be rounded down to the next
* boundary to meet these alignment requirements.
*/
top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
/* Save the adjusted stack values in the struct tcb_s */
tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack;
tcb->adj_stack_size = size_of_stack;
board_autoled_on(LED_STACKCREATED);
return OK;
}
return ERROR;
}
+147
View File
@@ -0,0 +1,147 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_doirq.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "group/group.h"
#include "lm32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
uint32_t *up_doirq(int irq, uint32_t *regs)
{
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
/* Current regs non-zero indicates that we are processing an interrupt;
* g_current_regs is also used to manage interrupt level context switches.
*
* Nested interrupts are not supported
*/
DEBUGASSERT(g_current_regs == NULL);
g_current_regs = regs;
/* Disable further occurrences of this interrupt (until the interrupt sources
* have been clear by the driver).
*/
up_disable_irq(irq);
/* Deliver the IRQ */
irq_dispatch(irq, regs);
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
/* Check for a context switch. If a context switch occurred, then
* g_current_regs will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then restore the floating
* point state and the establish the correct address environment before
* returning from the interrupt.
*/
if (regs != g_current_regs)
{
#ifdef CONFIG_ARCH_FPU
/* Restore floating point registers */
up_restorefpu((uint32_t *)g_current_regs);
#endif
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
(void)group_addrenv(NULL);
#endif
}
#endif
/* If a context switch occurred while processing the interrupt then
* g_current_regs may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uint32_t *)g_current_regs;
/* Set g_current_regs to NULL to indicate that we are no longer in an
* interrupt handler.
*/
g_current_regs = NULL;
/* Unmask the last interrupt (global interrupts are still disabled) */
up_enable_irq(irq);
#endif
board_autoled_off(LED_INIRQ);
return regs;
}
+228
View File
@@ -0,0 +1,228 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_dumpstate.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include "sched/sched.h"
#include "lm32.h"
#ifdef CONFIG_ARCH_STACKDUMP
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: up_getsp
****************************************************************************/
static inline uint32_t up_getsp(void)
{
register uint32_t sp;
__asm__ __volatile__("addi %0, sp, 0" : "=r" (sp));
return sp;
}
/****************************************************************************
* Name: up_stackdump
****************************************************************************/
static void up_stackdump(uint32_t sp, uint32_t stack_base)
{
# if 0
uint32_t stack ;
for (stack = sp & ~0x1f; stack < stack_base; stack += 32)
{
uint32_t *ptr = (uint32_t *)stack;
_alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
stack, ptr[0], ptr[1], ptr[2], ptr[3],
ptr[4], ptr[5], ptr[6], ptr[7]);
}
#endif
}
/****************************************************************************
* Name: up_registerdump
****************************************************************************/
static inline void up_registerdump(void)
{
#if 0
/* Are user registers available from interrupt processing? */
if (g_current_regs)
{
_alert("EPC:%08x \n",
g_current_regs[REG_EPC]);
_alert("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x A7:%08x\n",
g_current_regs[REG_A0], g_current_regs[REG_A1], g_current_regs[REG_A2],
g_current_regs[REG_A3], g_current_regs[REG_A4], g_current_regs[REG_A5],
g_current_regs[REG_A6], g_current_regs[REG_A7]);
_alert("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n",
g_current_regs[REG_T0], g_current_regs[REG_T1], g_current_regs[REG_T2],
g_current_regs[REG_T3], g_current_regs[REG_T4], g_current_regs[REG_T5],
g_current_regs[REG_T6]);
_alert("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n",
g_current_regs[REG_S0], g_current_regs[REG_S1], g_current_regs[REG_S2],
g_current_regs[REG_S3], g_current_regs[REG_S4], g_current_regs[REG_S5],
g_current_regs[REG_S6], g_current_regs[REG_S7]);
_alert("S8:%08x S9:%08x S10:%08x S11:%08x\n",
g_current_regs[REG_S8], g_current_regs[REG_S9], g_current_regs[REG_S10],
g_current_regs[REG_S11]);
#ifdef RISCV_SAVE_GP
_alert("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n",
g_current_regs[REG_GP], g_current_regs[REG_SP], g_current_regs[REG_FP],
g_current_regs[REG_TP], g_current_regs[REG_RA]);
#else
_alert("SP:%08x FP:%08x TP:%08x RA:%08x\n",
g_current_regs[REG_SP], g_current_regs[REG_FP], g_current_regs[REG_TP],
g_current_regs[REG_RA]);
#endif
}
#endif
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lm32_dumpstate
****************************************************************************/
void lm32_dumpstate(void)
{
struct tcb_s *rtcb = this_task();
uint32_t sp = up_getsp();
uint32_t ustackbase;
uint32_t ustacksize;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
uint32_t istackbase;
uint32_t istacksize;
#endif
/* Get the limits on the user stack memory */
if (rtcb->pid == 0)
{
ustackbase = g_idle_topstack - 4;
ustacksize = CONFIG_IDLETHREAD_STACKSIZE;
}
else
{
ustackbase = (uint32_t)rtcb->adj_stack_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
}
/* Get the limits on the interrupt stack memory */
#if CONFIG_ARCH_INTERRUPTSTACK > 3
istackbase = (uint32_t)&g_intstackbase;
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
/* Show interrupt stack info */
_alert("sp: %08x\n", sp);
_alert("IRQ stack:\n");
_alert(" base: %08x\n", istackbase);
_alert(" size: %08x\n", istacksize);
/* Does the current stack pointer lie within the interrupt
* stack?
*/
if (sp <= istackbase && sp > istackbase - istacksize)
{
/* Yes.. dump the interrupt stack */
up_stackdump(sp, istackbase);
/* Extract the user stack pointer which should lie
* at the base of the interrupt stack.
*/
sp = g_intstackbase;
_alert("sp: %08x\n", sp);
}
/* Show user stack info */
_alert("User stack:\n");
_alert(" base: %08x\n", ustackbase);
_alert(" size: %08x\n", ustacksize);
#else
_alert("sp: %08x\n", sp);
_alert("stack base: %08x\n", ustackbase);
_alert("stack size: %08x\n", ustacksize);
#endif
/* Dump the user stack if the stack pointer lies within the allocated user
* stack memory.
*/
if (sp > ustackbase || sp <= ustackbase - ustacksize)
{
#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4
_alert("ERROR: Stack pointer is not within allocated stack\n");
#endif
}
else
{
up_stackdump(sp, ustackbase);
}
/* Then dump the registers (if available) */
up_registerdump();
}
#endif /* CONFIG_ARCH_STACKDUMP */
+82
View File
@@ -0,0 +1,82 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_exit.c
*
* Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#ifdef CONFIG_DUMP_ON_EXIT
# include <nuttx/fs/fs.h>
#endif
#include "task/task.h"
#include "sched/sched.h"
#include "group/group.h"
#include "lm32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: _exit
*
* Description:
* This function causes the currently executing task to cease
* to exist. This is a special case of task_delete() where the task to
* be deleted is the currently executing task. It is more complex because
* a context switch must be perform to the next ready to run task.
*
****************************************************************************/
void _exit(int status)
{
#warning Missing logic
}
+96
View File
@@ -0,0 +1,96 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_idle.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include "lm32.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_idle
*
* Description:
* up_idle() is the logic that will be executed when their is no other
* ready-to-run task. This is processor idle time and will continue until
* some interrupt occurs to cause a context switch from the idle task.
*
* Processing in this state may be processor-specific. e.g., this is where
* power management operations might be performed.
*
****************************************************************************/
void up_idle(void)
{
#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
/* If the system is idle and there are no timer interrupts, then process
* "fake" timer interrupts. Hopefully, something will wake up.
*/
sched_process_timer();
#else
/* This would be an appropriate place to put some MCU-specific logic to
* sleep in a reduced power mode until an interrupt occurs to save power
*/
/* This is a kludge that I still don't understand. The call to kmm_trysemaphore()
* in the os_start.c IDLE loop seems necessary for the good health of the IDLE
* loop. When the work queue is enabled, this logic is removed from the IDLE
* loop and it appears that we are somehow left idling with interrupts non-
* functional. The following should be no-op, it just disables then re-enables
* interrupts. But it fixes the problem and will stay here until I understand
* the problem/fix better.
*
* And no, the contents of the CP0 status register are not incorrect. But for
* some reason the status register needs to be re-written again on this thread
* for it to take effect. This might be a PIC32-only issue?
*/
#ifdef CONFIG_SCHED_WORKQUEUE
irqstate_t flags = enter_critical_section();
leave_critical_section(flags);
#endif
#endif
}
+77
View File
@@ -0,0 +1,77 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_initialize.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched_note.h>
#include <nuttx/drivers/drivers.h>
#include <nuttx/fs/loop.h>
#include <nuttx/net/loopback.h>
#include <nuttx/net/tun.h>
#include <nuttx/net/telnet.h>
#include <nuttx/syslog/syslog.h>
#include <nuttx/syslog/syslog_console.h>
#include <nuttx/serial/pty.h>
#include <nuttx/crypto/crypto.h>
#include <nuttx/power/pm.h>
#include <arch/board/board.h>
#include "lm32.h"
/****************************************************************************
* Public Functionis
****************************************************************************/
void up_initialize(void)
{
/* Initialize the System Timer */
lm32_irq_initialize();
/* Initialize the serial driver */
#warning REVISIT: Here you should all lm32_serial_initialize(). That initializes the entire serial driver, a part of the operation is the uart initialization.
uart_init();
}
+120
View File
@@ -0,0 +1,120 @@
/****************************************************************************
* arch/misoc/src/lm32/up_initialstate.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#include "lm32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_initial_state
*
* Description:
* A new thread is being started and a new TCB
* has been created. This function is called to initialize
* the processor specific portions of the new TCB.
*
* This function must setup the intial architecture registers
* and/or stack so that execution will begin at tcb->start
* on the next context switch.
*
****************************************************************************/
void up_initial_state(struct tcb_s *tcb)
{
struct xcptcontext *xcp = &tcb->xcp;
/* Initialize the initial exception register context structure */
memset(xcp, 0, sizeof(struct xcptcontext));
/* Save the initial stack pointer. Hmmm.. the stack is set to the very
* beginning of the stack region. Some functions may want to store data on
* the caller's stack and it might be good to reserve some space. However,
* only the start function would do that and we have control over that one
*/
xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
/* Save the task entry point */
xcp->regs[REG_EPC] = (uint32_t)tcb->start;
/* If this task is running PIC, then set the PIC base register to the
* address of the allocated D-Space region.
*/
#ifdef CONFIG_PIC
# warning "Missing logic"
#endif
/* Set privileged- or unprivileged-mode, depending on how NuttX is
* configured and what kind of thread is being started.
*
* If the kernel build is not selected, then all threads run in
* privileged thread mode.
*/
#ifdef CONFIG_BUILD_KERNEL
# warning "Missing logic"
#endif
}
@@ -0,0 +1,62 @@
/****************************************************************************
* arch/misoc/src/lm32/up_interruptcontext.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <nuttx/arch.h>
#include "lm32.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_interrupt_context
*
* Description: Return true is we are currently executing in
* the interrupt handler context.
****************************************************************************/
bool up_interrupt_context(void)
{
return g_current_regs != NULL;
}
+121
View File
@@ -0,0 +1,121 @@
/****************************************************************************
* arch/misoc/src/lm32/_irq.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#include "misoc_irqasm.h"
#include "lm32.h"
/****************************************************************************
* Public Data
****************************************************************************/
volatile uint32_t *g_current_regs;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lm32_irq_initialize
****************************************************************************/
void lm32_irq_initialize(void)
{
/* currents_regs is non-NULL only while processing an interrupt */
g_current_regs = NULL;
/* Enable interrupt */
irq_setie(1);
}
irqstate_t up_irq_save(void)
{
irqstate_t flags;
irq_setie(0);
#warning Return value MUST be the previous IE value. Returning 1 will not work.
return 1;
}
void up_irq_restore(irqstate_t flags)
{
irq_setie(1);
}
/****************************************************************************
* Name: up_disable_irq
*
* Description:
* Disable the IRQ specified by 'irq'
*
****************************************************************************/
void up_disable_irq(int irq)
{
irqstate_t flags;
flags = irq_getmask();
flags &= ~(1 <<irq);
irq_setmask(flags);
}
/****************************************************************************
* Name: up_enable_irq
*
* Description:
* Enable the IRQ specified by 'irq'
*
****************************************************************************/
void up_enable_irq(int irq)
{
irqstate_t flags;
flags = irq_getmask();
flags |= (1 << irq);
irq_setmask(flags);
}
+149
View File
@@ -0,0 +1,149 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_releasepending.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sched.h>
#include <syscall.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include "sched/sched.h"
#include "group/group.h"
#include "lm32.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_release_pending
*
* Description:
* Release and ready-to-run tasks that have
* collected in the pending task list. This can call a
* context switch if a new task is placed at the head of
* the ready to run list.
*
****************************************************************************/
void up_release_pending(void)
{
struct tcb_s *rtcb = this_task();
sinfo("From TCB=%p\n", rtcb);
/* Merge the g_pendingtasks list into the ready-to-run task list */
/* sched_lock(); */
if (sched_mergepending())
{
/* The currently active task has changed! We will need to switch
* contexts.
*
* Update scheduler parameters.
*/
sched_suspend_scheduler(rtcb);
/* Are we operating in interrupt context? */
if (g_current_regs)
{
/* Yes, then we have to do things differently.
* Just copy the g_current_regs into the OLD rtcb.
*/
up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
up_restorestate(rtcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */
else
{
/* Switch context to the context of the task at the head of the
* ready to run list.
*/
struct tcb_s *nexttcb = this_task();
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
(void)group_addrenv(nexttcb);
#endif
/* Update scheduler parameters */
sched_resume_scheduler(nexttcb);
/* Then switch contexts */
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
* normal sense. When it does return, it is because the blocked
* task is again ready to run and has execution priority.
*/
}
}
}
+115
View File
@@ -0,0 +1,115 @@
/****************************************************************************
* arch/misoc/src/lm32/up_releasestack.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include "lm32.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_release_stack
*
* Description:
* A task has been stopped. Free all stack related resources retained in
* the defunct TCB.
*
* Input Parmeters
* - dtcb: The TCB containing information about the stack to be released
* - ttype: The thread type. This may be one of following (defined in
* include/nuttx/sched.h):
*
* TCB_FLAG_TTYPE_TASK Normal user task
* TCB_FLAG_TTYPE_PTHREAD User pthread
* TCB_FLAG_TTYPE_KERNEL Kernel thread
*
* This thread type is normally available in the flags field of the TCB,
* however, there are certain error recovery contexts where the TCB may
* not be fully initialized when up_release_stack is called.
*
* If CONFIG_BUILD_KERNEL is defined, then this thread type may affect
* how the stack is freed. For example, kernel thread stacks may have
* been allocated from protected kernel memory. Stacks for user tasks
* and threads must have come from memory that is accessible to user
* code.
*
* Returned Value:
* None
*
****************************************************************************/
void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
{
/* Is there a stack allocated? */
if (dtcb->stack_alloc_ptr)
{
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
/* Use the kernel allocator if this is a kernel thread */
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
sched_kfree(dtcb->stack_alloc_ptr);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
sched_ufree(dtcb->stack_alloc_ptr);
}
/* Mark the stack freed */
dtcb->stack_alloc_ptr = NULL;
}
/* The size of the allocated stack is now zero */
dtcb->adj_stack_size = 0;
}
+136
View File
@@ -0,0 +1,136 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_stackframe.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <sched.h>
#include <debug.h>
#include <nuttx/arch.h>
#include "lm32.h"
/****************************************************************************
* Pre-processor Macros
****************************************************************************/
/* LM32 requires at least a 4-byte stack alignment. For floating point use,
* however, the stack must be aligned to 8-byte addresses.
*/
#ifdef CONFIG_LIBC_FLOATINGPOINT
# define STACK_ALIGNMENT 8
#else
# define STACK_ALIGNMENT 4
#endif
/* Stack alignment macros */
#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_stack_frame
*
* Description:
* Allocate a stack frame in the TCB's stack to hold thread-specific data.
* This function may be called anytime after up_create_stack() or
* up_use_stack() have been called but before the task has been started.
*
* Thread data may be kept in the stack (instead of in the TCB) if it is
* accessed by the user code directly. This includes such things as
* argv[]. The stack memory is guaranteed to be in the same protection
* domain as the thread.
*
* The following TCB fields will be re-initialized:
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
* - adj_stack_ptr: Adjusted initial stack pointer after the frame has
* been removed from the stack. This will still be the initial value
* of the stack pointer when the task is started.
*
* Inputs:
* - tcb: The TCB of new task
* - frame_size: The size of the stack frame to allocate.
*
* Returned Value:
* - A pointer to bottom of the allocated stack frame. NULL will be
* returned on any failures. The alignment of the returned value is
* the same as the alignment of the stack itself.
*
****************************************************************************/
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
uintptr_t topaddr;
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
/* Is there already a stack allocated? Is it big enough? */
if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
{
return NULL;
}
/* Save the adjusted stack values in the struct tcb_s */
topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
tcb->adj_stack_ptr = (FAR void *)topaddr;
tcb->adj_stack_size -= frame_size;
/* Reset the initial stack pointer */
tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
/* And return the pointer to the allocated region */
return (FAR void *)(topaddr + sizeof(uint32_t));
}
+330
View File
@@ -0,0 +1,330 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_swint.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <string.h>
#include <syscall.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/sched.h>
#include <arch/irq.h>
#include "lm32.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: up_registerdump
****************************************************************************/
#ifdef CONFIG_DEBUG_SYSCALL_INFO
static void up_registerdump(const uint32_t *regs)
{
#if 0
svcinfo("EPC:%08x\n",
regs[REG_EPC]);
svcinfo("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x A7:%08x\n",
regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3],
regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]);
svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n",
regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3],
regs[REG_T4], regs[REG_T5], regs[REG_T6]);
svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n",
regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3],
regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]);
svcinfo("S8:%08x S9:%08x S10:%08x S11:%08x\n",
regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]);
#ifdef LM3232_SAVE_GP
svcinfo("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n",
regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]);
#else
svcinfo("SP:%08x FP:%08x TP:%08x RA:%08x\n",
regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]);
#endif
#endif
}
#else
# define up_registerdump(regs)
#endif
/****************************************************************************
* Name: dispatch_syscall
*
* Description:
* Call the stub function corresponding to the system call.
*
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
static void dispatch_syscall(void) naked_function;
static void dispatch_syscall(void)
{
# error "Missing logic"
/* Refer to arch/arm/src/armv7-m/up_svcall.h for how this is done for ARM */
/* __asm__ __volatile__ */
/* ( */
/* Save registers */
/* Get the base of the stub lookup table */
/* Get the offset of the stub for this syscall */
/* Load the entry of the stub for this syscall */
/* Call the stub */
/* Restore regsisters */
/* Return from the syscall */
/* ); */
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lm32_swint
*
* Description:
* This is software interrupt exception handler that performs context
* switching and manages system calls
*
****************************************************************************/
uint32_t lm32_swint(int irq, FAR void *context)
{
uint32_t *regs = (uint32_t *)context;
DEBUGASSERT(g_current_regs == NULL);
g_current_regs = regs;
/* Software interrupt 0 is invoked with REG_A0 (REG_X10) = system call
* command and REG_A1-6 = variable number of
* arguments depending on the system call.
*/
#ifdef CONFIG_DEBUG_SYSCALL_INFO
svcinfo("Entry: regs: %p cmd: %d\n", regs, regs[REG_A0]);
up_registerdump(regs);
#endif
/* Handle the SWInt according to the command in $a0 */
switch (regs[REG_A0])
{
/* A0=SYS_restore_context: This a restore context command:
*
* void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
*
* At this point, the following values are saved in context:
*
* A0 = SYS_restore_context
* A1 = restoreregs
*
* In this case, we simply need to set g_current_regs to restore register
* area referenced in the saved R1. context == g_current_regs is the normal
* exception return. By setting g_current_regs = context[R1], we force
* the return to the saved context referenced in $a1.
*/
case SYS_restore_context:
{
DEBUGASSERT(regs[REG_A1] != 0);
g_current_regs = (uint32_t *)regs[REG_A1];
}
break;
/* A0=SYS_switch_context: This a switch context command:
*
* void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_switch_context
* A1 = saveregs
* A2 = restoreregs
*
* In this case, we save the context registers to the save register
* area reference by the saved contents of R5 and then set
* g_current_regs to to the save register area referenced by the saved
* contents of R6.
*/
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
lm32_copystate((uint32_t *)regs[REG_A1], regs);
g_current_regs = (uint32_t *)regs[REG_A2];
}
break;
/* A0=SYS_syscall_return: This a switch context command:
*
* void up_sycall_return(void);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_syscall_return
*
* We need to restore the saved return address and return in
* unprivileged thread mode.
*/
#ifdef CONFIG_BUILD_KERNEL
case SYS_syscall_return:
{
struct tcb_s *rtcb = sched_self();
int index = (int)rtcb->xcp.nsyscalls - 1;
/* Make sure that there is a saved syscall return address. */
DEBUGASSERT(index >= 0);
/* Setup to return to the saved syscall return address in
* the original mode.
*/
g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
#error "Missing logic -- need to restore the original mode"
rtcb->xcp.nsyscalls = index;
}
break;
#endif
/* This is not an architecture-specify system call. If NuttX is built
* as a standalone kernel with a system call interface, then all of the
* additional system calls must be handled as in the default case.
*/
default:
{
#ifdef CONFIG_BUILD_KERNEL
FAR struct tcb_s *rtcb = sched_self();
int index = rtcb->xcp.nsyscalls;
/* Verify that the SYS call number is within range */
DEBUGASSERT(g_current_regs[REG_A0] < SYS_maxsyscall);
/* Make sure that we got here that there is a no saved syscall
* return address. We cannot yet handle nested system calls.
*/
DEBUGASSERT(index < CONFIG_SYS_NNEST);
/* Setup to return to dispatch_syscall in privileged mode. */
rtcb->xcpsyscall[index].sysreturn = regs[REG_EPC];
#error "Missing logic -- Need to save mode"
rtcb->xcp.nsyscalls = index + 1;
regs[REG_EPC] = (uint32_t)dispatch_syscall;
#error "Missing logic -- Need to set privileged mode"
/* Offset R0 to account for the reserved values */
g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED;
#else
svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
#endif
}
break;
}
/* Report what happened. That might difficult in the case of a context switch */
#ifdef CONFIG_DEBUG_SYSCALL_INFO
if (regs != g_current_regs)
{
svcinfo("SWInt Return: Context switch!\n");
up_registerdump((const uint32_t *)g_current_regs);
}
else
{
svcinfo("SWInt Return: %d\n", regs[REG_A0]);
}
#endif
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
/* Check for a context switch. If a context switch occurred, then
* g_current_regs will have a different value than it did on entry. If an
* interrupt level context switch has occurred, then restore the floating
* point state and the establish the correct address environment before
* returning from the interrupt.
*/
if (regs != g_current_regs)
{
#ifdef CONFIG_ARCH_FPU
/* Restore floating point registers */
up_restorefpu((uint32_t *)g_current_regs);
#endif
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
(void)group_addrenv(NULL);
#endif
}
#endif
/* If a context switch occurred while processing the interrupt then
* g_current_regs may have change value. If we return any value different
* from the input regs, then the lower level will know that a context
* switch occurred during interrupt processing.
*/
regs = (uint32_t *)g_current_regs;
/* Set g_current_regs to NULL to indicate that we are no longer in an
* interrupt handler.
*/
g_current_regs = NULL;
return regs;
}
+103
View File
@@ -0,0 +1,103 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_syscall.S
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Ramtin Amin <keytwo@gmail.com>
*
* Derives from RISC-V version:
*
* Copyright (C) 2016 Ken Pettit. All rights reserved.
* Author: Ken Pettit <pettitkd@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "up_syscall.S"
.global sys_call0
.global sys_call1
.global sys_call2
.global sys_call3
.global sys_call4
.global sys_call5
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_syscall0, up_syscall1, up_syscall2, up_syscall3
*
* Description:
* up_syscall0 - System call SYS_ argument and no additional parameters.
* up_syscall1 - System call SYS_ argument and one additional parameter.
* up_syscall2 - System call SYS_ argument and two additional parameters.
* up_syscall3 - System call SYS_ argument and three additional parameters.
* up_syscall4 - System call SYS_ argument and four additional parameters.
* up_syscall5 - System call SYS_ argument and five additional parameters.
*
* Assumption:
* All interrupts are disabled except for the software interrupts.
*
****************************************************************************/
.text
sys_call0: /* a0 holds the syscall number */
sys_call1: /* a0 holds the syscall number, argument in a1 */
sys_call2: /* a0 holds the syscall number, arguments in a1 and a2 */
sys_call3: /* a0 holds the syscall number, arguments in a1, a2, and a3 */
sys_call4: /* a0 holds the syscall number, arguments in a1, a2, a3 and a4 */
sys_call5: /* a0 holds the syscall number, arguments in a1, a2, a3, a4 and a5 */
/* Issue the ECALL opcode to perform a SW interrupt to the OS */
scall
/* The actual interrupt may not a occur for a few more cycles. Let's
* put a few nop's here in hope that the SW interrupt occurs during
* the sequence of nops.
*/
nop
nop
/* Then return with the result of the software interrupt in v0 */
ret
nop
+164
View File
@@ -0,0 +1,164 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_unblocktask.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Ramtin Amin <keytwo@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sched.h>
#include <syscall.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include "sched/sched.h"
#include "group/group.h"
#include "clock/clock.h"
#include "lm32.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_unblock_task
*
* Description:
* A task is currently in an inactive task list
* but has been prepped to execute. Move the TCB to the
* ready-to-run list, restore its context, and start execution.
*
* Inputs:
* tcb: Refers to the tcb to be unblocked. This tcb is
* in one of the waiting tasks lists. It must be moved to
* the ready-to-run list and, if it is the highest priority
* ready to run task, executed.
*
****************************************************************************/
void up_unblock_task(struct tcb_s *tcb)
{
struct tcb_s *rtcb = this_task();
/* Verify that the context switch can be performed */
ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) &&
(tcb->task_state <= LAST_BLOCKED_STATE));
/* Remove the task from the blocked task list */
sched_removeblocked(tcb);
/* Add the task in the correct location in the prioritized
* ready-to-run task list
*/
if (sched_addreadytorun(tcb))
{
/* The currently active task has changed! We need to do
* a context switch to the new task.
*/
/* Update scheduler parameters */
sched_suspend_scheduler(rtcb);
/* Are we in an interrupt handler? */
if (g_current_regs)
{
/* Yes, then we have to do things differently.
* Just copy the g_current_regs into the OLD rtcb.
*/
up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the ready-to-run task list.
*/
rtcb = this_task();
/* Update scheduler parameters */
sched_resume_scheduler(rtcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
up_restorestate(rtcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */
else
{
/* Restore the exception context of the new task that is ready to
* run (probably tcb). This is the new rtcb at the head of the
* ready-to-run task list.
*/
struct tcb_s *nexttcb = this_task();
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
* thread at the head of the ready-to-run list.
*/
(void)group_addrenv(nexttcb);
#endif
/* Update scheduler parameters */
sched_resume_scheduler(nexttcb);
/* Then switch contexts */
up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
/* up_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
* normal sense. When it does return, it is because the blocked
* task is again ready to run and has execution priority.
*/
}
}
}
+251
View File
@@ -0,0 +1,251 @@
/****************************************************************************
* arch/misoc/src/lm32/lm32_allocateheap.c
* LM32 C startup code.
*
* Adapted for NuttX:
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Ramtin Amin <keytwo@gmail.com>
*
* Derives from LatticeMico32 C startup code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <arch/lm32/irq.h>
/****************************************************************************
* Exception handlers - Must be 32 bytes long.
****************************************************************************/
.section .text, "ax", @progbits
.global __start
__start:
_reset_handler:
xor r0, r0, r0
wcsr IE, r0
mvhi r1, hi(_reset_handler)
ori r1, r1, lo(_reset_handler)
wcsr EBA, r1
bi _do_reset
nop
nop
_breakpoint_handler:
bi _breakpoint_handler
nop
nop
nop
nop
nop
nop
nop
_instruction_bus_error_handler:
bi _instruction_bus_error_handler
nop
nop
nop
nop
nop
nop
nop
_watchpoint_hander:
bi _watchpoint_hander
nop
nop
nop
nop
nop
nop
nop
_data_bus_error_handler:
bi _data_bus_error_handler
nop
nop
nop
nop
nop
nop
nop
_divide_by_zero_handler:
bi _divide_by_zero_handler
nop
nop
nop
nop
nop
nop
nop
_interrupt_handler:
sw (sp+0), ra
calli .save_all
rcsr r1, IP
calli up_doirq
bi .restore_all_and_eret
nop
nop
nop
_syscall_handler:
sw (sp+0), ra
calli .save_all
rcsr r1, IP
calli lm32_swint
bi .restore_all_and_eret
nop
nop
nop
_do_reset:
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
/* Clear BSS */
mvhi r1, hi(_sbss)
ori r1, r1, lo(_sbss)
mvhi r3, hi(_ebss)
ori r3, r3, lo(_ebss)
.clearBSS:
be r1, r3, .callMain
sw (r1+0), r0
addi r1, r1, 4
bi .clearBSS
.callMain:
bi os_start
.save_all:
addi sp, sp, -132
sw (sp+REG_X0), r0
sw (sp+REG_X1), r1
sw (sp+REG_X2), r2
sw (sp+REG_X3), r3
sw (sp+REG_X4), r4
sw (sp+REG_X5), r5
sw (sp+REG_X6), r6
sw (sp+REG_X7), r7
sw (sp+REG_X8), r8
sw (sp+REG_X9), r9
sw (sp+REG_X10), r10
sw (sp+REG_X11), r11
sw (sp+REG_X12), r12
sw (sp+REG_X13), r13
sw (sp+REG_X14), r14
sw (sp+REG_X15), r15
sw (sp+REG_X16), r16
sw (sp+REG_X17), r17
sw (sp+REG_X18), r18
sw (sp+REG_X19), r19
sw (sp+REG_X20), r20
sw (sp+REG_X21), r21
sw (sp+REG_X22), r22
sw (sp+REG_X23), r23
sw (sp+REG_X24), r24
sw (sp+REG_X25), r25
sw (sp+REG_GP), r26
sw (sp+REG_FP), r27
sw (sp+REG_SP), r28
/* reg RA done later */
sw (sp+REG_EA), r30
sw (sp+REG_BA), r31
/* ra needs to be moved from initial stack location */
lw r1, (sp+ 132)
sw (sp+REG_RA), r1
/* the 2nd argument is the regs pointer */
addi r2, sp, 0
ret
.restore_all_and_eret:
/* r1 should have the place where we restore ! */
lw r2, (r1+REG_X2)
lw r3, (r1+REG_X3)
lw r4, (r1+REG_X4)
lw r5, (r1+REG_X5)
lw r6, (r1+REG_X6)
lw r7, (r1+REG_X7)
lw r8, (r1+REG_X8)
lw r9, (r1+REG_X9)
lw r10, (r1+REG_X10)
lw r11, (r1+REG_X11)
lw r12, (r1+REG_X12)
lw r13, (r1+REG_X13)
lw r14, (r1+REG_X14)
lw r15, (r1+REG_X15)
lw r16, (r1+REG_X16)
lw r17, (r1+REG_X17)
lw r18, (r1+REG_X18)
lw r19, (r1+REG_X19)
lw r20, (r1+REG_X20)
lw r21, (r1+REG_X21)
lw r22, (r1+REG_X22)
lw r23, (r1+REG_X23)
lw r24, (r1+REG_X24)
lw r25, (r1+REG_X25)
lw r26, (r1+REG_GP)
lw r27, (r1+REG_FP)
lw r28, (r1+REG_SP)
lw r29, (r1+REG_RA)
lw r30, (r1+REG_EA)
lw r31, (r1+REG_BA)
lw r1, (r1+REG_X1)
addi sp, sp, 132
eret
/* This global variable is unsigned long g_idle_topstack and is
* exported from here only because of its coupling to other
* uses of _ebss in this file
*/
.data
.align 4
.globl g_idle_topstack
.type g_idle_topstack, object
g_idle_topstack:
.long _ebss+CONFIG_IDLETHREAD_STACKSIZE
.size g_idle_topstack, .-g_idle_topstack
.end