Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/main/main.c

    r597fa24 r128359eb  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
    32 * Copyright (c) 2001-2004 Jakub Jermar
    43 * All rights reserved.
     
    5352#include <stdio.h>
    5453#include <panic.h>
     54#include <assert.h>
    5555#include <config.h>
    5656#include <time/clock.h>
     
    8080#include <arch/arch.h>
    8181#include <arch.h>
     82#include <arch/faddr.h>
    8283#include <ipc/ipc.h>
    8384#include <macros.h>
     
    110111CHECK_INT_TYPE(64);
    111112
    112 task_t *kernel_task;
    113 
    114113/** Global configuration structure. */
    115114config_t config = {
     
    133132};
    134133
    135 static context_t ctx;
    136 
    137 // NOTE: All kernel stacks must be aligned to STACK_SIZE, see CURRENT.
    138 static const size_t bootstrap_stack_size = STACK_SIZE;
    139 static _Alignas(STACK_SIZE) uint8_t bootstrap_stack[STACK_SIZE];
    140 
    141 /* Just a convenient value for some assembly code. */
    142 uint8_t *const bootstrap_stack_top = bootstrap_stack + STACK_SIZE;
     134context_t ctx;
     135
     136/** Lowest safe stack virtual address. */
     137uintptr_t stack_safe = 0;
    143138
    144139/*
     
    175170            ALIGN_UP((uintptr_t) kdata_end - config.base, PAGE_SIZE);
    176171
    177         context_create(&ctx, main_bsp_separated_stack,
    178             bootstrap_stack, bootstrap_stack_size);
     172        /*
     173         * NOTE: All kernel stacks must be aligned to STACK_SIZE,
     174         *       see CURRENT.
     175         */
     176
     177        /* Place the stack after the kernel, init and ballocs. */
     178        config.stack_base =
     179            ALIGN_UP(config.base + config.kernel_size, STACK_SIZE);
     180        config.stack_size = STACK_SIZE;
     181
     182        /* Avoid placing stack on top of init */
     183        size_t i;
     184        for (i = 0; i < init.cnt; i++) {
     185                uintptr_t p = init.tasks[i].paddr + init.tasks[i].size;
     186                uintptr_t bottom = PA2KA(ALIGN_UP(p, STACK_SIZE));
     187
     188                if (config.stack_base < bottom)
     189                        config.stack_base = bottom;
     190        }
     191
     192        /* Avoid placing stack on top of boot allocations. */
     193        if (ballocs.size) {
     194                uintptr_t bottom =
     195                    ALIGN_UP(ballocs.base + ballocs.size, STACK_SIZE);
     196                if (config.stack_base < bottom)
     197                        config.stack_base = bottom;
     198        }
     199
     200        if (config.stack_base < stack_safe)
     201                config.stack_base = ALIGN_UP(stack_safe, STACK_SIZE);
     202
     203        context_save(&ctx);
     204        context_set(&ctx, FADDR(main_bsp_separated_stack),
     205            config.stack_base, STACK_SIZE);
    179206        context_restore(&ctx);
    180207        /* not reached */
     
    193220        version_print();
    194221
    195         LOG("\nconfig.base=%p config.kernel_size=%zu",
    196             (void *) config.base, config.kernel_size);
     222        LOG("\nconfig.base=%p config.kernel_size=%zu"
     223            "\nconfig.stack_base=%p config.stack_size=%zu",
     224            (void *) config.base, config.kernel_size,
     225            (void *) config.stack_base, config.stack_size);
    197226
    198227#ifdef CONFIG_KCONSOLE
     
    275304                panic("Cannot create kernel task.");
    276305
    277         kernel_task = kernel;
    278 
    279306        /*
    280307         * Create the first thread.
     
    284311        if (!kinit_thread)
    285312                panic("Cannot create kinit thread.");
    286         thread_start(kinit_thread);
    287         thread_detach(kinit_thread);
    288 
    289         /*
    290          * This call to scheduler_run() will return to kinit,
     313        thread_ready(kinit_thread);
     314
     315        /*
     316         * This call to scheduler() will return to kinit,
    291317         * starting the thread of kernel threads.
    292318         */
    293         current_copy(CURRENT, (current_t *) CPU_LOCAL->stack);
    294         context_replace(scheduler_run, CPU_LOCAL->stack, STACK_SIZE);
     319        scheduler();
    295320        /* not reached */
    296321}
     
    332357        ARCH_OP(post_cpu_init);
    333358
     359        current_copy(CURRENT, (current_t *) CPU->stack);
     360
    334361        /*
    335362         * If we woke kmp up before we left the kernel stack, we could
     
    337364         * switch to this cpu's private stack prior to waking kmp up.
    338365         */
    339         current_copy(CURRENT, (current_t *) CPU_LOCAL->stack);
    340         context_replace(main_ap_separated_stack, CPU_LOCAL->stack, STACK_SIZE);
     366        context_save(&CPU->saved_context);
     367        context_set(&CPU->saved_context, FADDR(main_ap_separated_stack),
     368            (uintptr_t) CPU->stack, STACK_SIZE);
     369        context_restore(&CPU->saved_context);
    341370        /* not reached */
    342371}
     
    354383        timeout_init();
    355384
    356         semaphore_up(&ap_completion_semaphore);
    357         scheduler_run();
     385        waitq_wakeup(&ap_completion_wq, WAKEUP_FIRST);
     386        scheduler();
    358387        /* not reached */
    359388}
Note: See TracChangeset for help on using the changeset viewer.