Interrupt Vector Table, first tests

Populated a relocated IVT, and tested SWI (Software Interrupt)
This commit is contained in:
giomba 2018-12-30 22:44:14 +01:00
parent 50361931df
commit b431e382e8
11 changed files with 254 additions and 10 deletions

View File

@ -1,6 +1,6 @@
.POSIX: .POSIX:
CCX=arm-none-eabi-g++ 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_HDR=$(wildcard include/*.h)
C_SRC=$(wildcard src/*.cpp) C_SRC=$(wildcard src/*.cpp)

View File

@ -1,8 +1,10 @@
#ifndef DBG_H #ifndef DBG_H
#define DBG_H #define DBG_H
#include <stdint.h>
extern "C" int printk(const char* msg); extern "C" int printk(const char* msg);
extern "C" int printkl(const char* msg); extern "C" int printkl(const char* msg);
extern "C" const char* itoa(uint32_t n);
namespace dbg { namespace dbg {

12
include/interrupt.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef INTERRUPT_H
#define INTERRUPT_H
#include <stdint.h>
extern "C" void setVectorBAR(void);
extern "C" address_t* getVectorBAR(void);
extern "C" void fireswi(void);
#endif

81
include/stdint.h Normal file
View File

@ -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
<http://www.gnu.org/licenses/>. */
/*
* ISO C99: 7.18 Integer types <stdint.h>
*/
/* Exact integral types. */
/* Signed. */
/* There is some amount of overlap with <sys/types.h> 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;

View File

@ -1,4 +1,5 @@
#include <dbg.h> #include <dbg.h>
#include <stdint.h>
/* Never call this function directly: always use the printk, /* Never call this function directly: always use the printk,
* which disables and reenables interrupts */ * which disables and reenables interrupts */
@ -17,3 +18,17 @@ extern "C" int printkl(const char* msg) {
return 0; 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];
}

24
src/fireswi.s Normal file
View File

@ -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

27
src/interrupt.s Normal file
View File

@ -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

View File

@ -1,10 +1,29 @@
#include <dbg.h> #include <dbg.h>
#include <stdint.h>
#include <interrupt.h>
/* KERNEL MAIN */ /* KERNEL MAIN */
extern "C" int main(int argc, char** argv) { extern "C" int main(int argc, char** argv) {
printkl("Welcome to STKARM -- Simple and Trivial Kernel for Advanced Reduced Instruction Set Computer Machines"); 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("EOK -- End of Kernel");
printkl("Now waiting for Godot in an endless loop");
while(true);
return 0; return 0;
} }

View File

@ -1,10 +1,31 @@
.text .text
.align 4 .align 4
.global _start .global _start
_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 bl main
endless_busy_loop: /* Endless busy loop */
cpsid if b .
b endless_busy_loop

View File

@ -1,15 +1,32 @@
ENTRY(_start) 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 SECTIONS
{ {
. = 0x10000; . = 0x40000000;
.text : { .text : ALIGN(0x1000) {
obj/s_vectab.o (.text)
*(.text) *(.text)
} } > m_text
.data : ALIGN(0x1000) { .data : ALIGN(0x1000) {
*(.data) *(.data)
} } > m_data
.bss : ALIGN(0x1000) { .bss : ALIGN(0x1000) {
*(.bss) *(.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 = .;
} }
}

26
src/vectab.s Normal file
View File

@ -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}^