diff --git a/arch/aarch64/kernel/entry.S b/arch/aarch64/kernel/entry.S index 520516587..95ad16c4b 100644 --- a/arch/aarch64/kernel/entry.S +++ b/arch/aarch64/kernel/entry.S @@ -209,7 +209,16 @@ mmu_on: /* Test core ID */ mrs x0, mpidr_el1 + ldr x0, =cpu_online + ldr x0, [x0] + cmp x0, 0 + b.ne smp_start + bl hermit_main + bl halt + +smp: + bl smp_main /* halt */ halt: @@ -273,6 +282,11 @@ _setup_cpu: ret _setup_pgtable: + ldr x0, =cpu_online + ldr x0, [x0] + cmp x0, 0 + b.ne 4f + ldr x0, =kernel_end /* align to a 16KByte boundary */ add x0, x0, 0x10000 @@ -320,6 +334,7 @@ _setup_pgtable: cmp x7, 511*PAGE_SIZE b.lo 3b +4: ret //_calc_offset: diff --git a/arch/aarch64/kernel/tasks.c b/arch/aarch64/kernel/tasks.c index ee18675f7..6fe4d16d4 100644 --- a/arch/aarch64/kernel/tasks.c +++ b/arch/aarch64/kernel/tasks.c @@ -37,6 +37,8 @@ #define TSL_ALIGNMASK ((~0L) << TLS_ALIGNBITS) #define TLS_FLOOR(addr) ((((size_t)addr) + TLS_ALIGNSIZE - 1) & TSL_ALIGNMASK) +extern int smp_main(void); + /* * Note that linker symbols are not variables, they have no memory allocated for * maintaining a value, rather their address is their value. @@ -45,6 +47,7 @@ extern const void tls_start; extern const void tls_end; extern atomic_int32_t cpu_online; +extern atomic_int32_t current_boot_id; static char tls[16][DEFAULT_STACK_SIZE]; static int id = 0; @@ -167,6 +170,19 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor return 0; } +#if MAX_CORES > 1 +int smp_start(void) +{ + int32_t core_id = atomic_int32_read(¤t_boot_id); + + LOG_INFO("Try to initialize processor (local id %d)\n", core_id); + + atomic_int32_inc(&cpu_online); + + return smp_main(); +} +#endif + int is_proxy(void) { return 0; diff --git a/arch/aarch64/kernel/timer.c b/arch/aarch64/kernel/timer.c index 1c39f510a..ed86c1691 100644 --- a/arch/aarch64/kernel/timer.c +++ b/arch/aarch64/kernel/timer.c @@ -175,6 +175,9 @@ int timer_wait(unsigned int ticks) int timer_init(void) { #ifdef DYNAMIC_TICKS + if (boot_tsc) + return 0; + boot_tsc = get_cntpct(); set_per_core(last_tsc, boot_tsc); #endif