Support smp for imx6q-sabrelite.

This commit is contained in:
TXuian 2024-03-21 14:54:52 +08:00
parent 620965dc2c
commit 0f5527d73a
21 changed files with 257 additions and 57 deletions

View File

@ -193,4 +193,6 @@ __attribute__((__always_inline__)) static inline void arch_set_return(struct tra
tf->r0 = (uint32_t)ret;
}
void cpu_start_secondary(uint8_t cpu_id);
void start_smp_cache_broadcast(int cpu_id);
#endif

View File

@ -1,3 +1,8 @@
SRC_FILES := ivt.c dcd.c imx6q_lowlevel_init.S cortexA9.S boot.S
SRC_FILES := ivt.c \
dcd.c \
boot.S \
imx6q_lowlevel_init.S \
cortexA9.S \
smp.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2010-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file smp.c
* @brief start multicore
* @version 3.0
* @author AIIT XUOS Lab
* @date 2024.03.10
*/
/*************************************************
File name: smp.c
Description:
Others:
History:
1. Date: 2024-03-10
Author: AIIT XUOS Lab
Modification:
1. No modifications
*************************************************/
#include "cortex_a9.h"
#include "regssrc.h"
extern void _boot_start();
void cpu_start_secondary(uint8_t cpu_id)
{
// 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 (cpu_id) {
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;
default:
break;
}
}
void start_smp_cache_broadcast(int cpu_id)
{
return;
}

View File

@ -1,3 +1,3 @@
SRC_FILES := boot.S cpu_init.S xil-crt0.S cortexA9.S
SRC_FILES := boot.S cpu_init.S xil-crt0.S cortexA9.S smp.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2010-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file smp.c
* @brief start multicore
* @version 3.0
* @author AIIT XUOS Lab
* @date 2024.03.10
*/
/*************************************************
File name: smp.c
Description:
Others:
History:
1. Date: 2024-03-10
Author: AIIT XUOS Lab
Modification:
1. No modifications
*************************************************/
#include "cortex_a9.h"
extern void _boot_start();
void cpu_start_secondary(uint8_t cpu_id)
{
return;
}
void start_smp_cache_broadcast(int cpu_id)
{
return;
}

View File

@ -109,7 +109,7 @@ void dabort_handler(struct trapframe* r)
LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs);
_abort_reason(dfs);
dump_tf(r);
sys_exit();
sys_exit(cur_cpu()->task);
context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler);
} else { // Exception occured in Kernel space: panic
LOG("program counter: 0x%x caused\n", r->pc);
@ -136,7 +136,7 @@ void iabort_handler(struct trapframe* r)
LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs);
_abort_reason(ifs);
dump_tf(r);
sys_exit();
sys_exit(cur_cpu()->task);
context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler);
} else { // Exception occured in Kernel space: panic
LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task);

View File

