Interrupt Vector Table, first tests
Populated a relocated IVT, and tested SWI (Software Interrupt)
This commit is contained in:
parent
50361931df
commit
b431e382e8
2
Makefile
2
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)
|
||||
|
@ -1,8 +1,10 @@
|
||||
#ifndef DBG_H
|
||||
#define DBG_H
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" int printk(const char* msg);
|
||||
extern "C" int printkl(const char* msg);
|
||||
extern "C" const char* itoa(uint32_t n);
|
||||
|
||||
namespace dbg {
|
||||
|
||||
|
12
include/interrupt.h
Normal file
12
include/interrupt.h
Normal 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
81
include/stdint.h
Normal 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;
|
15
src/dbg.cpp
15
src/dbg.cpp
@ -1,4 +1,5 @@
|
||||
#include <dbg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* 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];
|
||||
}
|
||||
|
||||
|
24
src/fireswi.s
Normal file
24
src/fireswi.s
Normal 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
27
src/interrupt.s
Normal 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
|
||||
|
||||
|
@ -1,10 +1,29 @@
|
||||
#include <dbg.h>
|
||||
#include <stdint.h>
|
||||
#include <interrupt.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
29
src/kernel.s
29
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 .
|
||||
|
@ -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 = .;
|
||||
|
||||
}
|
||||
|
||||
|
26
src/vectab.s
Normal file
26
src/vectab.s
Normal 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}^
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user