parent
5d27223ea5
commit
12d8a72913
@ -0,0 +1,9 @@ |
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
extra-y := start.o
|
||||
obj-y += cpu.o
|
@ -0,0 +1,8 @@ |
||||
#
|
||||
# (C) Copyright 2015
|
||||
# Kamil Lulko, <rev13@wp.pl>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
PLATFORM_CPPFLAGS += -march=armv7-m -mthumb
|
@ -0,0 +1,35 @@ |
||||
/*
|
||||
* (C) Copyright 2010,2011 |
||||
* Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com |
||||
* |
||||
* (C) Copyright 2015 |
||||
* Kamil Lulko, <rev13@wp.pl> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <asm/armv7m.h> |
||||
|
||||
/*
|
||||
* This is called right before passing control to |
||||
* the Linux kernel point. |
||||
*/ |
||||
int cleanup_before_linux(void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
/*
|
||||
* Perform the low-level reset. |
||||
*/ |
||||
void reset_cpu(ulong addr) |
||||
{ |
||||
/*
|
||||
* Perform reset but keep priority group unchanged. |
||||
*/ |
||||
writel((V7M_AIRCR_VECTKEY << V7M_AIRCR_VECTKEY_SHIFT) |
||||
| (V7M_SCB->aircr & V7M_AIRCR_PRIGROUP_MSK) |
||||
| V7M_AIRCR_SYSRESET, &V7M_SCB->aircr); |
||||
} |
@ -0,0 +1,15 @@ |
||||
/* |
||||
* (C) Copyright 2015 |
||||
* Kamil Lulko, <rev13@wp.pl>
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
.globl reset
|
||||
.type reset, %function |
||||
reset: |
||||
b _main |
||||
|
||||
.globl c_runtime_cpu_setup
|
||||
c_runtime_cpu_setup: |
||||
mov pc, lr |
@ -0,0 +1,60 @@ |
||||
/*
|
||||
* (C) Copyright 2010,2011 |
||||
* Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com |
||||
* |
||||
* (C) Copyright 2015 |
||||
* Kamil Lulko, <rev13@wp.pl> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef ARMV7M_H |
||||
#define ARMV7M_H |
||||
|
||||
#if defined(__ASSEMBLY__) |
||||
.syntax unified |
||||
.thumb |
||||
#endif |
||||
|
||||
#define V7M_SCB_BASE 0xE000ED00 |
||||
#define V7M_MPU_BASE 0xE000ED90 |
||||
|
||||
#define V7M_SCB_VTOR 0x08 |
||||
|
||||
#if !defined(__ASSEMBLY__) |
||||
struct v7m_scb { |
||||
uint32_t cpuid; /* CPUID Base Register */ |
||||
uint32_t icsr; /* Interrupt Control and State Register */ |
||||
uint32_t vtor; /* Vector Table Offset Register */ |
||||
uint32_t aircr; /* App Interrupt and Reset Control Register */ |
||||
}; |
||||
#define V7M_SCB ((struct v7m_scb *)V7M_SCB_BASE) |
||||
|
||||
#define V7M_AIRCR_VECTKEY 0x5fa |
||||
#define V7M_AIRCR_VECTKEY_SHIFT 16 |
||||
#define V7M_AIRCR_ENDIAN (1 << 15) |
||||
#define V7M_AIRCR_PRIGROUP_SHIFT 8 |
||||
#define V7M_AIRCR_PRIGROUP_MSK (0x7 << V7M_AIRCR_PRIGROUP_SHIFT) |
||||
#define V7M_AIRCR_SYSRESET (1 << 2) |
||||
|
||||
#define V7M_ICSR_VECTACT_MSK 0xFF |
||||
|
||||
struct v7m_mpu { |
||||
uint32_t type; /* Type Register */ |
||||
uint32_t ctrl; /* Control Register */ |
||||
uint32_t rnr; /* Region Number Register */ |
||||
uint32_t rbar; /* Region Base Address Register */ |
||||
uint32_t rasr; /* Region Attribute and Size Register */ |
||||
}; |
||||
#define V7M_MPU ((struct v7m_mpu *)V7M_MPU_BASE) |
||||
|
||||
#define V7M_MPU_CTRL_ENABLE (1 << 0) |
||||
#define V7M_MPU_CTRL_HFNMIENA (1 << 1) |
||||
|
||||
#define V7M_MPU_RASR_EN (1 << 0) |
||||
#define V7M_MPU_RASR_SIZE_BITS 1 |
||||
#define V7M_MPU_RASR_SIZE_4GB (31 << V7M_MPU_RASR_SIZE_BITS) |
||||
#define V7M_MPU_RASR_AP_RW_RW (3 << 24) |
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */ |
||||
#endif /* ARMV7M_H */ |
@ -0,0 +1,95 @@ |
||||
/*
|
||||
* (C) Copyright 2015 |
||||
* Kamil Lulko, <rev13@wp.pl> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
|
||||
/*
|
||||
* Upon exception entry ARMv7-M processors automatically save stack |
||||
* frames containing some registers. For simplicity initial |
||||
* implementation uses only this auto-saved stack frame. |
||||
* This does not contain complete register set dump, |
||||
* only R0-R3, R12, LR, PC and xPSR are saved. |
||||
*/ |
||||
|
||||
struct autosave_regs { |
||||
long uregs[8]; |
||||
}; |
||||
|
||||
#define ARM_XPSR uregs[7] |
||||
#define ARM_PC uregs[6] |
||||
#define ARM_LR uregs[5] |
||||
#define ARM_R12 uregs[4] |
||||
#define ARM_R3 uregs[3] |
||||
#define ARM_R2 uregs[2] |
||||
#define ARM_R1 uregs[1] |
||||
#define ARM_R0 uregs[0] |
||||
|
||||
int interrupt_init(void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
void enable_interrupts(void) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
int disable_interrupts(void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
void dump_regs(struct autosave_regs *regs) |
||||
{ |
||||
printf("pc : %08lx lr : %08lx xPSR : %08lx\n", |
||||
regs->ARM_PC, regs->ARM_LR, regs->ARM_XPSR); |
||||
printf("r12 : %08lx r3 : %08lx r2 : %08lx\n" |
||||
"r1 : %08lx r0 : %08lx\n", |
||||
regs->ARM_R12, regs->ARM_R3, regs->ARM_R2, |
||||
regs->ARM_R1, regs->ARM_R0); |
||||
} |
||||
|
||||
void bad_mode(void) |
||||
{ |
||||
panic("Resetting CPU ...\n"); |
||||
reset_cpu(0); |
||||
} |
||||
|
||||
void do_hard_fault(struct autosave_regs *autosave_regs) |
||||
{ |
||||
printf("Hard fault\n"); |
||||
dump_regs(autosave_regs); |
||||
bad_mode(); |
||||
} |
||||
|
||||
void do_mm_fault(struct autosave_regs *autosave_regs) |
||||
{ |
||||
printf("Memory management fault\n"); |
||||
dump_regs(autosave_regs); |
||||
bad_mode(); |
||||
} |
||||
|
||||
void do_bus_fault(struct autosave_regs *autosave_regs) |
||||
{ |
||||
printf("Bus fault\n"); |
||||
dump_regs(autosave_regs); |
||||
bad_mode(); |
||||
} |
||||
|
||||
void do_usage_fault(struct autosave_regs *autosave_regs) |
||||
{ |
||||
printf("Usage fault\n"); |
||||
dump_regs(autosave_regs); |
||||
bad_mode(); |
||||
} |
||||
|
||||
void do_invalid_entry(struct autosave_regs *autosave_regs) |
||||
{ |
||||
printf("Exception\n"); |
||||
dump_regs(autosave_regs); |
||||
bad_mode(); |
||||
} |
@ -0,0 +1,57 @@ |
||||
/* |
||||
* (C) Copyright 2015 |
||||
* Kamil Lulko, <rev13@wp.pl>
|
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <config.h> |
||||
#include <asm/armv7m.h> |
||||
#include <linux/linkage.h> |
||||
|
||||
.type __hard_fault_entry, %function |
||||
__hard_fault_entry: |
||||
mov r0, sp @ pass auto-saved registers as argument
|
||||
b do_hard_fault |
||||
|
||||
.type __mm_fault_entry, %function |
||||
__mm_fault_entry: |
||||
mov r0, sp @ pass auto-saved registers as argument
|
||||
b do_mm_fault |
||||
|
||||
.type __bus_fault_entry, %function |
||||
__bus_fault_entry: |
||||
mov r0, sp @ pass auto-saved registers as argument
|
||||
b do_bus_fault |
||||
|
||||
.type __usage_fault_entry, %function |
||||
__usage_fault_entry: |
||||
mov r0, sp @ pass auto-saved registers as argument
|
||||
b do_usage_fault |
||||
|
||||
.type __invalid_entry, %function |
||||
__invalid_entry: |
||||
mov r0, sp @ pass auto-saved registers as argument
|
||||
b do_invalid_entry |
||||
|
||||
.section .vectors |
||||
ENTRY(_start) |
||||
.long CONFIG_SYS_INIT_SP_ADDR @ 0 - Reset stack pointer
|
||||
.long reset @ 1 - Reset
|
||||
.long __invalid_entry @ 2 - NMI
|
||||
.long __hard_fault_entry @ 3 - HardFault
|
||||
.long __mm_fault_entry @ 4 - MemManage
|
||||
.long __bus_fault_entry @ 5 - BusFault
|
||||
.long __usage_fault_entry @ 6 - UsageFault
|
||||
.long __invalid_entry @ 7 - Reserved
|
||||
.long __invalid_entry @ 8 - Reserved
|
||||
.long __invalid_entry @ 9 - Reserved
|
||||
.long __invalid_entry @ 10 - Reserved
|
||||
.long __invalid_entry @ 11 - SVCall
|
||||
.long __invalid_entry @ 12 - Debug Monitor
|
||||
.long __invalid_entry @ 13 - Reserved
|
||||
.long __invalid_entry @ 14 - PendSV
|
||||
.long __invalid_entry @ 15 - SysTick
|
||||
.rept 255 - 16 |
||||
.long __invalid_entry @ 16..255 - External Interrupts
|
||||
.endr |
Loading…
Reference in new issue