Commit 02747e4a authored by Evan Lojewski's avatar Evan Lojewski Committed by Raptor Engineering Development Team

crt: Switch to slightyl modified crt from the bootrom repo.

parent a1a706e7
BUILD_DIR=../build/versa_ecp5
BUILD_DIR=/home/meklort/litex-repos/litex-boards/litex_boards/targets/build/versa_ecp5/
include $(BUILD_DIR)/software/include/generated/variables.mak
include $(SOC_DIRECTORY)/software/common.mak
OBJECTS=utility.o isr.o main.o fsi.o opencores_i2c.o
OBJECTS=crt0.o ivt.o crt1.o utility.o isr.o main.o fsi.o opencores_i2c.o
all: firmware.bin
......@@ -15,10 +15,9 @@ all: firmware.bin
chmod -x $@
firmware.elf: $(OBJECTS)
$(LD) $(LDFLAGS) \
${LD} $(LDFLAGS) \
-T linker.ld \
-N -o $@ \
$(BUILD_DIR)/software/libbase/crt0.o \
-o $@ \
$(OBJECTS) \
-L$(BUILD_DIR)/software/libbase \
-L$(BUILD_DIR)/software/libcompiler_rt \
......
/* Copyright 2013-2014 IBM Corp.
* Copyright 2020 Raptor Engineering, LLC
* Copyright 2021 Evan Lojewski
*
* Licensed 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.
*/
#define PHYSICAL_ADDRESS_WIDTH 32
#define FIXUP_ENDIAN \
tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
b 191f; /* Skip trampoline if endian is good */ \
.long 0xa600607d; /* mfmsr r11 */ \
.long 0x01006b69; /* xori r11,r11,1 */ \
.long 0x05009f42; /* bcl 20,31,$+4 */ \
.long 0xa602487d; /* mflr r10 */ \
.long 0x14004a39; /* addi r10,r10,20 */ \
.long 0xa64b5a7d; /* mthsrr0 r10 */ \
.long 0xa64b7b7d; /* mthsrr1 r11 */ \
.long 0x2402004c; /* hrfid */ \
191:
/* Load an immediate 32-bit value into a register */
#define LOAD_IMM32(r, e) \
lis r,(e)@h; \
ori r,r, (e)@l
/* Load an immediate 64-bit value into a register */
#define LOAD_IMM64(r, e) \
lis r,(e)@highest; \
ori r,r,(e)@higher; \
rldicr r,r, 32, 31; \
oris r,r, (e)@h; \
ori r,r, (e)@l;
.section .text.crt0
.global _start
.type _start, @function
_start:
FIXUP_ENDIAN
/* Get our TOC */
#if PHYSICAL_ADDRESS_WIDTH <= 32
LOAD_IMM32(%r2, .TOC.)
#else
LOAD_IMM64(%r2, .TOC.)
#endif
/* setup stack */
ld %r1, _fstack@got(%r2)
subi %r1, %r1, 0x100
/* Jump to compiled code */
b crt1
.size _start, . - _start
////////////////////////////////////////////////////////////////////////////////
///
/// @file crt1.c
///
/// @project
///
/// @brief Support routines to bring up the system before calling main.
///
////////////////////////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////////////////////////
///
/// @copyright Copyright (c) 2021, Evan Lojewski
/// @cond
///
/// All rights reserved.
///
/// 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 of the copyright holder 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 HOLDER 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.
/// @endcond
////////////////////////////////////////////////////////////////////////////////
#include <irq.h>
#include <string.h>
extern char _fbss[];
extern char _ebss[];
#pragma weak _fdata_rom
extern char _fdata_rom[];
extern char _fdata[];
extern char _edata[];
int main(int i, char **c);
// Default exception handler
extern void _exception_entry(void);
extern char _exception_entry_size[];
extern char _ivt_base[];
#define KESTREL_SPR_KAISB (850) /**< Kestrel architecture-specific Interrupt Vector Base register. */
#define EXCEPTION_MASK (0xFFF) /**< Maximum valid exception address */
#define EXCEPTION_RESET (0x100) /**< The causes of system reset exceptions are implementation-dependent. */
#define EXCEPTION_DSI (0x300) /**< A DSI exception occurs when a data memory access cannot be performed. */
#define EXCEPTION_DSegI (0x380) /**< A DSegI exception occurs when a data memory access cannot be performed due to a segment fault. */
#define EXCEPTION_ISI (0x400) /**< An ISI exception occurs when an instruction fetch cannot be performed. */
#define EXCEPTION_ISegI (0x480) /**< An ISegI exception occurs when an instruction fetch cannot be performed due to a segment fault. */
#define EXCEPTION_EXTERNAL_IRQ (0x500) /**< An external interrupt is generated only when an external exception is pending and the interrupt is enabled (MSR[EE] = 1). */
#define EXCEPTION_PROGRAM (0x700) /**< A program exception is caused by conditions which correspond to bit settings in SRR1 and arise during execution of an instruction. */
#define EXCEPTION_DECREMENTER (0x900) /**< The exception is created when the most significant bit changes from 0 to 1. */
#define EXCEPTION_SYSTEM_CALL (0xC00) /**< A system call exception occurs when a System Call (sc) instruction is executed. **/
/**
* Update the interupt vector table base address.
*
* @param ivt_base The 16K aligned interrupt vector table base address.
*/
static inline void irq_set_base(void *ivt_base)
{
__asm__ volatile("mtspr %0, %1" : : "i" (KESTREL_SPR_KAISB), "r" (ivt_base) : "memory");
}
/**
* Read the interupt vector table base address.
*
* @returns The 16K aligned interrupt vector table base address.
*/
static inline void *irq_get_base(void)
{
void* ivt_base;
__asm__ volatile("mfspr %0, %1" : "=r"(ivt_base) : "i" (KESTREL_SPR_KAISB) : "memory");
return ivt_base;
}
//lint -esym(714, crt1) // Referenced by crt0.s
void crt1(void)
{
// This is the main c entry point. Note that no functions that depend
// on initialized data should be called until after the data and bss
// sections are initialized.
// Initialize Data if required
if (_fdata_rom) //lint !e506 !e774
{
memcpy(_fdata, _fdata_rom, (size_t)(_edata - _fdata));
}
// Initialize BSS
memset(_fbss, 0, (size_t)(_ebss - _fbss));
// Initialize the IVT
// clang-format off
static const uint16_t vectors[] = {
EXCEPTION_DSI,
EXCEPTION_DSegI,
EXCEPTION_ISI,
EXCEPTION_ISegI,
EXCEPTION_EXTERNAL_IRQ,
EXCEPTION_PROGRAM,
EXCEPTION_DECREMENTER,
EXCEPTION_SYSTEM_CALL,
};
// clang-format on
irq_set_base(_ivt_base);
for (size_t i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++)
{
memcpy(_ivt_base + vectors[i], _exception_entry, (size_t)_exception_entry_size);
}
// Jump to the main routine
(void)main(0, NULL);
for (;;)
{
// Spin.
}
}
......@@ -17,6 +17,8 @@ void isr_dec(void);
void isr(uint64_t vec)
{
vec = vec & 0xFFF;
if (vec == 0x900)
{
// DEC interrupt
......
/* Copyright 2013-2014 IBM Corp.
* Copyright 2020 Raptor Engineering, LLC
* Copyright 2021 Evan Lojewski
*
* Licensed 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.
*/
#define PHYSICAL_ADDRESS_WIDTH 32
/* Load an immediate 64-bit value into a register */
#define LOAD_IMM64(r, e) \
lis r,(e)@highest; \
ori r,r,(e)@higher; \
rldicr r,r, 32, 31; \
oris r,r, (e)@h; \
ori r,r, (e)@l;
/* Load an immediate 32-bit value into a register */
#define LOAD_IMM32(r, e) \
lis r,(e)@h; \
ori r,r, (e)@l
#define REDZONE_SIZE (512)
#define REG_SAVE_SIZE ((32 + 5)*8)
#define STACK_FRAME_C_MINIMAL 64
#define SAVE_NIA (32*8)
#define SAVE_LR (33*8)
#define SAVE_CTR (34*8)
#define SAVE_CR (35*8)
#define SAVE_SRR1 (36*8)
.text
.global _exception_entry;
_exception_entry:
// Save r0 and r2
stdu %r1, -(REG_SAVE_SIZE+REDZONE_SIZE)(%r1)
std %r0, 1*8(%r1)
mflr %r0
std %r0, SAVE_LR(%r1)
std %r2, 2*8(%r1)
// Determine the exception id and jump to __isr
bcl 20,31,$+4
1:
mflr %r0
// Update LR with the __isr address.
#if PHYSICAL_ADDRESS_WIDTH == 32
LOAD_IMM32(%r2, __isr)
#else
LOAD_IMM64(%r2, __isr)
#endif
mtlr %r2
li %r2, (1b - _exception_entry)
sub %r0, %r0, %r2
// Branch to LR -> __isr
blr
nop
.global _exception_entry_size
_exception_entry_size = . - _exception_entry
.size _exception_entry, _exception_entry_size
// Exception handler
.section .text
.type __isr, @function
__isr:
/*
* Assume where we are coming from has a stack and can save there.
* We save the full register set. Since we are calling out to C, we
* could just save the ABI volatile registers
*/
/*
* The first three lines below are executed in the exception handler, so that r0
* can be used to store the origin exception vector
*/
// stdu %r1, -(REG_SAVE_SIZE+REDZONE_SIZE)(%r1)
// std %r0, 1*8(%r1)
// std %r1, 1*8(%r1)
// std %r2, 2*8(%r1)
std %r3, 3*8(%r1)
std %r4, 4*8(%r1)
std %r5, 5*8(%r1)
std %r6, 6*8(%r1)
std %r7, 7*8(%r1)
std %r8, 8*8(%r1)
std %r9, 9*8(%r1)
std %r10, 10*8(%r1)
std %r11, 11*8(%r1)
std %r12, 12*8(%r1)
std %r13, 13*8(%r1)
std %r14, 14*8(%r1)
std %r15, 15*8(%r1)
std %r16, 16*8(%r1)
std %r17, 17*8(%r1)
std %r18, 18*8(%r1)
std %r19, 19*8(%r1)
std %r20, 20*8(%r1)
std %r21, 21*8(%r1)
std %r22, 22*8(%r1)
std %r23, 23*8(%r1)
std %r24, 24*8(%r1)
std %r25, 25*8(%r1)
std %r26, 26*8(%r1)
std %r27, 27*8(%r1)
std %r28, 28*8(%r1)
std %r29, 29*8(%r1)
std %r30, 30*8(%r1)
std %r31, 31*8(%r1)
mr %r10, %r0
mfsrr0 %r0
std %r0, SAVE_NIA(%r1)
// mflr %r0
// std %r0, SAVE_LR(%r1)
mfctr %r0
std %r0, SAVE_CTR(%r1)
mfcr %r0
std %r0, SAVE_CR(%r1)
mfsrr1 %r0
std %r0, SAVE_SRR1(%r1)
stdu %r1, -STACK_FRAME_C_MINIMAL(%r1)
/* When linking with clang, the global entry stub is mistakenly not used here. Ensure r12 is always valid */
/* When using GCC to link, the function prolog is rewritten to use lis r2 instead of addis r2,r12, so this is unneeded. */
#if PHYSICAL_ADDRESS_WIDTH == 32
LOAD_IMM32(%r12, isr)
#else
LOAD_IMM64(%r12, isr)
#endif
mtctr %r12
mr %r3, %r10
bctrl
nop
ld %r1, 0(%r1)
ld %r0, 1*8(%r1)
// ld %r1, 1*8(%r1) // do this at rfid
ld %r2, 2*8(%r1)
// ld %r3, 3*8(%r1) // do this at rfid
ld %r4, 4*8(%r1)
ld %r5, 5*8(%r1)
ld %r6, 6*8(%r1)
ld %r7, 7*8(%r1)
ld %r8, 8*8(%r1)
ld %r9, 9*8(%r1)
ld %r10, 10*8(%r1)
ld %r11, 11*8(%r1)
ld %r12, 12*8(%r1)
ld %r13, 13*8(%r1)
ld %r14, 14*8(%r1)
ld %r15, 15*8(%r1)
ld %r16, 16*8(%r1)
ld %r17, 17*8(%r1)
ld %r18, 18*8(%r1)
ld %r19, 19*8(%r1)
ld %r20, 20*8(%r1)
ld %r21, 21*8(%r1)
ld %r22, 22*8(%r1)
ld %r23, 23*8(%r1)
ld %r24, 24*8(%r1)
ld %r25, 25*8(%r1)
ld %r26, 26*8(%r1)
ld %r27, 27*8(%r1)
ld %r28, 28*8(%r1)
ld %r29, 29*8(%r1)
ld %r30, 30*8(%r1)
ld %r31, 31*8(%r1)
ld %r3, SAVE_LR(%r1)
mtlr %r3
ld %r3, SAVE_CTR(%r1)
mtctr %r3
ld %r3, SAVE_CR(%r1)
mtcr %r3
ld %r3, SAVE_SRR1(%r1)
mtsrr1 %r3
ld %r3, SAVE_NIA(%r1)
mtsrr0 %r3
/* restore %r3 */
ld %r3, 3*8(%r1)
/* do final fixup r1 */
ld %r1, 0*8(%r1)
rfid
.size __isr, . - __isr
......@@ -44,6 +44,13 @@ SECTIONS
_edata = .;
} > main_ram
.ivt ALIGN(16K) (NOLOAD):
{
_ivt_base = .;
. += 4K;
} > main_ram
.bss :
{
. = ALIGN(8);
......@@ -69,6 +76,3 @@ SECTIONS
}
PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 8);
PROVIDE(_fdata_rom = LOADADDR(.data));
PROVIDE(_edata_rom = LOADADDR(.data) + SIZEOF(.data));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment