Skip to content

Commit

Permalink
enabled high interrupt vectors to enable higher-half interrupts
Browse files Browse the repository at this point in the history
Co-authored-by: Victor Roest <victor@xirion.net>
  • Loading branch information
jdonszelmann and Victor Roest committed Mar 8, 2020
1 parent 6e79bbc commit 2307bc6
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/os_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
sudo apt-get install build-essential qemu-system-arm python3 wget texinfo zlib1g-dev -y
- name: Install Toolchain
#if: steps.cache-toolchain.outputs.cache-hit != 'true'
if: steps.cache-toolchain.outputs.cache-hit != 'true'
run: rm -rf toolchain/arm-none-eabi/ && make toolchain

- name: Compile
Expand Down
52 changes: 26 additions & 26 deletions kernel/src/common/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,36 @@

/* copy vector table from wherever QEMU loads the kernel to 0x00 */
void init_vector_table() {
/* This doesn't seem to work well with virtual memory; reverting
* to old method.
extern uint32_t vector_table_start, vector_table_end;
uint32_t *src = &vector_table_start;
uint32_t *dst = (uint32_t *) HIVECTABLE;
while(src < &vector_table_end)
*dst++ = *src++;
*/
// allocate space for the IVR at the high vector location.
vm2_allocate_kernel_page(kernell1PageTable, HIGH_VECTOR_LOCATION, true);

/* Primary Vector Table */
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x0, BRANCH_INSTRUCTION);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x04, BRANCH_INSTRUCTION);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x08, BRANCH_INSTRUCTION);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x0C, BRANCH_INSTRUCTION);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x10, BRANCH_INSTRUCTION);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x14, BRANCH_INSTRUCTION);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x18, BRANCH_INSTRUCTION);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x1C, BRANCH_INSTRUCTION);
mmio_write(HIGH_VECTOR_LOCATION + 0x00, BRANCH_INSTRUCTION);
mmio_write(HIGH_VECTOR_LOCATION + 0x04, BRANCH_INSTRUCTION);
mmio_write(HIGH_VECTOR_LOCATION + 0x08, BRANCH_INSTRUCTION);
mmio_write(HIGH_VECTOR_LOCATION + 0x0C, BRANCH_INSTRUCTION);
mmio_write(HIGH_VECTOR_LOCATION + 0x10, BRANCH_INSTRUCTION);
mmio_write(HIGH_VECTOR_LOCATION + 0x14, BRANCH_INSTRUCTION);
mmio_write(HIGH_VECTOR_LOCATION + 0x18, BRANCH_INSTRUCTION);
mmio_write(HIGH_VECTOR_LOCATION + 0x1C, BRANCH_INSTRUCTION);

/* Secondary Vector Table */
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x20, &reset_handler);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x24, &undef_instruction_handler);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x28, &software_interrupt_handler);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x2C, &prefetch_abort_handler);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x30, &data_abort_handler);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x34, &reserved_handler);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x38, &irq_handler);
mmio_write(KERNEL_VIRTUAL_OFFSET + 0x3C, &fiq_handler);

mmio_write(HIGH_VECTOR_LOCATION + 0x20, &reset_handler);
mmio_write(HIGH_VECTOR_LOCATION + 0x24, &undef_instruction_handler);
mmio_write(HIGH_VECTOR_LOCATION + 0x28, &software_interrupt_handler);
mmio_write(HIGH_VECTOR_LOCATION + 0x2C, &prefetch_abort_handler);
mmio_write(HIGH_VECTOR_LOCATION + 0x30, &data_abort_handler);
mmio_write(HIGH_VECTOR_LOCATION + 0x34, &reserved_handler);
mmio_write(HIGH_VECTOR_LOCATION + 0x38, &irq_handler);
mmio_write(HIGH_VECTOR_LOCATION + 0x3C, &fiq_handler);

/// Enable high vectors (Vectors located at HIGH_VECTOR_LOCATION).
asm volatile (
"mrc p15, 0, r1, c1, c0, 0 \n" // Read p15
"orr r1, %0\n" // Enable High Vector bit
"mcr p15, 0, r1, c1, c0, 0\n" // Set p15
:: "r" (1u << 13u)
);
}

/* handlers */
Expand Down
6 changes: 6 additions & 0 deletions kernel/src/common/startup.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ _Reset:
cmp r1, #0
bne loop

// Move the interrupt vector tables to 0x80000000
ldr r0, =0xE000ED08
ldr r1, =0x80000000
str r1, [r0]


ldr sp, =EARLY_KERNEL_STACK_TOP // Set the kernel/SVC stack
push {r0-r11}

