Skip to content

Commit

Permalink
lab4
Browse files Browse the repository at this point in the history
  • Loading branch information
He11oLiu committed Apr 9, 2022
1 parent bef1cf6 commit 3a3ef0f
Show file tree
Hide file tree
Showing 113 changed files with 6,168 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
LAB := 3
LAB := 4

V := @
PROJECT_DIR := .
Expand Down
2 changes: 1 addition & 1 deletion config.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
chcore_config(CHCORE_CROSS_COMPILE STRING "" "Prefix for cross compiling toolchain")
chcore_config(CHCORE_PLAT STRING "" "Target hardware platform")
chcore_config(CHCORE_VERBOSE_BUILD BOOL OFF "Generate verbose build log?")
chcore_config(CHCORE_ROOT_PROGRAM STRING "hello.bin" "First userland program to run")
chcore_config(CHCORE_ROOT_PROGRAM STRING "lab4.bin" "First userland program to run")

chcore_config_include(kernel/config.cmake)
chcore_config_include(userland/config.cmake)
Binary file added docs/assets/IPC-overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
444 changes: 444 additions & 0 deletions docs/实验 4:多核多进程调度与IPC.md

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,20 @@ target_include_directories(
# Add source code directories
add_subdirectory(arch/${CHCORE_ARCH})
add_subdirectory(arch/${CHCORE_ARCH}/plat/${CHCORE_PLAT})
add_subdirectory(ipc)
add_subdirectory(semaphore)
add_subdirectory(irq)
add_subdirectory(lib)
add_subdirectory(mm)
add_subdirectory(object)
add_subdirectory(sched)
add_subdirectory(syscall)

# Kernel testing
if(CHCORE_KERNEL_TEST)
add_subdirectory(tests)
endif()

macro(_incbin _binary_name _binary_path)
set(binary_name ${_binary_name})
set(binary_path ${_binary_path})
Expand Down
34 changes: 32 additions & 2 deletions kernel/arch/aarch64/boot/raspi3/init/init_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
char boot_cpu_stack[PLAT_CPU_NUMBER][INIT_STACK_SIZE] ALIGN(16);

/*
* Initialize these varibles in order to make them not in .bss section.
* Initialize these variables in order to make them not in .bss section.
* So, they will have concrete initial value even on real machine.
*
* Non-primary CPUs will spin until they see the secondary_boot_flag becomes
* non-zero which is set in kernel (see enable_smp_cores).
*
* The secondary_boot_flag is initilized as {NOT_BSS, 0, 0, ...}.
* The secondary_boot_flag is initialized as {NOT_BSS, 0, 0, ...}.
*/
#define NOT_BSS (0xBEEFUL)
long secondary_boot_flag[PLAT_CPU_NUMBER] = {NOT_BSS};
Expand All @@ -23,6 +23,28 @@ volatile u64 clear_bss_flag = NOT_BSS;
void early_uart_init(void);
void uart_send_string(char *);

static void wakeup_other_cores(void)
{
u64 *addr;

/*
* Set the entry address for non-primary cores.
* 0xe0, 0xe8, 0xf0 are fixed in the firmware (armstub8.bin).
*/
addr = (u64 *)0xe0;
*addr = TEXT_OFFSET;
addr = (u64 *)0xe8;
*addr = TEXT_OFFSET;
addr = (u64 *)0xf0;
*addr = TEXT_OFFSET;

/*
* Instruction sev (set event) for waking up other (non-primary) cores
* that executes wfe instruction.
*/
asm volatile("sev");
}

static void clear_bss(void)
{
u64 bss_start_addr;
Expand All @@ -47,6 +69,8 @@ void init_c(void)
early_uart_init();
uart_send_string("boot: init_c\r\n");

wakeup_other_cores();

/* Initialize Boot Page Table. */
uart_send_string("[BOOT] Install boot page table\r\n");
init_boot_pt();
Expand All @@ -61,3 +85,9 @@ void init_c(void)

/* Never reach here */
}

void secondary_init_c(int cpuid)
{
el1_mmu_activate();
secondary_cpu_boot(cpuid);
}
35 changes: 33 additions & 2 deletions kernel/arch/aarch64/boot/raspi3/init/start.S
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,46 @@

.extern arm64_elX_to_el1
.extern boot_cpu_stack
.extern secondary_boot_flag
.extern secondary_init_c
.extern clear_bss_flag
.extern init_c

BEGIN_FUNC(_start)
mrs x8, mpidr_el1
and x8, x8, #0xFF
cbz x8, primary

/* hang all secondary processors before we introduce smp */
b .
/* Wait for bss clear */
wait_for_bss_clear:
adr x0, clear_bss_flag
ldr x1, [x0]
cmp x1, #0
bne wait_for_bss_clear

/* Turn to el1 from other exception levels. */
bl arm64_elX_to_el1

/* Prepare stack pointer and jump to C. */
mov x1, #INIT_STACK_SIZE
mul x1, x8, x1
ldr x0, =boot_cpu_stack
add x0, x0, x1
add x0, x0, #INIT_STACK_SIZE
mov sp, x0

wait_until_smp_enabled:
/* CPU ID should be stored in x8 from the first line */
mov x1, #8
mul x2, x8, x1
ldr x1, =secondary_boot_flag
add x1, x1, x2
ldr x3, [x1]
cbz x3, wait_until_smp_enabled

/* Set CPU id */
mov x0, x8
bl secondary_init_c

primary:
/* Turn to el1 from other exception levels. */
Expand Down
29 changes: 29 additions & 0 deletions kernel/arch/aarch64/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,32 @@ BEGIN_FUNC(start_kernel)

bl main
END_FUNC(start_kernel)

BEGIN_FUNC(secondary_cpu_boot)

/* We store the logical cpuid in TPIDR_EL1 */
msr TPIDR_EL1, x0

mov x1, #KERNEL_STACK_SIZE
mul x2, x0, x1
ldr x3, =kernel_stack
add x2, x2, x3
add x2, x2, KERNEL_STACK_SIZE
mov sp, x2

/*
* Make sure that we don't use low address in the kernel,
* until we have our first user-level process.
*/
mov x2, #0
msr ttbr0_el1, x2
isb

/*
* Call flush_tlb_all here to flush all the cached TLBs for
* the boot time TTBR0_EL1.
*/
bl flush_tlb_all

bl secondary_start
END_FUNC(secondary_cpu_boot)
19 changes: 19 additions & 0 deletions kernel/arch/aarch64/irq/irq_entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "irq_entry.h"

.extern syscall_table
.extern lock_kernel
.extern unlock_kernel

.macro exception_entry label
/* Each entry should be 0x80 aligned */
Expand Down Expand Up @@ -84,6 +86,12 @@ EXPORT(el1_vector)
*/

irq_el1h:
/* Simply reusing exception_enter/exit is OK. */
exception_enter
mov x0, IRQ_EL1h
bl handle_irq
exception_exit /* Lab4: Do not unlock! */

irq_el1t:
fiq_el1t:
fiq_el1h:
Expand Down Expand Up @@ -131,6 +139,9 @@ el0_syscall:
stp x12, x13, [sp, #16 * 6]
stp x14, x15, [sp, #16 * 7]

/* LAB 4 TODO BEGIN */

/* LAB 4 TODO END */

ldp x0, x1, [sp, #16 * 0]
ldp x2, x3, [sp, #16 * 1]
Expand All @@ -149,10 +160,17 @@ el0_syscall:

/* Ret from syscall */
str x0, [sp]

exception_exit


irq_el0_64:
exception_enter
mov x0, IRQ_EL0_64
bl handle_irq
/* should nerver reach here */
b .

error_el0_64:
fiq_el0_64:
sync_el0_32:
Expand All @@ -165,5 +183,6 @@ error_el0_32:
BEGIN_FUNC(__eret_to_thread)
mov sp, x0
dmb ish

exception_exit
END_FUNC(__eret_to_thread)
16 changes: 15 additions & 1 deletion kernel/arch/aarch64/irq/irq_entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ void arch_interrupt_init(void)

void handle_entry_c(int type, u64 esr, u64 address)
{
/* Acquire the big kernel lock, if the exception is not from kernel */
/* LAB 4 TODO BEGIN */

/* LAB 4 TODO END */

/* ec: exception class */
u32 esr_ec = GET_ESR_EL1_EC(esr);

Expand Down Expand Up @@ -131,12 +136,21 @@ void handle_entry_c(int type, u64 esr, u64 address)
/* Interrupt handler for interrupts happening when in EL0. */
void handle_irq(int type)
{
/**
* Lab4
* Acquire the big kernel lock, if :
* The irq is not from the kernel
* The thread being interrupted is an idle thread.
*/
if (type >= SYNC_EL0_64
|| current_thread->thread_ctx->type == TYPE_IDLE) {
/* LAB 4 TODO BEGIN */

/* LAB 4 TODO END */
}

plat_handle_irq();

sched();
eret_to_thread(switch_context());
}

Expand Down
38 changes: 38 additions & 0 deletions kernel/arch/aarch64/machine/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,44 @@ volatile char cpu_status[PLAT_CPU_NUM] = {cpu_hang};

u64 ctr_el0;

void enable_smp_cores(paddr_t boot_flag)
{
int i = 0;
long *secondary_boot_flag;

/* Set current cpu status */
cpu_status[smp_get_cpu_id()] = cpu_run;
secondary_boot_flag = (long *)phys_to_virt(boot_flag);
for (i = 0; i < PLAT_CPU_NUM; i++) {
/* Lab4
* You should set one flag to enable the APs to continue in
* _start. Then, what's the flag?
*/
/* LAB 4 TODO BEGIN */

/* LAB 4 TODO END */

flush_dcache_area((u64)secondary_boot_flag,
(u64)sizeof(u64) * PLAT_CPU_NUM);
asm volatile("dsb sy");

/* Lab4
* The BSP waits for the currently initializing AP finishing
* before activating the next one
*/
/* LAB 4 TODO BEGIN */

/* LAB 4 TODO END */
if (cpu_status[i] == cpu_run)
kinfo("CPU %d is active\n", i);
else
BUG("CPU %d not running!\n", i);
}
/* wait all cpu to boot */
kinfo("All %d CPUs are active\n", PLAT_CPU_NUM);
init_ipi_data();
}

inline u32 smp_get_cpu_id(void)
{
u64 cpuid = 0;
Expand Down
Loading

0 comments on commit 3a3ef0f

Please sign in to comment.