Add vector table
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
#include "aarch64_irq.h"
|
||||
|
||||
.globl aarch64_init
|
||||
aarch64_init:
|
||||
/* set vector table */
|
||||
adr x0, aarch64_vectors
|
||||
msr vbar_el1, x0
|
||||
mov x0, 0
|
||||
ret
|
||||
|
||||
.globl aarch64_get_el
|
||||
aarch64_get_el:
|
||||
mrs x0, CurrentEL
|
||||
lsr x0, x0, 0x02
|
||||
ret
|
||||
|
||||
.globl aarch64_get32r
|
||||
aarch64_get32r:
|
||||
ldr w0, [x0]
|
||||
ret
|
||||
|
||||
.globl aarch64_set32r
|
||||
aarch64_set32r:
|
||||
str w1, [x0]
|
||||
ret
|
||||
|
||||
.globl aarch64_delay
|
||||
aarch64_delay:
|
||||
subs x0, x0, 0x01
|
||||
bne aarch64_delay
|
||||
ret
|
||||
|
||||
.globl aarch64_irq_vector_init
|
||||
irq_vector_init:
|
||||
ret
|
||||
|
||||
.globl aarch64_irq_enable
|
||||
aarch64_irq_enable:
|
||||
msr daifclr, 2
|
||||
ret
|
||||
|
||||
.globl aarch64_irq_disable
|
||||
aarch64_irq_disable:
|
||||
msr daifset, 2
|
||||
ret
|
||||
|
||||
|
||||
/* Exceptions Vector Table
|
||||
* */
|
||||
.macro KERNEL_ENTER
|
||||
sub sp, sp, 256
|
||||
stp x0, x1, [sp, 16 * 0]
|
||||
stp x2, x3, [sp, 16 * 1]
|
||||
stp x4, x5, [sp, 16 * 2]
|
||||
stp x6, x7, [sp, 16 * 3]
|
||||
stp x8, x9, [sp, 16 * 4]
|
||||
stp x10, x11, [sp, 16 * 5]
|
||||
stp x12, x13, [sp, 16 * 6]
|
||||
stp x14, x15, [sp, 16 * 7]
|
||||
stp x16, x17, [sp, 16 * 8]
|
||||
stp x18, x19, [sp, 16 * 9]
|
||||
stp x20, x21, [sp, 16 * 10]
|
||||
stp x22, x23, [sp, 16 * 11]
|
||||
stp x24, x25, [sp, 16 * 12]
|
||||
stp x26, x27, [sp, 16 * 13]
|
||||
stp x28, x29, [sp, 16 * 14]
|
||||
str x30, [sp, 16 * 15]
|
||||
.endm
|
||||
|
||||
.macro KERNEL_LEAVE
|
||||
ldp x0, x1, [sp, 16 * 0]
|
||||
ldp x2, x3, [sp, 16 * 1]
|
||||
ldp x4, x5, [sp, 16 * 2]
|
||||
ldp x6, x7, [sp, 16 * 3]
|
||||
ldp x8, x9, [sp, 16 * 4]
|
||||
ldp x10, x11, [sp, 16 * 5]
|
||||
ldp x12, x13, [sp, 16 * 6]
|
||||
ldp x14, x15, [sp, 16 * 7]
|
||||
ldp x16, x17, [sp, 16 * 8]
|
||||
ldp x18, x19, [sp, 16 * 9]
|
||||
ldp x20, x21, [sp, 16 * 10]
|
||||
ldp x22, x23, [sp, 16 * 11]
|
||||
ldp x24, x25, [sp, 16 * 12]
|
||||
ldp x26, x27, [sp, 16 * 13]
|
||||
ldp x28, x29, [sp, 16 * 14]
|
||||
ldr x30, [sp, 16 * 15]
|
||||
add sp, sp, 256
|
||||
.endm
|
||||
|
||||
.macro VECTOR_ENTRY GOTO_LABEL
|
||||
.align 7
|
||||
b \GOTO_LABEL
|
||||
.endm
|
||||
|
||||
.macro EXCEPTION_FALLBACK EID
|
||||
KERNEL_ENTER
|
||||
mov x0, \EID
|
||||
mrs x1, esr_el1
|
||||
mrs x2, elr_el1
|
||||
bl k_irq_fallback
|
||||
b die
|
||||
.endm
|
||||
|
||||
die:
|
||||
b die
|
||||
|
||||
.align 11
|
||||
.globl aarch64_vectors
|
||||
aarch64_vectors:
|
||||
/* EL1t */
|
||||
VECTOR_ENTRY el1t_sync
|
||||
VECTOR_ENTRY el1t_irq
|
||||
VECTOR_ENTRY el1t_fiq
|
||||
VECTOR_ENTRY el1t_error
|
||||
/* EL1h */
|
||||
VECTOR_ENTRY el1h_sync
|
||||
VECTOR_ENTRY el1h_irq
|
||||
VECTOR_ENTRY el1h_fiq
|
||||
VECTOR_ENTRY el1h_error
|
||||
/* EL0 - 64bit */
|
||||
VECTOR_ENTRY el0_64_sync
|
||||
VECTOR_ENTRY el0_64_irq
|
||||
VECTOR_ENTRY el0_64_fiq
|
||||
VECTOR_ENTRY el0_64_error
|
||||
/* EL0 - 32bit */
|
||||
VECTOR_ENTRY el0_32_sync
|
||||
VECTOR_ENTRY el0_32_irq
|
||||
VECTOR_ENTRY el0_32_fiq
|
||||
VECTOR_ENTRY el0_32_error
|
||||
|
||||
el1t_sync:
|
||||
EXCEPTION_FALLBACK EL1t_SYNC
|
||||
|
||||
el1t_irq:
|
||||
EXCEPTION_FALLBACK EL1t_IRQ
|
||||
|
||||
el1t_fiq:
|
||||
EXCEPTION_FALLBACK EL1t_FIQ
|
||||
|
||||
el1t_error:
|
||||
EXCEPTION_FALLBACK EL1t_ERROR
|
||||
|
||||
el1h_sync:
|
||||
EXCEPTION_FALLBACK EL1h_SYNC
|
||||
|
||||
el1h_irq:
|
||||
KERNEL_ENTER
|
||||
bl k_irq_handler
|
||||
KERNEL_LEAVE
|
||||
eret
|
||||
|
||||
el1h_fiq:
|
||||
EXCEPTION_FALLBACK EL1h_FIQ
|
||||
|
||||
el1h_error:
|
||||
EXCEPTION_FALLBACK EL1h_ERROR
|
||||
|
||||
el0_64_sync:
|
||||
EXCEPTION_FALLBACK EL0_64_SYNC
|
||||
|
||||
el0_64_irq:
|
||||
EXCEPTION_FALLBACK EL0_64_IRQ
|
||||
|
||||
el0_64_fiq:
|
||||
EXCEPTION_FALLBACK EL0_64_FIQ
|
||||
|
||||
el0_64_error:
|
||||
EXCEPTION_FALLBACK EL0_64_ERROR
|
||||
|
||||
el0_32_sync:
|
||||
EXCEPTION_FALLBACK EL0_32_SYNC
|
||||
|
||||
el0_32_irq:
|
||||
EXCEPTION_FALLBACK EL0_32_IRQ
|
||||
|
||||
el0_32_fiq:
|
||||
EXCEPTION_FALLBACK EL0_32_FIQ
|
||||
|
||||
el0_32_error:
|
||||
EXCEPTION_FALLBACK EL0_32_ERROR
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||
* Please, refer LICENSE file for legal information
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @file util.h
|
||||
* @author Ilja Kartašov <ik@lowenware.com>
|
||||
* @brief
|
||||
*
|
||||
* @see https://lowenware.com/
|
||||
*/
|
||||
|
||||
#ifndef AARCH64_H_F3AA8888_CEB3_4C16_9835_C3F23B040BB5
|
||||
#define AARCH64_H_F3AA8888_CEB3_4C16_9835_C3F23B040BB5
|
||||
|
||||
#include "aarch64_reg.h"
|
||||
#include "aarch64_irq.h"
|
||||
|
||||
extern unsigned int
|
||||
aarch64_init(void);
|
||||
|
||||
extern unsigned int
|
||||
aarch64_get_el(void);
|
||||
|
||||
extern unsigned int
|
||||
aarch64_get32r(unsigned long reg);
|
||||
|
||||
extern void
|
||||
aarch64_set32r(unsigned long reg, unsigned int value);
|
||||
|
||||
extern void
|
||||
aarch64_delay(unsigned long cycles);
|
||||
|
||||
extern void
|
||||
aarch64_irq_enable(void);
|
||||
|
||||
extern void
|
||||
aarch64_irq_disable(void);
|
||||
|
||||
#endif /* !AARCH64_H */
|
||||
@@ -0,0 +1,16 @@
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* For some reason qemu UART doesn't work with smaller address */
|
||||
. = 0x40000000;
|
||||
|
||||
.boot . : { boot.o(.text) }
|
||||
.text : { *(.text) }
|
||||
.data : { *(.data) }
|
||||
.bss : { *(.bss COMMON) }
|
||||
|
||||
. = ALIGN(8);
|
||||
. = . + 0x1000;
|
||||
stack_ptr = . ;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||
* Please, refer LICENSE file for legal information
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @file aarch64_irq.h
|
||||
* @author Ilja Kartašov <ik@lowenware.com>
|
||||
* @brief
|
||||
*
|
||||
* @see https://lowenware.com/
|
||||
*/
|
||||
|
||||
#ifndef AARCH64_IRQ_H_286AEC6E_325F_469E_B140_53DDDD63876C
|
||||
#define AARCH64_IRQ_H_286AEC6E_325F_469E_B140_53DDDD63876C
|
||||
|
||||
#define EL1t_SYNC 0
|
||||
#define EL1t_IRQ 1
|
||||
#define EL1t_FIQ 2
|
||||
#define EL1t_ERROR 3
|
||||
#define EL1h_SYNC 4
|
||||
#define EL1h_IRQ 5
|
||||
#define EL1h_FIQ 6
|
||||
#define EL1h_ERROR 7
|
||||
#define EL0_64_SYNC 8
|
||||
#define EL0_64_IRQ 9
|
||||
#define EL0_64_FIQ 10
|
||||
#define EL0_64_ERROR 11
|
||||
#define EL0_32_SYNC 12
|
||||
#define EL0_32_IRQ 13
|
||||
#define EL0_32_FIQ 14
|
||||
#define EL0_32_ERROR 15
|
||||
|
||||
|
||||
#endif /* !AARCH64_IRQ_H */
|
||||
@@ -0,0 +1,59 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||
* Please, refer LICENSE file for legal information
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @file aarch64_reg.h
|
||||
* @author Ilja Kartašov <ik@lowenware.com>
|
||||
* @brief
|
||||
*
|
||||
* @see https://lowenware.com/
|
||||
*/
|
||||
|
||||
#ifndef AARCH64_REG_H_C74FE7BF_C8A6_4718_867A_C125CBF326BD
|
||||
#define AARCH64_REG_H_C74FE7BF_C8A6_4718_867A_C125CBF326BD
|
||||
|
||||
/* Saved Program Status Register (SPSR)
|
||||
* Exception Level 3 (EL3)
|
||||
* See page 389 of AArch64-Reference-Manual
|
||||
* */
|
||||
#define SPSR_MASK_ALL (7 << 6)
|
||||
#define SPSR_EL1h (5 << 0)
|
||||
#define SPSR_VALUE (SPSR_MASK_ALL | SPSR_EL1h)
|
||||
|
||||
/* Secure Configuration Register (SCR)
|
||||
* Exception Level 3 (EL3)
|
||||
* See page 2648 of AArch64-Reference-Manual
|
||||
* */
|
||||
#define SCR_RESERVED (3 << 4)
|
||||
#define SCR_RW (1 << 10)
|
||||
#define SCR_NS (1 << 0)
|
||||
#define SCR_VALUE (SCR_RESERVED | SCR_RW | SCR_NS)
|
||||
|
||||
/* Hypervisor Configuration Register (HCR)
|
||||
* Exception Level 2 (EL2)
|
||||
* See page 2487 of AArch64-Reference-Manual
|
||||
* */
|
||||
#define HCR_RW (1 << 31)
|
||||
#define HCR_VALUE HCR_RW
|
||||
|
||||
/* System Control REgister (SCTLR_EL1)
|
||||
* Exception Level 1 (EL1)
|
||||
* See page 2654 of AArch64-Reference-Manual
|
||||
* */
|
||||
#define SCTLR_RESERVED (3 << 28) | (3 << 22) | (1 << 20) | (1 << 11)
|
||||
#define SCTLR_EE_LITTLE_ENDIAN (0 << 25)
|
||||
#define SCTLR_EOE_LITTLE_ENDIAN (0 << 24)
|
||||
#define SCTLR_I_CACHE_DISABLED (0 << 12)
|
||||
#define SCTLR_D_CACHE_DISABLED (0 << 2)
|
||||
#define SCTLR_MMU_DISABLED (0 << 0)
|
||||
#define SCTLR_MMU_ENABLED (1 << 0)
|
||||
|
||||
#define SCTLR_VALUE_MMU_DISABLED (SCTLR_RESERVED | SCTLR_EE_LITTLE_ENDIAN \
|
||||
| SCTLR_I_CACHE_DISABLED | SCTLR_D_CACHE_DISABLED | SCTLR_MMU_DISABLED)
|
||||
|
||||
|
||||
#endif /* !AARCH64_REG_H */
|
||||
@@ -0,0 +1,74 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||
* Please, refer LICENSE file for legal information
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @file bcm2837.h
|
||||
* @author Ilja Kartašov <ik@lowenware.com>
|
||||
* @brief
|
||||
*
|
||||
* @see https://lowenware.com/
|
||||
*/
|
||||
|
||||
#ifndef BCM2837_H_13CD1DB9_AAD7_4F1C_8669_37DED77135D1
|
||||
#define BCM2837_H_13CD1DB9_AAD7_4F1C_8669_37DED77135D1
|
||||
|
||||
#define PERIPHERAL_BASE 0x3F000000
|
||||
|
||||
/* GPIO */
|
||||
#define GPFSEL1 (PERIPHERAL_BASE + 0x00200004)
|
||||
#define GPSET0 (PERIPHERAL_BASE + 0x0020001C)
|
||||
#define GPCLR0 (PERIPHERAL_BASE + 0x00200028)
|
||||
#define GPPUD (PERIPHERAL_BASE + 0x00200094)
|
||||
#define GPPUDCLK0 (PERIPHERAL_BASE + 0x00200098)
|
||||
|
||||
/* UART MINI */
|
||||
#define AUX_ENABLES (PERIPHERAL_BASE + 0x00215004)
|
||||
#define AUX_MU_IO_REG (PERIPHERAL_BASE + 0x00215040)
|
||||
#define AUX_MU_IER_REG (PERIPHERAL_BASE + 0x00215044)
|
||||
#define AUX_MU_IIR_REG (PERIPHERAL_BASE + 0x00215048)
|
||||
#define AUX_MU_LCR_REG (PERIPHERAL_BASE + 0x0021504C)
|
||||
#define AUX_MU_MCR_REG (PERIPHERAL_BASE + 0x00215050)
|
||||
#define AUX_MU_LSR_REG (PERIPHERAL_BASE + 0x00215054)
|
||||
#define AUX_MU_MSR_REG (PERIPHERAL_BASE + 0x00215058)
|
||||
#define AUX_MU_SCRATCH (PERIPHERAL_BASE + 0x0021505C)
|
||||
#define AUX_MU_CNTL_REG (PERIPHERAL_BASE + 0x00215060)
|
||||
#define AUX_MU_STAT_REG (PERIPHERAL_BASE + 0x00215064)
|
||||
#define AUX_MU_BAUD_REG (PERIPHERAL_BASE + 0x00215068)
|
||||
|
||||
/* IRQ */
|
||||
#define IRQ_BASIC_PENDING (PERIPHERAL_BASE + 0x0000B200)
|
||||
#define IRQ_PENDING_1 (PERIPHERAL_BASE + 0x0000B204)
|
||||
#define IRQ_PENDING_2 (PERIPHERAL_BASE + 0x0000B208)
|
||||
#define FIQ_CONTROL (PERIPHERAL_BASE + 0x0000B20C)
|
||||
#define ENABLE_IRQS_1 (PERIPHERAL_BASE + 0x0000B210)
|
||||
#define ENABLE_IRQS_2 (PERIPHERAL_BASE + 0x0000B214)
|
||||
#define ENABLE_BASIC_IRQS (PERIPHERAL_BASE + 0x0000B218)
|
||||
#define DISABLE_IRQS_1 (PERIPHERAL_BASE + 0x0000B21C)
|
||||
#define DISABLE_IRQS_2 (PERIPHERAL_BASE + 0x0000B220)
|
||||
#define DISABLE_BASIC_IRQS (PERIPHERAL_BASE + 0x0000B224)
|
||||
|
||||
/* SYSTEM TIMER */
|
||||
#define SYSTEM_TIMER_IRQ_0 (1 << 0)
|
||||
#define SYSTEM_TIMER_IRQ_1 (1 << 1)
|
||||
#define SYSTEM_TIMER_IRQ_2 (1 << 2)
|
||||
#define SYSTEM_TIMER_IRQ_3 (1 << 3)
|
||||
|
||||
/* TIMER */
|
||||
#define TIMER_CS (PERIPHERAL_BASE + 0x00003000)
|
||||
#define TIMER_CLO (PERIPHERAL_BASE + 0x00003004)
|
||||
#define TIMER_CHI (PERIPHERAL_BASE + 0x00003008)
|
||||
#define TIMER_C0 (PERIPHERAL_BASE + 0x0000300C)
|
||||
#define TIMER_C1 (PERIPHERAL_BASE + 0x00003010)
|
||||
#define TIMER_C2 (PERIPHERAL_BASE + 0x00003014)
|
||||
#define TIMER_C3 (PERIPHERAL_BASE + 0x00003018)
|
||||
|
||||
#define TIMER_CS_M0 (1 << 0)
|
||||
#define TIMER_CS_M1 (1 << 1)
|
||||
#define TIMER_CS_M2 (1 << 2)
|
||||
#define TIMER_CS_M3 (1 << 3)
|
||||
|
||||
#endif /* !BCM2837_H */
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
#include "aarch64_reg.h"
|
||||
|
||||
.globl _start
|
||||
|
||||
_start:
|
||||
mrs x0, mpidr_el1 /* Check CPU ID */
|
||||
mov x1, 0xC1000000
|
||||
bic x0, x0, x1
|
||||
cbz x0, set_el
|
||||
idle:
|
||||
b idle
|
||||
|
||||
set_el:
|
||||
/* check current exception level */
|
||||
bl aarch64_get_el
|
||||
cmp x0, 0x03
|
||||
bne set_stack
|
||||
/* set SCTRL_EL1 */
|
||||
ldr x0, =SCTLR_VALUE_MMU_DISABLED
|
||||
msr sctlr_el1, x0
|
||||
/* set HCR_EL2 */
|
||||
ldr x0, =HCR_VALUE
|
||||
msr hcr_el2, x0
|
||||
/* set SCR_EL3 */
|
||||
ldr x0, =SCR_VALUE
|
||||
msr scr_el3, x0
|
||||
/* set SPSR_EL3 */
|
||||
ldr x0, =SPSR_VALUE
|
||||
msr spsr_el3, x0
|
||||
/* set elr_el3 */
|
||||
adr x0, set_stack
|
||||
msr elr_el3, x0
|
||||
eret
|
||||
|
||||
set_stack:
|
||||
ldr x30, =stack_ptr /* defined in aarch64.ld */
|
||||
mov sp, x30
|
||||
bl k_main
|
||||
|
||||
|
||||
Reference in New Issue
Block a user