Expand Down
8 changes: 3 additions & 5 deletions kernel/src/drivers/chipset/bcm2836/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@ void bcm2836_timer_init() {

uint32_t freq = get_frequency();

kprintf("control frequency: %i\n", freq);
TRACE("control frequency: %i", freq);
// 1 (milli)second timer
write_interrupt_count_value(freq);

kprintf("value: %i\n", read_interrupt_count_value());
kprintf("value: %i\n", read_interrupt_count_value());
write_interrupt_count_value(freq * 100);

// when the register reaches the count value set above, interrupt.
// TODO: Enable timer
// mmio_write(&bcm2836_registers_base->Core0TimersInterruptControl, VIRTUAL_NONSECURE_TIMER);

// Enable timer interrupts.
Expand Down
6 changes: 4 additions & 2 deletions kernel/src/ds/u8_array_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <test.h>

U8ArrayList * u8a_create(uint32_t initial_cap) {
U8ArrayList * list = kmalloc(sizeof(U8ArrayList));
Expand Down Expand Up @@ -39,14 +40,15 @@ void u8a_set(U8ArrayList * list, uint32_t index, uint8_t data) {
uint32_t u8a_push(U8ArrayList * list, uint8_t data) {

if(list->capacity == 0 || list->length >= list->capacity - 1) {
uint32_t new_size = max((list->capacity + (list->capacity >> 2)), list->capacity + 2);
uint32_t new_size = max((list->capacity + (list->capacity >> 2u)), list->capacity + 2);

assert(new_size > list->capacity)

list->capacity = new_size;

list->array = krealloc(list->array, list->capacity * sizeof(uint8_t));
}

list->array[list->length++] = data;

return list->length;
Expand Down Expand Up @@ -97,4 +99,4 @@ U8ArrayList * u8a_clone(U8ArrayList * arr) {
}

return newarr;
}
}
2 changes: 2 additions & 0 deletions kernel/src/fs/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <stdint.h>
#include <fs.h>

#include <test.h>


const Path root = {
.length = 1,
Expand Down
1 change: 1 addition & 0 deletions kernel/src/fs/test/test_path.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ TEST_CREATE(path_parent_test_4, {
ASSERT(path_contents_equal(p1, p2));
path_free(p1);
path_free(p2);

})

TEST_CREATE(path_parent_test_5, {
Expand Down
8 changes: 6 additions & 2 deletions kernel/src/klibc/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@ uint32_t kmalloc_size(void* ptr) {
// TODO: Implement in-place realloc if the next block is free.
// Resize memory pointed to by ptr to new size
void * krealloc(void *ptr, uint32_t newsize) {
if (ptr == NULL) {
TRACE("[MEM DEBUG] Realloc with nullptr");
return kmalloc(newsize);
}

uint32_t oldsize = kmalloc_size(ptr);


if (newsize == 0) {
kfree(ptr);
return NULL;
} else if (ptr == NULL) {
return kmalloc(newsize);
} else if (newsize <= oldsize) {
return ptr;
} else {
Expand Down
19 changes: 10 additions & 9 deletions kernel/src/vm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

| Address | Description |
| ---------- | ---------------------------------------------------------------------- |
| 0x0000000 | Interrupt Vector Table |
| 0x0004000 | Kernel L1 page table |
| 0x0008000 | Kernel start |
| 0x00000000 | Interrupt Vector Table |
| 0x00004000 | Kernel L1 page table |
| 0x00080000 | Kernel start |
| ... | *Kernel* |
| ... | *Kernel* |
| KERNEL END | Physical Memory Manager starting point |
Expand All @@ -22,16 +22,17 @@

| Address | Description |
| ---------- | ---------------------------------------------------------------------- |
| 0x0000000 | Virtual Process Address Space |
| 0x8000000 | Interrupt Vector Table (remap of the first gigabyte of phys --> virt) |
| 0x8004000 | Kernel page table |
| 0x8008000 | Kernel start |
| 0x00000000 | Virtual Process Address Space |
| 0x80000000 | (start of) remap of physical 0x00000000-0x40000000 |
| 0x80004000 | Kernel page table |
| 0x80008000 | Kernel start |
| ... | *Kernel* |
| ... | *Kernel* |
| KERNEL END | Location of the PMM in virtual address space |
| ... | (Virtual) Physical Memory Manager |
| 0xC000000 | Kernel heap start (growing up) |
| 0xFFFFFFF | MMIO mappings (growing down) |
| 0xC0000000 | Kernel heap start (growing up) |
| 0xFFF00000 | MMIO mappings (growing down) |
| 0xFFFF0000 | High location of the vector table |

***Note:*** Both the MMIO mapping and kernel heap occupy the same gigabyte.
The sum of the two can't exceed 1 gigabyte and when the kernel heap grows to touch the MMIO top, the heap is full.
6 changes: 5 additions & 1 deletion kernel/src/vm/include/vm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,12 @@ extern const size_t __KERNEL_VIRTUAL_OFFSET[];
/// Location of the Kernel's Physical Memory Manager's Info structs. Can grow to a max of 16MiB when using 4GiB RAM.
#define KERNEL_PMM_BASE KERNEL_VIRTUAL_END

// Location of the vector table in memory table.
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABIFJFG.html
#define HIGH_VECTOR_LOCATION 0xFFFF0000

/// From this address down, mmio devices are mapped in the kernel's virtual address space.
#define KERNEL_MMIO_BASE (4 * Gibibyte)
#define KERNEL_MMIO_BASE ((4 * Gibibyte) - (1 * Mebibyte))

/// Address space for the kernel heap, grows towards the mmio
#define KERNEL_HEAP_BASE (3 * Gibibyte)
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/vm/vm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void vm2_start() {

/// Unmap the 1:1 mapped first megabyte which startup.s created to boot to a higher half kernel.
/// We don't need it anymore!
// kernell1PageTable->entries[0] = (L1PagetableEntry){0};
kernell1PageTable->entries[0] = (L1PagetableEntry){0};

/// Map the entire gigabyte (or less on some boards, but never more) physical ram to virtual 2GB-3GB.
/// this includes the kernel, kernel stack, kernel pagetables, process pagetables, pmm etc.
Expand Down

0 comments on commit 2307bc6

Please sign in to comment.