Add vector table
This commit is contained in:
parent
08ffb6ee94
commit
417106b967
90
Makefile
90
Makefile
|
@ -1,90 +1,26 @@
|
||||||
# environment
|
include Makevars.mk
|
||||||
|
|
||||||
AARCH64_TOOLCHAIN ?= aarch64-linux-gnu
|
# Rules
|
||||||
|
|
||||||
|
|
||||||
# Shortcuts
|
|
||||||
|
|
||||||
CC=clang --target=aarch64-none-elf -mcpu=cortex-a57
|
|
||||||
LD=ld.lld
|
|
||||||
OBJCOPY=$(AARCH64_TOOLCHAIN)-objcopy --target elf64-littleaarch64
|
|
||||||
|
|
||||||
CFLAGS += -O0
|
|
||||||
CFLAGS += -g
|
|
||||||
#CFLAGS += -nostdlib
|
|
||||||
#CFLAGS += -march=armv8-a
|
|
||||||
#CFLAGS += -std=c99
|
|
||||||
#CFLAGS += -pedantic
|
|
||||||
#CFLAGS += -Wall
|
|
||||||
#CFLAGS += -Wmissing-prototypes
|
|
||||||
#CFLAGS += -Wstrict-prototypes
|
|
||||||
#CFLAGS += -Wold-style-definition
|
|
||||||
|
|
||||||
BUILD_DIR=build
|
|
||||||
|
|
||||||
|
|
||||||
# Files
|
|
||||||
|
|
||||||
KERNEL_MEMMAP = aarch64/memmap
|
|
||||||
|
|
||||||
KERNEL_SOURCES = \
|
|
||||||
aarch64/boot.s \
|
|
||||||
sys/main.c \
|
|
||||||
sys/uart.c \
|
|
||||||
|
|
||||||
KERNEL_LIST := $(wildcard $(KERNEL_SOURCES))
|
|
||||||
KERNEL_OBJS := $(addsuffix .o, $(addprefix $(BUILD_DIR)/, ${KERNEL_LIST}))
|
|
||||||
|
|
||||||
all: kernel
|
all: kernel
|
||||||
|
|
||||||
|
$(BUILD_DIR)kernel:
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
# compilation
|
.PHONY: clean run debug kernel
|
||||||
|
|
||||||
kernel: $(BUILD_DIR)/kernel.elf # $(BUILD_DIR)/kernel.sym
|
|
||||||
|
|
||||||
$(BUILD_DIR)/kernel.elf: $(KERNEL_OBJS)
|
|
||||||
$(info linking target: $@)
|
|
||||||
$(LD) -T$(KERNEL_MEMMAP) -nostdlib $^ -o $@
|
|
||||||
$(info done: $@)
|
|
||||||
|
|
||||||
$(BUILD_DIR)/kernel.bin: $(BUILD_DIR)/kernel.elf
|
|
||||||
$(OBJCOPY) -O binary $< $@
|
|
||||||
|
|
||||||
$(BUILD_DIR)/kernel.sym: $(BUILD_DIR)/kernel.elf
|
|
||||||
$(OBJCOPY) --only-keep-debug $< $@
|
|
||||||
$(OBJCOPY) --strip-debug $@
|
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %
|
|
||||||
$(info compiling file: $<)
|
|
||||||
@mkdir -p $(dir ./$(BUILD_DIR)/$<)
|
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: clean run
|
|
||||||
|
|
||||||
# helpers
|
|
||||||
QEMU_CMD = \
|
|
||||||
qemu-system-aarch64 \
|
|
||||||
-M virt \
|
|
||||||
-cpu cortex-a57 \
|
|
||||||
-nographic \
|
|
||||||
-smp 4 \
|
|
||||||
-m 4096 \
|
|
||||||
-kernel build/kernel.elf \
|
|
||||||
-serial stdio \
|
|
||||||
-monitor none \
|
|
||||||
|
|
||||||
|
kernel: $(BUILD_DIR)kernel
|
||||||
|
cd kernel && BUILD_DIR=../$(BUILD_DIR)kernel/ make
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -Rf ./$(BUILD_DIR)/*
|
rm -Rf ./$(BUILD_DIR)*
|
||||||
|
|
||||||
run: kernel
|
run: kernel
|
||||||
$(QEMU_CMD)
|
$(AARCH64_QEMU)
|
||||||
|
|
||||||
|
|
||||||
debug: kernel
|
debug: kernel
|
||||||
$(QEMU_CMD) -S -gdb tcp::1234 & \
|
$(AARCH64_QEMU) -S -gdb tcp::1234 & \
|
||||||
gdb-multiarch -q \
|
gdb-multiarch -q \
|
||||||
-ex 'file build/kernel.elf' \
|
-ex 'file $(BUILD_DIR)kernel/kernel.elf' \
|
||||||
-ex 'target remote localhost:1234'
|
-ex 'target remote localhost:1234'
|
||||||
kill %1
|
kill %1
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#
|
||||||
|
# build.mk
|
||||||
|
# Ilja Kartašov, 2019-11-29 17:38
|
||||||
|
#
|
||||||
|
|
||||||
|
BUILD_DIR ?= build/
|
||||||
|
|
||||||
|
AARCH64_TOOLCHAIN ?= aarch64-linux-gnu
|
||||||
|
AARCH64_CC = clang --target=aarch64-none-elf -mcpu=cortex-a57
|
||||||
|
AARCH64_LD = ld.lld
|
||||||
|
AARCH64_OBJCOPY = $(AARCH64_TOOLCHAIN)-objcopy --target elf64-littleaarch64
|
||||||
|
|
||||||
|
AARCH64_QEMU = \
|
||||||
|
qemu-system-aarch64 \
|
||||||
|
-M virt \
|
||||||
|
-cpu cortex-a53 \
|
||||||
|
-nographic \
|
||||||
|
-smp 4 \
|
||||||
|
-m 4096 \
|
||||||
|
-kernel build/kernel/kernel.elf \
|
||||||
|
-serial stdio \
|
||||||
|
-monitor none \
|
||||||
|
|
||||||
|
# AARCH64_QEMU = \
|
||||||
|
# qemu-system-aarch64 \
|
||||||
|
# -M raspi3 \
|
||||||
|
# -nographic \
|
||||||
|
# -kernel build/kernel/kernel.elf \
|
||||||
|
# -serial stdio \
|
||||||
|
# -monitor none \
|
||||||
|
# vim:ft=make
|
||||||
|
#
|
|
@ -1,18 +0,0 @@
|
||||||
.globl _start
|
|
||||||
|
|
||||||
_start:
|
|
||||||
|
|
||||||
mrs x0, mpidr_el1 // Check CPU ID
|
|
||||||
mov x1, 0xC1000000
|
|
||||||
bic x0, x0, x1
|
|
||||||
cbz x0, set_stack
|
|
||||||
b idle
|
|
||||||
|
|
||||||
set_stack:
|
|
||||||
ldr x30, =stack_ptr // defined in sys/memmap
|
|
||||||
mov sp, x30
|
|
||||||
bl k_main
|
|
||||||
|
|
||||||
idle:
|
|
||||||
b idle
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# environment
|
||||||
|
|
||||||
|
include ../Makevars.mk
|
||||||
|
|
||||||
|
# CFLAGS
|
||||||
|
|
||||||
|
CFLAGS += -O0
|
||||||
|
CFLAGS += -g
|
||||||
|
CFLAGS += -nostdlib
|
||||||
|
CFLAGS += -march=armv8-a
|
||||||
|
# CFLAGS += -std=c99
|
||||||
|
# CFLAGS += -pedantic
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Wmissing-prototypes
|
||||||
|
CFLAGS += -Wstrict-prototypes
|
||||||
|
CFLAGS += -Wold-style-definition
|
||||||
|
|
||||||
|
INCS += -I./
|
||||||
|
|
||||||
|
# SOURCES
|
||||||
|
|
||||||
|
LD_SCRIPT = aarch64/aarch64.ld
|
||||||
|
|
||||||
|
SOURCE_FILES = \
|
||||||
|
aarch64/boot.S \
|
||||||
|
aarch64/aarch64.S \
|
||||||
|
\
|
||||||
|
core/main.c \
|
||||||
|
core/irq.c \
|
||||||
|
core/timer.c \
|
||||||
|
core/log.c \
|
||||||
|
\
|
||||||
|
device/uart/uart_mini.c \
|
||||||
|
device/uart/uart_qemu.c \
|
||||||
|
|
||||||
|
SOURCE_LIST := $(wildcard $(SOURCE_FILES))
|
||||||
|
OBJECT_FILES := $(addsuffix .o, $(addprefix $(BUILD_DIR), ${SOURCE_LIST}))
|
||||||
|
|
||||||
|
# rules
|
||||||
|
|
||||||
|
all: kernel
|
||||||
|
|
||||||
|
default: kernel
|
||||||
|
|
||||||
|
kernel: $(BUILD_DIR)kernel.elf
|
||||||
|
|
||||||
|
$(BUILD_DIR)kernel.elf: $(OBJECT_FILES)
|
||||||
|
$(info linking target: $@)
|
||||||
|
$(AARCH64_LD) -T$(LD_SCRIPT) -nostdlib $^ -o $@
|
||||||
|
$(info done: $@)
|
||||||
|
|
||||||
|
$(BUILD_DIR)kernel.bin: $(BUILD_DIR)/kernel.elf
|
||||||
|
$(AARCH64_OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)kernel.sym: $(BUILD_DIR)/kernel.elf
|
||||||
|
$(AARCH64_OBJCOPY) --only-keep-debug $< $@
|
||||||
|
$(AARCH64_OBJCOPY) --strip-debug $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)%.o: %
|
||||||
|
$(info compiling file: $<)
|
||||||
|
@mkdir -p $(dir ./$(BUILD_DIR)$<)
|
||||||
|
$(AARCH64_CC) $(INCS) $(CFLAGS) -c $< -o $@
|
||||||
|
|
|
@ -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,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
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file arch.h
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ARCH_H_F63C116D_51C9_4E25_9B1F_126833937268
|
||||||
|
#define ARCH_H_F63C116D_51C9_4E25_9B1F_126833937268
|
||||||
|
|
||||||
|
#include <aarch64/aarch64.h>
|
||||||
|
|
||||||
|
#define k_arch_init(...) aarch64_init(__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif /* !ARCH_H */
|
|
@ -0,0 +1,71 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file irq.c
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <aarch64/bcm2837.h>
|
||||||
|
#include "timer.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "irq.h"
|
||||||
|
|
||||||
|
static const char *m_types[] = {
|
||||||
|
"EL1t_SYNC",
|
||||||
|
"EL1t_IRQ",
|
||||||
|
"EL1t_FIQ",
|
||||||
|
"EL1t_ERROR",
|
||||||
|
"EL1h_SYNC",
|
||||||
|
"EL1h_IRQ",
|
||||||
|
"EL1h_FIQ",
|
||||||
|
"EL1h_ERROR",
|
||||||
|
"EL0_64_SYNC",
|
||||||
|
"EL0_64_IRQ",
|
||||||
|
"EL0_64_FIQ",
|
||||||
|
"EL0_64_ERROR",
|
||||||
|
"EL0_32_SYNC",
|
||||||
|
"EL0_32_IRQ",
|
||||||
|
"EL0_32_FIQ",
|
||||||
|
"EL0_32_ERROR"
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
k_irq_enable_controller()
|
||||||
|
{
|
||||||
|
aarch64_set32r(ENABLE_IRQS_1, SYSTEM_TIMER_IRQ_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
k_irq_handler(void)
|
||||||
|
{
|
||||||
|
unsigned int irq = aarch64_get32r(IRQ_PENDING_1);
|
||||||
|
switch(irq) {
|
||||||
|
case SYSTEM_TIMER_IRQ_1:
|
||||||
|
k_timer_irq_handler();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
k_logs("Unhandled irq: ");
|
||||||
|
k_logu(irq, 16);
|
||||||
|
k_logs("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
k_irq_fallback(int type, unsigned long esr, unsigned long address)
|
||||||
|
{
|
||||||
|
k_logs(m_types[type]);
|
||||||
|
k_logs(" -> ESR: ");
|
||||||
|
k_logu(esr, 16);
|
||||||
|
k_logs(", address: ");
|
||||||
|
k_logu(address, 16);
|
||||||
|
k_logs("\n");
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file irq.h
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IRQ_H_037ADD8D_3AAA_4541_A876_843DFF3A59E8
|
||||||
|
#define IRQ_H_037ADD8D_3AAA_4541_A876_843DFF3A59E8
|
||||||
|
|
||||||
|
#include <aarch64/aarch64.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
k_irq_enable_controller(void);
|
||||||
|
|
||||||
|
void
|
||||||
|
k_irq_handler(void);
|
||||||
|
|
||||||
|
void
|
||||||
|
k_irq_fallback(int type, unsigned long esr, unsigned long address);
|
||||||
|
|
||||||
|
#define k_irq_enable(...) aarch64_irq_enable(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define k_irq_disable(...) aarch64_irq_disable(__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif /* !IRQ_H */
|
|
@ -0,0 +1,81 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file log.c
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <device/uart/uart.h>
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
k_log_init(void)
|
||||||
|
{
|
||||||
|
uart_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ki32
|
||||||
|
k_logs(const Ki8 *string)
|
||||||
|
{
|
||||||
|
Ki8 c;
|
||||||
|
const Ki8 *p = string;
|
||||||
|
while((c = *p) != 0) {
|
||||||
|
if (uart_write(c))
|
||||||
|
return -1;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return (Ki32)(p - string);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ki32
|
||||||
|
k_logi(Ki64 value, Ku8 base)
|
||||||
|
{
|
||||||
|
Ki32 result;
|
||||||
|
|
||||||
|
if (value < 0) {
|
||||||
|
if (uart_write('-'))
|
||||||
|
return -1;
|
||||||
|
value = -value;
|
||||||
|
result = 1;
|
||||||
|
} else {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
result += k_logu(value, base);
|
||||||
|
return (result) ? result : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ki32
|
||||||
|
k_logu(Ku64 value, Ku8 base)
|
||||||
|
{
|
||||||
|
Ki32 i = 0, result;
|
||||||
|
Ku8 buffer[64];
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
return (uart_write('0')) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!(i < (sizeof(buffer) / sizeof(buffer[0]))))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
Ku64 r = value % base;
|
||||||
|
buffer[i++] = (r < 0x0A) ? '0' + r : 'A' + r - 0x0A;
|
||||||
|
value /= base;
|
||||||
|
} while (value);
|
||||||
|
|
||||||
|
result = i;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
if (uart_write(buffer[i]))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file print.h
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOG_H_AE38CD54_2822_47A5_AFB1_E785739FA01D
|
||||||
|
#define LOG_H_AE38CD54_2822_47A5_AFB1_E785739FA01D
|
||||||
|
|
||||||
|
#include <core/types.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
k_log_init(void);
|
||||||
|
|
||||||
|
Ki32
|
||||||
|
k_logs(const Ki8 *string);
|
||||||
|
|
||||||
|
Ki32
|
||||||
|
k_logi(Ki64 value, Ku8 base);
|
||||||
|
|
||||||
|
Ki32
|
||||||
|
k_logu(Ku64 value, Ku8 base);
|
||||||
|
|
||||||
|
#endif /* !LOG_H */
|
|
@ -0,0 +1,65 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file main.c
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <core/log.h>
|
||||||
|
#include <core/arch.h>
|
||||||
|
#include <core/irq.h>
|
||||||
|
#include <core/timer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
k_main(void);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
k_main(void)
|
||||||
|
{
|
||||||
|
k_log_init();
|
||||||
|
|
||||||
|
k_logs("Starting Lowe OS (EL");
|
||||||
|
k_logi(aarch64_get_el(), 10);
|
||||||
|
k_logs(")\n");
|
||||||
|
|
||||||
|
if (k_arch_init())
|
||||||
|
goto panic;
|
||||||
|
|
||||||
|
k_timer_init();
|
||||||
|
k_irq_enable_controller();
|
||||||
|
k_irq_enable();
|
||||||
|
|
||||||
|
goto ok;
|
||||||
|
/*
|
||||||
|
k_logs("\tclock");
|
||||||
|
if (k_clock_init())
|
||||||
|
goto panic;
|
||||||
|
|
||||||
|
k_logs(" - ok\n\tscheduler");
|
||||||
|
if (k_scheduler_init())
|
||||||
|
goto panic;
|
||||||
|
|
||||||
|
k_logs(" - ok\n");
|
||||||
|
|
||||||
|
k_scheduler_run();
|
||||||
|
*/
|
||||||
|
|
||||||
|
panic:
|
||||||
|
k_logs(" - ERROR\n");
|
||||||
|
ok:
|
||||||
|
for (;;) {
|
||||||
|
__asm__("WFE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file task.h
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TASK_H_AE13C166_79B5_4256_ABF3_74DF04E1CD18
|
||||||
|
#define TASK_H_AE13C166_79B5_4256_ABF3_74DF04E1CD18
|
||||||
|
|
||||||
|
#include <core/types.h>
|
||||||
|
|
||||||
|
typedef Ku32 KTaskId;
|
||||||
|
typedef void (*KTaskCallback)(void *p_ctx);
|
||||||
|
|
||||||
|
struct k_task {
|
||||||
|
KByte name[K_CONFIG_TASK_MAX_NAME_LEN + 1];
|
||||||
|
KTaskCallback callback;
|
||||||
|
Ku32 *stack;
|
||||||
|
Ku32 stack_size;
|
||||||
|
Ku32 priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
KTaskId
|
||||||
|
k_task_create(struct k_task *p_task, KTaskCallback callback, Ku32 *stack
|
||||||
|
, Ku32 stack_size);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !TASK_H */
|
|
@ -0,0 +1,39 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file timer.c
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <aarch64/aarch64.h>
|
||||||
|
#include <aarch64/bcm2837.h>
|
||||||
|
#include "timer.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
const unsigned int m_interval = 200000;
|
||||||
|
unsigned int m_current = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
k_timer_init(void)
|
||||||
|
{
|
||||||
|
m_current = aarch64_get32r(TIMER_CLO);
|
||||||
|
m_current += m_interval;
|
||||||
|
aarch64_set32r(TIMER_C1, m_current);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
k_timer_irq_handler(void)
|
||||||
|
{
|
||||||
|
m_current += m_interval;
|
||||||
|
aarch64_set32r(TIMER_C1, m_current);
|
||||||
|
aarch64_set32r(TIMER_CS, TIMER_CS_M1);
|
||||||
|
k_logs("Timer interrupt\n");
|
||||||
|
}
|
|
@ -6,29 +6,20 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file main.c
|
* @file timer.h
|
||||||
* @author Ilja Kartašov <ik@lowenware.com>
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
* @see https://lowenware.com/
|
* @see https://lowenware.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uart.h"
|
#ifndef TIMER_H_8D327261_47D6_4832_8DC5_31BF1614A21F
|
||||||
|
#define TIMER_H_8D327261_47D6_4832_8DC5_31BF1614A21F
|
||||||
|
|
||||||
void
|
void
|
||||||
k_main(void);
|
k_timer_init(void);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
k_main(void)
|
k_timer_irq_handler(void);
|
||||||
{
|
|
||||||
uart_init();
|
|
||||||
|
|
||||||
uart_puts((unsigned char *) "Lowe OS\n");
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
__asm__("WFE");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#endif /* !TIMER_H */
|
|
@ -0,0 +1,29 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file types.h
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TYPES_H_BC3DA9C0_C9EE_4853_B5F5_EAA4B801664C
|
||||||
|
#define TYPES_H_BC3DA9C0_C9EE_4853_B5F5_EAA4B801664C
|
||||||
|
|
||||||
|
typedef int KRetCode;
|
||||||
|
|
||||||
|
typedef int Ki32;
|
||||||
|
typedef unsigned int Ku32;
|
||||||
|
typedef long long Ki64;
|
||||||
|
typedef unsigned long long Ku64;
|
||||||
|
typedef char Ki8;
|
||||||
|
typedef unsigned char Ku8;
|
||||||
|
typedef char KByte;
|
||||||
|
|
||||||
|
#endif /* !TYPES_H */
|
|
@ -0,0 +1,47 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file uart.h
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UART_H_8AFC47F9_2953_42C1_A5C1_1AE5A1F52CD0
|
||||||
|
#define UART_H_8AFC47F9_2953_42C1_A5C1_1AE5A1F52CD0
|
||||||
|
|
||||||
|
#include "uart_mini.h"
|
||||||
|
#include "uart_qemu.h"
|
||||||
|
|
||||||
|
#define UART_MINI 0
|
||||||
|
#define UART_QEMU 1
|
||||||
|
|
||||||
|
#ifndef UART_DEFAULT
|
||||||
|
#define UART_DEFAULT UART_QEMU
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UART_DEFAULT == UART_MINI
|
||||||
|
|
||||||
|
#define uart_init(...) uart_mini_init(__VA_ARGS__)
|
||||||
|
#define uart_read(...) uart_mini_read(__VA_ARGS__)
|
||||||
|
#define uart_write(...) uart_mini_write(__VA_ARGS__)
|
||||||
|
|
||||||
|
#elif UART_DEFAULT == UART_QEMU
|
||||||
|
|
||||||
|
#define uart_init(...)
|
||||||
|
#define uart_read(...)
|
||||||
|
#define uart_write(...) uart_qemu_write(__VA_ARGS__)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#warning "Unsopported default UART"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !UART_H */
|
|
@ -0,0 +1,82 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file uart_mini.c
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <aarch64/aarch64.h>
|
||||||
|
#include <aarch64/bcm2837.h>
|
||||||
|
|
||||||
|
#include "uart_mini.h"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
uart_mini_init(void)
|
||||||
|
{
|
||||||
|
unsigned int sel;
|
||||||
|
|
||||||
|
/* Enable UART Mini and its registers*/
|
||||||
|
aarch64_set32r(AUX_ENABLES, 1);
|
||||||
|
/* Disable auto flow control, TX and RX */
|
||||||
|
aarch64_set32r(AUX_MU_CNTL_REG, 0);
|
||||||
|
/* Disable TX and RX interrupts */
|
||||||
|
aarch64_set32r(AUX_MU_IER_REG, 0);
|
||||||
|
/* Set 8bit mode */
|
||||||
|
aarch64_set32r(AUX_MU_LCR_REG, 0);
|
||||||
|
/* Set RTS line HIGH */
|
||||||
|
aarch64_set32r(AUX_MU_MCR_REG, 0);
|
||||||
|
/* Set baud rate 115200 */
|
||||||
|
aarch64_set32r(AUX_MU_BAUD_REG, 0x10E);
|
||||||
|
|
||||||
|
sel = aarch64_get32r(GPFSEL1);
|
||||||
|
/* clean and set ALT5 for GPIO14 */
|
||||||
|
sel &= ~(7 << 12);
|
||||||
|
sel |= (2 << 12);
|
||||||
|
/* clean and set ALT5 for GPIO15 */
|
||||||
|
sel &= ~(7 << 15);
|
||||||
|
sel |= (2 << 15);
|
||||||
|
aarch64_set32r(GPFSEL1, sel);
|
||||||
|
|
||||||
|
aarch64_set32r(GPPUD, 0);
|
||||||
|
aarch64_delay(150);
|
||||||
|
aarch64_set32r(GPPUDCLK0, (1 << 14) | (1 << 15));
|
||||||
|
aarch64_delay(150);
|
||||||
|
aarch64_set32r(GPPUDCLK0, 0);
|
||||||
|
|
||||||
|
/* Enable TX and RX */
|
||||||
|
aarch64_set32r(AUX_MU_CNTL_REG, 0x03);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
uart_mini_write(char c)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
if (aarch64_get32r(AUX_MU_LSR_REG) & 0x20)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
aarch64_set32r(AUX_MU_IO_REG, c);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
uart_mini_read(char *pc)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
if (aarch64_get32r(AUX_MU_LSR_REG) & 0x01)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pc = aarch64_get32r(AUX_MU_IO_REG) & 0xFF;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -6,28 +6,23 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file uart.h
|
* @file uart_mini.h
|
||||||
* @author Ilja Kartašov <ik@lowenware.com>
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
* @see https://lowenware.com/
|
* @see https://lowenware.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UART_H_8AFC47F9_2953_42C1_A5C1_1AE5A1F52CD0
|
#ifndef UART_MINI_H_B0DFA3CF_5B4F_4EB0_B393_391C0069A04F
|
||||||
#define UART_H_8AFC47F9_2953_42C1_A5C1_1AE5A1F52CD0
|
#define UART_MINI_H_B0DFA3CF_5B4F_4EB0_B393_391C0069A04F
|
||||||
|
|
||||||
|
int
|
||||||
|
uart_mini_init(void);
|
||||||
|
|
||||||
#define UART_BASE 0x09000000
|
int
|
||||||
|
uart_mini_write(char c);
|
||||||
|
|
||||||
void
|
int
|
||||||
uart_init(void);
|
uart_mini_read(char *pc);
|
||||||
|
|
||||||
|
#endif /* !UART_MINI_H */
|
||||||
void
|
|
||||||
uart_putc(unsigned char c);
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
uart_puts(const unsigned char *s);
|
|
||||||
|
|
||||||
#endif /* !UART_H */
|
|
|
@ -13,29 +13,18 @@
|
||||||
* @see https://lowenware.com/
|
* @see https://lowenware.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uart.h"
|
#include "uart_qemu.h"
|
||||||
|
|
||||||
|
#define UART_BASE 0x09000000;
|
||||||
|
|
||||||
volatile unsigned int *UART0 = (unsigned int *)UART_BASE;
|
volatile unsigned int *UART0 = (unsigned int *)UART_BASE;
|
||||||
|
|
||||||
|
int
|
||||||
void
|
uart_qemu_write(unsigned char c)
|
||||||
uart_init(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
uart_putc(unsigned char c)
|
|
||||||
{
|
{
|
||||||
*UART0 = (unsigned int) c;
|
*UART0 = (unsigned int) c;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
uart_puts(const unsigned char *s)
|
|
||||||
{
|
|
||||||
while(*s) {
|
|
||||||
*UART0 = (unsigned int) *(s++);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 by Löwenware Ltd
|
||||||
|
* Please, refer LICENSE file for legal information
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file uart_qemu.h
|
||||||
|
* @author Ilja Kartašov <ik@lowenware.com>
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @see https://lowenware.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UART_QEMU_H_EDB39A0E_9BED_4A47_91CD_E804A9B4E8ED
|
||||||
|
#define UART_QEMU_H_EDB39A0E_9BED_4A47_91CD_E804A9B4E8ED
|
||||||
|
|
||||||
|
int
|
||||||
|
uart_qemu_write(unsigned char c);
|
||||||
|
|
||||||
|
#endif /* !UART_QEMU_H */
|
38
sys/core.s
38
sys/core.s
|
@ -1,38 +0,0 @@
|
||||||
# file: core.s
|
|
||||||
# project: Löwe OS
|
|
||||||
# authors: Elias Löwe <elias@lowenware.com>
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.global _core_init
|
|
||||||
.extern _uart_puts
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
_core_init:
|
|
||||||
# set up stack pointer using x30 register
|
|
||||||
LDR x30, =0x40001000
|
|
||||||
MOV sp, x30
|
|
||||||
bl 1f
|
|
||||||
|
|
||||||
1:
|
|
||||||
LDR x0, =some_int
|
|
||||||
BL _uart_putx
|
|
||||||
LDR x0, =greeting
|
|
||||||
BL _uart_puts
|
|
||||||
2:
|
|
||||||
B 2b
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.data
|
|
||||||
|
|
||||||
greeting:
|
|
||||||
.asciz "\nStarting Lowe OS\n"
|
|
||||||
|
|
||||||
|
|
||||||
.equ some_int, 0x1234567890ABCDEF
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
93
sys/uart.s
93
sys/uart.s
|
@ -1,93 +0,0 @@
|
||||||
// file : uart.s
|
|
||||||
// project : Löwe OS
|
|
||||||
// authors : Elias Löwe <elias@lowenware.com>
|
|
||||||
|
|
||||||
// address of UART for virt device in qemu
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.global _uart_putc // print single character uart
|
|
||||||
.global _uart_putx // print integer in HEX format to uart
|
|
||||||
.global _uart_puts // print null-terminated string to uart
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
// helper to avoid extra data moving
|
|
||||||
// @x1 character print
|
|
||||||
uart_putc:
|
|
||||||
STP x2, lr, [sp, -16]!
|
|
||||||
|
|
||||||
MOV x2, 0x09000000 // set UART address
|
|
||||||
STRB w1, [x2] // put character out
|
|
||||||
|
|
||||||
LDP x2, lr, [sp], 16
|
|
||||||
RET
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
// print character to uart
|
|
||||||
// @x0 character print
|
|
||||||
_uart_putc:
|
|
||||||
STR lr, [sp, -16]!
|
|
||||||
|
|
||||||
MOV x1, x0 // set arguments
|
|
||||||
BL uart_putc // put character out
|
|
||||||
|
|
||||||
LDR lr, [sp], 16
|
|
||||||
RET
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// @x0 integer to print
|
|
||||||
_uart_putx:
|
|
||||||
STP lr, x3, [sp, -32]!
|
|
||||||
STP x0, x1, [sp, 16]
|
|
||||||
|
|
||||||
LDR x3, =60 // init bits counter 64-4
|
|
||||||
|
|
||||||
1:
|
|
||||||
LSR x1, x0, x3 // shift to digit
|
|
||||||
AND x1, x1, 0xF // keep only digit
|
|
||||||
CMP x1, 9 // compare it to 9
|
|
||||||
BLS 2f // less or equal
|
|
||||||
ADD x1, x1, 0x37 // turn into ASCII HEX char
|
|
||||||
B 3f // continue to output
|
|
||||||
|
|
||||||
2:
|
|
||||||
ADD x1, x1, 0x30 // turn into ASCII num char
|
|
||||||
|
|
||||||
3:
|
|
||||||
BL uart_putc // output carachter
|
|
||||||
CBZ x3, 0f // if counter == 0 return
|
|
||||||
SUB x3, x3, 4 // otherwise subtract counter by 4
|
|
||||||
B 1b // repeat
|
|
||||||
|
|
||||||
0:
|
|
||||||
LDP lr, x3, [sp], 16
|
|
||||||
LDP x0, x1, [sp], 16
|
|
||||||
RET
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// @x0 pointer to string
|
|
||||||
|
|
||||||
_uart_puts:
|
|
||||||
STR lr, [sp, -16]!
|
|
||||||
STP x0, x1, [sp, -16]!
|
|
||||||
|
|
||||||
1:
|
|
||||||
LDRB w1, [x0], 1 // load byte of string from address in x0
|
|
||||||
CBZ w1, 0f // return if zero
|
|
||||||
BL uart_putc // put charcter out
|
|
||||||
B 1b // loop
|
|
||||||
|
|
||||||
0:
|
|
||||||
LDP x0, x1, [sp], 16
|
|
||||||
LDR lr, [sp], 16
|
|
||||||
RET
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
Loading…
Reference in New Issue