1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/** @file kernel.c
*
* @brief kernel entry.
*
* @author Hanjie Wu (hanjiew)
* @bug No functional bugs
*/
#include <common_kern.h>
/* libc includes. */
#include <simics.h> /* lprintf() */
#include <stdio.h>
#include <string.h>
/* multiboot header file */
#include <mptable.h>
#include <multiboot.h> /* boot_info */
#include <smp.h>
/* x86 specific includes */
#include <x86/asm.h> /* enable_interrupts() */
#include <x86/cr.h>
#include <assert.h>
#include <common.h>
#include <interrupt.h>
#include <mm.h>
#include <paging.h>
#include <pts.h>
#include <pv.h>
#include <sched.h>
#include <timer.h>
#include <toad.h>
void print_toad();
/**
* @brief entry for a cpu core
* @param cpuid cpuid
*/
static void kernel_smp_entry(int cpuid);
/**
* @brief main function for a cpu core
*/
static void kernel_smp_main();
/** @brief Kernel entrypoint.
*
* This is the entrypoint for the kernel.
*
* @return Does not return
*/
int kernel_main(mbinfo_t* mbinfo, int argc, char** argv, char** envp) {
int smp_good = (smp_init(mbinfo) == 0);
paging_init();
percpu_t percpu;
setup_percpu(&percpu);
thread_t kthread;
process_t kprocess;
setup_kth(&kthread, &kprocess);
set_mapped_phys_page(mapped_phys_pages);
set_mapped_phys_page_pte(mapped_phys_page_ptes);
setup_pts();
idt_init();
mm_init();
timer_init();
pv_init();
print_toad();
const char* init_args[] = {INIT_NAME};
thread_t* init = create_process(INIT_PID, INIT_NAME, 1, init_args);
init_process = init->process;
add_thread(init);
insert_ready_tail(init);
if (smp_good && smp_num_cpus() > 1 && 0) {
/* SMP not enabled */
smp_boot(kernel_smp_entry);
}
kernel_smp_main();
return -1;
}
static void kernel_smp_entry(int cpuid) {
paging_enable();
percpu_t percpu;
setup_percpu(&percpu);
thread_t kthread;
process_t kprocess;
setup_kth(&kthread, &kprocess);
set_mapped_phys_page(mapped_phys_pages + cpuid * PAGE_SIZE);
set_mapped_phys_page_pte(mapped_phys_page_ptes + cpuid);
kernel_smp_main();
}
static void kernel_smp_main() {
const char* idle_args[] = {IDLE_NAME};
thread_t* idle = create_process(IDLE_PID, IDLE_NAME, 1, idle_args);
set_idle(idle);
while (1) {
int old_if = spl_lock(&ready_lock);
thread_t* t = select_next();
yield_to_spl_unlock(t, &ready_lock, old_if);
/* when a thread borrow kthread's stack and free itself, it will return
* here and we continue yielding
*/
}
panic("kthread should not return");
}
|