blob: 7b13052331486f4995e9b32d5a8b5f18bcc2a9a7 [file] [log] [blame]
/****************************************************************************
* arch/misoc/src/lm32/lm32_allocateheap.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Linker memory organization ***********************************************/
/* Data memory is organized as follows:
*
* 1) Initialized data (.data):
* Start: _sdata
* End(+1): _edata
* 2) Uninitialized data (.bss):
* Start: _sbss
* End(+1): _ebss
*
* The following are placed outside of the "normal" memory segments -- mostly
* so that they do not have to be cleared on power up.
*
* 3) Idle thread stack:
* Start: _ebss
* End(+1): _ebss+CONFIG_IDLETHREAD_STACKSIZE
* 4) Heap:
* Start: _ebss+CONFIG_IDLETHREAD_STACKSIZE
* End(+1): to the end of memory
*/
#define LM32_STACK_BASE _ebss
#define LM32_STACK_TOP _ebss+CONFIG_IDLETHREAD_STACKSIZE
#define LM32_HEAP_BASE LM32_STACK_TOP
/****************************************************************************
* Exception handlers - Must be 32 bytes long.
****************************************************************************/
.section .text, "ax", @progbits
.global g_idle_topstack
.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 lm32_decodeirq
bi .restore_all_and_eret
nop
nop
nop
_syscall_handler:
sw (sp+0), ra
addi ea, ea, 4
calli .save_all
mvi r1, LM32_IRQ_SWINT
calli lm32_doirq
bi .restore_all_and_eret
nop
nop
_do_reset:
/* Setup stack and global pointer */
mvhi sp, hi(LM32_STACK_TOP)
ori sp, sp, lo(LM32_STACK_TOP)
/* 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 nx_start
.save_all:
addi sp, sp, -136
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
/* Save SP before we add 136 */
addi r1, sp, 136
sw (sp+REG_SP), r1
/* 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+ 136)
sw (sp+REG_RA), r1
/* Get IE/REG_INT_CTX */
rcsr r1, IE
sw (sp+REG_INT_CTX), r1
/* The 2nd argument is the regs pointer */
addi r2, sp, 0
/* Move sp away from X0 */
addi sp, sp, -4
ret
.restore_all_and_eret:
/* r1 should have the place where we restore ! */
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 r2, (r1+REG_INT_CTX)
wcsr IE, r2
lw r2, (r1+REG_X2)
lw r1, (r1+REG_X1)
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
.type g_idle_topstack, object
g_idle_topstack:
.long LM32_STACK_TOP
.size g_idle_topstack, .-g_idle_topstack
.end