forked from xuos/xiuos
177 lines
5.1 KiB
C
177 lines
5.1 KiB
C
/*
|
|
* 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();
|
|
|
|
// 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);
|
|
// // p_dcache_driver->enable();
|
|
// // p_dcache_driver->invalidateall();
|
|
// // p_icache_driver->enable();
|
|
// // p_icache_driver->invalidateall();
|
|
// p_dcache_driver->disable();
|
|
// p_icache_driver->disable();
|
|
|
|
// 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"));
|
|
|
|
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)
|
|
;
|
|
xizi_task_manager.task_scheduler(scheduler_rights);
|
|
|
|
// never reached
|
|
return 0;
|
|
}
|
|
|
|
__attribute__((weak)) void _exit(int32_t status)
|
|
{
|
|
(void)status;
|
|
while (1) {
|
|
;
|
|
}
|
|
} |