Skip to content

Commit c7e18a1

Browse files
authored
Merge pull request #4 from junqi-xie/lab4
Complete Preemptive Multitasking
2 parents e9030c5 + c450c58 commit c7e18a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+5284
-33
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ set(KERNEL_SYSCALL_PATH "${KERNEL_PATH}/syscall")
4646
set(KERNEL_EXCEPTION_PATH "${KERNEL_PATH}/exception")
4747
set(KERNEL_PROCESS_PATH "${KERNEL_PATH}/process")
4848
set(KERNEL_SCHED_PATH "${KERNEL_PATH}/sched")
49+
set(KERNEL_IPC_PATH "${KERNEL_PATH}/ipc")
50+
set(KERNEL_TESTS_PATH "${KERNEL_PATH}/tests")
4951

5052
include_directories(".")
5153
include_directories("${KERNEL_PATH}")
@@ -56,6 +58,8 @@ add_subdirectory("${KERNEL_PROCESS_PATH}")
5658
add_subdirectory("${KERNEL_SYSCALL_PATH}")
5759
add_subdirectory("${KERNEL_EXCEPTION_PATH}")
5860
add_subdirectory("${KERNEL_SCHED_PATH}")
61+
add_subdirectory("${KERNEL_IPC_PATH}")
62+
add_subdirectory("${KERNEL_TESTS_PATH}")
5963

