xiuos/Ubiquitous/XiZi_AIoT/softkernel/main.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) {
;
}
}