forked from xuos/xiuos
227 lines
7.8 KiB
C
227 lines
7.8 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 hardkerenl_init.c
|
|
* @brief init hardkernel
|
|
* @version 3.0
|
|
* @author AIIT XUOS Lab
|
|
* @date 2023.08.25
|
|
*/
|
|
|
|
/*************************************************
|
|
File name: hardkerenl_init.c
|
|
Description: init hardkernel
|
|
Others:
|
|
History:
|
|
1. Date: 2023-08-28
|
|
Author: AIIT XUOS Lab
|
|
Modification:
|
|
1. first version
|
|
*************************************************/
|
|
#include "kern_init.h"
|
|
|
|
#include "cache_common_ope.h"
|
|
#include "clock_common_op.h"
|
|
#include "mmu_common.h"
|
|
#include "trap_common.h"
|
|
#include "uart_common_ope.h"
|
|
|
|
#include "assert.h"
|
|
#include "pagetable.h"
|
|
#include "spinlock.h"
|
|
|
|
#define KERN_BOOT_DRIVER(n, bi, f) \
|
|
{ \
|
|
n, bi, f \
|
|
}
|
|
|
|
static struct TraceTag hardkernel_tag;
|
|
|
|
static bool xizi_uart_init()
|
|
{
|
|
struct XiziSerialDriver* p_uart_driver = hardkernel_uart_init(&hardkernel_tag);
|
|
if (p_uart_driver == NULL) {
|
|
ERROR("uart driver init failed\n");
|
|
return false;
|
|
}
|
|
|
|
struct TraceTag uart_driver_tag;
|
|
if (!CreateResourceTag(&uart_driver_tag, &hardkernel_tag, "uart-ac-resource", TRACER_HARDKERNEL_AC_RESOURCE, p_uart_driver)) {
|
|
ERROR("Create uart resource failed.\n");
|
|
return false;
|
|
}
|
|
|
|
serial_init(&uart_driver_tag);
|
|
return true;
|
|
}
|
|
|
|
static bool xizi_intr_init()
|
|
{
|
|
/* init intr driver */
|
|
struct XiziTrapDriver* p_intr_driver = hardkernel_intr_init(&hardkernel_tag);
|
|
if (UNLIKELY(p_intr_driver == NULL)) {
|
|
ERROR("intr driver init failed\n");
|
|
return false;
|
|
}
|
|
|
|
struct TraceTag intr_driver_tag = {};
|
|
if (!CreateResourceTag(&intr_driver_tag, &hardkernel_tag, "intr-ac-resource", TRACER_HARDKERNEL_AC_RESOURCE, p_intr_driver)) {
|
|
ERROR("Create intr resource failed.\n");
|
|
return false;
|
|
}
|
|
|
|
/* grant rights to intr dispatcher */
|
|
struct IrqDispatcherRightGroup irq_dispatcher_rights = { .intr_driver_tag = intr_driver_tag };
|
|
if (!intr_distributer_init(&irq_dispatcher_rights)) {
|
|
ERROR("init intr distributer failed.\n");
|
|
return false;
|
|
}
|
|
|
|
/* grant rights to syscall dispatcher */
|
|
struct SwiDispatcherRightGroup swi_dispatcher_rights = { .intr_driver_tag = intr_driver_tag };
|
|
if (!swi_distributer_init(&swi_dispatcher_rights)) {
|
|
ERROR("init syscall distributer failed.\n");
|
|
return false;
|
|
}
|
|
|
|
/* grant rights to spinlock module*/
|
|
if (!module_spinlock_use_intr_init()) {
|
|
ERROR("spinlock init using interrupt failed\n");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool xizi_gpt_init()
|
|
{
|
|
/* init clock driver and create clock driver tag */
|
|
struct XiziClockDriver* p_clock_driver = hardkernel_clock_init(&hardkernel_tag);
|
|
if (UNLIKELY(p_clock_driver == NULL)) {
|
|
ERROR("clock driver init failed\n");
|
|
return false;
|
|
}
|
|
|
|
struct TraceTag clock_driver_tag;
|
|
if (!CreateResourceTag(&clock_driver_tag, &hardkernel_tag, "clock-ac-resource", TRACER_HARDKERNEL_AC_RESOURCE, p_clock_driver)) {
|
|
ERROR("Create clock resource failed.\n");
|
|
return false;
|
|
}
|
|
|
|
/* enable clock interrupt */
|
|
if (!clock_intr_handler_init(&clock_driver_tag)) {
|
|
ERROR("clock interrupt init failed.\n");
|
|
return false;
|
|
}
|
|
// get intr driver tag
|
|
struct TraceTag intr_driver_tag;
|
|
if (!AchieveResourceTag(&intr_driver_tag, &hardkernel_tag, "intr-ac-resource")) {
|
|
ERROR("Achieve intr resource failed.\n");
|
|
return false;
|
|
}
|
|
// register clock handler to intr
|
|
struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&intr_driver_tag);
|
|
p_intr_driver->bind_irq_handler(p_clock_driver->get_clock_int(), xizi_clock_handler);
|
|
p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), 0, 0);
|
|
return true;
|
|
}
|
|
|
|
static bool xizi_cache_init()
|
|
{
|
|
struct TraceTag icache_driver_tag, dcache_driver_tag;
|
|
|
|
struct ICacheDone* p_icache_done = hardkernel_icache_init(&hardkernel_tag);
|
|
if (UNLIKELY(p_icache_done == NULL)) {
|
|
ERROR("icache driver init failed.\n");
|
|
return false;
|
|
}
|
|
if (!CreateResourceTag(&icache_driver_tag, &hardkernel_tag, "icache-ac-resource", TRACER_HARDKERNEL_AC_RESOURCE, p_icache_done)) {
|
|
ERROR("Create icache resource failed.\n");
|
|
return false;
|
|
}
|
|
|
|
struct DCacheDone* p_dcache_done = hardkernel_dcache_init(&hardkernel_tag);
|
|
if (UNLIKELY(p_dcache_done == NULL)) {
|
|
ERROR("dcache driver init failed.\n");
|
|
return false;
|
|
}
|
|
if (!CreateResourceTag(&dcache_driver_tag, &hardkernel_tag, "dcache-ac-resource", TRACER_HARDKERNEL_AC_RESOURCE, p_dcache_done)) {
|
|
ERROR("Create dcache resource failed.\n");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool xizi_mmu_init()
|
|
{
|
|
struct MmuCommonDone* p_mmu_done = hardkernel_mmu_init(&hardkernel_tag, "icache-ac-resource", "dcache-ac-resource");
|
|
if (UNLIKELY(p_mmu_done == NULL)) {
|
|
ERROR("mmu driver init failed\n");
|
|
return false;
|
|
}
|
|
|
|
/* create trace for mmu driver */
|
|
struct TraceTag mmu_driver_tag;
|
|
CreateResourceTag(&mmu_driver_tag, &hardkernel_tag, "mmu-ac-resource", TRACER_HARDKERNEL_AC_RESOURCE, p_mmu_done);
|
|
|
|
return true;
|
|
}
|
|
|
|
struct XiziBootNode hardkernel_init_array[] = {
|
|
KERN_BOOT_DRIVER("uart", "Xizi uart driver initialized successfully.", xizi_uart_init),
|
|
KERN_BOOT_DRIVER("intr", "Xizi interrupt driver initialized successfully.", xizi_intr_init),
|
|
KERN_BOOT_DRIVER("cache", "Xizi cache driver initialized successfully.", xizi_cache_init),
|
|
KERN_BOOT_DRIVER("mmu", "Xizi mmu driver initialized successfully.", xizi_mmu_init),
|
|
KERN_BOOT_DRIVER("clock", "Xizi clock driver initialized successfully.", xizi_gpt_init),
|
|
};
|
|
|
|
bool hardkernel_init(struct TraceTag* _hardkernel_tag)
|
|
{
|
|
hardkernel_tag = *_hardkernel_tag;
|
|
|
|
for (uint32_t i = 0; i < sizeof(hardkernel_init_array) / sizeof(struct XiziBootNode); i++) {
|
|
if (!hardkernel_init_array[i].init()) {
|
|
return false;
|
|
}
|
|
LOG_PRINTF(hardkernel_init_array[i].bootinfo);
|
|
LOG_PRINTF("\n");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag)
|
|
{
|
|
struct TraceTag init_intr_tag, init_icache_tag, init_dcache_tag, init_clock_tag, init_mmu_tag;
|
|
AchieveResourceTag(&init_intr_tag, _hardkernel_tag, "intr-ac-resource");
|
|
AchieveResourceTag(&init_icache_tag, _hardkernel_tag, "icache-ac-resource");
|
|
AchieveResourceTag(&init_dcache_tag, _hardkernel_tag, "dcache-ac-resource");
|
|
AchieveResourceTag(&init_clock_tag, _hardkernel_tag, "clock-ac-resource");
|
|
AchieveResourceTag(&init_mmu_tag, _hardkernel_tag, "mmu-ac-resource");
|
|
struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&init_intr_tag);
|
|
struct ICacheDone* p_icache_driver = (struct ICacheDone*)AchieveResource(&init_icache_tag);
|
|
struct DCacheDone* p_dcache_driver = (struct DCacheDone*)AchieveResource(&init_dcache_tag);
|
|
struct XiziClockDriver* p_clock_driver = (struct XiziClockDriver*)AchieveResource(&init_clock_tag);
|
|
|
|
// secondary cpu init hardwares
|
|
// intr
|
|
p_intr_driver->sys_irq_init(cpu_id);
|
|
p_intr_driver->cpu_irq_disable();
|
|
// cache
|
|
p_icache_driver->enable();
|
|
p_dcache_driver->enable();
|
|
// clock
|
|
p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0);
|
|
// mmu
|
|
secondary_cpu_load_kern_pgdir(&init_mmu_tag, &init_intr_tag);
|
|
return true;
|
|
} |