6064
set(BINARY_KERNEL_IMG_PATH "CMakeFiles/kernel.img.dir")
6165
set(init_object
@@ -79,6 +83,8 @@ add_executable(kernel.img ${files}
7983
$<TARGET_OBJECTS:${PROJECT_NAME}-syscall>
8084
$<TARGET_OBJECTS:${PROJECT_NAME}-sched>
8185
$<TARGET_OBJECTS:${PROJECT_NAME}-exception>
86+
$<TARGET_OBJECTS:${PROJECT_NAME}-ipc>
87+
$<TARGET_OBJECTS:${PROJECT_NAME}-tests>
8288
${USER_PATH}/binary_include.S
8389
)
8490

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ ifndef QEMU
33
QEMU := qemu-system-aarch64
44
endif
55

6-
LAB := 3
6+
LAB := 4
77
# try to generate a unique GDB port
88
GDBPORT := 1234
99
QEMUOPTS = -machine raspi3 -serial null -serial mon:stdio -m size=1G -kernel $(BUILD_DIR)/kernel.img -gdb tcp::1234
@@ -33,6 +33,7 @@ qemu-gdb: $(IMAGES)
3333
gdbport:
3434
@echo $(GDBPORT)
3535

36+
3637
docker: FORCE
3738
./scripts/run_docker.sh
3839

boot/boot.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ extern void el1_mmu_activate(void);
44
extern void init_boot_pt(void);
55

66
extern void start_kernel(void *boot_flag);
7+
extern void secondary_cpu_boot(int cpuid);
78

89
extern char _bss_start;
910
extern char _bss_end;

boot/init_c.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,30 @@ volatile u64 clear_bss_flag = NOT_BSS;
2424
void early_uart_init(void);
2525
void uart_send_string(char *);
2626

27+
static void wakeup_other_cores(void)
28+
{
29+
u64 *addr;
30+
31+
/*
32+
* Set the entry address for non-primary cores.
33+
* 0xe0, 0xe8, 0xf0 are fixed in the firmware (armstub8.bin).
34+
*/
35+
// addr = (u64 *)0xd8;
36+
// *addr = TEXT_OFFSET;
37+
addr = (u64 *) 0xe0;
38+
*addr = TEXT_OFFSET;
39+
addr = (u64 *) 0xe8;
40+
*addr = TEXT_OFFSET;
41+
addr = (u64 *) 0xf0;
42+
*addr = TEXT_OFFSET;
43+
44+
/*
45+
* Instruction sev (set event) for waking up other (non-primary) cores
46+
* that executes wfe instruction.
47+
*/
48+
asm volatile ("sev");
49+
}
50+
2751
static void clear_bss(void)
2852
{
2953
u64 bss_start_addr;
@@ -48,6 +72,8 @@ void init_c(void)
4872
early_uart_init();
4973
uart_send_string("boot: init_c\r\n");
5074

75+
wakeup_other_cores();
76+
5177
/* Initialize Boot Page Table. */
5278
uart_send_string("[BOOT] Install boot page table\r\n");
5379
init_boot_pt();
@@ -62,3 +88,9 @@ void init_c(void)
6288

6389
/* Never reach here */
6490
}
91+
92+
void secondary_init_c(int cpuid)
93+
{
94+
el1_mmu_activate();
95+
secondary_cpu_boot(cpuid);
96+
}

boot/start.S

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
.extern arm64_elX_to_el1
44
.extern boot_cpu_stack
55
.extern secondary_boot_flag
6+
.extern secondary_init_c
67
.extern clear_bss_flag
78
.extern init_c
89

@@ -11,9 +12,36 @@ BEGIN_FUNC(_start)
1112
and x8, x8, #0xFF
1213
cbz x8, primary
1314

14-
/* hang all secondary processors before we intorduce multi-processors */
15-
secondary_hang:
16-
bl secondary_hang
15+
/* Wait for bss clear */
16+
wait_for_bss_clear:
17+
adr x0, clear_bss_flag
18+
ldr x1, [x0]
19+
cmp x1, #0
20+
bne wait_for_bss_clear
21+
22+
/* Turn to el1 from other exception levels. */
23+
bl arm64_elX_to_el1
24+
25+
/* Prepare stack pointer and jump to C. */
26+
mov x1, #0x1000
27+
mul x1, x8, x1
28+
adr x0, boot_cpu_stack
29+
add x0, x0, x1
30+
add x0, x0, #0x1000
31+
mov sp, x0
32+
33+
wait_until_smp_enabled:
34+
/* CPU ID should be stored in x8 from the first line */
35+
mov x1, #8
36+
mul x2, x8, x1
37+
ldr x1, =secondary_boot_flag
38+
add x1, x1, x2
39+
ldr x3, [x1]
40+
cbz x3, wait_until_smp_enabled
41+
42+
/* Set CPU id */
43+
mov x0, x8
44+
bl secondary_init_c
1745

1846
primary:
1947

kernel/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ add_library(${PROJECT_NAME}-arch process
55
main.c
66
monitor.c
77
common/tools.S
8+
common/smp.c
89
common/cpio.c
910
common/elf.c
1011
common/uart.c
12+
common/lock.c
1113
common/printk.c
14+
common/fs.c
1215
common/radix.c
1316
)

kernel/common/fs.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3+
* OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
4+
* You can use this software according to the terms and conditions of the Mulan PSL v1.
5+
* You may obtain a copy of Mulan PSL v1 at:
6+
* http://license.coscl.org.cn/MulanPSL
7+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8+
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9+
* PURPOSE.
10+
* See the Mulan PSL v1 for more details.
11+
*/
12+
#include <common/fs.h>
13+
#include <process/capability.h>
14+
#include <process/process.h>
15+
#include <process/thread.h>
16+
#include <common/uaccess.h>
17+
#include <common/kmalloc.h>
18+
#include <common/mm.h>
19+
#include <mm/vmspace.h>
20+
21+
int sys_fs_load_cpio(u64 vaddr)
22+
{
23+
struct pmobject *cpio_pmo;
24+
struct vmspace *vmspace;
25+
int cpio_pmo_cap, ret;
26+
size_t len;
27+
28+
cpio_pmo = obj_alloc(TYPE_PMO, sizeof(*cpio_pmo));
29+
if (!cpio_pmo) {
30+
return -ENOMEM;
31+
}
32+
len = ROUND_UP(binary_cpio_bin_size, PAGE_SIZE);
33+
pmo_init(cpio_pmo, PMO_DATA, len, 0);
34+
35+
cpio_pmo_cap = cap_alloc(current_process, cpio_pmo, 0);
36+
if (cpio_pmo_cap < 0) {
37+
obj_free(cpio_pmo);
38+
return -ENOMEM;
39+
}
40+
41+
vmspace = obj_get(current_process, VMSPACE_OBJ_ID, TYPE_VMSPACE);
42+
43+
ret = vmspace_map_range(vmspace, vaddr, len, VMR_READ, cpio_pmo);
44+
memcpy((void *)phys_to_virt(cpio_pmo->start),
45+
&binary_cpio_bin_start, binary_cpio_bin_size);
46+
47+
obj_put(vmspace);
48+
return ret;
49+
}

kernel/common/fs.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3+
* OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
4+
* You can use this software according to the terms and conditions of the Mulan PSL v1.
5+
* You may obtain a copy of Mulan PSL v1 at:
6+
* http://license.coscl.org.cn/MulanPSL
7+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8+
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9+
* PURPOSE.
10+
* See the Mulan PSL v1 for more details.
11+
*/
12+
13+
#pragma once
14+
15+
#include <common/types.h>
16+
17+
/* RAMDISK symbol */
18+
extern const char binary_cpio_bin_start;
19+
extern size_t binary_cpio_bin_size;
20+
21+
int sys_fs_load_cpio(u64 vaddr);

kernel/common/lock.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS),
3+
* Shanghai Jiao Tong University (SJTU) OS-Lab-2020 (i.e., ChCore) is licensed
4+
* under the Mulan PSL v1. You can use this software according to the terms and
5+
* conditions of the Mulan PSL v1. You may obtain a copy of Mulan PSL v1 at:
6+
* http://license.coscl.org.cn/MulanPSL
7+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
8+
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
9+
* NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the
10+
* Mulan PSL v1 for more details.
11+
*/
12+
13+
#include <common/smp.h>
14+
#include <common/sync.h>
15+
#include <common/errno.h>
16+
#include <common/kprint.h>
17+
#include <common/lock.h>
18+
#include <common/macro.h>
19+
#include <common/types.h>
20+
21+
struct lock big_kernel_lock;
22+
23+
int lock_init(struct lock *lock)
24+
{
25+
BUG_ON(!lock);
26+
/* Initialize ticket lock */
27+
lock->owner = 0;
28+
lock->next = 0;
29+
return 0;
30+
}
31+
32+
/**
33+
* Lock the ticket lock
34+
* This function will block until the lock is held
35+
*/
36+
void lock(struct lock *lock)
37+
{
38+
u32 lockval = 0, newval = 0, ret = 0;
39+
40+
BUG_ON(!lock);
41+
42+
/**
43+
* The following asm code means:
44+
*
45+
* lock->next = fetch_and_add(1);
46+
* while(lock->next != lock->owner);
47+
*/
48+
asm volatile (" prfm pstl1strm, %3\n"
49+
"1: ldaxr %w0, %3\n"
50+
" add %w1, %w0, #0x1\n"
51+
" stxr %w2, %w1, %3\n"
52+
" cbnz %w2, 1b\n"
53+
"2: ldar %w2, %4\n"
54+
" cmp %w0, %w2\n"
55+
" b.ne 2b\n":"=&r" (lockval), "=&r"(newval),
56+
"=&r"(ret), "+Q"(lock->next)
57+
:"Q"(lock->owner)
58+
:"memory");
59+
}
60+
61+
/**
62+
* Try to lock the ticket lock
63+
* Return 0 if succeed, -1 otherwise
64+
*/
65+
int try_lock(struct lock *lock)
66+
{
67+
68+
u32 lockval = 0, newval = 0, ret = 0, ownerval = 0;
69+
70+
BUG_ON(!lock);
71+
asm volatile (" prfm pstl1strm, %4\n" " ldaxr %w0, %4\n" " ldar %w3, %5\n" " add %w1, %w0, #0x1\n" " cmp %w0, %w3\n" " b.ne 1f\n" " stxr %w2, %w1, %4\n" " cbz %w2, 2f\n" "1: mov %w2, #0xffffffffffffffff\n" /* fail */
72+
" b 3f\n" "2: mov %w2, #0x0\n" /* success */
73+
" dmb ish\n" /* barrier */
74+
"3:\n":"=&r" (lockval), "=&r"(newval), "=&r"(ret),
75+
"=&r"(ownerval), "+Q"(lock->next)
76+
:"Q"(lock->owner)
77+
:"memory");
78+
return ret;
79+
}
80+
81+
/**
82+
* Unlock the ticket lock
83+
*/
84+
void unlock(struct lock *lock)
85+
{
86+
BUG_ON(!lock);
87+
asm volatile ("dmb ish");
88+
89+
/**
90+
* Unlock the ticket lock here
91+
* Your code should be no more than 5 lines
92+
*/
93+
lock->owner++;
94+
}
95+
96+
/**
97+
* Check whether the ticket lock is locked
98+
* Return 1 if locked, 0 otherwise
99+
* Your code should be no more than 5 lines
100+
*/
101+
int is_locked(struct lock *lock)
102+
{
103+
return lock->owner != lock->next;
104+
}
105+
106+
/**
107+
* Initialization of the big kernel lock
108+
*/
109+
void kernel_lock_init(void)
110+
{
111+
lock_init(&big_kernel_lock);
112+
}
113+
114+
/**
115+
* Acquire the big kernel lock
116+
*/
117+
void lock_kernel(void)
118+
{
119+
lock(&big_kernel_lock);
120+
}
121+
122+
/**
123+
* Release the big kernel lock
124+
*/
125+
void unlock_kernel(void)
126+
{
127+
unlock(&big_kernel_lock);
128+
}

kernel/common/lock.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3+
* OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
4+
* You can use this software according to the terms and conditions of the Mulan PSL v1.
5+
* You may obtain a copy of Mulan PSL v1 at:
6+
* http://license.coscl.org.cn/MulanPSL
7+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8+
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9+
* PURPOSE.
10+
* See the Mulan PSL v1 for more details.
11+
*/
12+
13+
#pragma once
14+
15+
#include <common/types.h>
16+
17+
struct lock {
18+
volatile u32 owner;
19+
char pad0[pad_to_cache_line(sizeof(u32))];
20+
21+
volatile u32 next;
22+
char pad1[pad_to_cache_line(sizeof(u32))];
23+
} __attribute__ ((aligned(CACHELINE_SZ)));
24+
25+
int lock_init(struct lock *lock);
26+
void lock(struct lock *lock);
27+
int try_lock(struct lock *lock);
28+
void unlock(struct lock *lock);
29+
int is_locked(struct lock *lock);
30+
31+
/* Global locks */
32+
extern struct lock big_kernel_lock;
33+
void kernel_lock_init(void);
34+
void lock_kernel(void);
35+
void unlock_kernel(void);

0 commit comments

Comments
 (0)