add aarch64 support.
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -46,7 +46,7 @@
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
// "miDebuggerPath": "/opt/homebrew/bin/arm-none-eabi-gdb",
|
||||
"miDebuggerPath": "/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb",
|
||||
"miDebuggerPath": "/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
|
||||
// "miDebuggerPath": "/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gdb",
|
||||
"miDebuggerServerAddress": "127.0.0.1:3333",
|
||||
"MIMode": "gdb",
|
||||
|
||||
16
.vscode/settings.json
vendored
16
.vscode/settings.json
vendored
@@ -329,7 +329,21 @@
|
||||
"gui_interface_extern.h": "c",
|
||||
"gui.h": "c",
|
||||
"gui_timeout.h": "c",
|
||||
"bitmap.h": "c"
|
||||
"bitmap.h": "c",
|
||||
"early_boot.h": "c",
|
||||
"sysregs.h": "c",
|
||||
"types_asm.h": "c",
|
||||
"pager.h": "c",
|
||||
"thread_arch.h": "c",
|
||||
"aarch64_ptregs.h": "c",
|
||||
"psci.h": "c",
|
||||
"buddy.h": "c",
|
||||
"atomics.h": "c",
|
||||
"asm_config.h": "c",
|
||||
"slab.h": "c",
|
||||
"arm_local_reg.h": "c",
|
||||
"timer.h": "c",
|
||||
"arm_gicv2.h": "c"
|
||||
},
|
||||
"cortex-debug.showRTOS": false,
|
||||
"cortex-debug.variableUseNaturalFormat": false,
|
||||
|
||||
@@ -26,15 +26,13 @@ execute_process(
|
||||
)
|
||||
string(STRIP ${DATE} DATE)
|
||||
string(STRIP ${TIME} TIME)
|
||||
# string(STRIP ${COMMIT} COMMIT)
|
||||
# string(STRIP ${BRANCH} BRANCH)
|
||||
set(code_version ${BRANCH}-${COMMIT} CACHE STRING " " FORCE)
|
||||
set(compile_time "${DATE}\" \"${TIME}" CACHE STRING " " FORCE)
|
||||
|
||||
|
||||
add_subdirectory(mkrtos_bootstrap)
|
||||
add_subdirectory(mkrtos_knl)
|
||||
add_subdirectory(mkrtos_img)
|
||||
add_subdirectory(mkrtos_user)
|
||||
# add_subdirectory(mkrtos_img)
|
||||
# add_subdirectory(mkrtos_user)
|
||||
|
||||
|
||||
|
||||
22
aarch64.cmake
Normal file
22
aarch64.cmake
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
message("========use aarch64.cmake")
|
||||
|
||||
set(CMAKE_C_FLAGS "-O0 -g3 -D=MKRTOS \
|
||||
-std=gnu11 -ffunction-sections -fdata-sections -fno-builtin -u=_printf_float \
|
||||
-nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker \
|
||||
-fno-stack-protector -Wl,--gc-sections \
|
||||
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \
|
||||
" CACHE STRING "" FORCE)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-O0 -g3 -D=MKRTOS -std=c++11 \
|
||||
-fmessage-length=0 -Xlinker --print-map -Wall -W -fno-stack-protector -g \
|
||||
-u=_printf_float \
|
||||
-ffunction-sections -fdata-sections -fno-builtin -nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker \
|
||||
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \
|
||||
" CACHE STRING "" FORCE)
|
||||
|
||||
set(CMAKE_ASM_FLAGS "-O0 -g3 -D=MKRTOS \
|
||||
-u=_printf_float -std=gnu11 -ffunction-sections -fdata-sections -fno-builtin \
|
||||
-nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker -fno-stack-protector \
|
||||
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \
|
||||
" CACHE STRING "" FORCE)
|
||||
21
armv7_8.cmake
Normal file
21
armv7_8.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
message("========use armv7_8.cmake")
|
||||
|
||||
set(CMAKE_C_FLAGS "-mcpu=${CONFIG_ARCH} -O0 -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -mno-thumb-interwork -D=MKRTOS \
|
||||
-std=gnu11 -ffunction-sections -fdata-sections -fno-builtin -u=_printf_float \
|
||||
-nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker \
|
||||
-fno-stack-protector -Wl,--gc-sections \
|
||||
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \
|
||||
" CACHE STRING "" FORCE)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-mcpu=${CONFIG_ARCH} -O0 -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -mno-thumb-interwork -D=MKRTOS -std=c++11 \
|
||||
-fmessage-length=0 -Xlinker --print-map -Wall -W -fno-stack-protector -g \
|
||||
-u=_printf_float \
|
||||
-ffunction-sections -fdata-sections -fno-builtin -nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker \
|
||||
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \
|
||||
" CACHE STRING "" FORCE)
|
||||
|
||||
set(CMAKE_ASM_FLAGS "-mcpu=${CONFIG_ARCH} -O0 -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -mno-thumb-interwork -D=MKRTOS \
|
||||
-u=_printf_float -std=gnu11 -ffunction-sections -fdata-sections -fno-builtin \
|
||||
-nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker -fno-stack-protector \
|
||||
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \
|
||||
" CACHE STRING "" FORCE)
|
||||
@@ -85,15 +85,42 @@ elseif(${CONFIG_CPU_TYPE} STREQUAL "swm34s" )
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/SWM34/SWM341_StdPeriph_Driver/SWM341_StdPeriph_Driver
|
||||
)
|
||||
add_subdirectory(bsp/SWM34S)
|
||||
elseif(${CONFIG_CPU_TYPE} STREQUAL "aarch64_qemu" )
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bootstrap/bsp/AARCH64_QEMU
|
||||
)
|
||||
add_subdirectory(bsp/AARCH64_QEMU)
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
gen_sys_cpio
|
||||
|
||||
COMMAND
|
||||
cd ${CMAKE_SOURCE_DIR}/build/output/cpio
|
||||
COMMAND
|
||||
ls | cpio -H newc -o > ${CMAKE_SOURCE_DIR}/build/output/rootfs.cpio
|
||||
COMMAND
|
||||
cd ${CMAKE_SOURCE_DIR}/build/output
|
||||
COMMAND
|
||||
${CMAKE_OBJCOPY} -I binary -O elf64-littleaarch64 -B aarch64 rootfs.cpio rootfs.cpio.elf --rename-section .data=.cpio
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/build/output
|
||||
BYPRODUCTS ${CMAKE_SOURCE_DIR}/build/output/rootfs.cpio.elf
|
||||
)
|
||||
add_dependencies(
|
||||
gen_sys_cpio
|
||||
mkrtos_dump
|
||||
)
|
||||
|
||||
set_source_files_properties(${CMAKE_SOURCE_DIR}/build/output/rootfs.cpio.elf PROPERTIES EXTERNAL_OBJECT true)
|
||||
|
||||
add_executable(bootstrap.elf
|
||||
${deps}
|
||||
${CMAKE_SOURCE_DIR}/build/output/rootfs.cpio.elf
|
||||
)
|
||||
message("CONFIG_CPU_TYPE"=${CONFIG_CPU_TYPE})
|
||||
# message("CONFIG_CPU_TYPE="${CONFIG_CPU_TYPE})
|
||||
string(TOUPPER ${CONFIG_CPU_TYPE} cpu_type)
|
||||
set_target_properties(bootstrap.elf PROPERTIES LINK_FLAGS
|
||||
"-T ${CMAKE_CURRENT_LIST_DIR}/bsp/${cpu_type}/link.lds --gc-section ")
|
||||
"-T ${CMAKE_CURRENT_LIST_DIR}/bsp/${cpu_type}/link.lds")
|
||||
|
||||
target_link_libraries(
|
||||
bootstrap.elf
|
||||
@@ -110,9 +137,9 @@ add_custom_target(
|
||||
COMMAND
|
||||
mkdir -p ${CMAKE_SOURCE_DIR}/build/output
|
||||
COMMAND
|
||||
cp bootstrap.bin ${CMAKE_SOURCE_DIR}/build/output/bootstrap
|
||||
mkdir -p ${CMAKE_SOURCE_DIR}/build/output/cpio
|
||||
COMMAND
|
||||
cp bootstrap.bin ${CMAKE_SOURCE_DIR}/build/output/bootstrap.bin
|
||||
cp bootstrap.bin ${CMAKE_SOURCE_DIR}/build/output/bootstrap
|
||||
COMMAND
|
||||
cp bootstrap.elf ${CMAKE_SOURCE_DIR}/build/output/bootstrap.elf
|
||||
COMMAND
|
||||
@@ -120,3 +147,4 @@ add_custom_target(
|
||||
)
|
||||
add_dependencies(bootstrap_dump bootstrap.elf)
|
||||
add_dependencies(bootstrap.elf boot_bsp)
|
||||
add_dependencies(bootstrap.elf gen_sys_cpio)
|
||||
14
mkrtos_bootstrap/bsp/AARCH64_QEMU/CMakeLists.txt
Executable file
14
mkrtos_bootstrap/bsp/AARCH64_QEMU/CMakeLists.txt
Executable file
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
|
||||
file(GLOB_RECURSE deps *.S *.s *.C *.c)
|
||||
|
||||
add_library(boot_bsp STATIC ${deps})
|
||||
target_include_directories(
|
||||
boot_bsp
|
||||
PUBLIC
|
||||
)
|
||||
|
||||
target_link_libraries(boot_bsp
|
||||
PRIVATE
|
||||
)
|
||||
38
mkrtos_bootstrap/bsp/AARCH64_QEMU/aarch64_start.c
Normal file
38
mkrtos_bootstrap/bsp/AARCH64_QEMU/aarch64_start.c
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
#include <mk_sys.h>
|
||||
#include <elf_loader.h>
|
||||
#include <uart.h>
|
||||
#include "cpio.h"
|
||||
__ALIGN__(16)
|
||||
uint64_t stack[4096 / sizeof(uint64_t)];
|
||||
|
||||
|
||||
#define KERNEL_NAME "mkrtos.elf"
|
||||
|
||||
// 内核的启动地址,其它核跳转使用
|
||||
extern uint64_t knl_entry;
|
||||
// #define KERNEL_NAME "mkrtos_smart.elf"
|
||||
#define KERNEL_IMG_START_ADDR (0x40000000 + 0x01000000 + 0x4000)
|
||||
|
||||
typedef void (*main_func)(umword_t cpio_addr);
|
||||
|
||||
void jump2kernel(addr_t cpio_start, addr_t cpio_end)
|
||||
{
|
||||
uart_init();
|
||||
uart_write_str("bootstrap...\n");
|
||||
umword_t knl_st_addr = cpio_find_file((umword_t)cpio_start, (umword_t)cpio_end, KERNEL_NAME);
|
||||
if (!knl_st_addr)
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
Elf64_Addr entry;
|
||||
|
||||
elf_load_knl(knl_st_addr, &entry);
|
||||
main_func entry_fun = (main_func)entry;
|
||||
knl_entry = entry;
|
||||
entry_fun((mword_t)cpio_start);
|
||||
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
82
mkrtos_bootstrap/bsp/AARCH64_QEMU/cpio.c
Normal file
82
mkrtos_bootstrap/bsp/AARCH64_QEMU/cpio.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "mk_sys.h"
|
||||
#include "cpio.h"
|
||||
#include <string.h>
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< 最小值
|
||||
#define ALIGN(mem, align) (((mem) + ((align) - 1)) & (~((align) - 1))) //!< 向上对齐
|
||||
|
||||
umword_t cpio_find_file(umword_t st, umword_t en, const char *name)
|
||||
{
|
||||
uint8_t rByte;
|
||||
int32_t bk_inx;
|
||||
cpio_fs_t *file_info;
|
||||
|
||||
for (umword_t i = st; st < en;)
|
||||
{
|
||||
file_info = (cpio_fs_t *)i;
|
||||
|
||||
if (check_magic((char *)file_info) < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int name_size = htoi(file_info->c_namesize, 8);
|
||||
const char *f_name = (char *)(i + sizeof(cpio_fs_t));
|
||||
if (strcmp(f_name, name) == 0)
|
||||
{
|
||||
return (mword_t)(ALIGN(i + sizeof(cpio_fs_t) + name_size, 4));
|
||||
}
|
||||
|
||||
if (strcmp("TRAILER!!", f_name) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int file_size = htoi(file_info->c_filesize, 8);
|
||||
|
||||
i = ALIGN(ALIGN(i + sizeof(cpio_fs_t) + name_size, 4) +
|
||||
file_size,
|
||||
4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int htoi(char *str, int len)
|
||||
{
|
||||
int n = 0;
|
||||
int i = 0;
|
||||
|
||||
if (str == NULL || len <= 0)
|
||||
return -1;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (str[i] != '0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
str += i;
|
||||
while (1)
|
||||
{
|
||||
if (*str >= '0' && *str <= '9')
|
||||
{
|
||||
n = 16 * n + (*str - '0');
|
||||
}
|
||||
else if (*str >= 'A' && *str <= 'F') // 十六进制还要判断字符是不是在A-F或者a-f之间
|
||||
{
|
||||
n = 16 * n + (*str - 'A' + 10);
|
||||
}
|
||||
else if (*str >= 'a' && *str <= 'f')
|
||||
{
|
||||
n = 16 * n + (*str - 'a' + 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
str++;
|
||||
i++;
|
||||
if (i >= len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
34
mkrtos_bootstrap/bsp/AARCH64_QEMU/cpio.h
Normal file
34
mkrtos_bootstrap/bsp/AARCH64_QEMU/cpio.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "mk_sys.h"
|
||||
//! 26bytes
|
||||
#pragma pack(1)
|
||||
typedef struct cpio_fs
|
||||
{
|
||||
char c_magic[6];
|
||||
char c_ino[8];
|
||||
char c_mode[8];
|
||||
char c_uid[8];
|
||||
char c_gid[8];
|
||||
char c_nlink[8];
|
||||
char c_mtime[8];
|
||||
char c_filesize[8];
|
||||
char c_devmajor[8];
|
||||
char c_devminor[8];
|
||||
char c_rdevmajor[8];
|
||||
char c_rdevminor[8];
|
||||
char c_namesize[8];
|
||||
char c_check[8];
|
||||
} cpio_fs_t;
|
||||
|
||||
static inline int64_t check_magic(char *magic)
|
||||
{
|
||||
if (magic[0] == '0' && magic[1] == '7' && magic[2] == '0' &&
|
||||
magic[3] == '7' && magic[4] == '0' && magic[5] == '1')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int htoi(char *str, int len);
|
||||
umword_t cpio_find_file(umword_t st, umword_t en, const char *name);
|
||||
60
mkrtos_bootstrap/bsp/AARCH64_QEMU/elf.h
Normal file
60
mkrtos_bootstrap/bsp/AARCH64_QEMU/elf.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <mk_sys.h>
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
#define EI_NIDENT (16)
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* 一个字节数组用来确认文件是否是一个ELF文件 */
|
||||
Elf64_Half e_type; /* 描述文件是,可执行文件elf=2,重定位so=3 */
|
||||
Elf64_Half e_machine; /* 目标主机架构 */
|
||||
Elf64_Word e_version; /* ELF文件格式的版本 */
|
||||
Elf64_Addr e_entry; /* 入口点虚拟地址 */
|
||||
Elf64_Off e_phoff; /* 程序头文件偏移 */
|
||||
Elf64_Off e_shoff; /* 节头表文件偏移 */
|
||||
Elf64_Word e_flags; /* ELF文件标志 */
|
||||
Elf64_Half e_ehsize; /* ELF头大小 */
|
||||
Elf64_Half e_phentsize; /* 程序头大小 */
|
||||
Elf64_Half e_phnum; /* 程序头表计数 */
|
||||
Elf64_Half e_shentsize; /* 节头表大小 */
|
||||
Elf64_Half e_shnum; /* 节头表计数 */
|
||||
Elf64_Half e_shstrndx; /* 字符串表索引节头 */
|
||||
} Elf64_Ehdr;
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word p_type; /* Segment type */
|
||||
Elf64_Word p_flags; /* Segment flags */
|
||||
Elf64_Off p_offset; /* Segment file offset */
|
||||
Elf64_Addr p_vaddr; /* Segment virtual address */
|
||||
Elf64_Addr p_paddr; /* Segment physical address */
|
||||
Elf64_Xword p_filesz; /* Segment size in file */
|
||||
Elf64_Xword p_memsz; /* Segment size in memory */
|
||||
Elf64_Xword p_align; /* Segment alignment */
|
||||
} Elf64_Phdr;
|
||||
#define PT_NULL 0 /* Program header table entry unused */
|
||||
#define PT_LOAD 1 /* Loadable program segment */
|
||||
#define PT_DYNAMIC 2 /* Dynamic linking information */
|
||||
#define PT_INTERP 3 /* Program interpreter */
|
||||
#define PT_NOTE 4 /* Auxiliary information */
|
||||
#define PT_SHLIB 5 /* Reserved */
|
||||
#define PT_PHDR 6 /* Entry for header table itself */
|
||||
#define PT_TLS 7 /* Thread-local storage segment */
|
||||
#define PT_NUM 8 /* Number of defined types */
|
||||
#define PT_LOOS 0x60000000 /* Start of OS-specific */
|
||||
#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
|
||||
#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
|
||||
#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
|
||||
#define PT_LOSUNW 0x6ffffffa
|
||||
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
|
||||
#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
|
||||
#define PT_HISUNW 0x6fffffff
|
||||
#define PT_HIOS 0x6fffffff /* End of OS-specific */
|
||||
#define PT_LOPROC 0x70000000 /* Start of processor-specific */
|
||||
#define PT_HIPROC 0x7fffffff /* End of processor-specific */
|
||||
21
mkrtos_bootstrap/bsp/AARCH64_QEMU/elf_loader.c
Normal file
21
mkrtos_bootstrap/bsp/AARCH64_QEMU/elf_loader.c
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
#include <elf.h>
|
||||
#include <string.h>
|
||||
|
||||
void elf_load_knl(mword_t elf_data, Elf64_Addr *entry)
|
||||
{
|
||||
Elf64_Ehdr *elf_header;
|
||||
|
||||
elf_header = (Elf64_Ehdr *)elf_data;
|
||||
*entry = elf_header->e_entry;
|
||||
int size = elf_header->e_phentsize;
|
||||
Elf64_Phdr *elf_phdr = (Elf64_Phdr *)(elf_header->e_phoff + elf_data);
|
||||
|
||||
for (int i = 0; i < elf_header->e_phnum; i++, elf_phdr++)
|
||||
{
|
||||
if (elf_phdr->p_type == PT_LOAD)
|
||||
{
|
||||
memcpy((char *)elf_phdr->p_paddr, (char *)(elf_data + elf_phdr->p_offset), elf_phdr->p_filesz);
|
||||
}
|
||||
}
|
||||
}
|
||||
5
mkrtos_bootstrap/bsp/AARCH64_QEMU/elf_loader.h
Normal file
5
mkrtos_bootstrap/bsp/AARCH64_QEMU/elf_loader.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include <elf.h>
|
||||
#include <mk_sys.h>
|
||||
|
||||
void elf_load_knl(mword_t elf_data, Elf64_Addr *entry);
|
||||
70
mkrtos_bootstrap/bsp/AARCH64_QEMU/link.lds
Executable file
70
mkrtos_bootstrap/bsp/AARCH64_QEMU/link.lds
Executable file
@@ -0,0 +1,70 @@
|
||||
ENTRY(_start);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/*
|
||||
* 0x40000000
|
||||
*
|
||||
* 这里“.”表示location counter,当前位置
|
||||
*/
|
||||
. = 0x40000000 + 0x01000000;
|
||||
/*
|
||||
* text代码段
|
||||
*/
|
||||
_text = .;
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
_etext = .;
|
||||
|
||||
/*
|
||||
* 只读数据段
|
||||
*/
|
||||
|
||||
_rodata = .;
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
_erodata = .;
|
||||
|
||||
|
||||
/*
|
||||
* 数据段
|
||||
*/
|
||||
_data = .;
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
|
||||
. = ALIGN(0x8);
|
||||
_pre_cpu_data_start = .;
|
||||
KEEP (*(.data.per_cpu))
|
||||
_pre_cpu_data_end = .;
|
||||
}
|
||||
_edata = .;
|
||||
|
||||
/*
|
||||
* bss段
|
||||
*
|
||||
* ALIGN(8)表示8个字节对齐
|
||||
* bss_begin的起始地址以8字节对齐
|
||||
*/
|
||||
. = ALIGN(0x8);
|
||||
_bss = .;
|
||||
bss_begin = .;
|
||||
.bss :
|
||||
{
|
||||
*(.bss*)
|
||||
}
|
||||
bss_end = .;
|
||||
_ebss = .;
|
||||
|
||||
. = ALIGN(0x8);
|
||||
.cpio : {
|
||||
cpio_start = .;
|
||||
*(.cpio*)
|
||||
cpio_end = .;
|
||||
}
|
||||
}
|
||||
62
mkrtos_bootstrap/bsp/AARCH64_QEMU/mk_sys.h
Normal file
62
mkrtos_bootstrap/bsp/AARCH64_QEMU/mk_sys.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef long long int64_t;
|
||||
|
||||
typedef unsigned long umword_t;
|
||||
typedef unsigned short uhmword_t;
|
||||
typedef long mword_t;
|
||||
|
||||
typedef signed long int intptr_t;
|
||||
typedef unsigned long int uintptr_t;
|
||||
|
||||
typedef umword_t size_t;
|
||||
typedef mword_t ssize_t;
|
||||
typedef umword_t ptr_t;
|
||||
typedef char bool_t;
|
||||
typedef unsigned long obj_addr_t;
|
||||
typedef umword_t uintptr_t;
|
||||
typedef umword_t addr_t;
|
||||
typedef umword_t obj_handler_t;
|
||||
typedef umword_t time_t;
|
||||
typedef umword_t pid_t;
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (!(FALSE))
|
||||
#endif
|
||||
|
||||
#define WORD_BYTES (sizeof(void *))
|
||||
#define WORD_BITS (sizeof(void *) * 8)
|
||||
|
||||
#define __ALIGN__(size) __attribute__((aligned(size)))
|
||||
|
||||
#define read_reg(addr) (*((volatile umword_t *)(addr)))
|
||||
#define write_reg(addr, data) \
|
||||
do \
|
||||
{ \
|
||||
(*((volatile umword_t *)(addr))) = data; \
|
||||
} while (0)
|
||||
|
||||
#define read_reg32(addr) (*((volatile uint32_t *)(addr)))
|
||||
#define write_reg32(addr, data) \
|
||||
do \
|
||||
{ \
|
||||
(*((volatile uint32_t *)(addr))) = (uint32_t)data; \
|
||||
} while (0)
|
||||
|
||||
void jump2kernel(addr_t cpio_start, addr_t cpio_end);
|
||||
37
mkrtos_bootstrap/bsp/AARCH64_QEMU/start.S
Normal file
37
mkrtos_bootstrap/bsp/AARCH64_QEMU/start.S
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
/* 8字节对齐,否则会出错*/
|
||||
.align 3
|
||||
.globl sp_addr
|
||||
.section ".data.boot"
|
||||
sp_addr:
|
||||
.quad stack + 4096 - 8 //pt regs is 320 bytes.
|
||||
|
||||
.align 3
|
||||
.globl knl_entry
|
||||
.section ".data.boot"
|
||||
knl_entry:
|
||||
.quad 0
|
||||
|
||||
.section ".text.boot"
|
||||
.globl _start
|
||||
_start:
|
||||
msr daifset, #0xf // 关闭中断
|
||||
//进入多核启动流程
|
||||
mrs x0, mpidr_el1 // 读取该寄存器获取处理器id
|
||||
and x0, x0,#0xFF // Check processor id
|
||||
cbz x0, master // Hang for all non-primary CPU
|
||||
//spin table
|
||||
ldr x1, = knl_entry
|
||||
spin_jump:
|
||||
ldr x3, [x1, #0]
|
||||
cbz x3, spin_jump
|
||||
br x3
|
||||
b .
|
||||
|
||||
master:
|
||||
ldr x8, = sp_addr
|
||||
ldr x9, [x8]
|
||||
mov sp, x9
|
||||
bl main
|
||||
|
||||
b .
|
||||
160
mkrtos_bootstrap/bsp/AARCH64_QEMU/uart.c
Normal file
160
mkrtos_bootstrap/bsp/AARCH64_QEMU/uart.c
Normal file
@@ -0,0 +1,160 @@
|
||||
#include "mk_sys.h"
|
||||
|
||||
#define UART01x_DR 0x00 /* Data read or written from the interface. */
|
||||
#define UART01x_RSR 0x04 /* Receive status register (Read). */
|
||||
#define UART01x_ECR 0x04 /* Error clear register (Write). */
|
||||
#define UART010_LCRH 0x08 /* Line control register, high byte. */
|
||||
#define ST_UART011_DMAWM 0x08 /* DMA watermark configure register. */
|
||||
#define UART010_LCRM 0x0C /* Line control register, middle byte. */
|
||||
#define ST_UART011_TIMEOUT 0x0C /* Timeout period register. */
|
||||
#define UART010_LCRL 0x10 /* Line control register, low byte. */
|
||||
#define UART010_CR 0x14 /* Control register. */
|
||||
#define UART01x_FR 0x18 /* Flag register (Read only). */
|
||||
#define UART010_IIR 0x1C /* Interrupt identification register (Read). */
|
||||
#define UART010_ICR 0x1C /* Interrupt clear register (Write). */
|
||||
#define ST_UART011_LCRH_RX 0x1C /* Rx line control register. */
|
||||
#define UART01x_ILPR 0x20 /* IrDA low power counter register. */
|
||||
#define UART011_IBRD 0x24 /* Integer baud rate divisor register. */
|
||||
#define UART011_FBRD 0x28 /* Fractional baud rate divisor register. */
|
||||
#define UART011_LCRH 0x2c /* Line control register. */
|
||||
#define UART011_LCRH_WLEN_8 0x60
|
||||
#define ST_UART011_LCRH_TX 0x2c /* Tx Line control register. */
|
||||
#define UART011_CR 0x30 /* Control register. */
|
||||
#define UART011_IFLS 0x34 /* Interrupt fifo level select. */
|
||||
#define UART011_IMSC 0x38 /* Interrupt mask. */
|
||||
#define UART011_RIS 0x3c /* Raw interrupt status. */
|
||||
#define UART011_MIS 0x40 /* Masked interrupt status. */
|
||||
#define UART011_ICR 0x44 /* Interrupt clear register. */
|
||||
#define UART011_DMACR 0x48 /* DMA control register. */
|
||||
#define ST_UART011_XFCR 0x50 /* XON/XOFF control register. */
|
||||
#define ST_UART011_XON1 0x54 /* XON1 register. */
|
||||
#define ST_UART011_XON2 0x58 /* XON2 register. */
|
||||
#define ST_UART011_XOFF1 0x5C /* XON1 register. */
|
||||
#define ST_UART011_XOFF2 0x60 /* XON2 register. */
|
||||
#define ST_UART011_ITCR 0x80 /* Integration test control register. */
|
||||
#define ST_UART011_ITIP 0x84 /* Integration test input register. */
|
||||
#define ST_UART011_ABCR 0x100 /* Autobaud control register. */
|
||||
#define ST_UART011_ABIMSC 0x15C /* Autobaud interrupt mask/clear register. */
|
||||
|
||||
#define UART011_FR_RI 0x100
|
||||
#define UART011_FR_TXFE 0x080
|
||||
#define UART011_FR_RXFF 0x040
|
||||
#define UART01x_FR_TXFF 0x020
|
||||
#define UART01x_FR_RXFE 0x010
|
||||
#define UART01x_FR_BUSY 0x008
|
||||
#define UART01x_FR_DCD 0x004
|
||||
#define UART01x_FR_DSR 0x002
|
||||
#define UART01x_FR_CTS 0x001
|
||||
#define UART01x_FR_TMSK (UART01x_FR_TXFF + UART01x_FR_BUSY)
|
||||
|
||||
#define UART011_CR_CTSEN 0x8000 /* CTS hardware flow control */
|
||||
#define UART011_CR_RTSEN 0x4000 /* RTS hardware flow control */
|
||||
#define UART011_CR_OUT2 0x2000 /* OUT2 */
|
||||
#define UART011_CR_OUT1 0x1000 /* OUT1 */
|
||||
#define UART011_CR_RTS 0x0800 /* RTS */
|
||||
#define UART011_CR_DTR 0x0400 /* DTR */
|
||||
#define UART011_CR_RXE 0x0200 /* receive enable */
|
||||
#define UART011_CR_TXE 0x0100 /* transmit enable */
|
||||
#define UART011_CR_LBE 0x0080 /* loopback enable */
|
||||
#define UART010_CR_RTIE 0x0040
|
||||
#define UART010_CR_TIE 0x0020
|
||||
#define UART010_CR_RIE 0x0010
|
||||
#define UART010_CR_MSIE 0x0008
|
||||
#define ST_UART011_CR_OVSFACT 0x0008 /* Oversampling factor */
|
||||
#define UART01x_CR_IIRLP 0x0004 /* SIR low power mode */
|
||||
#define UART01x_CR_SIREN 0x0002 /* SIR enable */
|
||||
#define UART01x_CR_UARTEN 0x0001 /* UART enable */
|
||||
|
||||
#define UART011_OEIM (1 << 10) /* overrun error interrupt mask */
|
||||
#define UART011_BEIM (1 << 9) /* break error interrupt mask */
|
||||
#define UART011_PEIM (1 << 8) /* parity error interrupt mask */
|
||||
#define UART011_FEIM (1 << 7) /* framing error interrupt mask */
|
||||
#define UART011_RTIM (1 << 6) /* receive timeout interrupt mask */
|
||||
#define UART011_TXIM (1 << 5) /* transmit interrupt mask */
|
||||
#define UART011_RXIM (1 << 4) /* receive interrupt mask */
|
||||
#define UART011_DSRMIM (1 << 3) /* DSR interrupt mask */
|
||||
#define UART011_DCDMIM (1 << 2) /* DCD interrupt mask */
|
||||
#define UART011_CTSMIM (1 << 1) /* CTS interrupt mask */
|
||||
#define UART011_RIMIM (1 << 0) /* RI interrupt mask */
|
||||
|
||||
#define UART011_OEIS (1 << 10) /* overrun error interrupt status */
|
||||
#define UART011_BEIS (1 << 9) /* break error interrupt status */
|
||||
#define UART011_PEIS (1 << 8) /* parity error interrupt status */
|
||||
#define UART011_FEIS (1 << 7) /* framing error interrupt status */
|
||||
#define UART011_RTIS (1 << 6) /* receive timeout interrupt status */
|
||||
#define UART011_TXIS (1 << 5) /* transmit interrupt status */
|
||||
#define UART011_RXIS (1 << 4) /* receive interrupt status */
|
||||
#define UART011_DSRMIS (1 << 3) /* DSR interrupt status */
|
||||
#define UART011_DCDMIS (1 << 2) /* DCD interrupt status */
|
||||
#define UART011_CTSMIS (1 << 1) /* CTS interrupt status */
|
||||
#define UART011_RIMIS (1 << 0) /* RI interrupt status */
|
||||
|
||||
#define UART011_OEIC (1 << 10) /* overrun error interrupt clear */
|
||||
#define UART011_BEIC (1 << 9) /* break error interrupt clear */
|
||||
#define UART011_PEIC (1 << 8) /* parity error interrupt clear */
|
||||
#define UART011_FEIC (1 << 7) /* framing error interrupt clear */
|
||||
#define UART011_RTIC (1 << 6) /* receive timeout interrupt clear */
|
||||
#define UART011_TXIC (1 << 5) /* transmit interrupt clear */
|
||||
#define UART011_RXIC (1 << 4) /* receive interrupt clear */
|
||||
#define UART011_DSRMIC (1 << 3) /* DSR interrupt clear */
|
||||
#define UART011_DCDMIC (1 << 2) /* DCD interrupt clear */
|
||||
#define UART011_CTSMIC (1 << 1) /* CTS interrupt clear */
|
||||
#define UART011_RIMIC (1 << 0) /* RI interrupt clear */
|
||||
|
||||
#define UART011_BASE_ADDR 0x9000000 //!< 寄存器基地址
|
||||
#define UART011_FREQ 0x0 //!< 频率
|
||||
#define UART011_DEFAULT_BAUD 115200
|
||||
void uart_set_baud(int baud)
|
||||
{
|
||||
uint32_t fi_val = UART011_FREQ * 4 / baud;
|
||||
|
||||
write_reg32(UART011_BASE_ADDR + UART011_FBRD, fi_val & 0x3f);
|
||||
write_reg32(UART011_BASE_ADDR + UART011_IBRD, fi_val >> 6);
|
||||
}
|
||||
void uart_write_byte(uint8_t byte)
|
||||
{
|
||||
int i = 3000000;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
if (!(read_reg32(UART011_BASE_ADDR + UART01x_FR) & UART01x_FR_TXFF))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
write_reg32(UART011_BASE_ADDR + UART01x_DR, byte);
|
||||
}
|
||||
void uart_write_bytes(uint8_t *bytes, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
uart_write_byte((bytes[i]));
|
||||
}
|
||||
}
|
||||
void uart_write_str(const char *str)
|
||||
{
|
||||
for (int i = 0; str[i]; i++)
|
||||
{
|
||||
uart_write_byte((str[i]));
|
||||
}
|
||||
}
|
||||
void uart_init(void)
|
||||
{
|
||||
write_reg32(UART011_BASE_ADDR + UART011_CR, UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE);
|
||||
if (UART011_FREQ)
|
||||
{
|
||||
uart_set_baud(UART011_DEFAULT_BAUD);
|
||||
}
|
||||
write_reg32(UART011_BASE_ADDR + UART011_LCRH, UART011_LCRH_WLEN_8);
|
||||
write_reg32(UART011_BASE_ADDR + UART011_IMSC, 0);
|
||||
|
||||
int i = 4000000;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
if (!(read_reg32(UART011_BASE_ADDR + UART01x_FR) & UART01x_FR_BUSY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
4
mkrtos_bootstrap/bsp/AARCH64_QEMU/uart.h
Normal file
4
mkrtos_bootstrap/bsp/AARCH64_QEMU/uart.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void uart_init(void);
|
||||
void uart_write_str(const char *str);
|
||||
@@ -67,5 +67,5 @@ SECTIONS
|
||||
|
||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||
assert(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||
}
|
||||
16
mkrtos_bootstrap/inc/string.h
Normal file → Executable file
16
mkrtos_bootstrap/inc/string.h
Normal file → Executable file
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
static inline void memset(void *data, int val, int size)
|
||||
{
|
||||
unsigned int *_d = data;
|
||||
#include "types.h"
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
_d[0] = 0;
|
||||
}
|
||||
}
|
||||
void *memccpy(void *dst, const void *src, int c, size_t count);
|
||||
void memcpy(void *dst, void *src, size_t len);
|
||||
void *memset(void *dst, char s, size_t count);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
char *strcpy(register char *s1, register const char *s2);
|
||||
size_t strlen(const char *s);
|
||||
char *strncpy(char *dest, const char *src, uint32_t n);
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
#include <types.h>
|
||||
#include <mk_sys.h>
|
||||
extern char cpio_start[];
|
||||
extern char cpio_end[];
|
||||
int main(void)
|
||||
{
|
||||
jump2kernel();
|
||||
jump2kernel((addr_t)cpio_start, (addr_t)cpio_end);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
65
mkrtos_bootstrap/string.c
Executable file
65
mkrtos_bootstrap/string.c
Executable file
@@ -0,0 +1,65 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "string.h"
|
||||
void *memccpy(void *dst, const void *src, int c, size_t count)
|
||||
{
|
||||
char *a = dst;
|
||||
const char *b = src;
|
||||
while (count--)
|
||||
{
|
||||
*a++ = *b;
|
||||
if (*b == c)
|
||||
{
|
||||
return (void *)a;
|
||||
}
|
||||
b++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void memcpy(void *dst, void *src, size_t len)
|
||||
{
|
||||
register char *b_dst = dst;
|
||||
register char *b_src = src;
|
||||
for (; len; len--)
|
||||
{
|
||||
(*b_dst++) = (*b_src++);
|
||||
}
|
||||
}
|
||||
void *memset(void *dst, char s, size_t count)
|
||||
{
|
||||
register char *a = dst;
|
||||
count++; /* this actually creates smaller code than using count-- */
|
||||
while (--count)
|
||||
*a++ = s;
|
||||
return dst;
|
||||
}
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 && *s1 == *s2)
|
||||
s1++, s2++;
|
||||
return (*s1 - *s2);
|
||||
}
|
||||
char *strcpy(register char *s1, register const char *s2)
|
||||
{
|
||||
register char *res = s1;
|
||||
while ((*s1++ = *s2++))
|
||||
;
|
||||
return (res);
|
||||
}
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *t = s;
|
||||
unsigned long word;
|
||||
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
for (; *s++;)
|
||||
;
|
||||
return (size_t)(s - t) - 1;
|
||||
}
|
||||
char *strncpy(char *dest, const char *src, uint32_t n)
|
||||
{
|
||||
memccpy(dest, src, 0, n);
|
||||
return dest;
|
||||
}
|
||||
118
mkrtos_configs/aarch64_qemu_defconfig
Normal file
118
mkrtos_configs/aarch64_qemu_defconfig
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
#
|
||||
# Knl config
|
||||
#
|
||||
CONFIG_KNL_INFO=y
|
||||
CONFIG_KNL_TEXT_ADDR=0x1000
|
||||
CONFIG_KNL_TEXT_SIZE=0x100000
|
||||
CONFIG_KNL_DATA_ADDR=0x40000000
|
||||
CONFIG_KNL_DATA_SIZE=0x800000
|
||||
CONFIG_KNL_OFFSET=0x1000
|
||||
CONFIG_INIT_TASK_OFFSET=0x10000
|
||||
CONFIG_BOOTFS_OFFSET=0x02000000
|
||||
CONFIG_MK_MPU_CFG=n
|
||||
CONFIG_FT_ADDR_NR=16
|
||||
CONFIG_SYS_SCHE_HZ=1000
|
||||
CONFIG_USER_ISR_START_NO=16
|
||||
CONFIG_IRQ_REG_TAB_SIZE=80
|
||||
CONFIG_REGION_NUM=8
|
||||
CONFIG_OBJ_MAP_TAB_SIZE=32
|
||||
CONFIG_OBJ_MAP_ENTRY_SIZE=32
|
||||
CONFIG_PRINTK_CACHE_SIZE=128
|
||||
# end of Knl config
|
||||
|
||||
#
|
||||
# Libc backend
|
||||
#
|
||||
CONFIG_FD_MAP_ROW_CN=16
|
||||
CONFIG_FD_MAP_ROW_NR=16
|
||||
# end of Libc backend
|
||||
|
||||
#
|
||||
# Sys util config
|
||||
#
|
||||
CONFIG_USING_SIG=n
|
||||
CONFIG_SIG_THREAD_STACK_SIZE=512
|
||||
CONFIG_SIG_THREAD_PRIO=3
|
||||
# end of Sys util config
|
||||
|
||||
#
|
||||
# DFS: device virtual file system
|
||||
#
|
||||
CONFIG_RT_USING_DFS=y
|
||||
CONFIG_DFS_USING_POSIX=y
|
||||
CONFIG_DFS_USING_WORKDIR=y
|
||||
# CONFIG_RT_USING_DFS_MNTTABLE is not set
|
||||
CONFIG_DFS_FD_MAX=16
|
||||
CONFIG_RT_USING_DFS_V1=y
|
||||
# CONFIG_RT_USING_DFS_V2 is not set
|
||||
CONFIG_DFS_FILESYSTEMS_MAX=4
|
||||
CONFIG_DFS_FILESYSTEM_TYPES_MAX=4
|
||||
# CONFIG_RT_USING_DFS_ELMFAT is not set
|
||||
CONFIG_RT_USING_DFS_DEVFS=y
|
||||
# CONFIG_RT_USING_DFS_ROMFS is not set
|
||||
# CONFIG_RT_USING_DFS_CROMFS is not set
|
||||
# CONFIG_RT_USING_DFS_RAMFS is not set
|
||||
# CONFIG_RT_USING_DFS_TMPFS is not set
|
||||
# CONFIG_RT_USING_DFS_MQUEUE is not set
|
||||
# end of DFS: device virtual file system
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
# CONFIG_RT_USING_DM is not set
|
||||
CONFIG_RT_USING_DEVICE_IPC=y
|
||||
CONFIG_RT_UNAMED_PIPE_NUMBER=64
|
||||
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
|
||||
CONFIG_RT_USING_SERIAL=y
|
||||
CONFIG_RT_USING_SERIAL_V1=y
|
||||
# CONFIG_RT_USING_SERIAL_V2 is not set
|
||||
CONFIG_RT_SERIAL_USING_DMA=y
|
||||
CONFIG_RT_SERIAL_RB_BUFSZ=64
|
||||
# CONFIG_RT_USING_CAN is not set
|
||||
# CONFIG_RT_USING_HWTIMER is not set
|
||||
# CONFIG_RT_USING_CPUTIME is not set
|
||||
# CONFIG_RT_USING_I2C is not set
|
||||
# CONFIG_RT_USING_PHY is not set
|
||||
CONFIG_RT_USING_PIN=y
|
||||
# CONFIG_RT_USING_ADC is not set
|
||||
# CONFIG_RT_USING_DAC is not set
|
||||
# CONFIG_RT_USING_NULL is not set
|
||||
# CONFIG_RT_USING_ZERO is not set
|
||||
# CONFIG_RT_USING_RANDOM is not set
|
||||
# CONFIG_RT_USING_PWM is not set
|
||||
# CONFIG_RT_USING_MTD_NOR is not set
|
||||
# CONFIG_RT_USING_MTD_NAND is not set
|
||||
# CONFIG_RT_USING_PM is not set
|
||||
# CONFIG_RT_USING_RTC is not set
|
||||
# CONFIG_RT_USING_SDIO is not set
|
||||
# CONFIG_RT_USING_SPI is not set
|
||||
# CONFIG_RT_USING_WDT is not set
|
||||
# CONFIG_RT_USING_AUDIO is not set
|
||||
# CONFIG_RT_USING_SENSOR is not set
|
||||
# CONFIG_RT_USING_TOUCH is not set
|
||||
# CONFIG_RT_USING_LCD is not set
|
||||
# CONFIG_RT_USING_HWCRYPTO is not set
|
||||
# CONFIG_RT_USING_PULSE_ENCODER is not set
|
||||
# CONFIG_RT_USING_INPUT_CAPTURE is not set
|
||||
# CONFIG_RT_USING_DEV_BUS is not set
|
||||
# CONFIG_RT_USING_WIFI is not set
|
||||
# CONFIG_RT_USING_VIRTIO is not set
|
||||
|
||||
#
|
||||
# Using USB
|
||||
#
|
||||
# CONFIG_RT_USING_USB_HOST is not set
|
||||
# CONFIG_RT_USING_USB_DEVICE is not set
|
||||
# end of Using USB
|
||||
# end of Device Drivers
|
||||
|
||||
CONFIG_CPU_TYPE="aarch64_qemu"
|
||||
CONFIG_RTT_DIR="./"
|
||||
CONFIG_ARCH="aarch64"
|
||||
CONFIG_BOARD_NAME="aarch64_qemu"
|
||||
CONFIG_BUDDY_SLAB=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_CPU=4
|
||||
CONFIG_THREAD_BLOCK_SIZE=0x1000
|
||||
CONFIG_PAGE_SHIFT=12
|
||||
@@ -10,7 +10,7 @@ add_custom_target(
|
||||
srec_cat -output ${CMAKE_SOURCE_DIR}/build/output/kernel.img -binary
|
||||
${CMAKE_SOURCE_DIR}/build/output/bootstrap -binary -offset 0x0
|
||||
${CMAKE_SOURCE_DIR}/build/output/mkrtos -binary -offset ${CONFIG_KNL_OFFSET}
|
||||
${CMAKE_SOURCE_DIR}/build/output/init -binary -offset ${CONFIG_INIT_TASK_OFFSET}
|
||||
# ${CMAKE_SOURCE_DIR}/build/output/init -binary -offset ${CONFIG_INIT_TASK_OFFSET}
|
||||
${CMAKE_SOURCE_DIR}/build/output/rootfs.cpio -binary -offset ${CONFIG_BOOTFS_OFFSET}
|
||||
COMMAND
|
||||
cp ${CMAKE_SOURCE_DIR}/build/output/kernel.img ${CMAKE_SOURCE_DIR}/build/output/kernel.bin
|
||||
@@ -23,9 +23,9 @@ add_custom_target(
|
||||
add_dependencies(mkrtos_img_dump
|
||||
bootstrap_dump
|
||||
mkrtos_dump
|
||||
init_dump
|
||||
# init_dump
|
||||
# app_dump
|
||||
shell_dump
|
||||
# shell_dump
|
||||
# fatfs_dump
|
||||
# cpiofs_dump
|
||||
# tcc_dump
|
||||
|
||||
@@ -8,7 +8,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \
|
||||
-Wno-unused-variable \
|
||||
-Wno-builtin-declaration-mismatch \
|
||||
")
|
||||
set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS})
|
||||
|
||||
message(编译参数:${CMAKE_C_FLAGS})
|
||||
add_subdirectory(arch)
|
||||
@@ -37,7 +36,7 @@ add_dependencies(mkrtos.elf knl)
|
||||
add_dependencies(mkrtos.elf lib)
|
||||
|
||||
set_target_properties(mkrtos.elf PROPERTIES
|
||||
LINK_FLAGS "-T ${CMAKE_CURRENT_LIST_DIR}/link.lds -z max-page-size=0x1000 --gc-section ")
|
||||
LINK_FLAGS "-T ${CMAKE_CURRENT_LIST_DIR}/arch/${CONFIG_ARCH}/link.lds -z max-page-size=0x1000 --gc-section ")
|
||||
|
||||
add_custom_target(
|
||||
link_file_dump ALL
|
||||
@@ -48,8 +47,8 @@ add_custom_target(
|
||||
-DKNL_OFFSET=${CONFIG_KNL_OFFSET}
|
||||
# -DKNL_DATA_SIZE=$ENV{KNL_DATA_SIZE}
|
||||
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h
|
||||
-E -P -<${CMAKE_CURRENT_LIST_DIR}/link.lds.S>
|
||||
${CMAKE_CURRENT_LIST_DIR}/link.lds
|
||||
-E -P -<${CMAKE_CURRENT_LIST_DIR}/arch/${CONFIG_ARCH}/link.lds.S>
|
||||
${CMAKE_CURRENT_LIST_DIR}/arch/${CONFIG_ARCH}/link.lds
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
@@ -59,10 +58,14 @@ add_custom_target(
|
||||
COMMAND
|
||||
mkdir -p ${CMAKE_SOURCE_DIR}/build/output
|
||||
COMMAND
|
||||
mkdir -p ${CMAKE_SOURCE_DIR}/build/output/cpio
|
||||
COMMAND
|
||||
cp mkrtos.bin ${CMAKE_SOURCE_DIR}/build/output/mkrtos
|
||||
COMMAND
|
||||
cp mkrtos.elf ${CMAKE_SOURCE_DIR}/build/output/mkrtos.elf
|
||||
COMMAND
|
||||
cp mkrtos.elf ${CMAKE_SOURCE_DIR}/build/output/cpio/mkrtos.elf
|
||||
COMMAND
|
||||
${CMAKE_OBJDUMP} -s -S mkrtos.elf > ${CMAKE_SOURCE_DIR}/build/output/mkrtos.S
|
||||
COMMAND
|
||||
${CMAKE_SIZE} mkrtos.elf
|
||||
|
||||
@@ -5,6 +5,23 @@ menuconfig KNL_INFO
|
||||
bool "knl info set"
|
||||
default y
|
||||
if KNL_INFO
|
||||
config PAGE_SHIFT
|
||||
int "page shift"
|
||||
default 9
|
||||
config SMP
|
||||
bool "support smp."
|
||||
default n
|
||||
if SMP
|
||||
config CPU
|
||||
int "CPU Core number."
|
||||
default 1
|
||||
endif
|
||||
config BUDDY_SLAB
|
||||
bool "use BUDDY & SLAB"
|
||||
default n
|
||||
config THREAD_BLOCK_SIZE
|
||||
hex "kthread block size"
|
||||
default 0x400
|
||||
config KNL_TEXT_ADDR
|
||||
hex "The first address of the kernel text section"
|
||||
default 0x8000000
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
add_subdirectory(armv7m)
|
||||
add_subdirectory(${ARCH})
|
||||
|
||||
|
||||
|
||||
34
mkrtos_knl/arch/aarch64/CMakeLists.txt
Executable file
34
mkrtos_knl/arch/aarch64/CMakeLists.txt
Executable file
@@ -0,0 +1,34 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
file(GLOB deps *.c *.S)
|
||||
list(REMOVE_ITEM deps ${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/aarch64/link.lds.S)
|
||||
add_library(arch STATIC ${deps})
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__MPU_PRESENT=1 -DUSE_STDPERIPH_DRIVER=1 ")
|
||||
message(=======${CONFIG_CPU_TYPE})
|
||||
|
||||
if (${CONFIG_CPU_TYPE} STREQUAL "aarch64_qemu" )
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${ARCH}/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/drv
|
||||
)
|
||||
|
||||
add_subdirectory(${CONFIG_CPU_TYPE})
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
arch
|
||||
PUBLIC
|
||||
knl_bsp
|
||||
)
|
||||
target_include_directories(
|
||||
arch
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/lib
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
|
||||
|
||||
)
|
||||
21
mkrtos_knl/arch/aarch64/aarch64_ptregs.h
Normal file
21
mkrtos_knl/arch/aarch64/aarch64_ptregs.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* pt_regs栈框,用来保存中断现场或者异常现场
|
||||
*
|
||||
* pt_regs栈框通常位于进程的内核栈的顶部。
|
||||
* pt_regs栈框通常位于进程的内核栈的顶部。
|
||||
* 而sp的栈顶通常 紧挨着 pt_regs栈框,在pt_regs栈框下方。
|
||||
* 保存内容:
|
||||
* x0 ~ x30 通用寄存器
|
||||
* sp
|
||||
* pc
|
||||
* pstate
|
||||
*/
|
||||
typedef struct pt_regs
|
||||
{
|
||||
unsigned long regs[31];
|
||||
unsigned long sp;
|
||||
unsigned long pc;
|
||||
unsigned long pstate;
|
||||
} pt_regs_t;
|
||||
18
mkrtos_knl/arch/aarch64/aarch64_qemu/CMakeLists.txt
Executable file
18
mkrtos_knl/arch/aarch64/aarch64_qemu/CMakeLists.txt
Executable file
@@ -0,0 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
|
||||
file(GLOB_RECURSE deps *.s *.S *.C *.c)
|
||||
# list(APPEND deps ${bsp_src})
|
||||
|
||||
add_library(knl_bsp STATIC ${deps})
|
||||
target_include_directories(
|
||||
knl_bsp
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/lib
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/inc
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/
|
||||
|
||||
)
|
||||
108
mkrtos_knl/arch/aarch64/aarch64_qemu/arch.c
Normal file
108
mkrtos_knl/arch/aarch64/aarch64_qemu/arch.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @file arch.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-09-25
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "arch.h"
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
#include "init.h"
|
||||
#include "config.h"
|
||||
#include "thread.h"
|
||||
#include "mk_sys.h"
|
||||
#include "mpu.h"
|
||||
#include <psci.h>
|
||||
#include <arm_gicv2.h>
|
||||
#include <timer/timer.h>
|
||||
#include <hyp.h>
|
||||
__ALIGN__(THREAD_BLOCK_SIZE)
|
||||
static uint8_t thread_knl_stack[THREAD_BLOCK_SIZE] = {0};
|
||||
void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE;
|
||||
|
||||
/**
|
||||
* 进行调度
|
||||
*/
|
||||
void to_sche(void)
|
||||
{
|
||||
// 开启pensv中断
|
||||
/*TODO:*/
|
||||
}
|
||||
/**
|
||||
* 进行一些系统的初始化
|
||||
*/
|
||||
void sys_startup(void)
|
||||
{
|
||||
/*TODO:*/
|
||||
init_arm_hyp();
|
||||
timer_init(arch_get_current_cpu_id());
|
||||
}
|
||||
void sys_reset(void)
|
||||
{
|
||||
/*TODO:*/
|
||||
}
|
||||
void arch_disable_irq(int inx)
|
||||
{
|
||||
/*TODO:*/
|
||||
}
|
||||
void arch_enable_irq(int inx)
|
||||
{
|
||||
/*TODO:*/
|
||||
}
|
||||
uint32_t arch_get_sys_clk(void)
|
||||
{
|
||||
/*TODO:*/
|
||||
return 0;
|
||||
}
|
||||
void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio)
|
||||
{
|
||||
/*TODO:*/
|
||||
}
|
||||
extern char _data_boot[], _edata_boot[];
|
||||
extern char _text_boot[], _etext_boot[];
|
||||
extern char _text[], _etext[];
|
||||
extern char _rodata[], _erodata[];
|
||||
extern char _data[], _edata[];
|
||||
extern char _bss[], _ebss[];
|
||||
extern char _buddy_data_start[];
|
||||
extern char _buddy_data_end[];
|
||||
|
||||
static void print_mem(void)
|
||||
{
|
||||
printk("MKRTOS image layout:\n");
|
||||
printk(" .text.boot: 0x%08lx - 0x%08lx (%6ld B)\n",
|
||||
(unsigned long)_text_boot, (unsigned long)_etext_boot,
|
||||
(unsigned long)(_etext_boot - _text_boot));
|
||||
printk(" .text.data: 0x%08lx - 0x%08lx (%6ld B)\n",
|
||||
(unsigned long)_data_boot, (unsigned long)_edata_boot,
|
||||
(unsigned long)(_edata_boot - _data_boot));
|
||||
printk(" .text: 0x%08lx - 0x%08lx (%6ld B)\n",
|
||||
(unsigned long)_text, (unsigned long)_etext,
|
||||
(unsigned long)(_etext - _text));
|
||||
printk(" .rodata: 0x%08lx - 0x%08lx (%6ld B)\n",
|
||||
(unsigned long)_rodata, (unsigned long)_erodata,
|
||||
(unsigned long)(_erodata - _rodata));
|
||||
printk(" .data: 0x%08lx - 0x%08lx (%6ld B)\n",
|
||||
(unsigned long)_data, (unsigned long)_edata,
|
||||
(unsigned long)(_edata - _data));
|
||||
printk(" .bss: 0x%08lx - 0x%08lx (%6ld B)\n",
|
||||
(unsigned long)_bss, (unsigned long)_ebss,
|
||||
(unsigned long)(_ebss - _bss));
|
||||
printk(" .buddy: 0x%08lx - 0x%08lx (%6ld B)\n",
|
||||
(unsigned long)_buddy_data_start, (unsigned long)_buddy_data_end,
|
||||
(unsigned long)(_buddy_data_end - _buddy_data_start));
|
||||
}
|
||||
|
||||
void arch_init(void)
|
||||
{
|
||||
printk("MKRTOS running on EL:%d\n", arch_get_currentel() >> 2);
|
||||
print_mem();
|
||||
psci_init();
|
||||
gic_init(arm_gicv2_get_global(),
|
||||
0x08000000, 0x08010000); /*TODO:*/
|
||||
}
|
||||
INIT_LOW_HARD(arch_init);
|
||||
167
mkrtos_knl/arch/aarch64/aarch64_qemu/arch.h
Executable file
167
mkrtos_knl/arch/aarch64/aarch64_qemu/arch.h
Executable file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* @file arch.h
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-10-04
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "arch.h"
|
||||
#include <thread_arch.h>
|
||||
#include <aarch64_ptregs.h>
|
||||
#define LOG_INTR_NO 37 // USART1_IRQn
|
||||
|
||||
#define _barrier() __asm__ __volatile__("" : : : "memory")
|
||||
#define _dmb(ins) \
|
||||
asm volatile("dmb " #ins : : : "memory")
|
||||
#define _isb() asm volatile("isb" : : : "memory")
|
||||
#define _dsb(ins) \
|
||||
asm volatile("dsb " #ins : : : "memory")
|
||||
|
||||
#define read_reg(addr) (*((volatile umword_t *)(addr)))
|
||||
#define write_reg(addr, data) \
|
||||
do \
|
||||
{ \
|
||||
_barrier(); \
|
||||
(*((volatile umword_t *)(addr))) = data; \
|
||||
_barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define read_reg32(addr) (*((volatile uint32_t *)(addr)))
|
||||
#define write_reg32(addr, data) \
|
||||
do \
|
||||
{ \
|
||||
_barrier(); \
|
||||
(*((volatile uint32_t *)(addr))) = (uint32_t)data; \
|
||||
_barrier(); \
|
||||
} while (0)
|
||||
|
||||
//! 读取系统寄存器
|
||||
#define read_sysreg(reg) ({ \
|
||||
unsigned long _val; \
|
||||
asm volatile("mrs %0, " #reg \
|
||||
: "=r"(_val)); \
|
||||
_val; \
|
||||
})
|
||||
//! 写入系统寄存器
|
||||
#define write_sysreg(val, reg) ({ \
|
||||
unsigned long _val = (unsigned long)val; \
|
||||
asm volatile("msr " #reg ", %x0" ::"rZ"(_val)); \
|
||||
})
|
||||
|
||||
static inline uint64_t arch_get_currentel(void)
|
||||
{
|
||||
unsigned long _val;
|
||||
|
||||
asm volatile("mrs %0, CurrentEL"
|
||||
: "=r"(_val));
|
||||
return _val;
|
||||
}
|
||||
static inline int arch_get_current_cpu_id(void)
|
||||
{
|
||||
return read_sysreg(mpidr_el1) & 0XFFUL;
|
||||
}
|
||||
|
||||
#define is_run_knl() \
|
||||
({ \
|
||||
/*TODO:*/ \
|
||||
})
|
||||
|
||||
void to_sche(void);
|
||||
|
||||
#define get_sp() ( \
|
||||
{ \
|
||||
mword_t sp; \
|
||||
do \
|
||||
{ \
|
||||
asm volatile("mov %0, sp" : "=r"(sp)); \
|
||||
} while (0); \
|
||||
sp; \
|
||||
})
|
||||
#define set_sp(sp) ( \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
asm volatile("mov sp, %0" : : "r"(sp)); \
|
||||
} while (0); \
|
||||
})
|
||||
static inline umword_t arch_get_sp(void)
|
||||
{
|
||||
return get_sp();
|
||||
}
|
||||
static inline umword_t arch_get_isr_no(void)
|
||||
{
|
||||
/*TODO:获取中断号*/
|
||||
return 0;
|
||||
}
|
||||
static inline void arch_set_knl_sp(umword_t sp)
|
||||
{
|
||||
set_sp(sp);
|
||||
}
|
||||
static inline umword_t arch_get_knl_sp(void)
|
||||
{
|
||||
return get_sp();
|
||||
}
|
||||
static inline void arch_set_user_sp(umword_t sp)
|
||||
{
|
||||
}
|
||||
static inline umword_t arch_get_user_sp(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void arch_disable_irq(int inx);
|
||||
void arch_enable_irq(int inx);
|
||||
void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio);
|
||||
|
||||
/**
|
||||
* 开中断
|
||||
*/
|
||||
#define sti() \
|
||||
do \
|
||||
{ \
|
||||
asm volatile( \
|
||||
"msr daifclr, #3" \
|
||||
: \
|
||||
: \
|
||||
: "memory"); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* 关中断
|
||||
*/
|
||||
#define cli() \
|
||||
do \
|
||||
{ \
|
||||
asm volatile( \
|
||||
"msr daifset, #3" \
|
||||
: \
|
||||
: \
|
||||
: "memory"); \
|
||||
} while (0)
|
||||
|
||||
static inline __attribute__((optimize(0))) void preemption(void)
|
||||
{
|
||||
sti();
|
||||
cli();
|
||||
}
|
||||
|
||||
static inline umword_t intr_status(void)
|
||||
{
|
||||
umword_t ret;
|
||||
|
||||
asm volatile("mrs %0, daif" : "=r"(ret));
|
||||
return !(ret & 0xc0);
|
||||
}
|
||||
|
||||
void sys_startup(void);
|
||||
void sys_reset(void);
|
||||
|
||||
// systick.c
|
||||
umword_t sys_tick_cnt_get(void);
|
||||
|
||||
uint32_t arch_get_sys_clk(void);
|
||||
118
mkrtos_knl/arch/aarch64/aarch64_qemu/entry.S
Normal file
118
mkrtos_knl/arch/aarch64/aarch64_qemu/entry.S
Normal file
@@ -0,0 +1,118 @@
|
||||
#include <asm/sysregs.h>
|
||||
#include <asm_config.h>
|
||||
.section .rodata
|
||||
.align 3
|
||||
.globl string1
|
||||
string1:
|
||||
.string "Booting at EL"
|
||||
|
||||
/* 8字节对齐,否则会出错*/
|
||||
.align 3
|
||||
.globl sp_addr
|
||||
.section ".data.boot"
|
||||
sp_addr:
|
||||
.quad per_cpu_stack + THREAD_BLOCK_SIZE - 8 - PT_REGS_SIZE //pt regs is 320 bytes.
|
||||
.align 3
|
||||
.globl cpio_images
|
||||
.section ".data.boot"
|
||||
cpio_images:
|
||||
.quad 0 //pt regs is 320 bytes.
|
||||
|
||||
.align 3
|
||||
.global cpu_jump_addr
|
||||
.section ".data.boot"
|
||||
cpu_jump_addr:
|
||||
.zero (32) //TODO: cpu_num*MWORD_BYTES
|
||||
|
||||
.align 3
|
||||
.global per_cpu_stack_addr
|
||||
.section ".data.boot"
|
||||
per_cpu_stack_addr:
|
||||
.zero (32) //TODO: cpu_num*MWORD_BYTES
|
||||
|
||||
.section ".text.boot"
|
||||
.globl _start
|
||||
_start:
|
||||
msr daifset, #0xf // 关闭中断
|
||||
mov x9, x0
|
||||
#ifdef CONFIG_DEBUG_ON_EARLY_ASM
|
||||
/* init uart and print the string*/
|
||||
bl __init_uart
|
||||
#endif
|
||||
|
||||
mrs x5, CurrentEL
|
||||
cmp x5, #CurrentEL_EL3
|
||||
b.eq el3_entry //进入el3的处理函数
|
||||
b el2_entry
|
||||
|
||||
el3_entry:
|
||||
#ifdef CONFIG_DEBUG_ON_EARLY_ASM
|
||||
bl print_el
|
||||
#endif
|
||||
ldr x0, =SCTLR_EL2_VALUE_MMU_DISABLED
|
||||
msr sctlr_el2, x0
|
||||
|
||||
ldr x0, =(1<<31)|(1<<4)|(1<<29)
|
||||
msr hcr_el2, x0
|
||||
|
||||
ldr x0, =((1UL) | (1UL<<7) | (1UL<<8) | (1UL<<10))
|
||||
msr scr_el3, x0
|
||||
|
||||
ldr x0, =SPSR_EL2
|
||||
msr spsr_el3, x0
|
||||
|
||||
adr x0, el2_entry
|
||||
msr elr_el3, x0
|
||||
|
||||
eret
|
||||
|
||||
el2_entry: //进入el2
|
||||
|
||||
|
||||
/* Generic timers. */
|
||||
//mrs x0, cnthctl_el2
|
||||
//orr x0, x0, #3 // Enable EL1 physical timers
|
||||
//msr cnthctl_el2, x0
|
||||
//msr cntvoff_el2, xzr // Clear virtual offset
|
||||
|
||||
mrs x0, cpacr_el1
|
||||
orr x0, x0, 0x3 << 20
|
||||
msr cpacr_el1, x0
|
||||
|
||||
/* 设置异常向量表基地址到vbar寄存器 */
|
||||
ldr x5, =vectors
|
||||
msr vbar_el2, x5
|
||||
isb
|
||||
|
||||
//进入多核启动流程
|
||||
mrs x0, mpidr_el1 // 读取该寄存器获取处理器id
|
||||
and x0, x0,#0xFF // Check processor id
|
||||
cbz x0, master // Hang for all non-primary CPU
|
||||
|
||||
//spin table
|
||||
ldr x1, = cpu_jump_addr
|
||||
lsl x2, x0, MWORD_SHIFT
|
||||
spin_jump:
|
||||
ldr x3, [x1, x2]
|
||||
cbz x3, spin_jump
|
||||
ldr x4, = per_cpu_stack_addr
|
||||
ldr x4, [x4, x2] //获取sp启动的值
|
||||
mov sp, x4 //cpu启动的sp地址
|
||||
br x3
|
||||
b .
|
||||
master:
|
||||
ldr x0, = cpio_images
|
||||
str x9, [x0, #0]
|
||||
/* set sp to top of init_task_union */
|
||||
ldr x8, =sp_addr
|
||||
ldr x9, [x8]
|
||||
mov sp, x9
|
||||
bl boot_mapping
|
||||
proc_hang:
|
||||
b proc_hang // should never come here
|
||||
|
||||
.globl jump_kenel_main
|
||||
jump_kenel_main:
|
||||
ldr x1, = start_kernel
|
||||
br x1
|
||||
b .
|
||||
6
mkrtos_knl/arch/aarch64/aarch64_qemu/mk_sys.h
Executable file
6
mkrtos_knl/arch/aarch64/aarch64_qemu/mk_sys.h
Executable file
@@ -0,0 +1,6 @@
|
||||
#ifndef __SYS_H
|
||||
#define __SYS_H
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
268
mkrtos_knl/arch/aarch64/aarch64_qemu/vector.S
Executable file
268
mkrtos_knl/arch/aarch64/aarch64_qemu/vector.S
Executable file
@@ -0,0 +1,268 @@
|
||||
#include <asm_config.h>
|
||||
#include <asm_offset.h>
|
||||
|
||||
#define BAD_SYNC 0
|
||||
#define BAD_IRQ 1
|
||||
#define BAD_FIQ 2
|
||||
#define BAD_ERROR 3
|
||||
|
||||
|
||||
/*保存x0~x29,x30(lr),sp, elr, spsr保存到 栈中
|
||||
*/
|
||||
.macro kernel_entry el
|
||||
/*
|
||||
SP指向了栈底, S_FRAME_SIZE表示一个栈框的大小.
|
||||
定义一个struct pt_regs来描述一个栈框,
|
||||
用在异常发生时保存上下文.
|
||||
*/
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
|
||||
/*
|
||||
保存通用寄存器x0~x29到栈框里pt_regs->x0~x29
|
||||
*/
|
||||
stp x0, x1, [sp, #16 *0]
|
||||
stp x2, x3, [sp, #16 *1]
|
||||
stp x4, x5, [sp, #16 *2]
|
||||
stp x6, x7, [sp, #16 *3]
|
||||
stp x8, x9, [sp, #16 *4]
|
||||
stp x10, x11, [sp, #16 *5]
|
||||
stp x12, x13, [sp, #16 *6]
|
||||
stp x14, x15, [sp, #16 *7]
|
||||
stp x16, x17, [sp, #16 *8]
|
||||
stp x18, x19, [sp, #16 *9]
|
||||
stp x20, x21, [sp, #16 *10]
|
||||
stp x22, x23, [sp, #16 *11]
|
||||
stp x24, x25, [sp, #16 *12]
|
||||
stp x26, x27, [sp, #16 *13]
|
||||
stp x28, x29, [sp, #16 *14]
|
||||
|
||||
/* x21: 栈顶 的位置*/
|
||||
add x21, sp, #S_FRAME_SIZE
|
||||
mov x0, sp
|
||||
|
||||
mrs x22, elr_el2
|
||||
mrs x23, spsr_el2
|
||||
|
||||
/* 把lr保存到pt_regs->lr, 把sp保存到pt_regs->sp位置*/
|
||||
stp lr, x21, [sp, #S_LR]
|
||||
/* 把elr_el1保存到pt_regs->pc中
|
||||
把spsr_elr保存到pt_regs->pstate中*/
|
||||
stp x22, x23, [sp, #S_PC]
|
||||
.endm
|
||||
|
||||
/*
|
||||
恢复异常发生时保存下来的上下文
|
||||
*/
|
||||
.macro kernel_exit el
|
||||
/* 从pt_regs->pc中恢复elr_el1,
|
||||
从pt_regs->pstate中恢复spsr_el1
|
||||
*/
|
||||
ldp x21, x22, [sp, #S_PC] // load ELR, SPSR
|
||||
msr elr_el2, x21 // set up the return data
|
||||
msr spsr_el2, x22
|
||||
|
||||
ldp x0, x1, [sp, #16 * 0]
|
||||
ldp x2, x3, [sp, #16 * 1]
|
||||
ldp x4, x5, [sp, #16 * 2]
|
||||
ldp x6, x7, [sp, #16 * 3]
|
||||
ldp x8, x9, [sp, #16 * 4]
|
||||
ldp x10, x11, [sp, #16 * 5]
|
||||
ldp x12, x13, [sp, #16 * 6]
|
||||
ldp x14, x15, [sp, #16 * 7]
|
||||
ldp x16, x17, [sp, #16 * 8]
|
||||
ldp x18, x19, [sp, #16 * 9]
|
||||
ldp x20, x21, [sp, #16 * 10]
|
||||
ldp x22, x23, [sp, #16 * 11]
|
||||
ldp x24, x25, [sp, #16 * 12]
|
||||
ldp x26, x27, [sp, #16 * 13]
|
||||
ldp x28, x29, [sp, #16 * 14]
|
||||
|
||||
/* 从pt_regs->lr中恢复lr*/
|
||||
ldr lr, [sp, #S_LR]
|
||||
add sp, sp, #S_FRAME_SIZE // restore sp
|
||||
eret // return to kernel
|
||||
.endm
|
||||
|
||||
/*
|
||||
处理无效的异常向量
|
||||
*/
|
||||
.macro inv_entry el, reason
|
||||
//kernel_entry el
|
||||
mov x0, sp
|
||||
mov x1, #\reason
|
||||
mrs x2, esr_el2
|
||||
b bad_mode
|
||||
.endm
|
||||
|
||||
/*
|
||||
vector table entry
|
||||
每个表项是128字节, align 7表示128字节对齐
|
||||
*/
|
||||
.macro vtentry label
|
||||
.align 7
|
||||
b \label
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Vector Table
|
||||
*
|
||||
* ARM64的异常向量表一共占用2048个字节
|
||||
* 分成4组,每组4个表项,每个表项占128字节
|
||||
* 参见ARMv8 spec v8.6第D1.10节
|
||||
* align 11表示2048字节对齐
|
||||
*/
|
||||
.align 11
|
||||
.global vectors
|
||||
.section ".text.boot"
|
||||
vectors:
|
||||
/* Current EL with SP0
|
||||
当前系统运行在EL1时使用EL0的栈指针SP
|
||||
这是一种异常错误的类型
|
||||
*/
|
||||
vtentry el1_sync_invalid
|
||||
vtentry el1_irq_invalid
|
||||
vtentry el1_fiq_invalid
|
||||
vtentry el1_error_invalid
|
||||
|
||||
/* Current EL with SPx
|
||||
当前系统运行在EL1时使用EL1的栈指针SP
|
||||
这说明系统在内核态发生了异常
|
||||
|
||||
Note: 我们暂时只实现IRQ中断
|
||||
*/
|
||||
|
||||
vtentry el1_sync_invalid
|
||||
vtentry el1_irq
|
||||
vtentry el1_fiq_invalid
|
||||
vtentry el1_error_invalid
|
||||
|
||||
/* Lower EL using AArch64
|
||||
在用户态的aarch64的程序发生了异常
|
||||
*/
|
||||
vtentry el1_sync_invalid
|
||||
vtentry el1_irq
|
||||
vtentry el0_fiq_invalid
|
||||
vtentry el0_error_invalid
|
||||
|
||||
/* Lower EL using AArch32
|
||||
在用户态的aarch32的程序发生了异常
|
||||
*/
|
||||
vtentry el0_sync_invalid
|
||||
vtentry el0_irq_invalid
|
||||
vtentry el0_fiq_invalid
|
||||
vtentry el0_error_invalid
|
||||
el1_sync_invalid:
|
||||
kernel_entry 2
|
||||
//mrs x25, ESR_EL2
|
||||
//lsr x24, x25, 26
|
||||
//cmp x24, 0x16
|
||||
//b.eq el2_svc
|
||||
//inv_entry 0, BAD_SYNC
|
||||
//el2_svc:
|
||||
// mov x0, sp
|
||||
// bl el2_svc_handler
|
||||
bl thread_sync_entry
|
||||
b ret_to_user
|
||||
|
||||
el1_irq_invalid:
|
||||
inv_entry 1, BAD_IRQ
|
||||
el1_fiq_invalid:
|
||||
inv_entry 1, BAD_FIQ
|
||||
el1_error_invalid:
|
||||
inv_entry 1, BAD_ERROR
|
||||
el0_sync_invalid:
|
||||
inv_entry 0, BAD_SYNC
|
||||
el0_irq_invalid:
|
||||
inv_entry 0, BAD_IRQ
|
||||
el0_fiq_invalid:
|
||||
inv_entry 0, BAD_FIQ
|
||||
el0_error_invalid:
|
||||
inv_entry 0, BAD_ERROR
|
||||
tsk .req x28 // current thread_info
|
||||
|
||||
.macro get_thread_info, rd
|
||||
mov \rd, sp
|
||||
and \rd, \rd, #(~(4096 - 1)) // top of stack
|
||||
.endm
|
||||
el1_irq:
|
||||
kernel_entry 2
|
||||
bl entry_handler
|
||||
get_thread_info tsk
|
||||
// bl 2f
|
||||
//1:
|
||||
// kernel_exit 2
|
||||
//2:
|
||||
// mov x24, lr
|
||||
//bl sched_printf
|
||||
bl SysTick_Handler
|
||||
kernel_exit 2
|
||||
// ret x24
|
||||
//
|
||||
|
||||
//string_test:
|
||||
// .string "t"
|
||||
|
||||
.global trigger_alignment
|
||||
trigger_alignment:
|
||||
ldr x0, =0x80002
|
||||
str wzr, [x0]
|
||||
|
||||
/*
|
||||
对于用户进程,暂时还没实现
|
||||
*/
|
||||
.align 2
|
||||
.global ret_to_user
|
||||
ret_to_user:
|
||||
kernel_exit 2
|
||||
//inv_entry 0, BAD_ERROR
|
||||
/*
|
||||
对于内核线程:
|
||||
x19保存了进程回调函数的入口
|
||||
x20保存进程的回调函数的参数
|
||||
对于用户线程:
|
||||
x19为零时,跳转到ret_to_user执行
|
||||
*/
|
||||
.align 2
|
||||
.global ret_form_run
|
||||
ret_form_run:
|
||||
bl sched_tail
|
||||
cbz x19, 1f
|
||||
mov x0, x20
|
||||
blr x19
|
||||
1:
|
||||
//ldr x19, =test_user_stack
|
||||
//add x19, x19, #(4096 - 8)
|
||||
//msr sp_el1, x19
|
||||
b ret_to_user
|
||||
|
||||
/* 进程切换: 保存prev进程的上下文,并且恢复next进程
|
||||
的上下文
|
||||
cpu_switch_to(struct cpu_context *prev,
|
||||
struct cpu_context *next);
|
||||
|
||||
需要保存的上下文: x19 ~ x29, sp, lr
|
||||
保存到进程的task_struct->cpu_context
|
||||
*/
|
||||
.align
|
||||
.global cpu_switch_to
|
||||
cpu_switch_to:
|
||||
mov x8, x0
|
||||
mov x9, sp
|
||||
stp x19, x20, [x8], #16
|
||||
stp x21, x22, [x8], #16
|
||||
stp x23, x24, [x8], #16
|
||||
stp x25, x26, [x8], #16
|
||||
stp x27, x28, [x8], #16
|
||||
stp x29, x9, [x8], #16
|
||||
str lr, [x8]
|
||||
|
||||
mov x8, x1
|
||||
ldp x19, x20, [x8], #16
|
||||
ldp x21, x22, [x8], #16
|
||||
ldp x23, x24, [x8], #16
|
||||
ldp x25, x26, [x8], #16
|
||||
ldp x27, x28, [x8], #16
|
||||
ldp x29, x9, [x8], #16
|
||||
ldr lr, [x8]
|
||||
mov sp, x9
|
||||
ret
|
||||
10
mkrtos_knl/arch/aarch64/arm_gicv2.c
Normal file
10
mkrtos_knl/arch/aarch64/arm_gicv2.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <arm_gicv2.h>
|
||||
|
||||
static gic_t m_irq;
|
||||
|
||||
|
||||
gic_t *arm_gicv2_get_global(void)
|
||||
{
|
||||
return &m_irq;
|
||||
}
|
||||
|
||||
290
mkrtos_knl/arch/aarch64/arm_gicv2.h
Normal file
290
mkrtos_knl/arch/aarch64/arm_gicv2.h
Normal file
@@ -0,0 +1,290 @@
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
#include <arch.h>
|
||||
#include <printk.h>
|
||||
#include <util.h>
|
||||
#include <assert.h>
|
||||
// #include <timer.h>
|
||||
/*
|
||||
* ID0-ID15,分配给SGI (一般会将0-7给REE,8-15给TEE)
|
||||
* ID16-ID31,分配给PPI
|
||||
* ID32-ID1019,分配给SPI
|
||||
* ID1020-ID1023,特殊中断号
|
||||
* ID1024-ID8191,reserved
|
||||
* 8192及其以上,LPI
|
||||
*/
|
||||
typedef struct gic
|
||||
{
|
||||
uint16_t irqs_number; //!< 支持的irq数量
|
||||
|
||||
addr_t disp_base_addr; //!< 分发器起始地址
|
||||
addr_t inter_base_addr; //!< 接口起始地址
|
||||
} gic_t;
|
||||
|
||||
// #define GIC2_BASE (0xFF840000)
|
||||
// #define GIC2_GICD_BASE (GIC2_BASE + 0x1000)
|
||||
|
||||
#define GICD_CTLR(GIC2_GICD_BASE) (0x0 + GIC2_GICD_BASE)
|
||||
#define GICD_TYPER(GIC2_GICD_BASE) (0x4 + GIC2_GICD_BASE)
|
||||
#define GICD_IIDR(GIC2_GICD_BASE) (0x8 + GIC2_GICD_BASE)
|
||||
#define GICD_IGROUPRn(GIC2_GICD_BASE) (0x80 + GIC2_GICD_BASE)
|
||||
#define GICD_ISENABLERn(GIC2_GICD_BASE) (0x100 + GIC2_GICD_BASE)
|
||||
#define GICD_ICENABLERn(GIC2_GICD_BASE) (0x180 + GIC2_GICD_BASE)
|
||||
#define GICD_ISPENDRn(GIC2_GICD_BASE) (0x200 + GIC2_GICD_BASE)
|
||||
#define GICD_ICPENDRn(GIC2_GICD_BASE) (0x280 + GIC2_GICD_BASE)
|
||||
#define GICD_ISACTIVERn(GIC2_GICD_BASE) (0x300 + GIC2_GICD_BASE)
|
||||
#define GICD_ICACTIVERn(GIC2_GICD_BASE) (0x380 + GIC2_GICD_BASE)
|
||||
#define GICD_IPRIORITYRn(GIC2_GICD_BASE) (0x400 + GIC2_GICD_BASE)
|
||||
#define GICD_ITARGETSRn(GIC2_GICD_BASE) (0x800 + GIC2_GICD_BASE)
|
||||
#define GICD_ICFGRn(GIC2_GICD_BASE) (0xC00 + GIC2_GICD_BASE)
|
||||
#define GICD_SGIR(GIC2_GICD_BASE) (0xf00 + GIC2_GICD_BASE)
|
||||
#define GICD_CPENDSGIRn(GIC2_GICD_BASE) (0xf10 + GIC2_GICD_BASE)
|
||||
#define GICD_SPENDSGIRn(GIC2_GICD_BASE) (0xf20 + GIC2_GICD_BASE)
|
||||
|
||||
// #define (GIC2_GICC_BASE) (GIC2_BASE + 0x2000)
|
||||
#define GICC_CTLR(GIC2_GICC_BASE) (0x0 + GIC2_GICC_BASE)
|
||||
#define GICC_PMR(GIC2_GICC_BASE) (0x4 + GIC2_GICC_BASE)
|
||||
#define GICC_BPR(GIC2_GICC_BASE) (0x8 + GIC2_GICC_BASE)
|
||||
#define GICC_IAR(GIC2_GICC_BASE) (0xc + GIC2_GICC_BASE)
|
||||
#define GICC_EOIR(GIC2_GICC_BASE) (0x10 + GIC2_GICC_BASE)
|
||||
#define GICC_RPR(GIC2_GICC_BASE) (0x14 + GIC2_GICC_BASE)
|
||||
#define GICC_HPPIR(GIC2_GICC_BASE) (0x18 + GIC2_GICC_BASE)
|
||||
#define GICC_APRn(GIC2_GICC_BASE) (0xd0 + GIC2_GICC_BASE)
|
||||
#define GICC_IIDR(GIC2_GICC_BASE) (0x00FC + GIC2_GICC_BASE)
|
||||
|
||||
#define MAX_INTR_NO 1020
|
||||
|
||||
static inline void gic2_set_disp_cpu(gic_t *irq, uint64_t cpu_mask)
|
||||
{
|
||||
write_reg32(GICD_SGIR(irq->disp_base_addr),
|
||||
read_reg32(GICD_SGIR(irq->disp_base_addr)) |
|
||||
((cpu_mask & 0xff) << 16UL));
|
||||
}
|
||||
static inline void gic2_clear_disp_cpu(gic_t *irq, uint8_t cpu_mask)
|
||||
{
|
||||
write_reg32(GICD_SGIR(irq->disp_base_addr),
|
||||
read_reg32(GICD_SGIR(irq->disp_base_addr)) &
|
||||
((~(cpu_mask & 0xff)) << 16UL));
|
||||
}
|
||||
static inline void gic2_set_unmask(gic_t *irq, uint64_t inx)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
void *addr = (void *)(GICD_ISENABLERn(irq->disp_base_addr) + ((inx >> 5) << 2));
|
||||
uint32_t tmp = read_reg32(addr);
|
||||
uint32_t bit_inx = inx % 32;
|
||||
|
||||
MK_CLR_BIT(tmp, bit_inx);
|
||||
tmp |= (1) << bit_inx;
|
||||
write_reg32((uint32_t *)addr, tmp);
|
||||
}
|
||||
static inline void gic2_set_mask(gic_t *irq, uint64_t inx)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
void *addr = (void *)(GICD_ICENABLERn(irq->disp_base_addr) + ((inx >> 5) << 2));
|
||||
uint32_t tmp = read_reg32(addr);
|
||||
uint32_t bit_inx = inx % 32;
|
||||
|
||||
MK_CLR_BIT(tmp, bit_inx);
|
||||
tmp |= (1) << bit_inx;
|
||||
write_reg32((uint32_t *)addr, tmp);
|
||||
}
|
||||
static inline bool_t gic2_get_mask(gic_t *irq, uint64_t inx)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
void *addr = (void *)(GICD_ISENABLERn(irq->disp_base_addr) +
|
||||
((inx >> 5) << 2));
|
||||
uint32_t tmp = read_reg32((uint32_t *)addr);
|
||||
uint32_t bit_inx = inx % 32;
|
||||
|
||||
return !!((tmp >> bit_inx) & 0x1ul);
|
||||
}
|
||||
static inline void gic2_set_active(gic_t *irq, uint64_t inx)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
void *addr = (void *)(GICD_ISACTIVERn(irq->disp_base_addr) + ((inx >> 5) << 2));
|
||||
uint32_t tmp = read_reg32(addr);
|
||||
uint32_t bit_inx = inx % 32;
|
||||
|
||||
MK_CLR_BIT(tmp, bit_inx);
|
||||
tmp |= (1) << bit_inx;
|
||||
write_reg32((uint32_t *)addr, tmp);
|
||||
}
|
||||
static inline void gic2_clear_active(gic_t *irq, uint64_t inx)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
void *addr = (void *)(GICD_ICACTIVERn(irq->disp_base_addr) + ((inx >> 5) << 2));
|
||||
uint32_t tmp = read_reg32(addr);
|
||||
uint32_t bit_inx = inx % 32;
|
||||
|
||||
MK_CLR_BIT(tmp, bit_inx);
|
||||
tmp |= (1) << bit_inx;
|
||||
write_reg32((uint32_t *)addr, tmp);
|
||||
}
|
||||
static inline void gic2_set_pending(gic_t *irq, uint64_t inx)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
void *addr = (void *)(GICD_ISPENDRn(irq->disp_base_addr) + ((inx >> 5) << 2));
|
||||
uint32_t tmp = read_reg32(addr);
|
||||
uint32_t bit_inx = inx % 32;
|
||||
|
||||
MK_CLR_BIT(tmp, bit_inx);
|
||||
tmp |= (1) << bit_inx;
|
||||
write_reg32((uint32_t *)addr, tmp);
|
||||
}
|
||||
static inline void gic2_clear_pending(gic_t *irq, uint64_t inx)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
void *addr = (void *)(GICD_ICPENDRn(irq->disp_base_addr) + ((inx >> 5) << 2));
|
||||
uint32_t tmp = read_reg32(addr);
|
||||
uint32_t bit_inx = inx % 32;
|
||||
|
||||
MK_CLR_BIT(tmp, bit_inx);
|
||||
tmp |= (1) << bit_inx;
|
||||
write_reg32((uint32_t *)addr, tmp);
|
||||
}
|
||||
|
||||
static inline void gic2_set_target_cpu(gic_t *irq, uint64_t inx, uint64_t target_cpu)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
// assert(target_cpu < 8);
|
||||
void *addr = (void *)(GICD_ITARGETSRn((irq->disp_base_addr)) +
|
||||
((inx >> 2) << 2));
|
||||
uint32_t bit_inx = inx % 4;
|
||||
uint32_t tmp = read_reg32((uint32_t *)addr);
|
||||
|
||||
tmp &= ~(0xffUL << (bit_inx << 3));
|
||||
tmp |= target_cpu << (bit_inx << 3);
|
||||
write_reg32((uint32_t *)addr, tmp);
|
||||
tmp = read_reg32((uint32_t *)addr);
|
||||
}
|
||||
static inline uint64_t gic2_get_target_cpu(gic_t *irq, uint64_t inx)
|
||||
{
|
||||
assert(inx < MAX_INTR_NO);
|
||||
void *addr = (void *)(GICD_ITARGETSRn(irq->disp_base_addr) +
|
||||
((inx >> 2) << 2));
|
||||
uint32_t bit_inx = inx % 4;
|
||||
uint32_t tmp = read_reg32((uint32_t *)addr);
|
||||
|
||||
return (tmp >> (bit_inx << 3)) & 0xff;
|
||||
}
|
||||
static inline void gic2_set_edge_mode(gic_t *irq, int inx, int mode)
|
||||
{
|
||||
uint32_t tmp = read_reg32(GICD_ICFGRn(irq->disp_base_addr) +
|
||||
((inx >> 4) << 2));
|
||||
|
||||
tmp &= ~(0x3ul << ((inx % 16) << 1));
|
||||
tmp |= (!!mode << 1) << ((inx % 16) << 1);
|
||||
write_reg32(GICD_ICFGRn(irq->disp_base_addr) +
|
||||
((inx >> 4) << 2),
|
||||
tmp);
|
||||
}
|
||||
static inline int gic2_get_edge_mode(gic_t *irq, int inx)
|
||||
{
|
||||
uint32_t tmp = read_reg32(GICD_ICFGRn(irq->disp_base_addr) +
|
||||
((inx >> 4) << 2));
|
||||
|
||||
return ((tmp >> ((inx % 16) << 1)) & 0x3UL) >> 1;
|
||||
}
|
||||
static inline void gic_enable(gic_t *irq)
|
||||
{
|
||||
write_reg32(GICD_CTLR(irq->disp_base_addr), TRUE);
|
||||
}
|
||||
static inline void gic_disable(gic_t *irq)
|
||||
{
|
||||
write_reg32(GICD_CTLR(irq->disp_base_addr), FALSE);
|
||||
}
|
||||
static inline void gic2_set_prio(gic_t *irq, int inx, uint64_t prio)
|
||||
{
|
||||
uint32_t tmp = read_reg32(GICD_IPRIORITYRn(irq->disp_base_addr) +
|
||||
((inx >> 2) << 2));
|
||||
|
||||
tmp &= ~(0xffUL << ((inx % 4) << 3));
|
||||
tmp |= (prio & 0xffUL) << ((inx % 4) << 3);
|
||||
write_reg32(GICD_IPRIORITYRn(irq->disp_base_addr) +
|
||||
((inx >> 2) << 2),
|
||||
tmp);
|
||||
}
|
||||
static inline uint8_t gic2_get_prio(gic_t *irq, int inx)
|
||||
{
|
||||
uint32_t tmp = read_reg32(GICD_IPRIORITYRn(irq->disp_base_addr) +
|
||||
((inx >> 2) << 2));
|
||||
|
||||
return ((tmp) >> ((inx % 4) << 3)) & 0xffUL;
|
||||
}
|
||||
|
||||
// cpu inter
|
||||
static inline void gic2_cpu_enable(gic_t *irq)
|
||||
{
|
||||
write_reg32(GICC_CTLR(irq->inter_base_addr), TRUE);
|
||||
}
|
||||
static inline void gic2_cpu_disable(gic_t *irq)
|
||||
{
|
||||
write_reg32(GICC_CTLR(irq->inter_base_addr), FALSE);
|
||||
}
|
||||
|
||||
static inline void gic_dist_init(gic_t *irq)
|
||||
{
|
||||
gic_disable(irq);
|
||||
|
||||
for (int i = 32; i < irq->irqs_number; i++)
|
||||
{
|
||||
gic2_set_unmask(irq, i);
|
||||
gic2_set_edge_mode(irq, i, 0);
|
||||
gic2_clear_active(irq, i);
|
||||
}
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
gic2_set_unmask(irq, i);
|
||||
}
|
||||
|
||||
gic_enable(irq);
|
||||
}
|
||||
static inline void gic_inter_init(gic_t *irq)
|
||||
{
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
gic2_set_prio(irq, i, 0xa0);
|
||||
}
|
||||
|
||||
write_reg32(GICC_PMR(irq->inter_base_addr), 0xf0UL);
|
||||
gic2_cpu_enable(irq);
|
||||
}
|
||||
static inline void gic2_eoi_irq(gic_t *irq, int inx)
|
||||
{
|
||||
write_reg32(GICC_EOIR(irq->inter_base_addr), inx);
|
||||
}
|
||||
static inline void gic_init(gic_t *irq, addr_t disp_addr, addr_t inter_addr)
|
||||
{
|
||||
irq->irqs_number = ((read_reg32(GICD_TYPER(disp_addr)) & 0x1ful) + 1) * 32;
|
||||
if (irq->irqs_number > MAX_INTR_NO)
|
||||
{
|
||||
irq->irqs_number = MAX_INTR_NO;
|
||||
}
|
||||
irq->disp_base_addr = disp_addr;
|
||||
irq->inter_base_addr = inter_addr;
|
||||
|
||||
printk("irqs_number %d, disp_base 0x%lx inter_base 0x%lx.\n", irq->irqs_number, irq->disp_base_addr, irq->inter_base_addr);
|
||||
|
||||
gic_dist_init(irq);
|
||||
gic_inter_init(irq);
|
||||
}
|
||||
gic_t *arm_gicv2_get_global(void);
|
||||
// static inline void gic_handle_irq(void)
|
||||
// {
|
||||
// extern gic_t m_irq;
|
||||
|
||||
// do
|
||||
// {
|
||||
// uint32_t irqstat =
|
||||
// read_reg32(GICC_IAR(m_irq.inter_base_addr));
|
||||
// uint32_t irqnr = irqstat & 0x3ff;
|
||||
|
||||
// if (irqnr == 30)
|
||||
// handle_timer_irq();
|
||||
|
||||
// gic2_eoi_irq(&m_irq, irqnr);
|
||||
|
||||
// } while (0);
|
||||
// }
|
||||
52
mkrtos_knl/arch/aarch64/asm/arm_local_reg.h
Executable file
52
mkrtos_knl/arch/aarch64/asm/arm_local_reg.h
Executable file
@@ -0,0 +1,52 @@
|
||||
#include "asm/base.h"
|
||||
|
||||
/*
|
||||
* ARM Local register for PI
|
||||
* see <BCM2711 ARM Peripherals> 6.5.2
|
||||
*/
|
||||
|
||||
#define ARM_CONTROL (ARM_LOCAL_BASE + 0x0)
|
||||
#define CORE_IRQ_CONTROL (ARM_LOCAL_BASE + 0xc)
|
||||
#define PMU_CONTROL_SET (ARM_LOCAL_BASE + 0x10)
|
||||
#define PMU_CONTROL_CLR (ARM_LOCAL_BASE + 0x14)
|
||||
#define PERI_IRQ_ROUTE0 (ARM_LOCAL_BASE + 0x24)
|
||||
#define AXI_QUIET_TIME (ARM_LOCAL_BASE + 0x30)
|
||||
#define LOCAL_TIMER_CONTROL (ARM_LOCAL_BASE + 0x34)
|
||||
#define LOCAL_TIMER_IRQ (ARM_LOCAL_BASE + 0x38)
|
||||
|
||||
#define TIMER_CNTRL0 (ARM_LOCAL_BASE + 0x40)
|
||||
#define TIMER_CNTRL1 (ARM_LOCAL_BASE + 0x44)
|
||||
#define TIMER_CNTRL2 (ARM_LOCAL_BASE + 0x48)
|
||||
#define TIMER_CNTRL3 (ARM_LOCAL_BASE + 0x4c)
|
||||
/* Secure Physical Timer Event for IRQ */
|
||||
#define CNT_PS_IRQ (1 << 0)
|
||||
/* Nonsecure Physical Timer Event for IRQ */
|
||||
#define CNT_PNS_IRQ (1 << 1)
|
||||
/* Hypervisor Physical Timer Event for IRQ */
|
||||
#define CNT_HP_IRQ (1 << 2)
|
||||
/* Virtual Timer Event for IRQ */
|
||||
#define CNT_V_IRQ (1 << 3)
|
||||
/* Secure Physical Timer Event for FIQ */
|
||||
#define CNT_PS_IRQ_FIQ (1 << 4)
|
||||
/* Nonsecure Physical Timer Event for FIQ */
|
||||
#define CNT_PNS_IRQ_FIQ (1 << 5)
|
||||
/* Hypervisor Physical Timer Event for FIQ */
|
||||
#define CNT_HP_IRQ_FIQ (1 << 6)
|
||||
/* Virtual Timer Event for FIQ */
|
||||
#define CNT_V_IRQ_FIQ (1 << 7)
|
||||
|
||||
#define ARM_LOCAL_IRQ_SOURCE0 (ARM_LOCAL_BASE + 0x60)
|
||||
#define ARM_LOCAL_IRQ_SOURCE1 (ARM_LOCAL_BASE + 0x64)
|
||||
#define ARM_LOCAL_IRQ_SOURCE2 (ARM_LOCAL_BASE + 0x68)
|
||||
#define ARM_LOCAL_IRQ_SOURCE3 (ARM_LOCAL_BASE + 0x6c)
|
||||
#define MAILBOX_IRQ_SHIFT 4
|
||||
#define CORE_IRQ (1 << 8)
|
||||
#define PMU_IRQ (1 << 9)
|
||||
#define AXI_QUIET (1 << 10)
|
||||
#define TIMER_IRQ (1 << 11)
|
||||
#define AXI_IRQ (1 << 30)
|
||||
|
||||
#define ARM_LOCAL_FRQ_SOURCE0 (ARM_LOCAL_BASE + 0x70)
|
||||
#define ARM_LOCAL_FRQ_SOURCE1 (ARM_LOCAL_BASE + 0x74)
|
||||
#define ARM_LOCAL_FRQ_SOURCE2 (ARM_LOCAL_BASE + 0x78)
|
||||
#define ARM_LOCAL_FRQ_SOURCE3 (ARM_LOCAL_BASE + 0x7c)
|
||||
26
mkrtos_knl/arch/aarch64/asm/base.h
Executable file
26
mkrtos_knl/arch/aarch64/asm/base.h
Executable file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef CONFIG_BOARD_PI3B
|
||||
#define PBASE 0x3F000000
|
||||
#define ARM_LOCAL_BASE 0x40000000
|
||||
#define PBASE_END 0x41000000
|
||||
#else
|
||||
/* Main peripherals on Low Peripheral mode
|
||||
* - ARM and GPU can access
|
||||
* see <BCM2711 ARM Peripherals> 1.2.4
|
||||
*/
|
||||
#define PBASE 0x08000000
|
||||
#define PBASE_END 0x100000000
|
||||
/*
|
||||
* ARM LOCAL register on Low Peripheral mode
|
||||
* - Only ARM can access
|
||||
* see <BCM2711 ARM Peripherals> 6.5.2
|
||||
*/
|
||||
#define ARM_LOCAL_BASE 0xff800000
|
||||
#endif
|
||||
|
||||
#define DEVICE_SIZE 0x2000000
|
||||
#define ARCH_PHYS_OFFSET 0
|
||||
|
||||
#define GIC_V2_DISTRIBUTOR_BASE (ARM_LOCAL_BASE + 0x00041000)
|
||||
#define GIC_V2_CPU_INTERFIACE_BASE (ARM_LOCAL_BASE + 0x00042000)
|
||||
13
mkrtos_knl/arch/aarch64/asm/gpio.h
Executable file
13
mkrtos_knl/arch/aarch64/asm/gpio.h
Executable file
@@ -0,0 +1,13 @@
|
||||
#ifndef _P_GPIO_H
|
||||
#define _P_GPIO_H
|
||||
|
||||
#include "asm/base.h"
|
||||
|
||||
#define GPFSEL1 (PBASE+0x00200004)
|
||||
#define GPSET0 (PBASE+0x0020001C)
|
||||
#define GPCLR0 (PBASE+0x00200028)
|
||||
#define GPPUD (PBASE+0x00200094)
|
||||
#define GPPUDCLK0 (PBASE+0x00200098)
|
||||
#define GPIO_PUP_PDN_CNTRL_REG0 (PBASE+0x002000E4)
|
||||
|
||||
#endif /*_P_GPIO_H */
|
||||
35
mkrtos_knl/arch/aarch64/asm/io.h
Executable file
35
mkrtos_knl/arch/aarch64/asm/io.h
Executable file
@@ -0,0 +1,35 @@
|
||||
|
||||
#ifndef _P_IO_H
|
||||
#define _P_BASE_H
|
||||
|
||||
#if 1
|
||||
#define __arch_getl(a) (*(volatile unsigned int *)(a))
|
||||
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
|
||||
|
||||
#ifndef dmb
|
||||
#define dmb() __asm__ __volatile__ ("" : : : "memory")
|
||||
#endif
|
||||
#define __iormb() dmb()
|
||||
#define __iowmb() dmb()
|
||||
|
||||
#define readl(c) ({ unsigned int __v = __arch_getl(c); __iormb(); __v; })
|
||||
#define writel(v,c) ({ unsigned int __v = v; __iowmb(); __arch_putl(__v,c);})
|
||||
#else
|
||||
static inline void writel(unsigned int value, unsigned int addr)
|
||||
{
|
||||
*(volatile unsigned int *)addr = value;
|
||||
}
|
||||
|
||||
static inline unsigned int readl(unsigned int addr)
|
||||
{
|
||||
return *(volatile unsigned int *)addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void delay(unsigned int n)
|
||||
{
|
||||
while(n--)
|
||||
;
|
||||
}
|
||||
|
||||
#endif
|
||||
26
mkrtos_knl/arch/aarch64/asm/irq.h
Executable file
26
mkrtos_knl/arch/aarch64/asm/irq.h
Executable file
@@ -0,0 +1,26 @@
|
||||
#include "base.h"
|
||||
|
||||
#define IRQ_BASIC_PENDING (PBASE+0x0000B200)
|
||||
#define IRQ_PENDING_1 (PBASE+0x0000B204)
|
||||
#define IRQ_PENDING_2 (PBASE+0x0000B208)
|
||||
#define FIQ_CONTROL (PBASE+0x0000B20C)
|
||||
#define ENABLE_IRQS_1 (PBASE+0x0000B210)
|
||||
#define ENABLE_IRQS_2 (PBASE+0x0000B214)
|
||||
#define ENABLE_BASIC_IRQS (PBASE+0x0000B218)
|
||||
#define DISABLE_IRQS_1 (PBASE+0x0000B21C)
|
||||
#define DISABLE_IRQS_2 (PBASE+0x0000B220)
|
||||
#define DISABLE_BASIC_IRQS (PBASE+0x0000B224)
|
||||
|
||||
#define SYSTEM_TIMER_IRQ_0 (1 << 0)
|
||||
#define SYSTEM_TIMER_IRQ_1 (1 << 1)
|
||||
#define SYSTEM_TIMER_IRQ_2 (1 << 2)
|
||||
#define SYSTEM_TIMER_IRQ_3 (1 << 3)
|
||||
|
||||
#define ARM_TIMER_IRQ (1 << 0)
|
||||
|
||||
#define CORE0_INT_CTR (PERIPHERAL_BASE+0x40)
|
||||
#define CORE0_INT_SOURCE (PERIPHERAL_BASE+0x60)
|
||||
#define LOCAL_TIMER_INT (1 << 11)
|
||||
#define CNTPNSIRQ_Int (1 << 1)
|
||||
|
||||
void handle_timer_irq(void);
|
||||
13
mkrtos_knl/arch/aarch64/asm/mm.h
Executable file
13
mkrtos_knl/arch/aarch64/asm/mm.h
Executable file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#define CONFIG_ARM64_VA_BITS 40
|
||||
|
||||
#define PAGE_SHIFT (CONFIG_PAGE_SHIFT)
|
||||
#define PAGE_SIZE (1 << PAGE_SHIFT)
|
||||
#define VA_BITS (CONFIG_ARM64_VA_BITS)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
void memzero(unsigned long src, unsigned long n);
|
||||
|
||||
#endif
|
||||
16
mkrtos_knl/arch/aarch64/asm/pl_uart.h
Executable file
16
mkrtos_knl/arch/aarch64/asm/pl_uart.h
Executable file
@@ -0,0 +1,16 @@
|
||||
#ifndef _P_UART_H
|
||||
#define _P_UART_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
#define U_BASE (PBASE+0x00201000)
|
||||
|
||||
#define U_DATA_REG (U_BASE)
|
||||
#define U_FR_REG (U_BASE+0x18)
|
||||
#define U_IBRD_REG (U_BASE+0x24)
|
||||
#define U_FBRD_REG (U_BASE+0x28)
|
||||
#define U_LCRH_REG (U_BASE+0x2C)
|
||||
#define U_CR_REG (U_BASE+0x30)
|
||||
#define U_IMSC_REG (U_BASE+0x38)
|
||||
|
||||
#endif /*_P_UART_H */
|
||||
200
mkrtos_knl/arch/aarch64/asm/sysregs.h
Executable file
200
mkrtos_knl/arch/aarch64/asm/sysregs.h
Executable file
@@ -0,0 +1,200 @@
|
||||
#ifndef _SYSREGS_H
|
||||
#define _SYSREGS_H
|
||||
|
||||
#include "types_asm.h"
|
||||
|
||||
/*
|
||||
* SCTLR_EL1, System Control Register (EL1)
|
||||
* AArch64-Reference-Manual v8.6, D13.2.113
|
||||
*/
|
||||
/* Common SCTLR_ELx flags. */
|
||||
#define SCTLR_ELx_DSSBS (_BITUL(44))
|
||||
#define SCTLR_ELx_ENIA (_BITUL(31))
|
||||
#define SCTLR_ELx_ENIB (_BITUL(30))
|
||||
#define SCTLR_ELx_ENDA (_BITUL(27))
|
||||
#define SCTLR_ELx_EE (_BITUL(25))
|
||||
#define SCTLR_ELx_IESB (_BITUL(21))
|
||||
#define SCTLR_ELx_WXN (_BITUL(19))
|
||||
#define SCTLR_ELx_ENDB (_BITUL(13))
|
||||
#define SCTLR_ELx_I (_BITUL(12))
|
||||
#define SCTLR_ELx_SA (_BITUL(3))
|
||||
#define SCTLR_ELx_C (_BITUL(2))
|
||||
#define SCTLR_ELx_A (_BITUL(1))
|
||||
#define SCTLR_ELx_M (_BITUL(0))
|
||||
|
||||
#define SCTLR_ELx_FLAGS (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
|
||||
SCTLR_ELx_SA | SCTLR_ELx_I | SCTLR_ELx_IESB)
|
||||
|
||||
/* SCTLR_EL2 specific flags. */
|
||||
#define SCTLR_EL2_RES1 \
|
||||
((_BITUL(4)) | (_BITUL(5)) | (_BITUL(11)) | (_BITUL(16)) | \
|
||||
(_BITUL(18)) | (_BITUL(22)) | (_BITUL(23)) | (_BITUL(28)) | \
|
||||
(_BITUL(29)))
|
||||
#define SCTLR_EL2_RES0 \
|
||||
((_BITUL(6)) | (_BITUL(7)) | (_BITUL(8)) | (_BITUL(9)) | \
|
||||
(_BITUL(10)) | (_BITUL(13)) | (_BITUL(14)) | (_BITUL(15)) | \
|
||||
(_BITUL(17)) | (_BITUL(20)) | (_BITUL(24)) | (_BITUL(26)) | \
|
||||
(_BITUL(27)) | (_BITUL(30)) | (_BITUL(31)) | \
|
||||
(0xffffefffUL << 32))
|
||||
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
#define ENDIAN_SET_EL2 SCTLR_ELx_EE
|
||||
#define ENDIAN_CLEAR_EL2 0
|
||||
#else
|
||||
#define ENDIAN_SET_EL2 0
|
||||
#define ENDIAN_CLEAR_EL2 SCTLR_ELx_EE
|
||||
#endif
|
||||
|
||||
/* SCTLR_EL2 value used for the hyp-stub */
|
||||
#define SCTLR_EL2_SET (SCTLR_ELx_IESB | ENDIAN_SET_EL2 | SCTLR_EL2_RES1)
|
||||
#define SCTLR_EL2_CLEAR (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
|
||||
SCTLR_ELx_SA | SCTLR_ELx_I | SCTLR_ELx_WXN | \
|
||||
SCTLR_ELx_DSSBS | ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0)
|
||||
|
||||
#define SCTLR_EL2_VALUE_MMU_DISABLED (SCTLR_EL2_RES1 | ENDIAN_SET_EL2)
|
||||
|
||||
/* SCTLR_EL1 specific flags. */
|
||||
#define SCTLR_EL1_UCI (_BITUL(26))
|
||||
#define SCTLR_EL1_E0E (_BITUL(24))
|
||||
#define SCTLR_EL1_SPAN (_BITUL(23))
|
||||
#define SCTLR_EL1_NTWE (_BITUL(18))
|
||||
#define SCTLR_EL1_NTWI (_BITUL(16))
|
||||
#define SCTLR_EL1_UCT (_BITUL(15))
|
||||
#define SCTLR_EL1_DZE (_BITUL(14))
|
||||
#define SCTLR_EL1_UMA (_BITUL(9))
|
||||
#define SCTLR_EL1_SED (_BITUL(8))
|
||||
#define SCTLR_EL1_ITD (_BITUL(7))
|
||||
#define SCTLR_EL1_CP15BEN (_BITUL(5))
|
||||
#define SCTLR_EL1_SA0 (_BITUL(4))
|
||||
|
||||
#define SCTLR_EL1_RES1 \
|
||||
((_BITUL(11)) | (_BITUL(20)) | (_BITUL(22)) | (_BITUL(28)) | \
|
||||
(_BITUL(29)))
|
||||
#define SCTLR_EL1_RES0 \
|
||||
((_BITUL(6)) | (_BITUL(10)) | (_BITUL(13)) | (_BITUL(17)) | \
|
||||
(_BITUL(27)) | (_BITUL(30)) | (_BITUL(31)) | \
|
||||
(0xffffefffUL << 32))
|
||||
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
#define ENDIAN_SET_EL1 (SCTLR_EL1_E0E | SCTLR_ELx_EE)
|
||||
#define ENDIAN_CLEAR_EL1 0
|
||||
#else
|
||||
#define ENDIAN_SET_EL1 0
|
||||
#define ENDIAN_CLEAR_EL1 (SCTLR_EL1_E0E | SCTLR_ELx_EE)
|
||||
#endif
|
||||
|
||||
#define SCTLR_EL1_SET (SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA |\
|
||||
SCTLR_EL1_SA0 | SCTLR_EL1_SED | SCTLR_ELx_I |\
|
||||
SCTLR_EL1_DZE | SCTLR_EL1_UCT |\
|
||||
SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN |\
|
||||
ENDIAN_SET_EL1 | SCTLR_EL1_UCI | SCTLR_EL1_RES1)
|
||||
#define SCTLR_EL1_CLEAR (SCTLR_ELx_A | SCTLR_EL1_CP15BEN | SCTLR_EL1_ITD |\
|
||||
SCTLR_EL1_UMA | SCTLR_ELx_WXN | ENDIAN_CLEAR_EL1 |\
|
||||
SCTLR_ELx_DSSBS | SCTLR_EL1_NTWI | SCTLR_EL1_RES0)
|
||||
|
||||
#define SCTLR_EL1_VALUE_MMU_DISABLED (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
|
||||
|
||||
/*
|
||||
* HCR_EL2, Hypervisor Configuration Register (EL2)
|
||||
* AArch64-Reference-Manual v8.6, D13.2.47
|
||||
*/
|
||||
#define HCR_FWB (UL(1) << 46)
|
||||
#define HCR_API (UL(1) << 41)
|
||||
#define HCR_APK (UL(1) << 40)
|
||||
#define HCR_TEA (UL(1) << 37)
|
||||
#define HCR_TERR (UL(1) << 36)
|
||||
#define HCR_TLOR (UL(1) << 35)
|
||||
#define HCR_E2H (UL(1) << 34)
|
||||
#define HCR_ID (UL(1) << 33)
|
||||
#define HCR_CD (UL(1) << 32)
|
||||
#define HCR_RW_SHIFT 31
|
||||
#define HCR_RW (UL(1) << HCR_RW_SHIFT)
|
||||
#define HCR_TRVM (UL(1) << 30)
|
||||
#define HCR_HCD (UL(1) << 29)
|
||||
#define HCR_TDZ (UL(1) << 28)
|
||||
#define HCR_TGE (UL(1) << 27)
|
||||
#define HCR_TVM (UL(1) << 26)
|
||||
#define HCR_TTLB (UL(1) << 25)
|
||||
#define HCR_TPU (UL(1) << 24)
|
||||
#define HCR_TPC (UL(1) << 23)
|
||||
#define HCR_TSW (UL(1) << 22)
|
||||
#define HCR_TAC (UL(1) << 21)
|
||||
#define HCR_TIDCP (UL(1) << 20)
|
||||
#define HCR_TSC (UL(1) << 19)
|
||||
#define HCR_TID3 (UL(1) << 18)
|
||||
#define HCR_TID2 (UL(1) << 17)
|
||||
#define HCR_TID1 (UL(1) << 16)
|
||||
#define HCR_TID0 (UL(1) << 15)
|
||||
#define HCR_TWE (UL(1) << 14)
|
||||
#define HCR_TWI (UL(1) << 13)
|
||||
#define HCR_DC (UL(1) << 12)
|
||||
#define HCR_BSU (3 << 10)
|
||||
#define HCR_BSU_IS (UL(1) << 10)
|
||||
#define HCR_FB (UL(1) << 9)
|
||||
#define HCR_VSE (UL(1) << 8)
|
||||
#define HCR_VI (UL(1) << 7)
|
||||
#define HCR_VF (UL(1) << 6)
|
||||
#define HCR_AMO (UL(1) << 5)
|
||||
#define HCR_IMO (UL(1) << 4)
|
||||
#define HCR_FMO (UL(1) << 3)
|
||||
#define HCR_PTW (UL(1) << 2)
|
||||
#define HCR_SWIO (UL(1) << 1)
|
||||
#define HCR_VM (UL(1) << 0)
|
||||
|
||||
/*
|
||||
* The bits we set in HCR:
|
||||
* TLOR: Trap LORegion register accesses
|
||||
* RW: 64bit by default, can be overridden for 32bit VMs
|
||||
* TAC: Trap ACTLR
|
||||
* TSC: Trap SMC
|
||||
* TVM: Trap VM ops (until M+C set in SCTLR_EL1)
|
||||
* TSW: Trap cache operations by set/way
|
||||
* TWE: Trap WFE
|
||||
* TWI: Trap WFI
|
||||
* TIDCP: Trap L2CTLR/L2ECTLR
|
||||
* BSU_IS: Upgrade barriers to the inner shareable domain
|
||||
* FB: Force broadcast of all maintenance operations
|
||||
* AMO: Override CPSR.A and enable signaling with VA
|
||||
* IMO: Override CPSR.I and enable signaling with VI
|
||||
* FMO: Override CPSR.F and enable signaling with VF
|
||||
* SWIO: Turn set/way invalidates into set/way clean+invalidate
|
||||
*/
|
||||
#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
|
||||
HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \
|
||||
HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
|
||||
HCR_FMO | HCR_IMO)
|
||||
#define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
|
||||
#define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_E2H)
|
||||
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
|
||||
|
||||
/*
|
||||
* SCR_EL3, Secure Configuration Register (EL3), Page 2648 of
|
||||
* AArch64-Reference-Manual.
|
||||
*/
|
||||
|
||||
#define SCR_RESERVED (3 << 4)
|
||||
#define SCR_RW (1 << 10)
|
||||
#define SCR_NS (1 << 0)
|
||||
// #define SCR_VALUE (SCR_RESERVED | SCR_RW | SCR_NS)
|
||||
#define SCR_VALUE (\
|
||||
SCR_NS|SCR_RW|(1UL<<7)|(1UL<<8)\
|
||||
)
|
||||
/*
|
||||
* SPSR_EL3, Saved Program Status Register (EL3) Page 389 of
|
||||
* AArch64-Reference-Manual.
|
||||
*/
|
||||
#define SPSR_MASK_ALL (7 << 6)
|
||||
#define SPSR_EL1h (5 << 0)
|
||||
#define SPSR_EL2h (9 << 0)
|
||||
#define SPSR_EL1 (SPSR_MASK_ALL | SPSR_EL1h)
|
||||
#define SPSR_EL2 (SPSR_MASK_ALL | SPSR_EL2h)
|
||||
|
||||
/* Current Exception Level values, as contained in CurrentEL */
|
||||
#define CurrentEL_EL1 (1 << 2)
|
||||
#define CurrentEL_EL2 (2 << 2)
|
||||
#define CurrentEL_EL3 (3 << 2)
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
30
mkrtos_knl/arch/aarch64/asm/system.h
Normal file
30
mkrtos_knl/arch/aarch64/asm/system.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
/*
|
||||
* PSR bits
|
||||
*/
|
||||
#define PSR_MODE_EL0t 0x00000000
|
||||
#define PSR_MODE_EL1t 0x00000004
|
||||
#define PSR_MODE_EL1h 0x00000005
|
||||
#define PSR_MODE_EL2t 0x00000008
|
||||
#define PSR_MODE_EL2h 0x00000009
|
||||
#define PSR_MODE_EL3t 0x0000000c
|
||||
#define PSR_MODE_EL3h 0x0000000d
|
||||
#define PSR_MODE_MASK 0x0000000f
|
||||
|
||||
typedef struct entry_frame {
|
||||
struct {
|
||||
mword_t regs[31];
|
||||
mword_t sp;
|
||||
mword_t pc;
|
||||
mword_t pstate;
|
||||
};
|
||||
|
||||
mword_t orig_x0;
|
||||
uint32_t syscallno;
|
||||
uint32_t unused2;
|
||||
|
||||
mword_t orig_addr_limit;
|
||||
mword_t unused;
|
||||
mword_t stackframe[2];
|
||||
} entry_frame_t;
|
||||
32
mkrtos_knl/arch/aarch64/asm/timer.h
Executable file
32
mkrtos_knl/arch/aarch64/asm/timer.h
Executable file
@@ -0,0 +1,32 @@
|
||||
#include "base.h"
|
||||
|
||||
/* System Timer on PI */
|
||||
#define TIMER_CS (PBASE+0x00003000)
|
||||
#define TIMER_CLO (PBASE+0x00003004)
|
||||
#define TIMER_CHI (PBASE+0x00003008)
|
||||
#define TIMER_C0 (PBASE+0x0000300C)
|
||||
#define TIMER_C1 (PBASE+0x00003010)
|
||||
#define TIMER_C2 (PBASE+0x00003014)
|
||||
#define TIMER_C3 (PBASE+0x00003018)
|
||||
|
||||
#define TIMER_CS_M0 (1 << 0)
|
||||
#define TIMER_CS_M1 (1 << 1)
|
||||
#define TIMER_CS_M2 (1 << 2)
|
||||
#define TIMER_CS_M3 (1 << 3)
|
||||
|
||||
/* ARM side Timer on PI
|
||||
* Reference: 12.2 Timer Registers
|
||||
*/
|
||||
#define ARM_TIMER_BASE (PBASE + 0xB000)
|
||||
#define ARM_TIMER_LOAD (ARM_TIMER_BASE + 0x400)
|
||||
#define ARM_TIMER_VALUE (ARM_TIMER_BASE + 0x404)
|
||||
#define ARM_TIMER_CTRL (ARM_TIMER_BASE + 0x408)
|
||||
#define ARM_TIMER_CLR (ARM_TIMER_BASE + 0x40c)
|
||||
|
||||
#define CTRL_23BIT (1 << 1) // 23-bit counter
|
||||
#define CTRL_INT_ENABLE (1 << 5) // Timer interrupt enabled
|
||||
#define CTRL_ENABLE (1 << 7) // Timer enabled
|
||||
|
||||
/* Local timer */
|
||||
#define TIMER_CTRL (PERIPHERAL_BASE+0x34)
|
||||
#define TIMER_FLAG (PERIPHERAL_BASE+0x38)
|
||||
20
mkrtos_knl/arch/aarch64/asm/types_asm.h
Normal file
20
mkrtos_knl/arch/aarch64/asm/types_asm.h
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#define _AC(X,Y) X
|
||||
#define _AT(T,X) X
|
||||
#else
|
||||
#define __AC(X,Y) (X##Y)
|
||||
#define _AC(X,Y) __AC(X,Y)
|
||||
#define _AT(T,X) ((T)(X))
|
||||
#endif
|
||||
|
||||
#define UL(x) (_UL(x))
|
||||
#define ULL(x) (_ULL(x))
|
||||
|
||||
#define _UL(x) (_AC(x, UL))
|
||||
#define _ULL(x) (_AC(x, ULL))
|
||||
|
||||
#define _BITUL(x) (_UL(1) << (x))
|
||||
#define _BITULL(x) (_ULL(1) << (x))
|
||||
14
mkrtos_knl/arch/aarch64/asm_config.h
Normal file
14
mkrtos_knl/arch/aarch64/asm_config.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef __ASM_CONFIG_H__
|
||||
#define __ASM_CONFIG_H__
|
||||
|
||||
#include "asm/mm.h"
|
||||
#include "thread_arch.h"
|
||||
#define SUPPORT_SMP CONFIG_SMP
|
||||
#define SYS_CPU_NUM CONFIG_CPU //!< 系统cpu数量
|
||||
|
||||
#define MWORD_BYTES (sizeof(mword_t))
|
||||
#define MWORD_BITS (sizeof(mword_t) << 3UL)
|
||||
#define MWORD_SHIFT (3)
|
||||
|
||||
#define PT_REGS_SIZE 320
|
||||
#endif
|
||||
42
mkrtos_knl/arch/aarch64/asm_offset.h
Normal file
42
mkrtos_knl/arch/aarch64/asm_offset.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef __ASM_OFFSETS_H__
|
||||
#define __ASM_OFFSETS_H__
|
||||
/*
|
||||
* DO NOT MODIFY.
|
||||
*
|
||||
* This file was generated by Kbuild
|
||||
*/
|
||||
|
||||
#define S_FRAME_SIZE 320 /* sizeof(struct pt_regs) // */
|
||||
#define S_X0 0 /* offsetof(struct pt_regs, regs[0]) // */
|
||||
#define S_X1 8 /* offsetof(struct pt_regs, regs[1]) // */
|
||||
#define S_X2 16 /* offsetof(struct pt_regs, regs[2]) // */
|
||||
#define S_X3 24 /* offsetof(struct pt_regs, regs[3]) // */
|
||||
#define S_X4 32 /* offsetof(struct pt_regs, regs[4]) // */
|
||||
#define S_X5 40 /* offsetof(struct pt_regs, regs[5]) // */
|
||||
#define S_X6 48 /* offsetof(struct pt_regs, regs[6]) // */
|
||||
#define S_X7 56 /* offsetof(struct pt_regs, regs[7]) // */
|
||||
#define S_X8 64 /* offsetof(struct pt_regs, regs[8]) // */
|
||||
#define S_X10 80 /* offsetof(struct pt_regs, regs[10]) // */
|
||||
#define S_X12 96 /* offsetof(struct pt_regs, regs[12]) // */
|
||||
#define S_X14 112 /* offsetof(struct pt_regs, regs[14]) // */
|
||||
#define S_X16 128 /* offsetof(struct pt_regs, regs[16]) // */
|
||||
#define S_X18 144 /* offsetof(struct pt_regs, regs[18]) // */
|
||||
#define S_X20 160 /* offsetof(struct pt_regs, regs[20]) // */
|
||||
#define S_X22 176 /* offsetof(struct pt_regs, regs[22]) // */
|
||||
#define S_X24 192 /* offsetof(struct pt_regs, regs[24]) // */
|
||||
#define S_X26 208 /* offsetof(struct pt_regs, regs[26]) // */
|
||||
#define S_X28 224 /* offsetof(struct pt_regs, regs[28]) // */
|
||||
#define S_FP 232 /* offsetof(struct pt_regs, regs[29]) // */
|
||||
#define S_LR 240 /* offsetof(struct pt_regs, regs[30]) // */
|
||||
#define S_SP 248 /* offsetof(struct pt_regs, sp) // */
|
||||
#define S_PSTATE 264 /* offsetof(struct pt_regs, pstate) // */
|
||||
#define S_PC 256 /* offsetof(struct pt_regs, pc) // */
|
||||
// #define S_ORIG_X0 272 /* offsetof(struct pt_regs, orig_x0) // */
|
||||
// #define S_SYSCALLNO 280 /* offsetof(struct pt_regs, syscallno) // */
|
||||
// #define S_ORIG_ADDR_LIMIT 288 /* offsetof(struct pt_regs, orig_addr_limit) // */
|
||||
// #define S_STACKFRAME 304 /* offsetof(struct pt_regs, stackframe) // */
|
||||
// #define THREAD_CPU_CONTEXT 16 /* offsetof(struct task_struct, cpu_context) // */
|
||||
// #define TI_PREEMPT 148 /* offsetof(struct task_struct, preempt_count) // */
|
||||
// #define NEED_RESCHED 144 /* offsetof(struct task_struct, need_resched) // */
|
||||
|
||||
#endif
|
||||
123
mkrtos_knl/arch/aarch64/atomics.c
Normal file
123
mkrtos_knl/arch/aarch64/atomics.c
Normal file
@@ -0,0 +1,123 @@
|
||||
|
||||
#include <types.h>
|
||||
#include <atomics.h>
|
||||
|
||||
bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new)
|
||||
{
|
||||
umword_t oldval, res;
|
||||
|
||||
asm volatile(
|
||||
"1:\n"
|
||||
"ldxr %1, %2\n"
|
||||
"eor %0, %1, %3\n"
|
||||
"cbnz %0, 2f\n"
|
||||
"stxr %w0, %4, %2\n"
|
||||
"cbnz %w0, 1b\n"
|
||||
"2:"
|
||||
: "=&r"(res), "=&r"(oldval), "+Q"(*v)
|
||||
: "r"(old), "r"(new)
|
||||
: "cc");
|
||||
return !res;
|
||||
}
|
||||
void atomic_and(umword_t *l, umword_t val)
|
||||
{
|
||||
umword_t tmp, ret;
|
||||
|
||||
asm volatile(
|
||||
"1:\n"
|
||||
"ldxr %0, %2\n"
|
||||
"and %0, %0, %3\n"
|
||||
"stxr %w1, %0, %2\n"
|
||||
"cbnz %w1, 1b\n"
|
||||
: "=&r"(tmp), "=&r"(ret), "+Q"(*l)
|
||||
: "r"(val)
|
||||
: "cc");
|
||||
}
|
||||
umword_t atomic_and_return(umword_t *l, umword_t val)
|
||||
{
|
||||
umword_t tmp, ret;
|
||||
|
||||
asm volatile(
|
||||
"ldxr %0, %2\n"
|
||||
"and %1, %0, %3\n"
|
||||
: "=&r"(tmp), "=&r"(ret), "+Q"(*l)
|
||||
: "r"(val)
|
||||
: "cc");
|
||||
return !!ret;
|
||||
}
|
||||
void atomic_or(umword_t *l, umword_t val)
|
||||
{
|
||||
umword_t tmp, ret;
|
||||
|
||||
asm volatile(
|
||||
"1:\n"
|
||||
"ldxr %0, %2\n"
|
||||
"orr %0, %0, %3\n"
|
||||
"stxr %w1, %0, %2\n"
|
||||
"cbnz %w1, 1b\n"
|
||||
: "=&r"(tmp), "=&r"(ret), "+Q"(*l)
|
||||
: "r"(val)
|
||||
: "cc");
|
||||
}
|
||||
umword_t atomic_sub_return(umword_t i, atomic64_t *v)
|
||||
{
|
||||
umword_t tmp;
|
||||
umword_t ret;
|
||||
|
||||
asm volatile(
|
||||
"1:\n"
|
||||
"ldxr %0, %2\n"
|
||||
"sub %0, %0, %3\n"
|
||||
"stxr %w1, %0, %2\n"
|
||||
"cbnz %w1, 1b\n"
|
||||
: "=&r"(ret), "=&r"(tmp), "+Q"(v->counter)
|
||||
: "r"(i));
|
||||
return ret;
|
||||
}
|
||||
umword_t atomic_add_return(umword_t i, atomic64_t *v)
|
||||
{
|
||||
umword_t tmp;
|
||||
umword_t ret;
|
||||
|
||||
asm volatile(
|
||||
"1:\n"
|
||||
"ldxr %0, %2\n"
|
||||
"add %0, %0, %3\n"
|
||||
"stxr %w1, %0, %2\n"
|
||||
"cbnz %w1, 1b\n"
|
||||
: "=&r"(ret), "=&r"(tmp), "+Q"(v->counter)
|
||||
: "r"(i));
|
||||
return ret;
|
||||
}
|
||||
umword_t atomic_fetch_and(umword_t i, atomic64_t *v)
|
||||
{
|
||||
umword_t tmp, ret;
|
||||
umword_t old;
|
||||
|
||||
asm volatile(
|
||||
"1:\n"
|
||||
"ldxr %2, %3\n"
|
||||
"and %0, %2, %4\n"
|
||||
"stxr %w1, %0, %3\n"
|
||||
"cbnz %w1, 1b\n"
|
||||
: "=&r"(tmp), "=&r"(ret), "=&r"(old), "+Q"(v->counter)
|
||||
: "r"(i)
|
||||
: "cc");
|
||||
return old;
|
||||
}
|
||||
umword_t atomic_fetch_or(umword_t i, atomic64_t *v)
|
||||
{
|
||||
umword_t tmp, ret;
|
||||
umword_t old;
|
||||
|
||||
asm volatile(
|
||||
"1:\n"
|
||||
"ldxr %2, %3\n"
|
||||
"orr %0, %2, %4\n"
|
||||
"stxr %w1, %0, %3\n"
|
||||
"cbnz %w1, 1b\n"
|
||||
: "=&r"(tmp), "=&r"(ret), "=&r"(old), "+Q"(v->counter)
|
||||
: "r"(i)
|
||||
: "cc");
|
||||
return old;
|
||||
}
|
||||
68
mkrtos_knl/arch/aarch64/atomics.h
Normal file
68
mkrtos_knl/arch/aarch64/atomics.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
typedef struct atomic64
|
||||
{
|
||||
umword_t counter;
|
||||
} atomic64_t;
|
||||
|
||||
typedef atomic64_t atomic_t;
|
||||
#define ATOMIC64_INIT(i) ((atomic64_t){(i)})
|
||||
|
||||
#define atomic_read(v) (*(volatile umword_t *)(&(v)->counter))
|
||||
#define atomic_set(v, i) (((v)->counter) = i)
|
||||
|
||||
bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new);
|
||||
void atomic_and(umword_t *l, umword_t val);
|
||||
umword_t atomic_and_return(umword_t *l, umword_t val);
|
||||
void atomic_or(umword_t *l, umword_t val);
|
||||
umword_t atomic_sub_return(umword_t i, atomic64_t *v);
|
||||
umword_t atomic_add_return(umword_t i, atomic64_t *v);
|
||||
umword_t atomic_fetch_and(umword_t i, atomic64_t *v);
|
||||
umword_t atomic_fetch_or(umword_t i, atomic64_t *v);
|
||||
|
||||
static inline void atomic_add(umword_t i, atomic64_t *v)
|
||||
{
|
||||
atomic_add_return(i, v);
|
||||
}
|
||||
static inline void atomic_sub(umword_t i, atomic64_t *v)
|
||||
{
|
||||
atomic_sub_return(i, v);
|
||||
}
|
||||
static inline void atomic_inc(atomic64_t *v)
|
||||
{
|
||||
atomic_add_return(1, v);
|
||||
}
|
||||
static inline void atomic_dec(atomic64_t *v)
|
||||
{
|
||||
atomic_sub_return(1, v);
|
||||
}
|
||||
static inline umword_t atomic_inc_return(atomic64_t *v)
|
||||
{
|
||||
return atomic_add_return(1, v);
|
||||
}
|
||||
static inline umword_t atomic_dec_return(atomic64_t *v)
|
||||
{
|
||||
return atomic_sub_return(1, v);
|
||||
}
|
||||
|
||||
static inline umword_t atomic_add_and_test(umword_t i, atomic64_t *v)
|
||||
{
|
||||
return atomic_add_return(i, v) == 0;
|
||||
}
|
||||
|
||||
static inline umword_t atomic_sub_and_test(umword_t i, atomic64_t *v)
|
||||
{
|
||||
return atomic_sub_return(i, v) == 0;
|
||||
}
|
||||
static inline umword_t atomic_inc_and_test(atomic64_t *v)
|
||||
{
|
||||
return atomic_inc_return(v) == 0;
|
||||
}
|
||||
static inline umword_t atomic_dec_and_test(atomic64_t *v)
|
||||
{
|
||||
return atomic_dec_return(v) == 0;
|
||||
}
|
||||
static inline umword_t atomic_add_negative(umword_t i, atomic64_t *v)
|
||||
{
|
||||
return (umword_t)atomic_add_return(i, v) < 0;
|
||||
}
|
||||
6
mkrtos_knl/arch/aarch64/complier.h
Normal file
6
mkrtos_knl/arch/aarch64/complier.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define tostring(s...) #s
|
||||
|
||||
#define BEGIN_FUNC(_name) .global _name ; .type _name, %function ; _name:
|
||||
#define END_FUNC(_name) .size _name, .-_name
|
||||
0
mkrtos_knl/arch/aarch64/dummy.c
Normal file
0
mkrtos_knl/arch/aarch64/dummy.c
Normal file
206
mkrtos_knl/arch/aarch64/early_boot.c
Normal file
206
mkrtos_knl/arch/aarch64/early_boot.c
Normal file
@@ -0,0 +1,206 @@
|
||||
|
||||
#include <arch.h>
|
||||
#include "early_boot.h"
|
||||
#include "asm/sysregs.h"
|
||||
#include "asm/base.h"
|
||||
#include "asm/mm.h"
|
||||
#include <types.h>
|
||||
#include <arch.h>
|
||||
#include "pager.h"
|
||||
#include <config.h>
|
||||
#include <spinlock.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define DATA_BOOT_SECTION ".data.boot"
|
||||
#define TEXT_BOOT_SECTION ".text.boot"
|
||||
|
||||
#define TCR_DEFAULT (((1UL) << 31) | (1UL << 23) | \
|
||||
(3UL << 12) | (1UL << 10) | (1UL << 8) | ((64UL - CONFIG_ARM64_VA_BITS)))
|
||||
|
||||
extern char _text_boot[];
|
||||
extern char _etext_boot[];
|
||||
extern char _data_boot[];
|
||||
extern char _edata_boot[];
|
||||
extern char _ebss[];
|
||||
extern char _text[];
|
||||
extern char _buddy_data_start[];
|
||||
extern char _buddy_data_end[];
|
||||
|
||||
#define BOOT_PAGER_NR 128
|
||||
// __ALIGN__(THREAD_BLOCK_SIZE) SECTION(DATA_BOOT_SECTION) uint8_t boot_stack[THREAD_BLOCK_SIZE] = {0};
|
||||
static SECTION(DATA_BOOT_SECTION) __ALIGN__(PAGE_SIZE) uint8_t pages[BOOT_PAGER_NR * SYS_CPU_NUM][PAGE_SIZE];
|
||||
static SECTION(DATA_BOOT_SECTION) uint8_t pages_used[BOOT_PAGER_NR * SYS_CPU_NUM];
|
||||
static SECTION(TEXT_BOOT_SECTION) inline int boot_get_current_cpu_id(void)
|
||||
{
|
||||
return read_sysreg(mpidr_el1) & 0XFFUL;
|
||||
}
|
||||
static SECTION(TEXT_BOOT_SECTION) void *page_alloc(void)
|
||||
{
|
||||
for (int i = 0; i < BOOT_PAGER_NR * SYS_CPU_NUM; i++)
|
||||
{
|
||||
if (pages_used[i + boot_get_current_cpu_id() * BOOT_PAGER_NR] == 0)
|
||||
{
|
||||
pages_used[i + boot_get_current_cpu_id() * BOOT_PAGER_NR] = 1;
|
||||
return (void *)pages[i + boot_get_current_cpu_id() * BOOT_PAGER_NR];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static SECTION(TEXT_BOOT_SECTION) void page_free(void *mem)
|
||||
{
|
||||
for (int i = 0; i < BOOT_PAGER_NR * SYS_CPU_NUM; i++)
|
||||
{
|
||||
if (pages_used[i + arch_get_current_cpu_id() * BOOT_PAGER_NR] == 1 && pages[i + arch_get_current_cpu_id() * BOOT_PAGER_NR] == mem)
|
||||
{
|
||||
pages_used[i + arch_get_current_cpu_id() * BOOT_PAGER_NR] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SECTION(TEXT_BOOT_SECTION) void *boot_memset(void *dst, int s, size_t count)
|
||||
{
|
||||
register char *a = dst;
|
||||
count++; /* this actually creates smaller code than using count-- */
|
||||
while (--count)
|
||||
*a++ = s;
|
||||
return dst;
|
||||
}
|
||||
|
||||
#define PTE_TYPE_BLOCK 0x0UL
|
||||
#define PTE_TYPE_TAB 0x3UL
|
||||
|
||||
static SECTION(DATA_BOOT_SECTION) pte_t boot_kpdir[PAGE_SIZE / MWORD_BYTES];
|
||||
SECTION(DATA_BOOT_SECTION)
|
||||
static page_entry_t kpdir = {
|
||||
.dir = boot_kpdir,
|
||||
.depth = PAGE_DEEP,
|
||||
.lv_shift_sizes[0] = 39,
|
||||
.lv_shift_sizes[1] = 30,
|
||||
.lv_shift_sizes[2] = 21,
|
||||
.lv_shift_sizes[3] = 12};
|
||||
|
||||
void knl_pdir_init(page_entry_t *pdir, pte_t *dir, int page_deep)
|
||||
{
|
||||
pdir->dir = dir;
|
||||
pdir->depth = page_deep;
|
||||
pdir->lv_shift_sizes[0] = 39;
|
||||
pdir->lv_shift_sizes[1] = 30;
|
||||
pdir->lv_shift_sizes[2] = 21;
|
||||
pdir->lv_shift_sizes[3] = 12;
|
||||
}
|
||||
|
||||
SECTION(TEXT_BOOT_SECTION)
|
||||
pte_t *pages_walk(page_entry_t *pdir, addr_t virt_addr, mword_t size, void *(*fn_alloc)(void))
|
||||
{
|
||||
int i;
|
||||
pte_t *next = &pdir->dir[(virt_addr >> pdir->lv_shift_sizes[(PAGE_DEEP - pdir->depth)]) & 0x1ffUL];
|
||||
|
||||
for (i = (PAGE_DEEP - pdir->depth); i < PAGE_DEEP; i++)
|
||||
{
|
||||
if (pdir->lv_shift_sizes[i] == size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(i != PAGE_DEEP);
|
||||
|
||||
for (int j = (PAGE_DEEP - pdir->depth); j < PAGE_DEEP; j++)
|
||||
{
|
||||
if (j == i)
|
||||
{
|
||||
return next;
|
||||
}
|
||||
if (next->pte == 0)
|
||||
{
|
||||
next->pte = (mword_t)fn_alloc();
|
||||
assert(next->pte);
|
||||
next->pte |= 3UL;
|
||||
_dmb(ishst);
|
||||
}
|
||||
assert((j + 1) < PAGE_DEEP);
|
||||
next = &((pte_t *)(next->pte & ~3UL))[(virt_addr >> pdir->lv_shift_sizes[j + 1]) & 0x1ffUL];
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
SECTION(TEXT_BOOT_SECTION)
|
||||
void map_mm(page_entry_t *pdir, addr_t virt_addr, addr_t phys_addr,
|
||||
mword_t page_order, mword_t pfn_cn, mword_t attr)
|
||||
{
|
||||
for (mword_t i = 0; i < pfn_cn; i++)
|
||||
{
|
||||
pte_t *pte = pages_walk(pdir, virt_addr + (i << page_order), page_order, page_alloc);
|
||||
|
||||
assert(pte);
|
||||
pte->pte = (phys_addr + (i << page_order)) | attr;
|
||||
_dmb(ishst);
|
||||
}
|
||||
}
|
||||
|
||||
static SECTION(TEXT_BOOT_SECTION) void boot_init_pageing(page_entry_t *kpdir, bool_t init_pages)
|
||||
{
|
||||
uint64_t parang;
|
||||
uint64_t tmp;
|
||||
|
||||
write_sysreg(0x00ff4400, mair_el2);
|
||||
if (init_pages)
|
||||
{
|
||||
map_mm(kpdir, 0x40000000, 0x40000000, 30, 1, 0x709);
|
||||
// map_mm(kpdir, _text_boot, _text_boot, PAGE_SHIFT, ALIGN(_edata_boot - _text_boot, PAGE_SIZE) >> PAGE_SHIFT, 0x70b);
|
||||
// map_mm(kpdir, _text, _edata_boot, PAGE_SHIFT, ALIGN(_buddy_data_end - _text, PAGE_SIZE) >> PAGE_SHIFT, 0x70b);
|
||||
map_mm(kpdir, PBASE, PBASE, 21, DEVICE_SIZE >> 21, 0x709);
|
||||
}
|
||||
tmp = read_sysreg(ID_AA64MMFR0_EL1);
|
||||
parang = tmp & 0xf;
|
||||
if (parang > ID_AA64MMFR0_PARANGE_48)
|
||||
{
|
||||
parang = ID_AA64MMFR0_PARANGE_48;
|
||||
}
|
||||
write_sysreg(TCR_DEFAULT | (parang << 16UL), tcr_el2);
|
||||
_dsb(sy);
|
||||
write_sysreg(kpdir->dir, ttbr0_el2);
|
||||
}
|
||||
|
||||
SECTION(TEXT_BOOT_SECTION)
|
||||
int boot_enable_mmu(void)
|
||||
{
|
||||
mword_t tmp;
|
||||
|
||||
_dsb(ish);
|
||||
asm volatile("tlbi alle2is");
|
||||
asm volatile("tlbi vmalle1is");
|
||||
_dsb(ish);
|
||||
// write_sysreg(SCTLR_ELx_M, sctlr_el2);
|
||||
write_sysreg(0x30c51835, sctlr_el2);
|
||||
_isb();
|
||||
asm volatile("ic iallu");
|
||||
_dsb(nsh);
|
||||
_isb();
|
||||
return 0;
|
||||
}
|
||||
|
||||
SECTION(TEXT_BOOT_SECTION)
|
||||
page_entry_t *boot_get_pdir(void)
|
||||
{
|
||||
return &kpdir;
|
||||
}
|
||||
|
||||
SECTION(TEXT_BOOT_SECTION)
|
||||
void per_cpu_boot_mapping(bool_t init_pages)
|
||||
{
|
||||
boot_init_pageing(&kpdir, init_pages);
|
||||
_dsb(ish);
|
||||
asm volatile("ic iallu");
|
||||
boot_enable_mmu();
|
||||
}
|
||||
extern void jump_kenel_main(void);
|
||||
|
||||
// 启动的恒等映射
|
||||
SECTION(TEXT_BOOT_SECTION)
|
||||
void boot_mapping(void)
|
||||
{
|
||||
boot_memset(pages, 0, sizeof(pages));
|
||||
boot_memset(pages_used, 0, sizeof(pages_used));
|
||||
per_cpu_boot_mapping(TRUE);
|
||||
jump_kenel_main();
|
||||
}
|
||||
22
mkrtos_knl/arch/aarch64/early_boot.h
Normal file
22
mkrtos_knl/arch/aarch64/early_boot.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
#include "pager.h"
|
||||
#include "asm/mm.h"
|
||||
#include "asm_config.h"
|
||||
|
||||
#define PAGE_DEEP 4
|
||||
|
||||
typedef struct page_entry
|
||||
{
|
||||
pte_t *dir; //!< 存储页表地址
|
||||
uint8_t lv_shift_sizes[PAGE_DEEP]; //!< 页表翻译的大小,order
|
||||
uint8_t depth; //!< 页表深度
|
||||
} page_entry_t;
|
||||
|
||||
pte_t *pages_walk(page_entry_t *pdir, addr_t virt_addr, mword_t size, void *(*fn_alloc)(void));
|
||||
void map_mm(page_entry_t *pdir, addr_t virt_addr, addr_t phys_addr,
|
||||
mword_t page_order, mword_t pfn_cn, mword_t attr);
|
||||
void per_cpu_boot_mapping(bool_t init_pages);
|
||||
page_entry_t *boot_get_pdir(void);
|
||||
void knl_pdir_init(page_entry_t *pdir, pte_t *dir, int page_deep);
|
||||
25
mkrtos_knl/arch/aarch64/exception.c
Normal file
25
mkrtos_knl/arch/aarch64/exception.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <printk.h>
|
||||
#include <arch.h>
|
||||
static const char *const bad_mode_handler[] = {
|
||||
"Sync Abort",
|
||||
"IRQ",
|
||||
"FIQ",
|
||||
"SError"};
|
||||
|
||||
void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
|
||||
{
|
||||
printk("Bad mode for %s handler detected, esr=0x%x ec=0x%x far_el2=0x%lx\n",
|
||||
bad_mode_handler[reason], esr, esr >> 26, read_sysreg(far_el2));
|
||||
|
||||
mword_t x29;
|
||||
|
||||
asm volatile("mov %0, x29" : "=r"(x29));
|
||||
printk("x29 %lx.\n", x29);
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
x29 = *(long *)(x29);
|
||||
printk("kernel sync instruction addr is %lx\n", *(long *)(x29 + 8));
|
||||
}
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
151
mkrtos_knl/arch/aarch64/hyp.c
Normal file
151
mkrtos_knl/arch/aarch64/hyp.c
Normal file
@@ -0,0 +1,151 @@
|
||||
#include <arch.h>
|
||||
enum Scr_bits
|
||||
{
|
||||
Scr_ns = 1UL << 0, ///< Non-Secure mode
|
||||
Scr_irq = 1UL << 1, ///< IRQ to EL3
|
||||
Scr_fiq = 1UL << 2, ///< FIQ to EL3
|
||||
Scr_ea = 1UL << 3, ///< External Abort and SError to EL3
|
||||
Scr_smd = 1UL << 7, ///< SMC disable
|
||||
Scr_hce = 1UL << 8, ///< HVC enable at EL1, EL2, and EL3
|
||||
Scr_sif = 1UL << 9, ///< Secure instruction fetch enable
|
||||
Scr_rw = 1UL << 10, ///< EL2 / EL1 is AArch64
|
||||
Scr_st = 1UL << 11, ///< Trap Secure EL1 access to timer to EL3
|
||||
Scr_twi = 1UL << 12, ///< Trap WFI to EL3
|
||||
Scr_twe = 1UL << 13, ///< Trap WFE to EL3
|
||||
Scr_apk = 1UL << 16, ///< Do not trap on Pointer Authentication key accesses
|
||||
Scr_api = 1UL << 17, ///< Do not trap on Pointer Authentication instructions
|
||||
Scr_eel2 = 1UL << 18, ///< Secure EL2 enable
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Sctlr_m = 1UL << 0,
|
||||
Sctlr_a = 1UL << 1,
|
||||
Sctlr_c = 1UL << 2,
|
||||
Sctlr_sa = 1UL << 3,
|
||||
Sctlr_sa0 = 1UL << 4,
|
||||
Sctlr_cp15ben = 1UL << 5,
|
||||
Sctlr_itd = 1UL << 7,
|
||||
Sctlr_sed = 1UL << 8,
|
||||
Sctlr_uma = 1UL << 9,
|
||||
Sctlr_i = 1UL << 12,
|
||||
Sctlr_dze = 1UL << 14,
|
||||
Sctlr_uct = 1UL << 15,
|
||||
Sctlr_ntwi = 1UL << 16,
|
||||
Sctlr_ntwe = 1UL << 18,
|
||||
Sctlr_wxn = 1UL << 19,
|
||||
Sctlr_e0e = 1UL << 24,
|
||||
Sctlr_ee = 1UL << 25,
|
||||
Sctlr_uci = 1UL << 26,
|
||||
|
||||
Sctlr_el1_res = (1UL << 11) | (1UL << 20) | (3UL << 22) | (3UL << 28),
|
||||
|
||||
Sctlr_el1_generic = Sctlr_c | Sctlr_cp15ben | Sctlr_i | Sctlr_dze | Sctlr_uct | Sctlr_uci | Sctlr_el1_res,
|
||||
};
|
||||
enum
|
||||
{
|
||||
Scr_default_bits = Scr_ns | Scr_rw | Scr_smd | Scr_hce,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Hcr_vm = 1UL << 0, ///< Virtualization enable
|
||||
Hcr_swio = 1UL << 1, ///< Set/way invalidation override
|
||||
Hcr_ptw = 1UL << 2, ///< Protected table walk
|
||||
Hcr_fmo = 1UL << 3, ///< Physical FIQ routing
|
||||
Hcr_imo = 1UL << 4, ///< Physical IRQ routing
|
||||
Hcr_amo = 1UL << 5, ///< Physical SError interrupt routing
|
||||
Hcr_dc = 1UL << 12, ///< Default cacheability
|
||||
Hcr_tid2 = 1UL << 17, ///< Trap CTR, CESSLR, etc.
|
||||
Hcr_tid3 = 1UL << 18, ///< Trap ID, etc.
|
||||
Hcr_tsc = 1UL << 19, ///< Trap SMC instructions
|
||||
Hcr_tidcp = 1UL << 20, ///< Trap implementation defined functionality
|
||||
Hcr_tactlr = 1UL << 21, ///< Trap ACTLR, etc.
|
||||
Hcr_tsw = 1UL << 22, ///< Trap cache maintenance instructions
|
||||
Hcr_ttlb = 1UL << 25, ///< Trap TLB maintenance instructions
|
||||
Hcr_tvm = 1UL << 26, ///< Trap virtual memory controls
|
||||
Hcr_tge = 1UL << 27, ///< Trap General Exceptions
|
||||
Hcr_hcd = 1UL << 29, ///< HVC instruction disable
|
||||
Hcr_trvm = 1UL << 30, ///< Trap reads of virtual memory controls
|
||||
Hcr_rw = 1UL << 31, ///< EL1 is AArch64
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Hcr_must_set_bits = Hcr_vm | Hcr_swio | Hcr_ptw | Hcr_amo | Hcr_imo | Hcr_fmo | Hcr_tidcp | Hcr_tsc | Hcr_tactlr,
|
||||
|
||||
/**
|
||||
* HCR value to be used for the VMM.
|
||||
*
|
||||
* The AArch64 VMM is currently running in EL1.
|
||||
*/
|
||||
Hcr_host_bits = Hcr_must_set_bits | Hcr_rw | Hcr_dc,
|
||||
|
||||
/**
|
||||
* HCR value to be used for normal threads.
|
||||
*
|
||||
* On AArch64 (with virtualization support) running in EL1.
|
||||
*/
|
||||
Hcr_non_vm_bits = Hcr_must_set_bits | Hcr_rw | Hcr_dc | Hcr_tsw | Hcr_ttlb | Hcr_tvm | Hcr_trvm
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Mdcr_hpmn_mask = 0xf,
|
||||
Mdcr_tpmcr = 1UL << 5,
|
||||
Mdcr_tpm = 1UL << 6,
|
||||
Mdcr_hpme = 1UL << 7,
|
||||
Mdcr_tde = 1UL << 8,
|
||||
Mdcr_tda = 1UL << 9,
|
||||
Mdcr_tdosa = 1UL << 10,
|
||||
Mdcr_tdra = 1UL << 11,
|
||||
|
||||
Mdcr_bits = Mdcr_tpmcr | Mdcr_tpm | Mdcr_tda | Mdcr_tdosa | Mdcr_tdra,
|
||||
Mdcr_vm_mask = 0xf00,
|
||||
};
|
||||
enum
|
||||
{
|
||||
/// Attributes for page-table walks
|
||||
Tcr_attribs = (3UL << 4) // SH0
|
||||
| (1UL << 2) // ORGN0
|
||||
| (1UL << 0), // IRGN0
|
||||
|
||||
/**
|
||||
* Memory Attribute Indirection (MAIR0)
|
||||
* Attr0: Device-nGnRnE memory
|
||||
* Attr1: Normal memory, Inner/Outer Non-cacheable
|
||||
* Attr2: Normal memory, RW, Inner/Outer Write-Back Cacheable (Non-transient)
|
||||
*/
|
||||
Mair0_prrr_bits = 0x00ff4400,
|
||||
Mair1_nmrr_bits = 0,
|
||||
};
|
||||
enum
|
||||
{
|
||||
Vtcr_bits = (1UL << 6) // SL0
|
||||
| (2UL << 16) // PS
|
||||
| (25UL << 0) // T0SZ
|
||||
};
|
||||
enum Hstr_values
|
||||
{
|
||||
Hstr_non_vm = 0x9f6f, // ALL but crn=13,7 (TPIDxxR, DSB) CP15 traped
|
||||
Hstr_vm = 0x0, // none
|
||||
};
|
||||
void init_arm_hyp(void)
|
||||
{
|
||||
// asm volatile ("msr VBAR_EL2, %x0" : : "r"(&exception_vector));
|
||||
asm volatile("msr VTCR_EL2, %x0" : : "r"((1UL << 31) // RES1
|
||||
| (Tcr_attribs << 8) | Vtcr_bits));
|
||||
|
||||
asm volatile("msr MDCR_EL2, %x0" : : "r"((mword_t)Mdcr_bits));
|
||||
|
||||
asm volatile("msr SCTLR_EL1, %x0" : : "r"((mword_t)Sctlr_el1_generic));
|
||||
asm volatile("msr HCR_EL2, %x0" : : "r"(Hcr_non_vm_bits));
|
||||
asm volatile("msr HSTR_EL2, %x0" : : "r"(Hstr_non_vm));
|
||||
|
||||
_dsb(sy);
|
||||
_isb();
|
||||
|
||||
// HCPTR
|
||||
asm volatile("msr CPTR_EL2, %x0" : : "r"(0x33ffUL // TCP: 0-9, 12-13
|
||||
| (1 << 20))); // TTA
|
||||
}
|
||||
3
mkrtos_knl/arch/aarch64/hyp.h
Normal file
3
mkrtos_knl/arch/aarch64/hyp.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void init_arm_hyp(void);
|
||||
85
mkrtos_knl/arch/aarch64/link.lds
Normal file
85
mkrtos_knl/arch/aarch64/link.lds
Normal file
@@ -0,0 +1,85 @@
|
||||
ENTRY(_start);
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40000000+0x1000;
|
||||
kernel_start = .;
|
||||
_text_boot = .;
|
||||
.text.boot :
|
||||
{
|
||||
*(.text.boot)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
_etext_boot = .;
|
||||
_data_boot = .;
|
||||
.data.boot :
|
||||
{
|
||||
*(.data.boot)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
_edata_boot = .;
|
||||
. = _edata_boot;
|
||||
_text = .;
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
. = ALIGN(8);
|
||||
_mkrtos_init_start = .;
|
||||
KEEP (*(SORT(.mkrtos.init.*)))
|
||||
_mkrtos_init_end = .;
|
||||
}
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array*))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
_etext = .;
|
||||
_rodata = .;
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
_erodata = .;
|
||||
_data = .;
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
. = ALIGN(0x8);
|
||||
_pre_cpu_data_start = .;
|
||||
KEEP (*(.data.per_cpu))
|
||||
_pre_cpu_data_end = .;
|
||||
}
|
||||
_edata = .;
|
||||
. = ALIGN(0x8);
|
||||
_bss = .;
|
||||
bss_begin = .;
|
||||
.bss :
|
||||
{
|
||||
*(.bss*)
|
||||
}
|
||||
bss_end = .;
|
||||
_ebss = .;
|
||||
. = ALIGN(4096);
|
||||
_buddy_data_start = .;
|
||||
.buddy :
|
||||
{
|
||||
*(.buddy*)
|
||||
. += 0x1000000;
|
||||
}
|
||||
_buddy_data_end = .;
|
||||
}
|
||||
121
mkrtos_knl/arch/aarch64/link.lds.S
Normal file
121
mkrtos_knl/arch/aarch64/link.lds.S
Normal file
@@ -0,0 +1,121 @@
|
||||
ENTRY(_start);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/*
|
||||
* 设置mkrtos的加载入口地址为0x80000
|
||||
*
|
||||
* 这里“.”表示location counter,当前位置
|
||||
*/
|
||||
. = 0x40000000+0x1000;
|
||||
kernel_start = .;
|
||||
/*
|
||||
* 这里是第一个段text.boot,起始地址就是0x80000
|
||||
* 这个段存放了benos的第一条指令
|
||||
*/
|
||||
_text_boot = .;
|
||||
.text.boot :
|
||||
{
|
||||
*(.text.boot)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
_etext_boot = .;
|
||||
|
||||
_data_boot = .;
|
||||
.data.boot :
|
||||
{
|
||||
*(.data.boot)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
_edata_boot = .;
|
||||
|
||||
. = _edata_boot;
|
||||
/*
|
||||
* text代码段
|
||||
*/
|
||||
_text = .;
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
. = ALIGN(8);
|
||||
_mkrtos_init_start = .;
|
||||
KEEP (*(SORT(.mkrtos.init.*)))
|
||||
_mkrtos_init_end = .;
|
||||
}
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array*))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
_etext = .;
|
||||
|
||||
/*
|
||||
* 只读数据段
|
||||
*/
|
||||
|
||||
_rodata = .;
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
_erodata = .;
|
||||
|
||||
|
||||
/*
|
||||
* 数据段
|
||||
*/
|
||||
_data = .;
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
|
||||
. = ALIGN(0x8);
|
||||
_pre_cpu_data_start = .;
|
||||
KEEP (*(.data.per_cpu))
|
||||
_pre_cpu_data_end = .;
|
||||
}
|
||||
_edata = .;
|
||||
|
||||
/*
|
||||
* bss段
|
||||
*
|
||||
* ALIGN(8)表示8个字节对齐
|
||||
* bss_begin的起始地址以8字节对齐
|
||||
*/
|
||||
. = ALIGN(0x8);
|
||||
_bss = .;
|
||||
bss_begin = .;
|
||||
.bss :
|
||||
{
|
||||
*(.bss*)
|
||||
}
|
||||
bss_end = .;
|
||||
_ebss = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
_buddy_data_start = .;
|
||||
.buddy :
|
||||
{
|
||||
*(.buddy*)
|
||||
. += 0x1000000;
|
||||
}
|
||||
_buddy_data_end = .;
|
||||
|
||||
|
||||
}
|
||||
65
mkrtos_knl/arch/aarch64/pager.c
Normal file
65
mkrtos_knl/arch/aarch64/pager.c
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
#include <types.h>
|
||||
// #include <mkrtos.h>
|
||||
#include "asm/sysregs.h"
|
||||
#include <arch.h>
|
||||
#include "asm/base.h"
|
||||
#include "pager.h"
|
||||
#include "asm/mm.h"
|
||||
#include <printk.h>
|
||||
static inline mword_t pgd_offset(addr_t virt)
|
||||
{
|
||||
return (((virt) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1));
|
||||
}
|
||||
static inline mword_t pmd_offset(addr_t virt)
|
||||
{
|
||||
return (((virt) >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
|
||||
}
|
||||
static inline mword_t pud_offset(addr_t virt)
|
||||
{
|
||||
return (((virt) >> PUD_SHIFT) & (PTRS_PER_PUD - 1));
|
||||
}
|
||||
static inline mword_t pte_offset(addr_t virt)
|
||||
{
|
||||
return (((virt) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
|
||||
}
|
||||
|
||||
static void pte_print(pgd_t *pgdp)
|
||||
{
|
||||
for (size_t i = 0; i < PAGE_SIZE / sizeof(void *); i++)
|
||||
{
|
||||
if (PTE_GET_VALID(pgdp[i].pgd))
|
||||
{
|
||||
printk("%d pgd 0x%lx, next pg 0x%lx\n", i, pgdp[i].pgd, PTE_ADDR(pgdp[i].pgd, PAGE_SHIFT));
|
||||
for (size_t j = 0; j < PAGE_SIZE / sizeof(void *); j++)
|
||||
{
|
||||
pud_t *pudp = &((pud_t *)(PTE_ADDR(pgdp[i].pgd, PAGE_SHIFT)))[j];
|
||||
if (PTE_GET_VALID(pudp->pud))
|
||||
{
|
||||
printk(" %d pud 0x%lx, next pg 0x%lx\n", j, pudp->pud, PTE_ADDR(pudp->pud, PAGE_SHIFT));
|
||||
for (size_t m = 0; m < PAGE_SIZE / sizeof(void *); m++)
|
||||
{
|
||||
pmd_t *pmdp = &((pmd_t *)(PTE_ADDR(pudp->pud, PAGE_SHIFT)))[m];
|
||||
if (PTE_GET_VALID(pmdp->pmd) && (pmdp->pmd & 0x2))
|
||||
{
|
||||
printk(" %d pmd 0x%lx, next pg 0x%lx\n", m, pmdp->pmd, PTE_ADDR(pmdp->pmd, PAGE_SHIFT));
|
||||
|
||||
for (size_t n = 0; n < PAGE_SIZE / sizeof(void *); n++)
|
||||
{
|
||||
pte_t *ptep = &((pte_t *)(PTE_ADDR(pmdp->pmd, PAGE_SHIFT)))[n];
|
||||
if (PTE_GET_VALID(ptep->pte))
|
||||
{
|
||||
printk(" %d pte 0x%lx, next pg 0x%lx\n", n, ptep->pte, PTE_ADDR(ptep->pte, PAGE_SHIFT));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PTE_GET_VALID(pmdp->pmd))
|
||||
{
|
||||
printk(" %d pmd 0x%lx, addr 0x%lx\n", m, pmdp->pmd, PTE_ADDR(pmdp->pmd, PAGE_SHIFT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
257
mkrtos_knl/arch/aarch64/pager.h
Normal file
257
mkrtos_knl/arch/aarch64/pager.h
Normal file
@@ -0,0 +1,257 @@
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
#include <util.h>
|
||||
typedef struct pgd
|
||||
{
|
||||
mword_t pgd;
|
||||
} pgd_t;
|
||||
|
||||
typedef struct pud
|
||||
{
|
||||
mword_t pud;
|
||||
} pud_t;
|
||||
|
||||
typedef struct pmd
|
||||
{
|
||||
mword_t pmd;
|
||||
} pmd_t;
|
||||
|
||||
typedef struct pte
|
||||
{
|
||||
mword_t pte;
|
||||
} pte_t;
|
||||
|
||||
#define PTE_GET_VALID(p) (p & 0x1UL)
|
||||
#define PTE_GET_TYPE(p) (p & 0x2UL)
|
||||
|
||||
#define PTE_LOW_ATTR(p) (MASK_LSB(p, 2) & 0x3ffUL)
|
||||
#define PTE_HIGH_ATTR(p) (MASK_LSB(p, 52) >> 52UL)
|
||||
|
||||
#define PTE_ADDR(p, n) (MASK_LSB(p, n))
|
||||
#define PTE_PA(p, n) PTE_ADDR(p, n)
|
||||
#define PTE_NEXT_BASE_ADDR(p, n) PTE_ADDR(p, n)
|
||||
|
||||
#define PTE_PA_4K(p) PTE_ADDR(p, 12)
|
||||
|
||||
/* PGD */
|
||||
#define PGDIR_SHIFT 39
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE - 1))
|
||||
#define PTRS_PER_PGD (1 << (VA_BITS - PGDIR_SHIFT))
|
||||
|
||||
/* PUD */
|
||||
#define PUD_SHIFT 30
|
||||
#define PUD_SIZE (1UL << PUD_SHIFT)
|
||||
#define PUD_MASK (~(PUD_SIZE - 1))
|
||||
#define PTRS_PER_PUD (1 << (PGDIR_SHIFT - PUD_SHIFT))
|
||||
|
||||
/* PMD */
|
||||
#define PMD_SHIFT 21
|
||||
#define PMD_SIZE (1UL << PMD_SHIFT)
|
||||
#define PMD_MASK (~(PMD_SIZE - 1))
|
||||
#define PTRS_PER_PMD (1 << (PUD_SHIFT - PMD_SHIFT))
|
||||
|
||||
/* PTE */
|
||||
#define PTE_SHIFT 12
|
||||
#define PTE_SIZE (1UL << PTE_SHIFT)
|
||||
#define PTE_MASK (~(PTE_SIZE - 1))
|
||||
#define PTRS_PER_PTE (1 << (PMD_SHIFT - PTE_SHIFT))
|
||||
|
||||
/* Section */
|
||||
#define SECTION_SHIFT PMD_SHIFT
|
||||
#define SECTION_SIZE (1UL << SECTION_SHIFT)
|
||||
#define SECTION_MASK (~(SECTION_SIZE - 1))
|
||||
|
||||
// Level 3 descriptor PTE高位属性
|
||||
#define PTE_TYPE_MASK (3UL << 0)
|
||||
#define PTE_TYPE_FAULT (0UL << 0)
|
||||
#define PTE_TYPE_PAGE (3UL << 0)
|
||||
#define PTE_TABLE_BIT (1UL << 1)
|
||||
#define PTE_USER (1UL << 6) /* AP[1] */
|
||||
#define PTE_RDONLY (1UL << 7) /* AP[2] */
|
||||
#define PTE_SHARED (3UL << 8) /* SH[1:0], inner shareable */
|
||||
#define PTE_AF (1UL << 10) /* Access Flag */
|
||||
#define PTE_NG (1UL << 11) /* nG */
|
||||
#define PTE_DBM (1UL << 51) /* Dirty Bit Management */
|
||||
#define PTE_CONT (1UL << 52) /* Contiguous range */
|
||||
#define PTE_PXN (1UL << 53) /* Privileged XN */
|
||||
#define PTE_UXN (1UL << 54) /* User XN */
|
||||
#define PTE_HYP_XN (1UL << 54) /* HYP XN */
|
||||
|
||||
/*
|
||||
* AttrIndx[2:0] encoding
|
||||
* (mapping attributes defined in the MAIR* registers).
|
||||
*/
|
||||
#define PTE_ATTRINDX(t) ((t) << 2)
|
||||
#define PTE_ATTRINDX_MASK (7 << 2)
|
||||
|
||||
// #define TCR_IPS_MASK (0x7UL << 32)
|
||||
// #define TCR_TG1_MASK (0x3UL << 30)
|
||||
// #define TCR_T1SZ_MASK (0x3fUL << 16)
|
||||
// #define TCR_TG0_MASK (0x3UL << 14)
|
||||
// #define TCR_T0SZ_MASK (0x3fUL << 0)
|
||||
|
||||
#define SCTLR_M_MASK (0x1UL << 0)
|
||||
#define SCTLR_I_MASK (0x1UL << 12)
|
||||
#define SCTRL_C_MASK (0x1UL << 2)
|
||||
|
||||
/*
|
||||
* Memory types available.
|
||||
*/
|
||||
#define MT_DEVICE_nGnRnE 0
|
||||
#define MT_DEVICE_nGnRE 1
|
||||
#define MT_DEVICE_GRE 2
|
||||
#define MT_NORMAL_NC 3
|
||||
#define MT_NORMAL 4
|
||||
#define MT_NORMAL_WT 5
|
||||
|
||||
/*
|
||||
* Software defined PTE bits definition.
|
||||
*/
|
||||
#define PTE_VALID (1UL << 0)
|
||||
#define PTE_WRITE (PTE_DBM) /* same as DBM (51) */
|
||||
#define PTE_DIRTY (1UL << 55)
|
||||
#define PTE_SPECIAL (1UL << 56)
|
||||
#define PTE_PROT_NONE (1UL << 58) /* only when !PTE_VALID */
|
||||
|
||||
#define MAIR(attr, mt) ((attr) << ((mt) * 8))
|
||||
|
||||
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
|
||||
#define PROT_DEFAULT (_PROT_DEFAULT)
|
||||
|
||||
#define PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
|
||||
#define PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
|
||||
#define PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN)
|
||||
|
||||
#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
|
||||
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
|
||||
#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define PAGE_KERNEL PROT_NORMAL
|
||||
|
||||
/*
|
||||
* TCR flags.
|
||||
*/
|
||||
#define TCR_T0SZ_OFFSET 0
|
||||
#define TCR_T1SZ_OFFSET 16
|
||||
#define TCR_T0SZ(x) ((UL(64) - (x)) << TCR_T0SZ_OFFSET)
|
||||
#define TCR_T1SZ(x) ((UL(64) - (x)) << TCR_T1SZ_OFFSET)
|
||||
#define TCR_TxSZ(x) (TCR_T0SZ(x) | TCR_T1SZ(x))
|
||||
#define TCR_TxSZ_WIDTH 6
|
||||
// #define TCR_T0SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET)
|
||||
|
||||
#define TCR_EPD0_SHIFT 7
|
||||
#define TCR_EPD0_MASK (UL(1) << TCR_EPD0_SHIFT)
|
||||
#define TCR_IRGN0_SHIFT 8
|
||||
#define TCR_IRGN0_MASK (UL(3) << TCR_IRGN0_SHIFT)
|
||||
#define TCR_IRGN0_NC (UL(0) << TCR_IRGN0_SHIFT)
|
||||
#define TCR_IRGN0_WBWA (UL(1) << TCR_IRGN0_SHIFT)
|
||||
#define TCR_IRGN0_WT (UL(2) << TCR_IRGN0_SHIFT)
|
||||
#define TCR_IRGN0_WBnWA (UL(3) << TCR_IRGN0_SHIFT)
|
||||
|
||||
#define TCR_EPD1_SHIFT 23
|
||||
#define TCR_EPD1_MASK (UL(1) << TCR_EPD1_SHIFT)
|
||||
#define TCR_IRGN1_SHIFT 24
|
||||
#define TCR_IRGN1_MASK (UL(3) << TCR_IRGN1_SHIFT)
|
||||
#define TCR_IRGN1_NC (UL(0) << TCR_IRGN1_SHIFT)
|
||||
#define TCR_IRGN1_WBWA (UL(1) << TCR_IRGN1_SHIFT)
|
||||
#define TCR_IRGN1_WT (UL(2) << TCR_IRGN1_SHIFT)
|
||||
#define TCR_IRGN1_WBnWA (UL(3) << TCR_IRGN1_SHIFT)
|
||||
|
||||
#define TCR_IRGN_NC (TCR_IRGN0_NC | TCR_IRGN1_NC)
|
||||
#define TCR_IRGN_WBWA (TCR_IRGN0_WBWA | TCR_IRGN1_WBWA)
|
||||
#define TCR_IRGN_WT (TCR_IRGN0_WT | TCR_IRGN1_WT)
|
||||
#define TCR_IRGN_WBnWA (TCR_IRGN0_WBnWA | TCR_IRGN1_WBnWA)
|
||||
#define TCR_IRGN_MASK (TCR_IRGN0_MASK | TCR_IRGN1_MASK)
|
||||
|
||||
#define TCR_ORGN0_SHIFT 10
|
||||
#define TCR_ORGN0_MASK (UL(3) << TCR_ORGN0_SHIFT)
|
||||
#define TCR_ORGN0_NC (UL(0) << TCR_ORGN0_SHIFT)
|
||||
#define TCR_ORGN0_WBWA (UL(1) << TCR_ORGN0_SHIFT)
|
||||
#define TCR_ORGN0_WT (UL(2) << TCR_ORGN0_SHIFT)
|
||||
#define TCR_ORGN0_WBnWA (UL(3) << TCR_ORGN0_SHIFT)
|
||||
|
||||
#define TCR_ORGN1_SHIFT 26
|
||||
#define TCR_ORGN1_MASK (UL(3) << TCR_ORGN1_SHIFT)
|
||||
#define TCR_ORGN1_NC (UL(0) << TCR_ORGN1_SHIFT)
|
||||
#define TCR_ORGN1_WBWA (UL(1) << TCR_ORGN1_SHIFT)
|
||||
#define TCR_ORGN1_WT (UL(2) << TCR_ORGN1_SHIFT)
|
||||
#define TCR_ORGN1_WBnWA (UL(3) << TCR_ORGN1_SHIFT)
|
||||
|
||||
#define TCR_ORGN_NC (TCR_ORGN0_NC | TCR_ORGN1_NC)
|
||||
#define TCR_ORGN_WBWA (TCR_ORGN0_WBWA | TCR_ORGN1_WBWA)
|
||||
#define TCR_ORGN_WT (TCR_ORGN0_WT | TCR_ORGN1_WT)
|
||||
#define TCR_ORGN_WBnWA (TCR_ORGN0_WBnWA | TCR_ORGN1_WBnWA)
|
||||
#define TCR_ORGN_MASK (TCR_ORGN0_MASK | TCR_ORGN1_MASK)
|
||||
|
||||
#define TCR_SH0_SHIFT 12
|
||||
#define TCR_SH0_MASK (UL(3) << TCR_SH0_SHIFT)
|
||||
#define TCR_SH0_INNER (UL(3) << TCR_SH0_SHIFT)
|
||||
|
||||
#define TCR_SH1_SHIFT 28
|
||||
#define TCR_SH1_MASK (UL(3) << TCR_SH1_SHIFT)
|
||||
#define TCR_SH1_INNER (UL(3) << TCR_SH1_SHIFT)
|
||||
#define TCR_SHARED (TCR_SH0_INNER | TCR_SH1_INNER)
|
||||
|
||||
#define TCR_TG0_SHIFT 14
|
||||
#define TCR_TG0_MASK (UL(3) << TCR_TG0_SHIFT)
|
||||
#define TCR_TG0_4K (UL(0) << TCR_TG0_SHIFT)
|
||||
#define TCR_TG0_64K (UL(1) << TCR_TG0_SHIFT)
|
||||
#define TCR_TG0_16K (UL(2) << TCR_TG0_SHIFT)
|
||||
|
||||
#define TCR_TG1_SHIFT 30
|
||||
#define TCR_TG1_MASK (UL(3) << TCR_TG1_SHIFT)
|
||||
#define TCR_TG1_16K (UL(1) << TCR_TG1_SHIFT)
|
||||
#define TCR_TG1_4K (UL(2) << TCR_TG1_SHIFT)
|
||||
#define TCR_TG1_64K (UL(3) << TCR_TG1_SHIFT)
|
||||
|
||||
#define TCR_IPS_SHIFT 32
|
||||
#define TCR_IPS_MASK (UL(7) << TCR_IPS_SHIFT)
|
||||
#define TCR_A1 (UL(1) << 22)
|
||||
#define TCR_ASID16 (UL(1) << 36)
|
||||
#define TCR_TBI0 (UL(1) << 37)
|
||||
#define TCR_TBI1 (UL(1) << 38)
|
||||
#define TCR_HA (UL(1) << 39)
|
||||
#define TCR_HD (UL(1) << 40)
|
||||
#define TCR_NFD1 (UL(1) << 54)
|
||||
|
||||
#define TCR_TG_FLAGS (TCR_TG0_4K | TCR_TG1_4K)
|
||||
#define TCR_KASLR_FLAGS 0
|
||||
#define TCR_KASAN_FLAGS 0
|
||||
#define TCR_SMP_FLAGS TCR_SHARED
|
||||
#define TCR_CACHE_FLAGS (TCR_IRGN_WBWA | TCR_ORGN_WBWA)
|
||||
|
||||
#define TCR_48BITS (((64 - VA_BITS) << 0) | ((64 - VA_BITS) << 16))
|
||||
#define TCR_IPS_48BITS (ID_AA64MMFR0_PARANGE_48 << 32)
|
||||
|
||||
/* id_aa64mmfr0 */
|
||||
#define ID_AA64MMFR0_TGRAN4_SHIFT 28
|
||||
#define ID_AA64MMFR0_TGRAN64_SHIFT 24
|
||||
#define ID_AA64MMFR0_TGRAN16_SHIFT 20
|
||||
#define ID_AA64MMFR0_BIGENDEL0_SHIFT 16
|
||||
#define ID_AA64MMFR0_SNSMEM_SHIFT 12
|
||||
#define ID_AA64MMFR0_BIGENDEL_SHIFT 8
|
||||
#define ID_AA64MMFR0_ASID_SHIFT 4
|
||||
#define ID_AA64MMFR0_PARANGE_SHIFT 0
|
||||
|
||||
#define ID_AA64MMFR0_TGRAN4_NI 0xf
|
||||
#define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0
|
||||
#define ID_AA64MMFR0_TGRAN64_NI 0xf
|
||||
#define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0
|
||||
#define ID_AA64MMFR0_TGRAN16_NI 0x0
|
||||
#define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1
|
||||
#define ID_AA64MMFR0_PARANGE_48 0x5
|
||||
#define ID_AA64MMFR0_PARANGE_52 0x6
|
||||
|
||||
#if defined(CONFIG_ARM64_4K_PAGES)
|
||||
#define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN4_SHIFT
|
||||
#define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN4_SUPPORTED
|
||||
#endif
|
||||
|
||||
#define PTE_ADDR_LOW (((1UL << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
|
||||
#define PTE_ADDR_MASK PTE_ADDR_LOW
|
||||
|
||||
void paging_init(void);
|
||||
50
mkrtos_knl/arch/aarch64/pre_cpu.c
Normal file
50
mkrtos_knl/arch/aarch64/pre_cpu.c
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
#include <pre_cpu.h>
|
||||
#include <types.h>
|
||||
#include <buddy.h>
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <arch.h>
|
||||
#include <assert.h>
|
||||
#include <asm_config.h>
|
||||
#if CONFIG_SMP
|
||||
extern char _pre_cpu_data_start[];
|
||||
extern char _pre_cpu_data_end[];
|
||||
|
||||
static void *pre_cpu_data;
|
||||
static mword_t pre_cpu_data_size;
|
||||
|
||||
void pre_cpu_init(void)
|
||||
{
|
||||
mword_t data_size = (addr_t)_pre_cpu_data_end - (addr_t)_pre_cpu_data_start;
|
||||
pre_cpu_data_size = ALIGN(data_size, MWORD_BYTES);
|
||||
|
||||
printk("pre_cpu data's size is %d bytes.\n", data_size);\
|
||||
printk("pre_cpu data's alloc size is %d bytes.\n", pre_cpu_data_size);
|
||||
|
||||
pre_cpu_data = buddy_alloc(buddy_get_alloter(),
|
||||
pre_cpu_data_size * SYS_CPU_NUM);
|
||||
assert(pre_cpu_data);
|
||||
memset(pre_cpu_data, 0, pre_cpu_data_size * SYS_CPU_NUM);
|
||||
}
|
||||
#else
|
||||
void pre_cpu_init(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void *pre_cpu_get_var_cpu(int cpu_inx, void *mem_addr)
|
||||
{
|
||||
#if CONFIG_SMP
|
||||
mword_t offset = (addr_t)mem_addr - (addr_t)_pre_cpu_data_start;
|
||||
|
||||
return (void *)((addr_t)pre_cpu_data +
|
||||
offset + cpu_inx * pre_cpu_data_size);
|
||||
#else
|
||||
return mem_addr;
|
||||
#endif
|
||||
}
|
||||
void *pre_cpu_get_current_cpu_var(void *mem_addr)
|
||||
{
|
||||
return pre_cpu_get_var_cpu(arch_get_current_cpu_id(), mem_addr);
|
||||
}
|
||||
12
mkrtos_knl/arch/aarch64/pre_cpu.h
Normal file
12
mkrtos_knl/arch/aarch64/pre_cpu.h
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <util.h>
|
||||
|
||||
#define PER_CPU(type, name) \
|
||||
__attribute__((used)) \
|
||||
SECTION(".data.per_cpu") type name
|
||||
|
||||
void pre_cpu_init(void);
|
||||
void *pre_get_current_cpu_var(void *mem_addr);
|
||||
void *pre_get_var_cpu(int cpu_inx, void *mem_addr);
|
||||
137
mkrtos_knl/arch/aarch64/psci.c
Normal file
137
mkrtos_knl/arch/aarch64/psci.c
Normal file
@@ -0,0 +1,137 @@
|
||||
|
||||
#include <types.h>
|
||||
#include <printk.h>
|
||||
#include <psci.h>
|
||||
enum
|
||||
{
|
||||
PSCI_FUNC_VERSION = 0,
|
||||
PSCI_FUNC_CPU_SUSPEND,
|
||||
PSCI_FUNC_CPU_OFF,
|
||||
PSCI_FUNC_CPU_ON,
|
||||
PSCI_FUNC_AFFINITY_INFO,
|
||||
PSCI_FUNC_MIGRATE,
|
||||
PSCI_FUNC_MIGRATE_INFO_TYPE,
|
||||
PSCI_FUNC_MIGRATE_INFO_UP_CPU,
|
||||
PSCI_FUNC_SYSTEM_OFF,
|
||||
PSCI_FUNC_SYSTEM_RESET,
|
||||
PSCI_FUNC_FEATURES,
|
||||
PSCI_FUNC_CPU_FREEZE,
|
||||
PSCI_FUNC_CPU_DEFAULT_SUSPEND,
|
||||
PSCI_FUNC_NODE_HW_STATE,
|
||||
PSCI_FUNC_SYSTEM_SUSPEND,
|
||||
PSCI_FUNC_SET_SUSPEND_MODE,
|
||||
PSCI_FUNC_STAT_RESIDENCY,
|
||||
PSCI_FUNC_STAT_COUNT,
|
||||
|
||||
PSCI_FUNC_BASE_SMC32 = 0x84000000,
|
||||
PSCI_FUNC_BASE_SMC64 = 0xC4000000,
|
||||
};
|
||||
static int v1;
|
||||
static umword_t psci_func(umword_t func_id)
|
||||
{
|
||||
switch (func_id)
|
||||
{
|
||||
case PSCI_FUNC_VERSION:
|
||||
case PSCI_FUNC_CPU_OFF:
|
||||
case PSCI_FUNC_MIGRATE_INFO_TYPE:
|
||||
case PSCI_FUNC_SYSTEM_OFF:
|
||||
case PSCI_FUNC_SYSTEM_RESET:
|
||||
case PSCI_FUNC_FEATURES:
|
||||
case PSCI_FUNC_CPU_FREEZE:
|
||||
case PSCI_FUNC_SET_SUSPEND_MODE:
|
||||
return PSCI_FUNC_BASE_SMC32 + func_id;
|
||||
default:
|
||||
return ((sizeof(long) == 8) ? PSCI_FUNC_BASE_SMC64 : PSCI_FUNC_BASE_SMC32) + func_id;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void psci_call(
|
||||
umword_t func_id,
|
||||
umword_t res[4],
|
||||
umword_t arg0,
|
||||
umword_t arg1,
|
||||
umword_t arg2,
|
||||
umword_t arg3,
|
||||
umword_t arg4,
|
||||
umword_t arg5,
|
||||
umword_t arg6)
|
||||
{
|
||||
register umword_t r0 asm("x0") = psci_func(func_id);
|
||||
register umword_t r1 asm("x1") = arg0;
|
||||
register umword_t r2 asm("x2") = arg1;
|
||||
register umword_t r3 asm("x3") = arg2;
|
||||
register umword_t r4 asm("x4") = arg3;
|
||||
register umword_t r5 asm("x5") = arg4;
|
||||
register umword_t r6 asm("x6") = arg5;
|
||||
register umword_t r7 asm("x7") = arg6;
|
||||
|
||||
// asm volatile("smc #0");
|
||||
arm_smc(r0, r1, r2, r3, r4, r5, r6, r7);
|
||||
|
||||
res[0] = r0;
|
||||
res[1] = r1;
|
||||
res[2] = r2;
|
||||
res[3] = r3;
|
||||
}
|
||||
void psci_init(void)
|
||||
{
|
||||
umword_t res[4];
|
||||
|
||||
printk("psci detecting..\n");
|
||||
psci_call(
|
||||
PSCI_FUNC_VERSION, res, 0, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
v1 = (res[0] >> 16) >= 1;
|
||||
|
||||
if (v1)
|
||||
{
|
||||
psci_call(PSCI_FUNC_FEATURES, res,
|
||||
psci_func(PSCI_FUNC_CPU_SUSPEND),
|
||||
0, 0, 0, 0, 0, 0);
|
||||
if (res[0] & (1UL << 31))
|
||||
{
|
||||
printk("psci CPU_SUSPEND not supported (%d)\n", (int)res[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("psci CPU_SUSPEND format %s, %s support OS-initiated mode\n",
|
||||
res[0] & 0x2 ? "extended" : "original v0.2",
|
||||
res[0] & 0x1 ? "" : "not");
|
||||
}
|
||||
}
|
||||
psci_call(PSCI_FUNC_MIGRATE_INFO_TYPE, res,
|
||||
0, 0, 0, 0, 0, 0, 0);
|
||||
if (res[0] == 0 || res[0] == 1)
|
||||
{
|
||||
printk("psci TOS:single core, %s migration capable\n",
|
||||
res[0] ? "not " : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("psci TOS:not present or not required\n");
|
||||
}
|
||||
}
|
||||
umword_t psci_cpu_on(umword_t cpuid, umword_t entry_point)
|
||||
{
|
||||
umword_t res[4];
|
||||
|
||||
psci_call(PSCI_FUNC_CPU_ON, res, cpuid, entry_point,
|
||||
0, 0, 0, 0, 0);
|
||||
return res[0];
|
||||
}
|
||||
void psci_system_reset(void)
|
||||
{
|
||||
umword_t res[4];
|
||||
|
||||
psci_call(PSCI_FUNC_SYSTEM_RESET, res,
|
||||
0, 0, 0, 0, 0, 0, 0);
|
||||
printk("psci system-reset failed.\n");
|
||||
}
|
||||
void psic_system_off(void)
|
||||
{
|
||||
umword_t res[4];
|
||||
|
||||
psci_call(PSCI_FUNC_SYSTEM_OFF, res,
|
||||
0, 0, 0, 0, 0, 0, 0);
|
||||
printk("psci system_off failed.\n");
|
||||
}
|
||||
16
mkrtos_knl/arch/aarch64/psci.h
Normal file
16
mkrtos_knl/arch/aarch64/psci.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
|
||||
void psci_init(void);
|
||||
umword_t psci_cpu_on(umword_t cpuid, umword_t entry_point);
|
||||
void psci_system_reset(void);
|
||||
void psic_system_off(void);
|
||||
void arm_smc(umword_t arg0,
|
||||
umword_t arg1,
|
||||
umword_t arg2,
|
||||
umword_t arg3,
|
||||
umword_t arg4,
|
||||
umword_t arg5,
|
||||
umword_t arg6,
|
||||
umword_t arg7);
|
||||
9
mkrtos_knl/arch/aarch64/psci_asm.S
Normal file
9
mkrtos_knl/arch/aarch64/psci_asm.S
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
#include <complier.h>
|
||||
|
||||
.section ".text"
|
||||
|
||||
BEGIN_FUNC(arm_smc)
|
||||
smc #0
|
||||
ret
|
||||
END_FUNC(arm_smc)
|
||||
58
mkrtos_knl/arch/aarch64/spin_table.c
Normal file
58
mkrtos_knl/arch/aarch64/spin_table.c
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
|
||||
// #include <config.h>
|
||||
#include <early_boot.h>
|
||||
#include <config.h>
|
||||
#include <util.h>
|
||||
#include <arch.h>
|
||||
#define DATA_BOOT_SECTION ".data.boot"
|
||||
#define TEXT_BOOT_SECTION ".text.boot"
|
||||
|
||||
extern mword_t cpu_jump_addr[SYS_CPU_NUM];
|
||||
extern mword_t per_cpu_stack_addr[SYS_CPU_NUM];
|
||||
|
||||
// 每个cpu的栈指针
|
||||
SECTION(DATA_BOOT_SECTION)
|
||||
__ALIGN__(PAGE_SIZE)
|
||||
mword_t per_cpu_stack[SYS_CPU_NUM][THREAD_BLOCK_SIZE / MWORD_BYTES];
|
||||
|
||||
void *get_cpu_stack(int cpu_inx)
|
||||
{
|
||||
return (void *)per_cpu_stack[cpu_inx];
|
||||
}
|
||||
|
||||
static inline SECTION(TEXT_BOOT_SECTION) uint64_t get_st_currentel(void)
|
||||
{
|
||||
unsigned long _val;
|
||||
|
||||
asm volatile("mrs %0, CurrentEL"
|
||||
: "=r"(_val));
|
||||
return _val;
|
||||
}
|
||||
static SECTION(TEXT_BOOT_SECTION) inline int boot_get_current_cpu_id(void)
|
||||
{
|
||||
return read_sysreg(mpidr_el1) & 0XFFUL;
|
||||
}
|
||||
|
||||
extern void cpu_kernel_init(void);
|
||||
void SECTION(TEXT_BOOT_SECTION) other_cpu_boot(void)
|
||||
{
|
||||
// int cpu_id;
|
||||
|
||||
// cpu_id = boot_get_current_cpu_id();
|
||||
// per_cpu_boot_mapping(&per_cpu_pkdir[cpu_id - 1]);
|
||||
per_cpu_boot_mapping(FALSE);
|
||||
|
||||
mword_t elx = get_st_currentel();
|
||||
|
||||
// kprint("cpuid %d run el%d.\n", cpu_id, elx);
|
||||
cpu_kernel_init();
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
void SECTION(TEXT_BOOT_SECTION) cpu_start_to(int cpu_id)
|
||||
{
|
||||
// knl_pdir_init(&per_cpu_pkdir[cpu_id - 1], per_cpu_boot_kpdir[cpu_id - 1]);
|
||||
per_cpu_stack_addr[cpu_id] = ((addr_t)per_cpu_stack[cpu_id]) + THREAD_BLOCK_SIZE - MWORD_BYTES - PT_REGS_SIZE;
|
||||
cpu_jump_addr[cpu_id] = (mword_t)other_cpu_boot;
|
||||
}
|
||||
4
mkrtos_knl/arch/aarch64/spin_table.h
Normal file
4
mkrtos_knl/arch/aarch64/spin_table.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void cpu_start_to(int cpu_id);
|
||||
void *get_cpu_stack(int cpu_inx);
|
||||
28
mkrtos_knl/arch/aarch64/spinlock_arch.c
Normal file
28
mkrtos_knl/arch/aarch64/spinlock_arch.c
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
#include <types.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
void spinlock_lock_arch(spinlock_t *lock)
|
||||
{
|
||||
mword_t dummy;
|
||||
mword_t tmp;
|
||||
|
||||
asm volatile(
|
||||
"sevl\n"
|
||||
"prfm pstl1keep, [%[lock]]\n"
|
||||
"1: wfe\n"
|
||||
"ldaxr %x[dummy],[%[lock]]\n"
|
||||
"cbnz %x[dummy],1b\n"
|
||||
"orr %x[tmp],%x[dummy],#1\n"
|
||||
"stxr %w[dummy], %x[tmp], [%[lock]]\n"
|
||||
"cbnz %w[dummy],1b\n"
|
||||
: [dummy] "=&r"(dummy), [tmp] "=&r"(tmp), "+m"(lock->val)
|
||||
: [lock] "r"(&lock->val)
|
||||
: "cc");
|
||||
}
|
||||
void spinlock_unlock_arch(spinlock_t *lock)
|
||||
{
|
||||
asm volatile(
|
||||
"stlr wzr, %[lock]"
|
||||
: [lock] "=Q"(lock->val));
|
||||
}
|
||||
6
mkrtos_knl/arch/aarch64/spinlock_arch.h
Normal file
6
mkrtos_knl/arch/aarch64/spinlock_arch.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <spinlock.h>
|
||||
|
||||
void spinlock_lock_arch(spinlock_t *lock);
|
||||
void spinlock_unlock_arch(spinlock_t *lock);
|
||||
3
mkrtos_knl/arch/aarch64/thread_arch.h
Normal file
3
mkrtos_knl/arch/aarch64/thread_arch.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define THREAD_BLOCK_SIZE CONFIG_THREAD_BLOCK_SIZE //!< 线程块大小,栈在块的顶部
|
||||
56
mkrtos_knl/arch/aarch64/thread_armv8.c
Normal file
56
mkrtos_knl/arch/aarch64/thread_armv8.c
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
|
||||
#include <types.h>
|
||||
#include <task.h>
|
||||
#include <thread.h>
|
||||
umword_t thread_get_pfa(void)
|
||||
{
|
||||
umword_t a;
|
||||
|
||||
asm volatile("mrs %0, far_el2" : "=r"(a));
|
||||
return a;
|
||||
}
|
||||
void thread_sync_entry(entry_frame_t *regs)
|
||||
{
|
||||
umword_t ec = 0;
|
||||
// umword_t ec = arm_esr_ec(esr_get());
|
||||
// thread_t *th = thread_current();
|
||||
// task_t *tk = (task_t *)th->task;
|
||||
|
||||
switch (ec)
|
||||
{
|
||||
case 0x20:
|
||||
{
|
||||
// mword_t addr = thread_get_pfa();
|
||||
|
||||
// if (vma_page_fault(&tk->vmam, &tk->mem_dir, MASK_LSB(addr, PAGE_SHIFT)) == NULL) {
|
||||
// //TODO: 如果是init进程则内核死机,否则干掉进程
|
||||
// MKRTOS_ASSERT(0);
|
||||
// }
|
||||
}
|
||||
return;
|
||||
case 0x24:
|
||||
{
|
||||
// mword_t addr = thread_get_pfa();
|
||||
|
||||
// if (vma_page_fault(&tk->vmam, &tk->mem_dir, MASK_LSB(addr, PAGE_SHIFT)) == NULL) {
|
||||
// //TODO: 如果是init进程则内核死机,否则干掉进程
|
||||
// MKRTOS_ASSERT(0);
|
||||
// }
|
||||
}
|
||||
return;
|
||||
case 0x12:
|
||||
case 0x11:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
// svc_handler(regs);
|
||||
return;
|
||||
case 0x00:
|
||||
return;
|
||||
case 0x07:
|
||||
break;
|
||||
case 0x03:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
file(GLOB deps *.c *.S)
|
||||
list(REMOVE_ITEM deps ${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/link.lds.S)
|
||||
|
||||
add_library(arch STATIC ${deps})
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__MPU_PRESENT=1 -DUSE_STDPERIPH_DRIVER=1 ")
|
||||
message(=======${CONFIG_CPU_TYPE})
|
||||
|
||||
target_include_directories(
|
||||
arch
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/
|
||||
)
|
||||
if (${CONFIG_CPU_TYPE} STREQUAL "stm32f1")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSTM32F10X_XL ")
|
||||
target_include_directories(
|
||||
arch
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/armv7m/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc
|
||||
@@ -20,38 +26,14 @@ if (${CONFIG_CPU_TYPE} STREQUAL "stm32f1")
|
||||
)
|
||||
add_subdirectory(${CONFIG_CPU_TYPE})
|
||||
elseif(${CONFIG_CPU_TYPE} STREQUAL "stm32f2" )
|
||||
# message(======="${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/${CONFIG_CPU_TYPE}")
|
||||
target_include_directories(
|
||||
arch
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/armv7m/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc
|
||||
|
||||
)
|
||||
add_subdirectory(${CONFIG_CPU_TYPE})
|
||||
elseif(${CONFIG_CPU_TYPE} STREQUAL "stm32f4" )
|
||||
if(${BOARD} STREQUAL "STM32F407VET6" )
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSTM32F40_41xxx ")
|
||||
endif()
|
||||
target_include_directories(
|
||||
arch
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/armv7m/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F4xx_DSP_StdPeriph_Lib_V1.9.0/Libraries/STM32F4xx_StdPeriph_Driver/inc
|
||||
)
|
||||
add_subdirectory(${CONFIG_CPU_TYPE})
|
||||
elseif(${CONFIG_CPU_TYPE} STREQUAL "swm34s" )
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/armv7m/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/SWM34/SWM341_StdPeriph_Driver/CMSIS/DeviceSupport
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/SWM34/SWM341_StdPeriph_Driver/CMSIS/CoreSupport
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/SWM34/SWM341_StdPeriph_Driver/SWM341_StdPeriph_Driver
|
||||
)
|
||||
add_subdirectory(${CONFIG_CPU_TYPE})
|
||||
endif()
|
||||
0
mkrtos_knl/arch/armv7m/atomic.S → mkrtos_knl/arch/cortex-m3/atomic.S
Executable file → Normal file
0
mkrtos_knl/arch/armv7m/atomic.S → mkrtos_knl/arch/cortex-m3/atomic.S
Executable file → Normal file
0
mkrtos_knl/link.lds.S → mkrtos_knl/arch/cortex-m3/link.lds.S
Executable file → Normal file
0
mkrtos_knl/link.lds.S → mkrtos_knl/arch/cortex-m3/link.lds.S
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
|
||||
file(GLOB_RECURSE deps **/*.s *.s **/*.C *.c)
|
||||
file(GLOB_RECURSE deps *.s *.S *.C *.c)
|
||||
file(GLOB bsp_src ${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/src/*.c)
|
||||
list(APPEND deps ${bsp_src})
|
||||
|
||||
@@ -12,7 +12,8 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Include
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Include
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/armv7m/stm32f2
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/${CONFIG_CPU_TYPE}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${CONFIG_ARCH}/
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/lib
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/inc
|
||||
3
mkrtos_knl/arch/cortex-m3/thread_arch.h
Normal file
3
mkrtos_knl/arch/cortex-m3/thread_arch.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define THREAD_BLOCK_SIZE CONFIG_THREAD_BLOCK_SIZE //!< 线程块大小,栈在块的顶部
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user