summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrett Weiland <brett_weiland@bpcspace.com>2021-09-24 14:20:20 -0500
committerBrett Weiland <brett_weiland@bpcspace.com>2021-09-24 14:20:20 -0500
commitb62706c9f2ceed65394457ae9b131996a2b29463 (patch)
treee00d7d68f4dcaac07ae8931e0a7871ef34d270d6
parentcf7cd8be60c254b44b444c97dcb238d7cf3afd4c (diff)
palloc/pfree found smp safe
-rw-r--r--README.md12
-rw-r--r--src/debug/gdbinit.gdb1
-rw-r--r--src/include/panic.h1
-rw-r--r--src/include/smp.h30
-rw-r--r--src/include/smp_racetest.h2
-rwxr-xr-xsrc/indigo_osbin45152 -> 0 bytes
-rw-r--r--src/kernel/kernel.c6
-rw-r--r--src/kernel/page.c37
-rw-r--r--src/kernel/panic.c5
-rw-r--r--src/kernel/printf.c2
-rw-r--r--src/kernel/smp.c1
-rw-r--r--src/kernel/smp_racetest.c84
12 files changed, 148 insertions, 33 deletions
diff --git a/README.md b/README.md
index f10c938..0566e9c 100644
--- a/README.md
+++ b/README.md
@@ -20,13 +20,21 @@ With all that out of the way, check out the features.
This project will likely go very slow and take multiple years, as I'm dealing with things such as college and adulting. If there are blatantly obvious bugs, or things look unfinished, I'm still working on them.
Additionally, there's some pretty messy code. I've improved while working on this project, so expect those things to be changed some time down the line.
+# Just completed
+1. palloc()/pfree() is now smp safe
+
# What I'm working on now
-1. Ensuring palloc() and malloc() are smp safe (current)
+1. Ensuring malloc()/free() is smp safe (current)
2. Creating kernel space threads with primitive scheduler
3. VFS filesystem
4. ACPI, PCI
5. ext2 filesystem
6. Userspace processes!!!
7. IO buffering, process waitlists
-8. Improve scheduler
+8. Implement permanent scheduler
9. Let's not get too ahead of ourselves...
+
+# Backlog
+## These are things I want to evencually fix, but don't effect current development
+1. Making the bootloader pass kernel command paramaters from fat filesystem. Bootloader has no filesystem and is part of kernel, this will be hard
+2. Making mutexes more space efficent; right now we use a 16 bit variable for every boolean operation
diff --git a/src/debug/gdbinit.gdb b/src/debug/gdbinit.gdb
index 516deba..b8aa7f5 100644
--- a/src/debug/gdbinit.gdb
+++ b/src/debug/gdbinit.gdb
@@ -3,7 +3,6 @@ symbol-file debug/debug_syms.o
set scheduler-locking step
-hb page.c:357
define cs2bs
print (1 << (5 + $arg0))
diff --git a/src/include/panic.h b/src/include/panic.h
index 43712a2..29e9f85 100644
--- a/src/include/panic.h
+++ b/src/include/panic.h
@@ -53,6 +53,7 @@ void panic(int reason, void *frame_p, struct registers *regs);
#define KERNEL_PANIC_INVALID_IOAPIC_VEC 36
#define KERNEL_PANIC_HPET_REQUIRED 37
#define KERNEL_PANIC_SMP_FAILED 38
+#define KERNEL_PANIC_PALLOC_TOO_LARGE 39
#define DEV_EMAIL "brett_weiland@bpcspace.com"
diff --git a/src/include/smp.h b/src/include/smp.h
index e331036..ba12c76 100644
--- a/src/include/smp.h
+++ b/src/include/smp.h
@@ -7,6 +7,7 @@
void smp_prepare();
extern uint8_t corecount;
+/**
static inline void lock(uint8_t *lock) {
asm("mov al, 1\n"
"spinlock:\n"
@@ -16,30 +17,45 @@ static inline void lock(uint8_t *lock) {
"jnz spinlock\n"
::"r"(lock):"al");
}
+**/
+static inline void lock(uint16_t *mutex) {
+ asm(".spinlock_%=:\n"
+ "lock bts %0, 0\n"
+ "jnc .done_%=\n"
+ "pause\n"
+ "jmp .spinlock_%=\n"
+ ".done_%=:\n"
+ ::"m"(*mutex));
+}
+
+static inline void unlock(uint16_t *mutex) {
+ asm("lock btr %0, 0\n"
+ ::"m"(*mutex));
+}
+
+/**
static inline void unlock(uint8_t *lock) {
asm("lock andb [%0], 0"::"r"(lock));
}
+**/
static inline bool get_set_mutex(uint16_t *mutex) {
bool ret;
asm("lock bts %1, 0\n"
- "jc .mutex_taken\n"
+ "jc .mutex_taken_%=\n"
"mov %0, 0\n"
- "jmp .done\n"
- ".mutex_taken:\n"
+ "jmp .done_%=\n"
+ ".mutex_taken_%=:\n"
"mov %0, 1\n"
- ".done:\n"
+ ".done_%=:\n"
:"=r"(ret)
:"m"(*mutex));
return ret;
}
-
-
//THIS IS ONLY UNTIL WE GET MULTITHREADING SET UP
uint8_t get_coreid();
-#define CREATE_LOTO(name)
#endif
diff --git a/src/include/smp_racetest.h b/src/include/smp_racetest.h
index 25ab7f3..f30c3be 100644
--- a/src/include/smp_racetest.h
+++ b/src/include/smp_racetest.h
@@ -1,6 +1,6 @@
#ifndef testmalloc_header
#define testmalloc_header
-void test_malloc(unsigned int cnt);
+void racetest();
#endif
diff --git a/src/indigo_os b/src/indigo_os
deleted file mode 100755
index 821f97a..0000000
--- a/src/indigo_os
+++ /dev/null
Binary files differ
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 0aa394e..bc5bae8 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -23,7 +23,7 @@
void kmain() {
printf("Kernal started on core %i\n", get_coreid());
- sync_malloc();
+ racetest();
PANIC(KERNEL_PANIC_KERNEL_RETURNED);
}
@@ -49,7 +49,6 @@ void kernel_init() {
init_klog();
init_pmap(pmap_size);
printf("\nKernal started on core 1!\n");
- //test_malloc(100);
find_root_sdp();
@@ -66,6 +65,9 @@ void kernel_init() {
//the rest of this needs to get done before the cores start executing
init_pmap_smp();
+
+
+
smp_unlocked = true;
fix_stack();
diff --git a/src/kernel/page.c b/src/kernel/page.c
index 0b286a4..c79b1fa 100644
--- a/src/kernel/page.c
+++ b/src/kernel/page.c
@@ -100,7 +100,6 @@ void fix_stack() {
:"r"(PA_OFFSET));
while(frame->next != 0) {
- printf("%p\n", frame->function_base);
frame->next = PHYS_TO_VIRT((void *)frame->next);
frame = frame->next;
}
@@ -171,14 +170,13 @@ void debug_pmap() {
}
}
-//TODO I know you don't want to, but you need to thoroughly check this.
void pfree(void *addr, size_t size) {
int blevel = 0;
uint64_t *onbyte;
uint64_t page_bitloc;
int bbitlen;
int lshift;
- pmap_t *pmap = first_pmap;
+ pmap_t *pmap;
/* note: there's no security check to see if the page is actually allocated,
* or if we are freeing the table itself.
@@ -192,10 +190,13 @@ void pfree(void *addr, size_t size) {
return;
}
size /= 0x1000;
- for(; pmap != 0; pmap = pmap->next) {
+ for(pmap = first_pmap; pmap; pmap = pmap->next) {
page_bitloc = (addr - (void *)pmap) / 0x1000;
onbyte = pmap->buddy[0] + (page_bitloc / 64);
- if((addr >= (void *)pmap) && onbyte < pmap->buddy[1]) break;
+ if((addr >= (void *)pmap) && onbyte < pmap->buddy[1]) {
+ lock(&pmap->mutex);
+ break;
+ }
}
while(blevel < MAX_BUDDY_ORDER) {
@@ -241,6 +242,7 @@ void pfree(void *addr, size_t size) {
blevel++;
}
}
+ unlock(&pmap->mutex);
}
@@ -276,13 +278,10 @@ void *palloc(size_t size) {
self_alloc = false;
min_blevel = 63 - __builtin_clzl(size);
if(size & (size - 1)) min_blevel++;
- if(min_blevel > MAX_BUDDY_ORDER - 1) return 0;
+ if(min_blevel > MAX_BUDDY_ORDER - 1) PANIC(KERNEL_PANIC_PALLOC_TOO_LARGE);
}
for(blevel = min_blevel; blevel < MAX_BUDDY_ORDER; blevel++) {
- //for(pmap = first_pmap; pmap != 0; pmap = pmap->next) {
- //while(!unlocked_pmaps_searched ||
- // is_empty(waiting_pmaps[core_id], sizeof(&pmap) * pmap_count)) {
pmap = first_pmap;
while(pmap) {
@@ -329,12 +328,13 @@ void *palloc(size_t size) {
return ret;
}
}
-get_next_pmap:
pmap->mutex = 0;
+get_next_pmap:
if(unlocked_pmaps_searched) {
pmap = 0;
for(searchingp_i = waitingp_i + 1; searchingp_i < pmap_count; searchingp_i++) {
if(waiting_pmaps[waitlist_i(searchingp_i)]) {
+ waitingp_i = searchingp_i;
pmap = waiting_pmaps[waitlist_i(searchingp_i)];
break;
}
@@ -342,6 +342,7 @@ get_next_pmap:
if(!pmap) {
for(searchingp_i = 0; searchingp_i <= waitingp_i; searchingp_i++) {
if(waiting_pmaps[waitlist_i(searchingp_i)]) {
+ waitingp_i = searchingp_i;
pmap = waiting_pmaps[waitlist_i(searchingp_i)];
break;
}
@@ -350,6 +351,7 @@ get_next_pmap:
}
else {
if(!pmap->next) {
+ waitingp_i = 0;
pmap = waiting_pmaps ? waiting_pmaps[waitlist_i(0)] : 0;
unlocked_pmaps_searched = true;
}
@@ -515,3 +517,18 @@ void *init_pmap(size_t pagetable_size) {
}
return pmap;
}
+
+void lock_all_maps() {
+ pmap_t *pmap;
+ for(pmap = first_pmap; pmap; pmap = pmap->next) pmap->mutex = 1;
+ pmap = first_pmap;
+ pmap_count++;
+ for(pmap = first_pmap;;pmap = pmap->next) {
+ if(!pmap->next) {
+ pmap->next = malloc(sizeof(pmap_t));
+ pmap->next->mutex = 1;
+ break;
+ }
+ }
+ first_pmap->mutex = 0;
+}
diff --git a/src/kernel/panic.c b/src/kernel/panic.c
index 06b37da..17a563d 100644
--- a/src/kernel/panic.c
+++ b/src/kernel/panic.c
@@ -6,7 +6,7 @@
#include <isv.h>
#include <smp.h>
-static uint8_t panic_lock = 0;
+static uint16_t panic_lock = 0;
void panic(int reason, void *eframe_p, struct registers *regs) { // will fill with debugging info latter
lock(&panic_lock);
@@ -56,6 +56,9 @@ void panic(int reason, void *eframe_p, struct registers *regs) { // will fill wi
case KERNEL_PANIC_SMP_FAILED:
printf("\nNot all cores booted successfully (see text before panic).\n");
break;
+ case KERNEL_PANIC_PALLOC_TOO_LARGE:
+ printf("\npalloc was called with a size greater then supported.\n");
+ break;
default:
printf("\nUnknown panic code %i\n.", reason);
break;
diff --git a/src/kernel/printf.c b/src/kernel/printf.c
index 62261ec..8e33981 100644
--- a/src/kernel/printf.c
+++ b/src/kernel/printf.c
@@ -873,7 +873,7 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const
///////////////////////////////////////////////////////////////////////////////
-static uint8_t printf_lock = 0;
+static uint16_t printf_lock = 0;
int printf_(const char* format, ...)
{
//BRETT modification
diff --git a/src/kernel/smp.c b/src/kernel/smp.c
index a55fe49..662f9ed 100644
--- a/src/kernel/smp.c
+++ b/src/kernel/smp.c
@@ -101,6 +101,7 @@ void smp_prepare() {
if(cores.apic_id[core_i] == cores.bsp) continue;
stackarray[stack_i].apic_id = cores.apic_id[core_i];
stackarray[stack_i].stack = palloc(0x1000);
+ printf("core %i's stack: %lx\n", core_i, stackarray[stack_i].stack);
stackarray[stack_i].secondary_bsp = (stack_i)? false : true;
stack_i++;
diff --git a/src/kernel/smp_racetest.c b/src/kernel/smp_racetest.c
index f86e030..84321de 100644
--- a/src/kernel/smp_racetest.c
+++ b/src/kernel/smp_racetest.c
@@ -1,3 +1,6 @@
+//Disregard bad code here.
+//I'm going to delete this whole file once I am confident smp is safe.
+
#define CHUNK_SIZE_FROM_INDEX(i) ((1 << ((i) + 5)))
#include <printf.h>
@@ -9,7 +12,7 @@
//will delete later
-static uint8_t lockeroni = 0;
+static uint16_t lockeroni = 0;
void test_malloc(unsigned int cnt) {
void *testchunks[cnt];
@@ -39,14 +42,79 @@ void test_malloc(unsigned int cnt) {
printf("____________________________________\n");
unlock(&lockeroni);
}
-uint8_t cores_waiting = 4;
-void sync_malloc() {
- void *mtest;
+
+#define DEBUG_CORE_CNT 2
+
+uint8_t cores_waiting = DEBUG_CORE_CNT;
+uint8_t cores_waiting_2 = DEBUG_CORE_CNT;
+uint8_t cores_waiting_3 = DEBUG_CORE_CNT;
+uint8_t cores_waiting_4 = DEBUG_CORE_CNT;
+uint8_t cores_waiting_5 = DEBUG_CORE_CNT;
+void *smp_outputs[DEBUG_CORE_CNT];
+
+void racetest() {
+ uint8_t core_id = get_coreid();
+ uint8_t c_check;
+ unsigned int core_i;
+
asm("lock decb [%0]\n"
- "spinlock:\n"
+ "spinlock_%=:\n"
"cmpb [%0], 0\n"
- "jnz spinlock\n"
+ "jnz spinlock_%=\n"
::"m"(cores_waiting));
- mtest = palloc(0x1000);
- printf("Make sure none of these match -> %lx\n", mtest);
+
+ smp_outputs[core_id] = palloc(0x1000);
+ printf("Make sure none of these match (palloc) -> %lx\n", smp_outputs[core_id]);
+ free(smp_outputs[core_id]);
+
+ asm("lock decb [%0]\n"
+ "spinlock_%=:\n"
+ "cmpb [%0], 0\n"
+ "jnz spinlock_%=\n"
+ ::"m"(cores_waiting_2));
+
+ if(core_id == 0) {
+ for(core_i = 0; core_i < DEBUG_CORE_CNT; core_i++) {
+ for(c_check = core_i + 1; c_check < DEBUG_CORE_CNT; c_check++) {
+ if(smp_outputs[core_i] == smp_outputs[c_check]) {
+ printf("TEST FAILED\n");
+ for(;;);
+ }
+ }
+ }
+ printf("TEST PASSED\n");
+ printf("malloc beforehand: \n");
+ debug_heap();
+ }
+
+
+ asm("lock decb [%0]\n"
+ "spinlock_%=:\n"
+ "cmpb [%0], 0\n"
+ "jnz spinlock_%=\n"
+ ::"m"(cores_waiting_3));
+
+
+ smp_outputs[core_id] = malloc(1);
+ printf("Make sure none of these match (malloc) -> %lx\n", smp_outputs[core_id]);
+
+ asm("lock decb [%0]\n"
+ "spinlock_%=:\n"
+ "cmpb [%0], 0\n"
+ "jnz spinlock_%=\n"
+ ::"m"(cores_waiting_4));
+
+ if(core_id == 0) {
+ for(core_i = 0; core_i < DEBUG_CORE_CNT; core_i++) {
+ for(c_check = core_i + 1; c_check < DEBUG_CORE_CNT; c_check++) {
+ if(smp_outputs[core_i] == smp_outputs[c_check]) {
+ printf("TEST FAILED\n");
+ for(;;);
+ }
+ }
+ }
+ printf("TEST PASSED\n");
+ printf("malloc afterhand: \n");
+ debug_heap();
+ }
}