@ -87,6 +87,8 @@ void handle_fiq(void)
static void _sys_irq_init(int cpu_id)
{
init_cpu_mode_stacks(cpu_id);
if (cpu_id == 0) {
/* load exception vectors */
volatile uint32_t* vector_base = &_vector_start;
@ -101,8 +103,6 @@ static void _sys_irq_init(int cpu_id)
vector_base[7] = (uint32_t)handle_fiq; // FIQ
}
init_cpu_mode_stacks(cpu_id);
/* active hardware irq responser */
XScuGic_Config* gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
if (NULL == gic_config) {
@ -244,7 +244,7 @@ static struct XiziTrapDriver xizi_trap_driver = {
struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag)
{
xizi_trap_driver.sys_irq_init();
xizi_trap_driver.sys_irq_init(0);
xizi_trap_driver.cpu_irq_enable();
return &xizi_trap_driver;
}

View File

@ -58,6 +58,11 @@ int yield()
return syscall(SYSCALL_YIELD, 0, 0, 0, 0);
}
int kill(int pid)
{
return syscall(SYSCALL_KILL, (intptr_t)pid, 0, 0, 0);
}
int register_server(char* name)
{
return syscall(SYSCALL_SERVER, (intptr_t)name, 0, 0, 0);

View File

@ -30,6 +30,8 @@
#define SYSCALL_EXEC 9 // run elf using current task
#define SYSCALL_SYS_STATE 10 // run system state
#define SYSCALL_REGISTER_IRQ 11 //
#define SYSCALL_KILL 12 // kill the task by id
// clang-format on
typedef enum {
@ -57,6 +59,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
int exit();
int yield();
int kill(int pid);
int register_server(char* name);
int session(char* path, int capacity, struct Session* user_session);
int poll_session(struct Session* userland_session_arr, int arr_capacity);

View File

@ -58,6 +58,11 @@ int yield()
return syscall(SYSCALL_YIELD, 0, 0, 0, 0);
}
int kill(int pid)
{
return syscall(SYSCALL_KILL, (intptr_t)pid, 0, 0, 0);
}
int register_server(char* name)
{
return syscall(SYSCALL_SERVER, (intptr_t)name, 0, 0, 0);

View File

@ -30,6 +30,8 @@
#define SYSCALL_EXEC 9 // run elf using current task
#define SYSCALL_SYS_STATE 10 // run system state
#define SYSCALL_REGISTER_IRQ 11 //
#define SYSCALL_KILL 12 // kill the task by id
// clang-format on
typedef enum {
@ -57,6 +59,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
int exit();
int yield();
int kill(int pid);
int register_server(char* name);
int session(char* path, int capacity, struct Session* user_session);
int poll_session(struct Session* userland_session_arr, int arr_capacity);

View File

@ -1725,6 +1725,11 @@ int shellRun(Shell* shell, const char* cmd)
}
}
void shellKill(int pid)
{
kill(pid);
}
/**
* @brief ls ()
*/

View File

@ -36,6 +36,7 @@ extern void shellMkdir(const char* path);
extern void shellRm(const char* path);
extern void shellCat(const char* path);
extern void shellKill(int pid);
extern void shellShowTasks();
extern void shellShowMemInfo();
extern void shellShowCpusInfo();
@ -97,8 +98,11 @@ const ShellCommand shellCommandList[] = {
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
sh, SHELL_AGENCY_FUNC_NAME(shellRun), run command directly),
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
kill, shellKill, kill task by id),
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
ls, shellLs, ls files),
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
cd, shellCd, go to target path),
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,

View File

@ -44,6 +44,8 @@ Modification:
#define SYSCALL_EXEC 9 // run elf using current task
#define SYSCALL_SYS_STATE 10 // run system state
#define SYSCALL_REGISTER_IRQ 11 //
#define SYSCALL_KILL 12 // kill the task by id
// clang-format on
#ifndef __ASSEMBLER__
@ -77,8 +79,9 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs
int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4);
int sys_spawn(char* img_start, char* name, char** argv);
int sys_exit();
int sys_exit(struct TaskMicroDescriptor* ptask);
int sys_yield();
int sys_kill(int id);
int sys_register_as_server(char* name);
int sys_connect_session(char* path, int capacity, struct Session* user_session);

View File

