Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 3dc629d

Browse files
committed
Kernel: Half-finished aarch64 implementation.
...And, this is me signing out for a while. It's been fun :)
1 parent 8b43831 commit 3dc629d

22 files changed

+259
-103
lines changed

.github/workflows/build-os.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,18 @@ jobs:
4949
5050
- name: Build duckOS (Release)
5151
run: |
52-
cd build/i386
53-
cmake ../.. -DCMAKE_TOOLCHAIN_FILE=build/i386/CMakeToolchain.txt -DCMAKE_BUILD_TYPE=Release
52+
cd build/i686
53+
cmake ../.. -DCMAKE_TOOLCHAIN_FILE=build/i686/CMakeToolchain.txt -DCMAKE_BUILD_TYPE=Release
5454
make install
5555
5656
- name: Make image
5757
run: |
58-
cd build/i386
58+
cd build/i686
5959
make image
6060
6161
- name: Upload image
6262
uses: actions/upload-artifact@v3
6363
with:
6464
name: Disk Image
65-
path: build/i386/duckOS.img
65+
path: build/i686/duckOS.img
6666

kernel/KernelMapper.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ void KernelMapper::print_stacktrace(size_t ebp) {
136136
//Finally, get the symbol name and print
137137
auto* sym = KernelMapper::get_symbol(stk[1]);
138138
if(sym)
139-
printf("0x%x %s\n", stk[1], sym->name);
139+
printf("0x%lx %s\n", stk[1], sym->name);
140140
else
141-
printf("0x%x\n", stk[1]);
141+
printf("0x%lx\n", stk[1]);
142142

143143
//Continue walking the stack
144144
stk = (size_t*) stk[0];

kernel/api/registers.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#pragma once
55
#include "types.h"
66

7+
#if defined(__i386__)
8+
79
__DECL_BEGIN
810

911
struct ptrace_registers {
@@ -30,4 +32,5 @@ union PTraceRegisters {
3032
};
3133
};
3234

33-
#endif
35+
#endif
36+
#endif // TODO: aarch64

kernel/arch/aarch64/PageDirectory.cpp

-17
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,16 @@
33

44
#include "kernel/kstd/vector.hpp"
55
#include "kernel/tasking/TaskManager.h"
6-
#include "kernel/kstd/defines.h"
7-
#include "kernel/Atomic.h"
86
#include "kernel/memory/MemoryManager.h"
9-
#include "kernel/kstd/KLog.h"
10-
#include "kernel/KernelMapper.h"
11-
#include "kernel/kstd/cstring.h"
127
#include "PageDirectory.h"
138

14-
#include <kernel/memory/PageDirectory.h>
15-
#include "rpi/MMIO.h"
16-
179
using namespace Aarch64;
1810

1911
__attribute__((aligned(4096))) MMU::TableDescriptor __kernel_pgd[512];
2012

2113

2214
void PageDirectory::init_paging() {
2315
setup_kernel_map();
24-
auto map_range = [&](VirtualAddress vstart, VirtualAddress pstart, size_t size, VMProt prot, bool dev) {
25-
size_t start_vpage = vstart / PAGE_SIZE;
26-
size_t start_ppage = pstart / PAGE_SIZE;
27-
size_t num_pages = ((vstart + size) / PAGE_SIZE) - start_vpage;
28-
for(size_t i = 0; i < num_pages; i++)
29-
if(MM.kernel_page_directory.map_page(start_vpage + i, start_ppage + i, prot, dev).is_error())
30-
PANIC("PAGING_INIT_FAIL", "Could not map the kernel when setting up paging.");
31-
};
32-
map_range(RPi::MMIO::phys_base, RPi::MMIO::phys_base, RPi::MMIO::phys_size, VMProt::RW, true);
3316

3417
asm volatile(
3518
"msr ttbr1_el1, %0 \n"

kernel/arch/aarch64/Processor.cpp

+106
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* Copyright © 2016-2024 Byteduck */
33

44
#include "Processor.h"
5+
#include <kernel/tasking/Thread.h>
56

67
void Processor::init() {
78

@@ -44,3 +45,108 @@ void Processor::disable_interrupts() {
4445
void Processor::enable_interrupts() {
4546

4647
}
48+
49+
extern "C" void thread_first_entry() {
50+
asm volatile (
51+
"ldp x0, x1, [sp, #0x00] \n"
52+
"ldp x2, x3, [sp, #0x10] \n"
53+
"ldp x4, x5, [sp, #0x20] \n"
54+
"ldp x6, x7, [sp, #0x30] \n"
55+
"ldp x8, x9, [sp, #0x40] \n"
56+
"ldp x10, x11, [sp, #0x50] \n"
57+
"ldp x12, x13, [sp, #0x60] \n"
58+
"ldp x14, x15, [sp, #0x70] \n"
59+
"ldp x16, x17, [sp, #0x80] \n"
60+
"ldp x18, x19, [sp, #0x90] \n"
61+
"ldp x20, x21, [sp, #0xa0] \n"
62+
"ldp x22, x23, [sp, #0xb0] \n"
63+
"ldp x24, x25, [sp, #0xc0] \n"
64+
"ldp x26, x27, [sp, #0xd0] \n"
65+
"ldp x28, x29, [sp, #0xe0] \n"
66+
"ldr x30, [sp, #0xf0] \n"
67+
"add sp, sp, #248 \n");
68+
printf("Cool!\n");
69+
while(1);
70+
}
71+
72+
ThreadRegisters Processor::initial_thread_registers(bool kernel, size_t entry, size_t sp) {
73+
ThreadRegisters ret {};
74+
ret.elr_el1 = (size_t) thread_first_entry;
75+
ret.gp.x30 = entry;
76+
return ret;
77+
}
78+
79+
void Processor::switch_threads(Thread* old_thread, Thread* new_thread) {
80+
asm volatile (
81+
"sub sp, sp, #248 \n" // Store GP
82+
"stp x0, x1, [sp, #0x00] \n"
83+
"stp x2, x3, [sp, #0x10] \n"
84+
"stp x4, x5, [sp, #0x20] \n"
85+
"stp x6, x7, [sp, #0x30] \n"
86+
"stp x8, x9, [sp, #0x40] \n"
87+
"stp x10, x11, [sp, #0x50] \n"
88+
"stp x12, x13, [sp, #0x60] \n"
89+
"stp x14, x15, [sp, #0x70] \n"
90+
"stp x16, x17, [sp, #0x80] \n"
91+
"stp x18, x19, [sp, #0x90] \n"
92+
"stp x20, x21, [sp, #0xa0] \n"
93+
"stp x22, x23, [sp, #0xb0] \n"
94+
"stp x24, x25, [sp, #0xc0] \n"
95+
"stp x26, x27, [sp, #0xd0] \n"
96+
"stp x28, x29, [sp, #0xe0] \n"
97+
"str x30, [sp, #0xf0] \n"
98+
99+
"mov x0, sp \n" // Switch stacks
100+
"str x0, %[old_sp] \n"
101+
"ldr x0, =1f \n"
102+
"str x0, %[old_ip] \n"
103+
"ldr x0, %[new_sp] \n"
104+
"mov sp, x0 \n"
105+
106+
"ldr x0, %[new_ip] \n"
107+
"br x0 \n"
108+
109+
"1: \n"
110+
"ldp x0, x1, [sp, #0x00] \n" // Load GP
111+
"ldp x2, x3, [sp, #0x10] \n"
112+
"ldp x4, x5, [sp, #0x20] \n"
113+
"ldp x6, x7, [sp, #0x30] \n"
114+
"ldp x8, x9, [sp, #0x40] \n"
115+
"ldp x10, x11, [sp, #0x50] \n"
116+
"ldp x12, x13, [sp, #0x60] \n"
117+
"ldp x14, x15, [sp, #0x70] \n"
118+
"ldp x16, x17, [sp, #0x80] \n"
119+
"ldp x18, x19, [sp, #0x90] \n"
120+
"ldp x20, x21, [sp, #0xa0] \n"
121+
"ldp x22, x23, [sp, #0xb0] \n"
122+
"ldp x24, x25, [sp, #0xc0] \n"
123+
"ldp x26, x27, [sp, #0xd0] \n"
124+
"ldp x28, x29, [sp, #0xe0] \n"
125+
"ldr x30, [sp, #0xf0] \n"
126+
"add sp, sp, #248 \n"
127+
128+
:
129+
"=m"(old_thread),
130+
"=m"(new_thread),
131+
[old_ip] "=m"(old_thread->registers.elr_el1),
132+
[old_sp] "=m"(old_thread->registers.sp)
133+
134+
:
135+
[old_thread] "m"(old_thread),
136+
[new_thread] "m"(new_thread),
137+
[new_ip] "m" (new_thread->registers.elr_el1),
138+
[new_sp] "m" (new_thread->registers.sp)
139+
140+
: "memory", "x0");
141+
}
142+
143+
void Processor::start_initial_thread(Thread* thread) {
144+
asm volatile (
145+
"ldr x0, %[new_sp] \n"
146+
"mov sp, x0 \n"
147+
"ldr x0, =thread_first_entry \n"
148+
"br x0 \n"
149+
150+
:: [new_sp] "m"(thread->registers.sp) : "x0");
151+
ASSERT(false);
152+
}

kernel/arch/aarch64/Processor.h

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#pragma once
55

66
#include <kernel/interrupt/IRQHandler.h>
7+
#include <kernel/kstd/Arc.h>
8+
9+
class Thread;
710

811
class Processor {
912
public:
@@ -18,4 +21,7 @@ class Processor {
1821
static void send_eoi(int irq);
1922
static void disable_interrupts();
2023
static void enable_interrupts();
24+
static ThreadRegisters initial_thread_registers(bool kernel, size_t entry, size_t user_stack);
25+
static void switch_threads(Thread* old_thread, Thread* new_thread);
26+
static void start_initial_thread(Thread* thread);
2127
};

kernel/arch/aarch64/registers.h

+52
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,57 @@ namespace Aarch64::Regs {
9797
return ret;
9898
}
9999
};
100+
101+
union GPRegisters {
102+
uint64_t regs[31];
103+
struct {
104+
uint64_t x0;
105+
uint64_t x1;
106+
uint64_t x2;
107+
uint64_t x3;
108+
uint64_t x4;
109+
uint64_t x5;
110+
uint64_t x6;
111+
uint64_t x7;
112+
uint64_t x8;
113+
uint64_t x9;
114+
uint64_t x10;
115+
uint64_t x11;
116+
uint64_t x12;
117+
uint64_t x13;
118+
uint64_t x14;
119+
uint64_t x15;
120+
uint64_t x16;
121+
uint64_t x17;
122+
uint64_t x18;
123+
uint64_t x19;
124+
uint64_t x20;
125+
uint64_t x21;
126+
uint64_t x22;
127+
uint64_t x23;
128+
uint64_t x24;
129+
uint64_t x25;
130+
uint64_t x26;
131+
uint64_t x27;
132+
uint64_t x28;
133+
uint64_t x29;
134+
uint64_t x30;
135+
};
136+
};
100137
}
138+
139+
struct ISRRegisters {};
140+
struct ThreadRegisters {
141+
Aarch64::Regs::GPRegisters gp;
142+
uint64_t sp;
143+
uint64_t spsr_el1;
144+
uint64_t elr_el1;
145+
uint64_t tpidr_el0;
146+
uint64_t ttbr0_el1;
147+
};
148+
struct IRQRegisters {};
149+
struct TrapFrame {
150+
TrapFrame* prev;
151+
};
152+
101153
#endif

kernel/arch/i386/Processor.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "isr.h"
99
#include "irq.h"
1010
#include "idt.h"
11+
#include <kernel/tasking/TaskManager.h>
1112

1213
char Processor::s_vendor[sizeof(uint32_t) * 3 + 1];
1314
CPUFeatures Processor::s_features = {};
@@ -90,3 +91,29 @@ void Processor::disable_interrupts() {
9091
void Processor::enable_interrupts() {
9192
asm volatile ("sti");
9293
}
94+
95+
ThreadRegisters Processor::initial_thread_registers(bool kernel, size_t entry, size_t user_stack) {
96+
ThreadRegisters registers;
97+
registers.iret.eflags = 0x202;
98+
registers.iret.cs = kernel ? 0x8 : 0x1B;
99+
registers.iret.eip = entry;
100+
registers.gp.eax = 0;
101+
registers.gp.ebx = 0;
102+
registers.gp.ecx = 0;
103+
registers.gp.edx = 0;
104+
registers.gp.ebp = user_stack;
105+
registers.gp.edi = 0;
106+
registers.gp.esi = 0;
107+
if (kernel) {
108+
registers.seg.ds = 0x10; // ds
109+
registers.seg.es = 0x10; // es
110+
registers.seg.fs = 0x10; // fs
111+
registers.seg.gs = 0x10; // gs
112+
} else {
113+
registers.seg.ds = 0x23; // ds
114+
registers.seg.es = 0x23; // es
115+
registers.seg.fs = 0x23; // fs
116+
registers.seg.gs = 0x23; // gs
117+
}
118+
return registers;
119+
}

kernel/arch/i386/Processor.h

+4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55

66
#include "../../api/stdint.h"
77
#include "CPUID.h"
8+
#include "registers.h"
9+
#include <kernel/kstd/Arc.h>
810

911
class IRQHandler;
12+
class Thread;
1013

1114
class Processor {
1215
public:
@@ -25,6 +28,7 @@ class Processor {
2528
static void send_eoi(int irq);
2629
static void disable_interrupts();
2730
static void enable_interrupts();
31+
static ThreadRegisters initial_thread_registers(bool kernel, size_t entry, size_t user_stack);
2832

2933

3034
private:

kernel/arch/i386/isr.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include <kernel/tasking/Thread.h>
2929
#include <kernel/tasking/Process.h>
3030
#include <kernel/KernelMapper.h>
31-
#include <kernel/arch/i386/registers.h>
31+
#include <kernel/arch/registers.h>
3232

3333
namespace Interrupt {
3434
TSS fault_tss;

kernel/arch/registers.h

+2
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55

66
#if defined(__i386__)
77
#include "i386/registers.h"
8+
#elif defined(__aarch64__)
9+
#include "aarch64/registers.h"
810
#endif

kernel/interrupt/IRQHandler.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#pragma once
2121

2222
#include <kernel/kstd/kstddef.h>
23-
#include <kernel/arch/i386/registers.h>
23+
#include <kernel/arch/registers.h>
2424

2525
class IRQHandler {
2626
public:

kernel/memory/Memory.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include "../kstd/kstddef.h"
77
#include "../api/page_size.h"
8-
#include <kernel/arch/i386/registers.h>
8+
#include <kernel/arch/registers.h>
99

1010
#if defined(__i386__)
1111
#define HIGHER_HALF 0xC0000000

0 commit comments

Comments
 (0)