| 
					
				 | 
			
			
				@@ -13,142 +13,119 @@ static inline void* align_down_to_16byte(void* addr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return (void*)((uint32_t)addr & 0xfffffff0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-thread* current_thread; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-process* current_process; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static bool is_scheduler_ready; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static types::list<process>* processes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static types::list<thread*>* ready_thds; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static inline void create_init_process(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    auto init = processes->emplace_back(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    init->kernel_esp = align_down_to_16byte((char*)k_malloc(THREAD_KERNEL_STACK_SIZE) + THREAD_KERNEL_STACK_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    memset((char*)init->kernel_esp - THREAD_KERNEL_STACK_SIZE, 0x00, THREAD_KERNEL_STACK_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    init->attr.system = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    init->mms = *kernel_mms; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tss.esp0 = (uint32_t)init->kernel_esp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    page_directory_entry* pd = alloc_pd(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    memcpy(pd, mms_get_pd(kernel_mms), PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (auto& item : init->mms) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        item.pd = pd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+thread* current_thread; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+process* current_process; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    auto user_mm = init->mms.emplace_back(mm { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .start = 0x40000000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .attr = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .read = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .write = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .system = 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .pgs = types::kernel_allocator_new<page_arr>(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .pd = pd, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+process::process(process&& val) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    : mms(types::move(val.mms)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    , thds(types::move(val.thds)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (current_process == &val) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current_process = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    auto thd = init->thds.emplace_back(thread { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .eip = (void*)0x40000000U, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .owner = init.ptr(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .regs {}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .eflags {}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .esp = 0x40100000U, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ready_thds->push_back(thd.ptr()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    attr.system = val.attr.system; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    k_esp = val.k_esp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (int i = 0; i < 1 * 1024 * 1024 / PAGE_SIZE; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        k_map(user_mm.ptr(), &empty_page, 1, 1, 0, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto& item : thds) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        item.owner = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    current_process = init.ptr(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    current_thread = thd.ptr(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    asm_switch_pd(pd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // movl $0x01919810, %eax 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // movl $0x00114514, %ebx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // jmp $. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    unsigned char instruction[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        0xb8, 0x10, 0x98, 0x91, 0x01, 0xbb, 0x14, 0x45, 0x11, 0x00, 0xeb, 0xfe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    void* user_mem = (void*)0x40000000U; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    memcpy(user_mem, instruction, sizeof(instruction)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    val.k_esp = nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    val.attr.system = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static inline void create_test_process(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+process::process(void* start_eip, uint8_t* image, size_t image_size, bool system) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    : mms(*kernel_mms) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    , thds {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    , attr { .system = system } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    auto proc = processes->emplace_back(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    proc->attr.system = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    proc->kernel_esp = align_down_to_16byte((char*)k_malloc(THREAD_KERNEL_STACK_SIZE) + THREAD_KERNEL_STACK_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    memset((char*)proc->kernel_esp - THREAD_KERNEL_STACK_SIZE, 0x00, THREAD_KERNEL_STACK_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    proc->mms = *kernel_mms; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    k_esp = align_down_to_16byte((char*)k_malloc(THREAD_KERNEL_STACK_SIZE) + THREAD_KERNEL_STACK_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memset((char*)k_esp - THREAD_KERNEL_STACK_SIZE, 0x00, THREAD_KERNEL_STACK_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     page_directory_entry* pd = alloc_pd(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     memcpy(pd, mms_get_pd(kernel_mms), PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (auto& item : proc->mms) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto& item : mms) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         item.pd = pd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    auto user_mm = proc->mms.emplace_back(mm { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .start = 0x40000000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto user_mm = mms.emplace_back(mm { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: change this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .start = 0x40000000U, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .attr = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             .read = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             .write = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            .system = 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .system = system, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .pgs = types::kernel_allocator_new<page_arr>(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .pd = pd, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    auto thd = proc->thds.emplace_back(thread { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .eip = (void*)0x40000000U, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        .owner = proc.ptr(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto thd = thds.emplace_back(thread { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .eip = start_eip, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .owner = this, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .regs {}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .eflags {}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: change this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .esp = 0x40100000U, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ready_thds->push_back(thd.ptr()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO: change this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for (int i = 0; i < 1 * 1024 * 1024 / PAGE_SIZE; ++i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         k_map(user_mm.ptr(), &empty_page, 1, 1, 0, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    page_directory_entry* init_pd = (page_directory_entry*)p_ptr_to_v_ptr(current_pd()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto* old_pd = reinterpret_cast<page_directory_entry*>(p_ptr_to_v_ptr(current_pd())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto* old_proc = current_process; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto* old_thd = current_thread; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    auto old_proc = current_process; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    auto old_thd = current_thread; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    current_process = proc.ptr(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    current_process = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     current_thread = thd.ptr(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     asm_switch_pd(pd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    unsigned char instruction[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        0xb8, 0x00, 0x81, 0x19, 0x19, 0xbb, 0x00, 0x14, 0x45, 0x11, 0xeb, 0xfe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    void* user_mem = (void*)0x40000000U; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    memcpy(user_mem, instruction, sizeof(instruction)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO: change this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memcpy((void*)0x40000000U, image, image_size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     current_process = old_proc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     current_thread = old_thd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    asm_switch_pd(init_pd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    asm_switch_pd(old_pd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static bool is_scheduler_ready; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void NORETURN init_scheduler() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     processes = types::kernel_allocator_new<types::list<process>>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ready_thds = types::kernel_allocator_new<types::list<thread*>>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tss.ss0 = KERNEL_DATA_SEGMENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // movl $0x01919810, %eax 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // movl $0x00114514, %ebx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // jmp $. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unsigned char instruction1[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        0xb8, 0x10, 0x98, 0x91, 0x01, 0xbb, 0x14, 0x45, 0x11, 0x00, 0xeb, 0xfe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    create_init_process(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    create_test_process(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint8_t instruction2[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        0xb8, 0x00, 0x81, 0x19, 0x19, 0xbb, 0x00, 0x14, 0x45, 0x11, 0xeb, 0xfe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    void* user_space_start = reinterpret_cast<void*>(0x40000000U); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    processes->emplace_back(user_space_start, instruction1, sizeof(instruction1), false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    processes->emplace_back(user_space_start, instruction2, sizeof(instruction2), false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // we need interrupts enabled for cow mapping 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     asm_cli(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto init_process = processes->begin(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    current_process = init_process.ptr(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    current_thread = init_process->thds.begin().ptr(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tss.ss0 = KERNEL_DATA_SEGMENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tss.esp0 = (uint32_t)init_process->k_esp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    asm_switch_pd(mms_get_pd(¤t_process->mms)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     is_scheduler_ready = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    go_user_space((void*)0x40000000U); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    go_user_space(user_space_start); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void context_switch(irq0_data* intrpt_data) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -167,7 +144,7 @@ void context_switch(irq0_data* intrpt_data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     process* pro = thd->owner; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (current_process != pro) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (!pro->attr.system) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            tss.esp0 = (uint32_t)pro->kernel_esp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tss.esp0 = (uint32_t)pro->k_esp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         current_process = pro; 
			 |