add aarch64 support.

This commit is contained in:
zhangzheng
2024-03-31 16:06:11 +00:00
parent 5791e49460
commit c57d9cbb82
166 changed files with 7423 additions and 117 deletions

2
.vscode/launch.json vendored
View File

@@ -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
View File

@@ -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,

View File

@@ -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
View 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
View 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)

View File

@@ -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)

View 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
)

View 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)
;
}

View 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;
}

View 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);

View 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 */

View 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);
}
}
}

View 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);

View 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 = .;
}
}

View 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);

View 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 .

View 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;
}
}
}

View File

@@ -0,0 +1,4 @@
#pragma once
void uart_init(void);
void uart_write_str(const char *str);

View File

@@ -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
View 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);

View File

@@ -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
View 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;
}

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
add_subdirectory(armv7m)
add_subdirectory(${ARCH})

View 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
)

View 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;

View 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}/
)

View 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);

View 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);

View 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 //cpusp
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 .

View File

@@ -0,0 +1,6 @@
#ifndef __SYS_H
#define __SYS_H
#endif

View 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~x29x30lrsp, elr, spsr
*/
.macro kernel_entry el
/*
SP, S_FRAME_SIZE.
struct pt_regs,
.
*/
sub sp, sp, #S_FRAME_SIZE
/*
x0~x29pt_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_el1pt_regs->pc
spsr_elrpt_regs->pstate*/
stp x22, x23, [sp, #S_PC]
.endm
/*
*/
.macro kernel_exit el
/* pt_regs->pcelr_el1,
pt_regs->pstatespsr_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 7128
*/
.macro vtentry label
.align 7
b \label
.endm
/*
* Vector Table
*
* ARM642048
* 44128
* ARMv8 spec v8.6D1.10
* align 112048
*/
.align 11
.global vectors
.section ".text.boot"
vectors:
/* Current EL with SP0
EL1使EL0SP
*/
vtentry el1_sync_invalid
vtentry el1_irq_invalid
vtentry el1_fiq_invalid
vtentry el1_error_invalid
/* Current EL with SPx
EL1使EL1SP
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
线
x19ret_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
/* prevnext
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

View File

@@ -0,0 +1,10 @@
#include <arm_gicv2.h>
static gic_t m_irq;
gic_t *arm_gicv2_get_global(void)
{
return &m_irq;
}

View 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-ID8191reserved
* 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);
// }

View 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)

View 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)

View 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 */

View 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

View 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);

View 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

View 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 */

View 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

View 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;

View 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)

View 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))

View 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

View 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

View 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;
}

View 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;
}

View 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

View File

View 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();
}

View 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);

View 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)
;
}

View 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
}

View File

@@ -0,0 +1,3 @@
#pragma once
void init_arm_hyp(void);

View 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 = .;
}

View File

@@ -0,0 +1,121 @@
ENTRY(_start);
SECTIONS
{
/*
* mkrtos0x80000
*
* .location counter
*/
. = 0x40000000+0x1000;
kernel_start = .;
/*
* text.boot0x80000
* 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_begin8
*/
. = ALIGN(0x8);
_bss = .;
bss_begin = .;
.bss :
{
*(.bss*)
}
bss_end = .;
_ebss = .;
. = ALIGN(4096);
_buddy_data_start = .;
.buddy :
{
*(.buddy*)
. += 0x1000000;
}
_buddy_data_end = .;
}

View 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));
}
}
}
}
}
}
}

View 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);

View 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);
}

View 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);

View 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");
}

View 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);

View File

@@ -0,0 +1,9 @@
#include <complier.h>
.section ".text"
BEGIN_FUNC(arm_smc)
smc #0
ret
END_FUNC(arm_smc)

View 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;
}

View File

@@ -0,0 +1,4 @@
#pragma once
void cpu_start_to(int cpu_id);
void *get_cpu_stack(int cpu_inx);

View 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));
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include <spinlock.h>
void spinlock_lock_arch(spinlock_t *lock);
void spinlock_unlock_arch(spinlock_t *lock);

View File

@@ -0,0 +1,3 @@
#pragma once
#define THREAD_BLOCK_SIZE CONFIG_THREAD_BLOCK_SIZE //!< 线程块大小,栈在块的顶部

View 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;
}
}

View File

@@ -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()

View File

View File

View 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

View 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