@ -28,8 +28,6 @@ Modification:
1. first version
*************************************************/
/// @todo use hardkernel
#include "cortex_a9.h"
#include "regssrc.h"
#include "kern_init.h"
#include "multicores.h"
@ -37,37 +35,9 @@ Modification:
#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;
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;
default:
break;
}
}
static int core_init_done = 0;
int main(void)
{
@ -126,6 +96,7 @@ int main(void)
while (core_init_done != (1 << NR_CPU) - 1)
;
start_smp_cache_broadcast(cpu_id);
xizi_task_manager.task_scheduler(scheduler_rights);
// never reached

View File

@ -9,6 +9,7 @@ SRC_FILES := syscall.c \
sys_register_irq.c \
sys_exit.c \
sys_state.c \
sys_mmap.c
sys_mmap.c \
sys_kill.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -36,20 +36,18 @@ Modification:
#include "syscall.h"
#include "task.h"
int sys_exit()
int sys_exit(struct TaskMicroDescriptor* ptask)
{
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
assert(cur_task != NULL);
assert(ptask != NULL);
/* handle sessions for condition 1, ref. delete_share_pages() */
// close all server_sessions
struct server_session* server_session = NULL;
while (!IS_DOUBLE_LIST_EMPTY(&cur_task->svr_sess_listhead)) {
server_session = CONTAINER_OF(cur_task->svr_sess_listhead.next, struct server_session, node);
while (!IS_DOUBLE_LIST_EMPTY(&ptask->svr_sess_listhead)) {
server_session = CONTAINER_OF(ptask->svr_sess_listhead.next, struct server_session, node);
// cut the connection from task to session
if (!server_session->closed) {
xizi_share_page_manager.unmap_task_share_pages(cur_task, server_session->buf_addr, CLIENT_SESSION_BACKEND(server_session)->nr_pages);
xizi_share_page_manager.unmap_task_share_pages(ptask, server_session->buf_addr, CLIENT_SESSION_BACKEND(server_session)->nr_pages);
server_session->closed = true;
}
doubleListDel(&server_session->node);
@ -61,11 +59,11 @@ int sys_exit()
}
// close all client_sessions
struct client_session* client_session = NULL;
while (!IS_DOUBLE_LIST_EMPTY(&cur_task->cli_sess_listhead)) {
client_session = CONTAINER_OF(cur_task->cli_sess_listhead.next, struct client_session, node);
while (!IS_DOUBLE_LIST_EMPTY(&ptask->cli_sess_listhead)) {
client_session = CONTAINER_OF(ptask->cli_sess_listhead.next, struct client_session, node);
// cut the connection from task to session
if (!client_session->closed) {
xizi_share_page_manager.unmap_task_share_pages(cur_task, client_session->buf_addr, CLIENT_SESSION_BACKEND(client_session)->nr_pages);
xizi_share_page_manager.unmap_task_share_pages(ptask, client_session->buf_addr, CLIENT_SESSION_BACKEND(client_session)->nr_pages);
client_session->closed = true;
}
doubleListDel(&client_session->node);
@ -76,16 +74,16 @@ int sys_exit()
}
}
if (cur_task->server_identifier.meta != NULL) {
if (ptask->server_identifier.meta != NULL) {
struct TraceTag server_identifier_owner;
AchieveResourceTag(&server_identifier_owner, RequireRootTag(), "softkernel/server-identifier");
assert(server_identifier_owner.meta != NULL);
DeleteResource(&cur_task->server_identifier, &server_identifier_owner);
DeleteResource(&ptask->server_identifier, &server_identifier_owner);
}
// delete task for pcb_list
xizi_task_manager.cur_task_yield_noschedule();
cur_task->state = DEAD;
ptask->state = DEAD;
return 0;
}

View File

@ -0,0 +1,50 @@
/*
* 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 sys_kill.c
* @brief task exit syscall
* @version 3.0
* @author AIIT XUOS Lab
* @date 2024.03.19
*/
/*************************************************
File name: sys_kill.c
Description: task kill syscall
Others:
History:
1. Date: 2023-03-19
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include "trap_common.h"
#include "task.h"
extern int sys_exit(struct TaskMicroDescriptor* task);
int sys_kill(int id)
{
struct TaskMicroDescriptor* task = NULL;
for (int prio = 0; prio < TASK_MAX_PRIORITY; prio++) {
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[prio], node)
{
if (task->pid == id) {
sys_exit(task);
return 0;
}
}
}
return -1;
}

View File

@ -28,6 +28,7 @@ Modification:
1. first version
*************************************************/
#include "log.h"
#include "multicores.h"
#include "trap_common.h"
#include "syscall.h"
@ -44,7 +45,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
ret = sys_spawn((char*)param1, (char*)param2, (char**)param3);
break;
case SYSCALL_EXIT:
ret = sys_exit();
ret = sys_exit(cur_cpu()->task);
break;
case SYSCALL_YIELD:
ret = sys_yield();
@ -73,6 +74,9 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
case SYSCALL_REGISTER_IRQ:
ret = sys_register_irq((int)param1, (int)param2);
break;
case SYSCALL_KILL:
ret = sys_kill((int)param1);
break;
default:
ERROR("Unsurport syscall(%d) right now\n", sys_num);

View File

@ -88,7 +88,8 @@ void intr_irq_dispatch(struct trapframe* tf)
p_intr_driver->curr_int[cpu] = 0;
p_intr_driver->hw_after_irq(int_info);
if (UNLIKELY(cur_cpu()->task == NULL && current_task != NULL)) {
if ((cur_cpu()->task == NULL && current_task != NULL) || current_task->state != RUNNING) {
cur_cpu()->task = NULL;
context_switch(&current_task->main_thread.context, cur_cpu()->scheduler);
}
assert(current_task == cur_cpu()->task);

View File

@ -68,11 +68,10 @@ void software_irq_dispatch(struct trapframe* tf)
if (syscall_num != SYSCALL_EXEC) {
arch_set_return(tf, ret);
}
} else {
ERROR("syscall by killed task.\n");
}
if (cur_cpu()->task == NULL && cur_task != NULL) {
if ((cur_cpu()->task == NULL && cur_task != NULL) || cur_task->state != RUNNING) {
cur_cpu()->task = NULL;
context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler);
}
assert(cur_task == cur_cpu()->task);