/* * Copyright (c) 2020 AIIT XUOS Lab * XiUOS is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * http://license.coscl.org.cn/MulanPSL2 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ /** * @file main.c * @brief main * @version 3.0 * @author AIIT XUOS Lab * @date 2023.08.25 */ /************************************************* File name: main.c Description: main Others: History: 1. Date: 2023-08-28 Author: AIIT XUOS Lab Modification: 1. first version *************************************************/ /// @todo use hardkernel #include "cortex_a9.h" #include "regssrc.h" #include "kern_init.h" #include "multicores.h" #include "assert.h" #include "task.h" #include "cache_common_ope.h" extern uint32_t _binary_init_start[], _binary_default_fs_start[]; static struct TraceTag hardkernel_tag, softkernel_tag; void configure_cpu(uint32_t cpu) { const unsigned int all_ways = 0xf; disable_strict_align_check(); // Enable branch prediction arm_branch_target_cache_invalidate(); arm_branch_prediction_enable(); // Enable L1 caches // arm_dcache_enable(); // arm_dcache_invalidate(); // arm_icache_enable(); // arm_icache_invalidate(); // Invalidate SCU copy of TAG RAMs scu_secure_invalidate(cpu, all_ways); // Join SMP scu_join_smp(); scu_enable_maintenance_broadcast(); } extern void _boot_start(); void cpu_start_secondary(uint8_t coreNumber) { // Prepare pointers for ROM code. The entry point is always _start, which does some // basic preparatory work and then calls the common_cpu_entry function, which itself // calls the entry point saved in s_core_info. switch (coreNumber) { case 1: HW_SRC_GPR3_WR((uint32_t)&_boot_start); HW_SRC_SCR.B.CORE1_ENABLE = 1; break; case 2: HW_SRC_GPR5_WR((uint32_t)&_boot_start); HW_SRC_SCR.B.CORE2_ENABLE = 1; break; case 3: HW_SRC_GPR7_WR((uint32_t)&_boot_start); HW_SRC_SCR.B.CORE3_ENABLE = 1; break; } } static int core_init_done = 0; int main(void) { /* init tracer */ uint32_t cpu_id = cur_cpuid(); if (cpu_id == 0) { tracer_init(); // init tracer system // clang-format off if (!CreateResourceTag(&hardkernel_tag, RequireRootTag(), "hardkernel", TRACER_OWNER, NULL) || !CreateResourceTag(&softkernel_tag, RequireRootTag(), "softkernel", TRACER_OWNER, NULL)) { ERROR("Failed to create hardkernel owner and softkernel owner.\n"); return -1; } // clang-format on /* init hardkernel */ if (!hardkernel_init(&hardkernel_tag)) { return -1; } spinlock_init(&whole_kernel_lock, "wklock"); } else { spinlock_lock(&whole_kernel_lock); secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag); spinlock_unlock(&whole_kernel_lock); } spinlock_lock(&whole_kernel_lock); if (cpu_id == 0) { /* init softkernel */ if (!softkernel_init(&hardkernel_tag, &softkernel_tag)) { return -1; } show_xizi_bar(); int cpu_count = NR_CPU; for (int i = 1; i < cpu_count; i++) { // start secondary cpus cpu_start_secondary(i); } /* start first task */ char* init_task_param[2] = { "/app/init", 0 }; spawn_embedded_task((char*)_binary_init_start, "init", init_task_param); char* fs_server_task_param[2] = { "/app/fs_server", 0 }; spawn_embedded_task((char*)_binary_default_fs_start, "memfs", fs_server_task_param); } /* start scheduler */ struct SchedulerRightGroup scheduler_rights; assert(AchieveResourceTag(&scheduler_rights.mmu_driver_tag, &hardkernel_tag, "mmu-ac-resource")); assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource")); struct TraceTag main_icache_tag, main_dcache_tag; AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource"); AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource"); struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag); struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag); core_init_done |= (1 << cpu_id); LOG_PRINTF("CPU %d init done\n", cpu_id); spinlock_unlock(&whole_kernel_lock); while (core_init_done != (1 << NR_CPU) - 1) ; DEBUG_PRINTF("%d", cpu_id); // scu_enable(); // configure_cpu(cpu_id); // p_dcache_driver->enable(); // p_icache_driver->enable(); // spinlock_lock(&whole_kernel_lock); // p_dcache_driver->flushall(); // spinlock_unlock(&whole_kernel_lock); // while (true) { // spinlock_lock(&whole_kernel_lock); // DEBUG("CPU: %d\n", cpu_id); // secondary_cpu_load_kern_pgdir(&scheduler_rights.mmu_driver_tag, NULL); // CLEARTLB(0); // p_dcache_driver->flushall(); // spinlock_unlock(&whole_kernel_lock); // } xizi_task_manager.task_scheduler(scheduler_rights); // never reached return 0; } __attribute__((weak)) void _exit(int32_t status) { (void)status; while (1) { ; } }