Skip to content
Snippets Groups Projects
Commit ea06554e authored by Paul Weiß (Poohl)'s avatar Paul Weiß (Poohl)
Browse files

u7 code

parent feab387b
No related branches found
No related tags found
No related merge requests found
#include "kernel/syscalls.h"
#include "kernel/process_mgmt.h"
#include "libs/printf.h"
#include "libs/delay.h"
__attribute__ ((section (".usertext"))) int child(char c, char n, volatile u32* global_counter_p) {
for (u32 local_counter = 0; local_counter < 3; ++local_counter, ++*global_counter_p) {
sys_debug_put_char(c);
sys_debug_put_char(n);
sys_debug_put_char(' ');
sys_debug_put_char(*global_counter_p + '0');
sys_debug_put_char(' ');
sys_debug_put_char(local_counter + '0');
sys_debug_put_char('\r');
sys_debug_put_char('\n');
sys_sleep(0, 1000);
}
}
__attribute__ ((section (".usertext"))) int lead(char c) {
u32 global_counter = 0;
init_thread_state_args child_args = default_init_thread_state_args;
child_args.new_address_space = false;
child_args.args[0] = c;
child_args.args[1] = '2';
child_args.args[2] = &global_counter;
child_args.start = (void_void_func_ptr) child;
char name[7] = {
'c', 'h', 'i', 'l', ' ', c, '2'
};
sys_new_thread(name, &child_args);
name[6] += 1;
child_args.args[1] += 1;
sys_new_thread(name, &child_args);
child(c, '1', &global_counter);
}
__attribute__ ((section (".usertext"))) int u7_demo() {
while (1) {
init_thread_state_args next_thread = default_init_thread_state_args;
next_thread.start = (void_void_func_ptr) lead;
next_thread.args[0] = sys_debug_get_char();
char name[7] = {
'l', 'e', 'a', 'd', ' ', (char) next_thread.args[0]
};
sys_new_thread(name, &next_thread);
}
}
__attribute__ ((section (".usertext"))) int u7_demo();
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#define INTERNAL_SRAM 0x200000 #define INTERNAL_SRAM 0x200000
#define MEGABYTE 0x100000 #define MEGABYTE 0x100000
#define KILOBYTE 1024
#define EXTERNAL_SRAM 0x20000000 #define EXTERNAL_SRAM 0x20000000
#define PROCESS_STACKS 0x20200000 #define PROCESS_STACKS 0x20200000
......
...@@ -3,28 +3,81 @@ ...@@ -3,28 +3,81 @@
#include "mmu.h" #include "mmu.h"
#include "board.h" #include "board.h"
static first_level_pagetable l1table; static first_level_pagetable address_spaces[8];
void init_first_level_pagetable() { typedef struct {
uint buff[8];
uint available;
uint next;
} addsp_queue;
addsp_queue addsp_q;
void init_addsp_queue(addsp_queue* q) {
for (int i = 0; i < 8; ++i)
q->buff[i] = i;
q->available = 7;
q->next = 0;
}
int get_addsp_slot(addsp_queue* q){
if (q->available > 0) {
int ret = q->buff[q->next];
q->available --;
q->next = q->next + 1 & 0x7;
return ret;
} else {
return -1;
}
}
void release_addsp_slot(addsp_queue* q, int slt) {
q->buff[q->next + q->available & 0x7] = slt;
q->available++;
}
void init_mmu_mgmt() {
init_addsp_queue(&addsp_q);
}
int get_address_space() {
int id = get_addsp_slot(&addsp_q);
if (id < 0)
return id;
init_first_level_pagetable(id);
return id;
}
void release_address_space(uint id) {
release_addsp_slot(&addsp_q, id);
}
void init_first_level_pagetable(uint address_space_id) {
// all initiallization applies to domain 0 // all initiallization applies to domain 0
// 1:1 mapping for all memories with priv-only access // 1:1 mapping for all memories with priv-only access
for (uint i = 0; i < 4096; ++i) { for (uint i = 0; i < 4096; ++i) {
l1table.desc[i] = (i << 20) | (AP_RW_NONE << 10) | 0b10; address_spaces[address_space_id].desc[i] = (i << 20) | (AP_RW_NONE << 10) | 0b10;
} }
// No access to Undefined memory even for priv // No access to Undefined memory even for priv
for (uint i = (UNDEF_MEMORY1 >> 20); i < 1519; ++i) for (uint i = (UNDEF_MEMORY1 >> 20); i < 1519; ++i)
l1table.desc[i] = (AP_NONE_NONE << 10) | 0b10; address_spaces[address_space_id].desc[i] = (AP_NONE_NONE << 10) | 0b10;
for (uint i = (UNDEF_MEMORY2 >> 20); i < 249; ++i) for (uint i = (UNDEF_MEMORY2 >> 20); i < 249; ++i)
l1table.desc[i] = (AP_NONE_NONE << 10) | 0b10; address_spaces[address_space_id].desc[i] = (AP_NONE_NONE << 10) | 0b10;
// make userland acessible by users // make userland acessible by users
uint userland_desc = EXTERNAL_SRAM >> 20; uint userland_desc = EXTERNAL_SRAM >> 20;
l1table.desc[userland_desc] = (userland_desc << 20) | (AP_RW_R << 10) | 0b10; address_spaces[address_space_id].desc[userland_desc] = (userland_desc << 20) | (AP_RW_R << 10) | 0b10;
for (uint i = 0; i < 63; ++i) { /*for (uint i = 0; i < 63; ++i) {
l1table.desc[userland_desc + 1 + i] |= (AP_RW_RW << 10); address_spaces[address_space_id].desc[userland_desc + 1 + i] |= (AP_RW_RW << 10);
} }*/
// modify the mapping to switch 1MB of sram with 1MB of undef memory // modify the mapping to switch 1MB of sram with 1MB of undef memory
l1table.desc[(EXTERNAL_SRAM + 17*MEGABYTE) >> 20] = (UNDEF_MEMORY1) | (AP_RW_RW << 10) | 0b10; //address_spaces[address_space_id].desc[(EXTERNAL_SRAM + 17*MEGABYTE) >> 20] = (UNDEF_MEMORY1) | (AP_RW_RW << 10) | 0b10;
l1table.desc[(UNDEF_MEMORY1) >> 20] = (EXTERNAL_SRAM + 17*MEGABYTE) | (AP_RW_RW << 10) | 0b10; //address_spaces[address_space_id].desc[(UNDEF_MEMORY1) >> 20] = (EXTERNAL_SRAM + 17*MEGABYTE) | (AP_RW_RW << 10) | 0b10;
}
int set_ap(uint address_space_id, void* address, uint size, void* dest, uint ap) {
if (size != MEGABYTE)
return -1;
address_spaces[address_space_id].desc[(u32) address >> 20] = (((u32) dest) & (~0 << 20)) | (ap << 10) | 0b10;
} }
void init_mmu() { void init_mmu() {
...@@ -35,7 +88,7 @@ void init_mmu() { ...@@ -35,7 +88,7 @@ void init_mmu() {
asm volatile( // set page-base-table asm volatile( // set page-base-table
"mcr p15, 0, %[table], c2, c0, 0" "mcr p15, 0, %[table], c2, c0, 0"
: :
: [table] "r" (l1table.desc) : [table] "r" (address_spaces[7].desc)
: "memory" : "memory"
); );
asm volatile( // enable mmu asm volatile( // enable mmu
...@@ -44,4 +97,24 @@ void init_mmu() { ...@@ -44,4 +97,24 @@ void init_mmu() {
"mcr p15, 0, r0, c1, c0, 0\n" "mcr p15, 0, r0, c1, c0, 0\n"
: : : "r0", "memory" : : : "r0", "memory"
); );
} }
\ No newline at end of file
void swap_address_space(uint src, uint dest) {
if (src == dest)
return;
asm volatile(
"MCR p15, 0, %0, c8, c7, 0\n" // invalidate caches
"mcr p15, 0, %0, c7, c7, 0\n" // invalidate tlb
:
: "r" (0)
: "memory"
);
asm volatile( // set page-base-table
"mcr p15, 0, %[table], c2, c0, 0\n"
:
: [table] "r" (address_spaces[dest].desc)
: "memory"
);
}
...@@ -11,6 +11,16 @@ typedef struct { ...@@ -11,6 +11,16 @@ typedef struct {
u32 desc[4096]; u32 desc[4096];
} first_level_pagetable __attribute__ ((aligned (16384))); } first_level_pagetable __attribute__ ((aligned (16384)));
void init_first_level_pagetable(); int get_address_space();
void release_address_space(uint id);
void init_first_level_pagetable(uint address_space_id);
int set_ap(uint address_space_id, void* address, uint size, void* dest, uint ap);
void swap_address_space(uint src, uint dest);
void init_mmu_mgmt();
void init_mmu(); void init_mmu();
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "apps/u5_demo.h" #include "apps/u5_demo.h"
#include "kernel/config.h" #include "kernel/config.h"
#include "drivers/mmu.h" #include "drivers/mmu.h"
#include "apps/u6_demo.h" #include "apps/u7_demo.h"
// needed to prevent gcc from optimizing c_entry out. // needed to prevent gcc from optimizing c_entry out.
#pragma GCC push_options #pragma GCC push_options
...@@ -36,6 +36,7 @@ void c_entry(void) { ...@@ -36,6 +36,7 @@ void c_entry(void) {
asm("mrs %0, cpsr" : "=r" (buff) : : ); asm("mrs %0, cpsr" : "=r" (buff) : : );
printf_cpsr(buff); printf_cpsr(buff);
init_mmu_mgmt();
init_process_mgmt(); init_process_mgmt();
...@@ -70,12 +71,12 @@ void c_entry(void) { ...@@ -70,12 +71,12 @@ void c_entry(void) {
//dbgu_write_async(17, "async writing!\r\n"); //dbgu_write_async(17, "async writing!\r\n");
//dbgu_async_write_flush(); //dbgu_async_write_flush();
init_first_level_pagetable(); init_first_level_pagetable(7);
init_mmu(); init_mmu();
init_thread_state_args reader_t = default_init_thread_state_args; init_thread_state_args demo_t = default_init_thread_state_args;
reader_t.start = &brick_it; demo_t.start = &u7_demo;
new_thread("reader", &reader_t); new_thread("demo", &demo_t);
/* interrupt tst loop*/ /* interrupt tst loop*/
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "libs/printf.h" #include "libs/printf.h"
#include "syscalls.h" #include "syscalls.h"
#include "config.h" #include "config.h"
#include "drivers/mmu.h"
#define DEAD 0 #define DEAD 0
#define ALIVE 1 #define ALIVE 1
...@@ -15,7 +16,10 @@ typedef struct { ...@@ -15,7 +16,10 @@ typedef struct {
int state; int state;
char name[8]; char name[8];
u64 sleepy; u64 sleepy;
uint address_space;
cpu_context context; cpu_context context;
uint children;
uint parent;
} tcb; } tcb;
typedef struct { typedef struct {
...@@ -65,8 +69,17 @@ void idle() { ...@@ -65,8 +69,17 @@ void idle() {
void exit(u32* hw_context) { void exit(u32* hw_context) {
// Don't call tis directly frem kernel... Why would you? // Don't call tis directly frem kernel... Why would you?
// if (current.open_handles == 0) // if (current.open_handles == 0)
processes[current].state = DEAD; if (processes[current].children > 0) {
release_tcb_slot(&tcbq, current); processes[current].state = ZOMBIE;
} else {
processes[current].state = DEAD;
if (processes[current].parent) {
processes[processes[current].parent].children -= 1;
} else {
release_address_space(processes[current].address_space);
}
release_tcb_slot(&tcbq, current);
}
if (--real_alive_threads == 1 && keep_interrupts_enabled < get_system_time()) if (--real_alive_threads == 1 && keep_interrupts_enabled < get_system_time())
set_timer_interval(0); set_timer_interval(0);
thread_swap_callback(hw_context); thread_swap_callback(hw_context);
...@@ -93,6 +106,7 @@ static int internal_new_thread_finalizer(char* name, int id) { ...@@ -93,6 +106,7 @@ static int internal_new_thread_finalizer(char* name, int id) {
processes[id].id = id; processes[id].id = id;
processes[id].state = ALIVE; processes[id].state = ALIVE;
processes[id].sleepy = 0; processes[id].sleepy = 0;
processes[id].children = 0;
printf("created thread with id %x\n", id); printf("created thread with id %x\n", id);
if (++real_alive_threads == 2) if (++real_alive_threads == 2)
set_timer_interval(SCHEDULER_TIMESLICE); set_timer_interval(SCHEDULER_TIMESLICE);
...@@ -103,7 +117,22 @@ int new_thread(char* name, init_thread_state_args* args) { ...@@ -103,7 +117,22 @@ int new_thread(char* name, init_thread_state_args* args) {
int id = get_tcb_slot(&tcbq); int id = get_tcb_slot(&tcbq);
if (id < 0) return -1; if (id < 0) return -1;
if (!args->stack) if (!args->stack)
args->stack = (void*) (PROCESS_STACKS - (id - 1) * 0x100000); args->stack = (void*) (PROCESS_STACKS);// - (id - 1) * 0x100000);
if (args->new_address_space) {
processes[id].address_space = get_address_space();
if (processes[id].address_space < 0) {
release_tcb_slot(&tcbq, id);
return -1;
}
printf("new ASP\r\n");
set_ap(processes[id].address_space, PROCESS_STACKS, MEGABYTE, PROCESS_STACKS + (id - 1) * MEGABYTE, AP_RW_RW);
processes[id].parent = 0;
} else {
processes[id].address_space = processes[current].address_space;
args->stack = (void*) (PROCESS_STACKS + id * 64 * KILOBYTE);
processes[current].children += 1;
processes[id].parent = current;
}
cpu_context_init(&processes[id].context, args); cpu_context_init(&processes[id].context, args);
return internal_new_thread_finalizer(name, id); return internal_new_thread_finalizer(name, id);
} }
...@@ -129,9 +158,12 @@ void thread_swap_callback(u32* context) { ...@@ -129,9 +158,12 @@ void thread_swap_callback(u32* context) {
break; break;
// get your chainsaw and your shotgun cause we're going on a zombie-hunt // get your chainsaw and your shotgun cause we're going on a zombie-hunt
if (processes[next].state == ZOMBIE) { if (processes[next].state == ZOMBIE && processes[next].children == 0) {
release_tcb_slot(&tcbq, processes[next].id); release_tcb_slot(&tcbq, processes[next].id);
release_address_space(processes[next].address_space);
processes[next].state = DEAD; processes[next].state = DEAD;
if (processes[next].parent)
processes[processes[next].parent].children -= 1;
printf("BOOM! -> %x\n", processes[next].id); printf("BOOM! -> %x\n", processes[next].id);
} }
} }
...@@ -139,6 +171,7 @@ void thread_swap_callback(u32* context) { ...@@ -139,6 +171,7 @@ void thread_swap_callback(u32* context) {
next = 0; next = 0;
} }
printf("Swap from slot %x to %x (%x total)\r\n", current, next, real_alive_threads); printf("Swap from slot %x to %x (%x total)\r\n", current, next, real_alive_threads);
swap_address_space(processes[current].address_space, processes[next].address_space);
swap(&processes[current].context, context, &processes[next].context); swap(&processes[current].context, context, &processes[next].context);
current = next; current = next;
//print_q(&tcbq); //print_q(&tcbq);
......
...@@ -18,6 +18,7 @@ struct _init_thread_state_args { ...@@ -18,6 +18,7 @@ struct _init_thread_state_args {
u32 args[4]; u32 args[4];
uint stack_size; uint stack_size;
bool is_sys; bool is_sys;
bool new_address_space;
}; };
void init_process_mgmt(); void init_process_mgmt();
...@@ -42,7 +43,8 @@ void unblock_now(uint id, u32* hw_context, u32 return_value); ...@@ -42,7 +43,8 @@ void unblock_now(uint id, u32* hw_context, u32 return_value);
.stack = NULL, \ .stack = NULL, \
.stack_size = 1 << 11, \ .stack_size = 1 << 11, \
.args = {0}, \ .args = {0}, \
.is_sys=false \ .is_sys=false, \
.new_address_space=true \
} }
void sleep(u32* hw_context, u32 delay); void sleep(u32* hw_context, u32 delay);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment