From b431e382e825c89d0b703303db653c2bf762be51 Mon Sep 17 00:00:00 2001 From: giomba Date: Sun, 30 Dec 2018 22:44:14 +0100 Subject: [PATCH] Interrupt Vector Table, first tests Populated a relocated IVT, and tested SWI (Software Interrupt) --- Makefile | 2 +- include/dbg.h | 2 ++ include/interrupt.h | 12 +++++++ include/stdint.h | 81 +++++++++++++++++++++++++++++++++++++++++++++ src/dbg.cpp | 15 +++++++++ src/fireswi.s | 24 ++++++++++++++ src/interrupt.s | 27 +++++++++++++++ src/kernel.cpp | 19 +++++++++++ src/kernel.s | 29 +++++++++++++--- src/linker.ld | 27 ++++++++++++--- src/vectab.s | 26 +++++++++++++++ 11 files changed, 254 insertions(+), 10 deletions(-) create mode 100644 include/interrupt.h create mode 100644 include/stdint.h create mode 100644 src/fireswi.s create mode 100644 src/interrupt.s create mode 100644 src/vectab.s diff --git a/Makefile b/Makefile index 206aa90..33d23c7 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .POSIX: CCX=arm-none-eabi-g++ -CCFLAGS=-c -Wall -fno-stack-protector -ffreestanding -fno-exceptions -march=armv7-a -nostdlib -Iinclude -g +CCFLAGS=-c -Wall -fno-stack-protector -ffreestanding -fno-exceptions -march=armv7-a -mno-unaligned-access -nostdlib -Iinclude -g C_HDR=$(wildcard include/*.h) C_SRC=$(wildcard src/*.cpp) diff --git a/include/dbg.h b/include/dbg.h index a71d8fe..d40ec7d 100644 --- a/include/dbg.h +++ b/include/dbg.h @@ -1,8 +1,10 @@ #ifndef DBG_H #define DBG_H +#include extern "C" int printk(const char* msg); extern "C" int printkl(const char* msg); +extern "C" const char* itoa(uint32_t n); namespace dbg { diff --git a/include/interrupt.h b/include/interrupt.h new file mode 100644 index 0000000..4f31bcf --- /dev/null +++ b/include/interrupt.h @@ -0,0 +1,12 @@ +#ifndef INTERRUPT_H +#define INTERRUPT_H + +#include + +extern "C" void setVectorBAR(void); +extern "C" address_t* getVectorBAR(void); + +extern "C" void fireswi(void); + + +#endif diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 0000000..977463a --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,81 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* + * ISO C99: 7.18 Integer types + */ + +/* Exact integral types. */ + +/* Signed. */ + +/* There is some amount of overlap with as known by inet code */ +#ifndef __int8_t_defined +# define __int8_t_defined +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +# if __WORDSIZE == 64 +typedef long int int64_t; +# else +__extension__ +typedef long long int int64_t; +# endif +#endif + +/* Unsigned. */ +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +#ifndef __uint32_t_defined +typedef unsigned int uint32_t; +# define __uint32_t_defined +#endif +#if __WORDSIZE == 64 +typedef unsigned long int uint64_t; +#else +__extension__ +typedef unsigned long long int uint64_t; +#endif + + +/* Small types. */ + +/* Signed. */ +typedef signed char int_least8_t; +typedef short int int_least16_t; +typedef int int_least32_t; +#if __WORDSIZE == 64 +typedef long int int_least64_t; +#else +__extension__ +typedef long long int int_least64_t; +#endif + +/* Unsigned. */ +typedef unsigned char uint_least8_t; +typedef unsigned short int uint_least16_t; +typedef unsigned int uint_least32_t; +#if __WORDSIZE == 64 +typedef unsigned long int uint_least64_t; +#else +__extension__ +typedef unsigned long long int uint_least64_t; +#endif + +/* Pointers */ +/* Suggested use address_t* only */ +typedef char address_t; diff --git a/src/dbg.cpp b/src/dbg.cpp index 9344e2b..490eea7 100644 --- a/src/dbg.cpp +++ b/src/dbg.cpp @@ -1,4 +1,5 @@ #include +#include /* Never call this function directly: always use the printk, * which disables and reenables interrupts */ @@ -17,3 +18,17 @@ extern "C" int printkl(const char* msg) { return 0; } +static char string[11]; +/* TODO: WARNING: this is not thread safe!! */ +extern "C" const char* itoa(uint32_t n) { + string[10] = '\0'; + string[0] = '0'; string[1] = 'x'; + + for (short i = 0; i < 8; ++i) { + string[9 - i] = "0123456789abcdef"[n & 0xF]; + n = n >> 4; + } + + return &string[0]; +} + diff --git a/src/fireswi.s b/src/fireswi.s new file mode 100644 index 0000000..6583201 --- /dev/null +++ b/src/fireswi.s @@ -0,0 +1,24 @@ +/* + Example SWI (Software Interrupt) + also known as SVC (go to SuperVisor) +*/ +.data +calledme: +.string "fireswi() has been called\0" +doneme: +.string "fireswi() has done\0" + +.text +.global fireswi +fireswi: + push {lr} + + ldr r0, =calledme + bl printkl + swi #8 + ldr r0, =doneme + bl printkl + + pop {lr} + mov pc, lr + diff --git a/src/interrupt.s b/src/interrupt.s new file mode 100644 index 0000000..cd296df --- /dev/null +++ b/src/interrupt.s @@ -0,0 +1,27 @@ +.text + +.global setVectorBAR +setVectorBAR: + /* Disable interrupts */ + cpsid if + + /* Enable BAR remapping (clears bit 13 of SCTLR) */ + mrc p15, 0, r0, c1, c0, 0 + and r0, #0xffffdfff + mcr p15, 0, r0, c1, c0, 0 + + /* Sets VBAR with custom vector table's address */ + ldr r0, =vectab + mcr p15, 0, r0, c12, c0, 0 + + /* Re-Enables interrupts */ + cpsie if + + mov pc, lr + +.global getVectorBAR +getVectorBAR: + mrc p15, 0, r0, c12, c0, 0 + mov pc, lr + + diff --git a/src/kernel.cpp b/src/kernel.cpp index 2e8ff0e..0ec1484 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -1,10 +1,29 @@ #include +#include +#include /* KERNEL MAIN */ extern "C" int main(int argc, char** argv) { printkl("Welcome to STKARM -- Simple and Trivial Kernel for Advanced Reduced Instruction Set Computer Machines"); + setVectorBAR(); + uint32_t bar = (uint32_t)getVectorBAR(); + printk("BAR is now at "); + printkl(itoa(bar)); + + uint32_t* table = (uint32_t*)(bar); + printkl("Vector table content:"); + for (short i = 0; i < 8; ++i) { + printk(itoa(i)); printk("\t"); + printkl(itoa(table[i])); + } + + printkl("Now firing software interrupt..."); + fireswi(); + printkl("EOK -- End of Kernel"); + printkl("Now waiting for Godot in an endless loop"); + while(true); return 0; } diff --git a/src/kernel.s b/src/kernel.s index 55d3b33..17f93bb 100644 --- a/src/kernel.s +++ b/src/kernel.s @@ -1,10 +1,31 @@ .text + .align 4 .global _start _start: + /* Initialize stack pointers */ + + ldr sp, =stack_svc + + cps #0x1b + ldr sp, =stack_und + cps #0x17 + ldr sp, =stack_abt + cps #0x12 + ldr sp, =stack_irq + cps #0x11 + ldr sp, =stack_fiq + + // Leave in sys mode + cps #0x1f + ldr sp, =stack_sys + +// Leave in usr mode +// cps #0x10 +// ldr sp, =stack_usr + + /* C-Main */ bl main -endless_busy_loop: - cpsid if - b endless_busy_loop - + /* Endless busy loop */ + b . diff --git a/src/linker.ld b/src/linker.ld index e7c803b..c17192b 100644 --- a/src/linker.ld +++ b/src/linker.ld @@ -1,15 +1,32 @@ ENTRY(_start) +MEMORY { + m_text (RX) : ORIGIN = 0x40000000, LENGTH = 16M + m_data (RW) : ORIGIN = 0x41000000, LENGTH = 16M + m_stack (RW) : ORIGIN = 0x42000000, LENGTH = 16M +} + SECTIONS { - . = 0x10000; - .text : { + . = 0x40000000; + .text : ALIGN(0x1000) { + obj/s_vectab.o (.text) *(.text) - } + } > m_text .data : ALIGN(0x1000) { *(.data) - } + } > m_data .bss : ALIGN(0x1000) { *(.bss) - } + } > m_data + + . = ALIGN(0x100); stack_svc = .; + . = . + 0x100; stack_und = .; + . = . + 0x100; stack_abt = .; + . = . + 0x100; stack_irq = .; + . = . + 0x100; stack_fiq = .; + . = . + 0x100; stack_sys = .; + . = . + 0x100; stack_usr = .; + } + diff --git a/src/vectab.s b/src/vectab.s new file mode 100644 index 0000000..8d56744 --- /dev/null +++ b/src/vectab.s @@ -0,0 +1,26 @@ +.data +swimsg: +.string "Hello. I am the sample SWI handler! =)\0" + +.text +.align 4 +.global vectab +vectab: + b _start + ldr pc, =swi_handler + ldr pc, =swi_handler + ldr pc, =swi_handler + ldr pc, =swi_handler + ldr pc, =swi_handler + ldr pc, =swi_handler + ldr pc, =swi_handler + +swi_handler: + stmfd sp!, {lr} + + ldr r0, =swimsg + bl printkl + + ldmfd sp!, {pc}^ + +