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:
|
.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)
|
||||||
|
@ -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
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 <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
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 <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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
src/kernel.s
29
src/kernel.s
@ -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
|
|
||||||
|
|
||||||
|
@ -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
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