Compare commits

..

23 Commits

Author SHA1 Message Date
floratest12 f55170aad3 ADD file via upload 2024-11-07 13:55:40 +08:00
floratest12 fb913e5551 ADD file via upload 2024-11-07 13:52:36 +08:00
floraachy 453a056534 Merge pull request 'fork合并到原仓库' (#8) from autotest/xiuos:master into master 2024-11-07 13:49:57 +08:00
autotest 8ccb8ae592 ADD file via upload 2024-11-07 13:49:27 +08:00
floraachy fdda7e0700 Merge pull request '因缺少xinput1_3.dll无' (#6) from dev12 into master 2024-11-07 11:48:30 +08:00
floraachy 2f539c1dbc ADD file via upload 2024-11-07 11:44:41 +08:00
floraachy 0783ae0cf0 Merge pull request '解决程序因缺少xinput1_3.dll无法运行的有效方法,有效修复丢失xinput1_3.dll' (#5) from dev1 into master 2024-11-07 11:44:15 +08:00
floraachy d7a2c213d1 Merge pull request 'Update Kernel' (#1) from dev into master 2024-11-07 11:43:11 +08:00
floraachy e7ad298ff3 ADD file via upload 2024-11-07 10:45:54 +08:00
floraachy 4b916b5392 ADD file via upload 2024-11-07 10:08:17 +08:00
xuedongliang 49b20dfa6a Fix compilation errors for imxrt1176 from wuzheng
it is OK
2024-10-10 18:08:24 +08:00
xuedongliang 0fdf4f2ace AdapterLoraTest() is used to run a testcase for Lora, but it failed to work due to creating a thread with a wrong function, and this pull request fixed it
it is OK
2024-10-10 18:06:19 +08:00
xuedongliang 1c0edba5bd Support Inovance H3U-3232MT Modbus TCP connection
it is OK
2024-10-10 18:05:53 +08:00
WuZheng 22b980cc08 fix compliation errors for imxrt1176. 2024-09-26 06:35:27 +00:00
chen_zhengning 64b2117012 fix a bug that made `AdapterLoraTest` cannot work correctly. 2024-09-14 15:41:46 +08:00
TLBF 16a31c6739 feat(APP_Framework/control_app): Inovance H3U-3232MT Modbus TCP App. 2024-08-06 10:33:47 +08:00
xuedongliang d664e2298e Koyo PLC ModBus TCP Master Mode from Liu_yongkai
it is OK
2024-07-29 11:12:16 +08:00
xuedongliang 02c82025c8 support amp
it is OK
2024-07-29 11:11:32 +08:00
xuedongliang dbaffab140 Support O2 optimization; Support blocking task; Support better KPrintf from Tu_yuyang
it is OK
2024-07-29 11:10:51 +08:00
TLBF 1e59fd2a8d feat(Applications/control_app): add Koyo NK1CPU40 PLC ModBus TCP Master and test result png 2024-07-05 16:45:11 +08:00
树数在变干 2e11a31da3 support amp 2024-05-22 17:37:23 +08:00
树数在变干 446c3746a6 update stack size and heap size 2024-05-22 15:10:22 +08:00
anguoyoula 293fd9fea9 update heap size 2024-03-12 16:28:50 +08:00
623 changed files with 5750 additions and 183920 deletions

View File

@ -1,3 +1,3 @@
SRC_DIR := advantech beckhoff br delta mitsubishi omron schneider siemens ge xinje inovance keyence panasonic fatek ab abb
SRC_DIR := advantech beckhoff br delta mitsubishi omron schneider siemens ge xinje inovance keyence panasonic fatek ab abb koyo
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,3 +1,3 @@
SRC_FILES := inovance_am401_cpu1608tn_ethernet.c inovance_am401_cpu1608tn_uart.c
SRC_FILES := inovance_am401_cpu1608tn_ethernet.c inovance_am401_cpu1608tn_uart.c inovance_H3U_cpu3232MT_ethernet.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2024 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file inovance_H3U_cpu3232MT_ethernet.c
* @brief PLC Inovance H3U-3232MT app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2024.08.06
*/
#include <control.h>
void ControlInovanceH3UCPU3232MTTest(void)
{
int i, j = 0;
int read_data_length = 0;
uint8_t read_data[128] = {0};
ControlProtocolType modbus_tcp_protocol = ControlProtocolFind();
if (NULL == modbus_tcp_protocol) {
printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol);
return;
}
printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol);
if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) {
ControlProtocolOpen(modbus_tcp_protocol);
for (;;) {
read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data));
printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length);
if (read_data_length) {
for (j = 0; j < read_data_length; j++) {
printf("j %d data 0x%x\n", j, read_data[j]);
}
}
i++;
memset(read_data, 0, sizeof(read_data));
PrivTaskDelay(10000);
}
// ControlProtocolClose(modbus_tcp_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlInovanceH3UCPU3232MTTest, Inovance PLC N3UCPU3232MT Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -0,0 +1,30 @@
{
"device_id": 1,
"device_name": "Ino_H3U3232MT",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.55",
"local_ip": "192.168.250.147",
"gateway": "192.168.250.252",
"netmask": "255.255.255.0",
"port": 502
},
"protocol_type": 2,
"read_period": 300,
"read_item_list": [
{
"value_name": "M8000",
"value_type": 1,
"function_code": 1,
"start_address": 8000,
"quantity": 1
},
{
"value_name": "D120",
"value_type": 3,
"function_code": 3,
"start_address": 120,
"quantity": 1
}
]
}

View File

@ -1,3 +1,3 @@
SRC_DIR := libnet net_server
SRC_FILES := koyo_nk1cpu40.c
include $(KERNEL_ROOT)/compiler.mk

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2024 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file koyo_nk1cpu40.c
* @brief PLC AB MICRO850 app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2024.07.03
*/
#include <control.h>
void ControlKoyoNK1CPU40Test(void)
{
int i, j = 0;
int read_data_length = 0;
uint8_t read_data[128] = {0};
ControlProtocolType modbus_tcp_protocol = ControlProtocolFind();
if (NULL == modbus_tcp_protocol) {
printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol);
return;
}
printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol);
if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) {
ControlProtocolOpen(modbus_tcp_protocol);
for (;;) {
read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data));
printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length);
if (read_data_length) {
for (j = 0; j < read_data_length; j++) {
printf("j %d data 0x%x\n", j, read_data[j]);
}
}
i++;
memset(read_data, 0, sizeof(read_data));
PrivTaskDelay(10000);
}
// ControlProtocolClose(modbus_tcp_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlKoyoNK1CPU40Test, Koyo Plc NK1CPU40 Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -977,7 +977,7 @@ int AdapterLoraTest(void)
char task_name_2[] = "adapter_lora_gateway";
args.pthread_name = task_name_2;
args.arg = (void *)adapter;
PrivTaskCreate(&lora_recv_data_task, &lora_gateway_attr, &LoraReceiveTask, (void *)&args);
PrivTaskCreate(&lora_gateway_task, &lora_gateway_attr, &LoraGatewayTask, (void *)&args);
#endif
PrivTaskStartup(&lora_gateway_task);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,7 +4,7 @@ MAKEFLAGS += --no-print-directory
.PHONY:COMPILE_APP COMPILE_KERNEL
riscv_support :=
arm_support += imx6q-sabrelite zynq7000-zc702 3568
arm_support += imx6q-sabrelite zynq7000-zc702 ok1028a-c
emulator_support +=
support := $(riscv_support) $(arm_support) $(emulator_support)
SRC_DIR :=
@ -34,8 +34,8 @@ export UBIQUITOUS_ROOT ?= ..
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )
include $(KERNEL_ROOT)/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_$(BOARD)/config.mk
endif
ifneq ($(findstring $(BOARD), 3568), )
include $(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_$(BOARD)/config.mk
ifneq ($(findstring $(BOARD), ok1028a-c), )
include $(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a72/preboot_for_$(BOARD)/config.mk
endif
export BSP_BUILD_DIR := $(KERNEL_ROOT)
export HOSTTOOLS_DIR ?= $(KERNEL_ROOT)/services/tools/hosttools
@ -133,8 +133,6 @@ clean:
@rm -rf services/tools/mkfs/mkfs
@rm -rf services/app/fs.img
@rm -rf services/app/user.map
@rm -rf services/net/net_server/user.map
@rm -rf services/net/net_server/bin
distclean:
@echo Clean all configuration

View File

@ -1,5 +1,5 @@
# The following three platforms support compatiable instructions.
ifneq ($(findstring $(BOARD), 3568), )
ifneq ($(findstring $(BOARD), ok1028a-c), )
SRC_DIR := armv8-a
endif
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )

View File

@ -1,6 +1,6 @@
# The following three platforms support compatiable instructions.
ifneq ($(findstring $(BOARD), 3568), )
SRC_DIR := cortex-a55
ifneq ($(findstring $(BOARD), ok1028a-c), )
SRC_DIR := cortex-a72
endif

View File

@ -1,168 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "core.h"
#define HCR_VALUE (1 << 31)
#define SPSR_EL2_VALUE (7 << 6) | (5 << 0)
#define SCTLR_EL1_VALUE (0x30D00800)
/* Macros for MAIR setting. */
#define MAIR(attr, mt) ((attr) << ((mt) * 8))
#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
.section ".text", "ax"
.global _boot_start
.global primary_cpu_init
.global el2_setup
/* The function for setting memory types and MAIR registers. */
.global __cpu_mair_setup
_boot_start:
bl el2_setup
/* set NSACR, both Secure and Non-secure access are allowed to NEON */
mov x0, #(3 << 20)
msr cpacr_el1, x0
isb
// clear some registers
msr elr_el1, XZR
ldr x0, =stacks_top
mov x1, #MODE_STACK_SIZE
// get cpu id, and subtract the offset from the stacks base address
mrs x2, mpidr_el1
and x2, x2, #0xFFF
lsr x2, x2, #8
mov x5, x2
mul x3, x2, x1
sub x0, x0, x3
mov sp, x0
mov x2, #ARM_MODE_EL1_h | DIS_INT
msr spsr_el1, x2
// check cpu id - cpu0 is primary cpu
mrs x2, mpidr_el1
and x2, x2, #0xFFF
lsr x2, x2, #8
mov x5, x2
cmp x5, #0
beq primary_cpu_init
bl __cpu_mair_setup
bl bootmain // for secondary cpus, jump to argument function pointer passed in by ROM
bl .
primary_cpu_init:
/* init .bss */
/* clear the .bss section (zero init) */
ldr x1, =boot_start_addr
ldr x2, =boot_end_addr
mov x3, #0
1:
cmp x1, x2
stp x3, x3, [x1], #16
b.lt 1b
bl __cpu_mair_setup
bl bootmain
.func el2_setup
el2_setup:
mrs x0, CurrentEL
lsr x0, x0, #2
and x0, x0, #3
cmp x0, #2
beq 1f
ret
/* Hyp configuration. */
1:
mov x0, #(1 << 31)
msr hcr_el2, x0
/* Generic timers. */
mrs x0, cnthctl_el2
orr x0, x0, #3 // Enable EL1 physicaltimers
msr cnthctl_el2, x0
/* Populate ID registers. */
mrs x0, midr_el1
mrs x1, mpidr_el1
msr vpidr_el2, x0
msr vmpidr_el2, x1
/* Disable Coprocessor traps. */
mov x0, #0x33ff
msr cptr_el2, x0 // Disable copro. traps to EL2
msr hstr_el2, xzr // Disable CP15 traps to EL2
mov x0, sp
msr sp_el1, x0
mrs x0, sctlr_el1
orr x0, x0, #(1 << 0)
bic x0, x0, #(1 << 1)
orr x0, x0, #(1 << 2)
msr sctlr_el1, x0
/* spsr */
mov x0, #SPSR_EL2_VALUE
msr spsr_el2, x0
msr elr_el2, lr
eret
.endfunc
.func __cpu_mair_setup
__cpu_mair_setup:
tlbi vmalle1 // Invalidate local TLB
dsb nsh
// mov x0, #3 << 20
// msr cpacr_el1, x0 // Enable FP/ASIMD
// mov x0, #1 << 12 // Reset mdscr_el1 and disable
// msr mdscr_el1, x0 // access to the DCC from EL0
isb // Unmask debug exceptions now,
// enable_dbg // since this is per-cpu
/*
* Memory region attributes for LPAE:
*
* n = AttrIndx[2:0]
* n MAIR
* DEVICE_nGnRnE 000 00000000
* DEVICE_nGnRE 001 00000100
* DEVICE_GRE 010 00001100
* NORMAL_NC 011 01000100
* NORMAL 100 11111111
* NORMAL_WT 101 10111011
*/
ldr x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \
MAIR(0x04, MT_DEVICE_nGnRE) | \
MAIR(0x0c, MT_DEVICE_GRE) | \
MAIR(0x44, MT_NORMAL_NC) | \
MAIR(0xff, MT_NORMAL) | \
MAIR(0xbb, MT_NORMAL_WT)
msr mair_el1, x5
ret
.endfunc
.end

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
.global __xizi_smccc_smc
.func __xizi_smccc_smc
__xizi_smccc_smc:
smc #0
ldr x4, [sp]
stp x0, x1, [x4, #0]
stp x2, x3, [x4, #16]
ldr x4, [sp, #8]
cbz x4, 1f /* no quirk structure */
ldr x9, [x4, #0]
cmp x9, #1
b.ne 1f
str x6, [x4, 8]
1: ret
.endfunc

View File

@ -29,7 +29,7 @@ Modification:
1. first version
*************************************************/
/*********cortex-a55 general register************
/*********cortex-a72 general register************
EL0 | EL1 | EL2 | EL3
x0;
@ -63,7 +63,7 @@ Modification:
x28;
x29;
x30;
*********cortex-a55 special register************
*********cortex-a72 special register************
XZR
PC
SP_EL0 SP_EL1 SP_EL2 SP_EL3

View File

@ -12,7 +12,7 @@
/**
* @file core.h
* @brief cortex-a55 core function
* @brief cortex-a72 core function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2024.04.11
@ -20,7 +20,7 @@
/*************************************************
File name: core.h
Description: cortex-a55 core function
Description: cortex-a72 core function
Others:
History:
Author: AIIT XUOS Lab
@ -71,7 +71,7 @@ Modification:
#include <stdint.h>
#include <string.h>
#include "cortex_a55.h"
#include "cortex_a72.h"
#define NR_CPU 4 // maximum number of CPUs
@ -79,6 +79,15 @@ __attribute__((always_inline)) static inline uint64_t EL0_mode() // Set ARM mode
{
uint64_t val = 0;
__asm__ __volatile__(
"mrs %0, spsr_el1"
: "=r"(val)
:
:);
val &= ~DIS_INT;
val &= ~SPSR_MODE_MASK;
val |= ARM_MODE_EL0_t;
return val;
}

View File

@ -1,6 +1,5 @@
SRC_FILES := boot.S \
xizi_smp.S \
smp.c \
cortexA55.S
cortexA72.S
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,81 @@
// #include "memlayout.h"
#include "core.h"
// #include "registers.h"
// #include "cortex_a72.h"
// qemu -kernel loads the kernel at 0x40000000
// and causes each CPU to jump there.
// kernel.ld causes the following code to
// be placed at 0x40000000.
.section ".text"
//.global _entry
.global _boot_start
.global primary_cpu_init
_boot_start:
// set up a stack for C.
// stack0 is declared in start.c,
// with a 4096-byte stack per CPU.
// sp = stack0 + ((cpuid+1) * 4096)
// cpuid = mpidr_el1 & 0xff
// save r0 for cores 1-3, r0 arg field passed by ROM
// r0 is a function pointer for secondary cpus
// mov x4, x0
mrs x0, spsr_el1 /* Enter EL1 (Exception Level 1) */
bic x0, x0, #0x1f
MOV x1, #0xC5
ORR x0, x0, x1
msr spsr_el1, x0
/* set NSACR, both Secure and Non-secure access are allowed to NEON */
MRS X1, CPACR_EL1
ORR X1, X1, #(0X3 << 20)
MSR CPACR_EL1, X1
ISB
// clear some registers
msr elr_el1, XZR
ldr x0, =stacks_top
mov x1, #MODE_STACK_SIZE
// get cpu id, and subtract the offset from the stacks base address
mrs x2, mpidr_el1
and x2, x2, #0x3
mov x5, x2
mul x3, x2, x1
sub x0, x0, x3
MOV X2, #ARM_MODE_EL1_h | DIS_INT
MSR SPSR_EL1, X2
mov sp, x0
SUB x0, x0,x1
// check cpu id - cpu0 is primary cpu
cmp x5, #0
beq primary_cpu_init
bl bootmain // for secondary cpus, jump to argument function pointer passed in by ROM
bl .
primary_cpu_init:
/* init .bss */
/* clear the .bss section (zero init) */
ldr x1, =boot_start_addr
ldr x2, =boot_end_addr
mov x3, #0
1:
cmp x1, x2
stp x3, x3, [x1], #16
b.lt 1b
// branch to c library entry point
mov x0, #0 // argc
mov x1, #0 // argv
mov x2, #0 // env
bl bootmain
.end

View File

@ -1,7 +1,8 @@
export CROSS_COMPILE ?= aarch64-none-elf-
export DEVICE = -mtune=cortex-a55 -ffreestanding -fno-common -fno-stack-protector -fno-pie -no-pie
export CFLAGS := $(DEVICE) -Wall -Werror -O2 -g -fno-omit-frame-pointer -fPIC
export LFLAGS := $(DEVICE) -Wl,-T -Wl,$(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/3568.lds -Wl,--start-group,-lgcc,-lc,--end-group
export DEVICE = -mtune=cortex-a72 -ffreestanding -fno-common -fno-stack-protector -fno-pie -no-pie
export CFLAGS := $(DEVICE) -Wall -Werror -O2 -g -fno-omit-frame-pointer -fPIC
# export AFLAGS := -c $(DEVICE) -x assembler-with-cpp -D__ASSEMBLY__ -gdwarf-2
export LFLAGS := $(DEVICE) -Wl,-T -Wl,$(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a72/preboot_for_ok1028a-c/nxp_ls1028.lds -Wl,--start-group,-lgcc,-lc,--end-group
export CXXFLAGS :=
export DEFINES := -DHAVE_CCONFIG_H -DCHIP_LS1028

View File

@ -1,14 +1,14 @@
/*!
* @file cortexA55.s
* @brief This file contains cortexA55 functions
* @file cortexA72.s
* @brief This file contains cortexA72 functions
*
*/
/*************************************************
File name: cortexA55.S
File name: cortexA72.S
Description: This file contains cortexA9 functions
Others:
History:
1. Date: 2024-05-08
1. Date: 202-05-08
Author: AIIT XUOS Lab
Modification:
1. No modifications
@ -21,8 +21,7 @@ Modification:
.func cpu_get_current
cpu_get_current:
mrs x0, mpidr_el1
and x0, x0, #0xFFF
lsr x0, x0, #8
and x0, x0, #3
ret
.endfunc
@ -33,6 +32,6 @@ psci_call:
# ------------------------------------------------------------
# End of cortexA55.s
# End of cortexA72.s
# ------------------------------------------------------------
.end

View File

@ -28,16 +28,16 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file cortex_a55.h
* @brief some cortex A55 core functions
* @file cortex_a72.h
* @brief some cortex A72 core functions
* @version 1.0
* @author AIIT XUOS Lab
* @date 2024.04.24
*/
/*************************************************
File name: cortex_a55.h
Description: some cortex A55 core functions
File name: cortex_a72.h
Description: some cortex A72 core functions
Others:
History:
Author: AIIT XUOS Lab
@ -45,8 +45,8 @@ Modification:
1. No modifications
*************************************************/
#if !defined(__CORTEX_A55_H__)
#define __CORTEX_A55_H__
#if !defined(__CORTEX_A72_H__)
#define __CORTEX_A72_H__
#include <stdbool.h>
#include <stdint.h>
@ -231,4 +231,4 @@ void scu_secure_invalidate(unsigned int cpu, unsigned int ways);
}
#endif
#endif //__CORTEX_A55_H__
#endif //__CORTEX_A72_H__

View File

@ -45,36 +45,30 @@ ENTRY( _ENTRY )
ENTRY( _boot_start )
MEMORY {
phy_ddr3 (rwx) : ORIGIN = 0x0000000010000000, LENGTH = 1024M
vir_ddr3 (rwx) : ORIGIN = 0x000000601040E000, LENGTH = 1024M
phy_ddr3 (rwx) : ORIGIN = 0x0000000040000000, LENGTH = 1024M
vir_ddr3 (rwx) : ORIGIN = 0x0000006040635000, LENGTH = 1024M
}
SECTIONS
{
.start_sec : {
. = ORIGIN(phy_ddr3);
. = ALIGN(0x1000);
/* initialization start checkpoint. */
_start_image_addr = .;
boot.o(.text)
bootmmu.o(.text .text.*)
boot.o(.text)
bootmmu.o(.text .text.*)
/* ns16550.o(.text .text.*) */
boot.o(.rodata .rodata.*)
bootmmu.o(.rodata .rodata.*)
boot.o(.rodata .rodata.*)
bootmmu.o(.rodata .rodata.*)
/* ns16550.o(.rodata .rodata.*) */
boot.o(.data .data.*)
bootmmu.o(.data .data.*)
boot.o(.data .data.*)
bootmmu.o(.data .data.*)
/* ns16550.o(.data .data.*) */
PROVIDE(boot_start_addr = .);
PROVIDE(boot_start_addr = .);
boot.o(.bss .bss.* COMMON)
bootmmu.o(.bss .bss.* COMMON)
/* ns16550.o(.bss .bss.* COMMON) */
boot.o(.bss .bss.* COMMON)
bootmmu.o(.bss .bss.* COMMON)
/* stack for booting code. */
. = ALIGN(0x1000);
@ -87,7 +81,7 @@ SECTIONS
PROVIDE(boot_end_addr = .);
} > phy_ddr3
.text : AT(0x1040E000) {
.text : AT(0x40635000) {
. = ALIGN(0x1000);
*(.text .text.* .gnu.linkonce.t.*)
} > vir_ddr3
@ -109,19 +103,17 @@ SECTIONS
PROVIDE(_binary_default_fs_start = .);
*(.rawdata_memfs*)
PROVIDE(_binary_default_fs_end = .);
PROVIDE(__init_array_start = .);
PROVIDE(__init_array_end = .);
} > vir_ddr3
. = ALIGN(0x1000);
_image_size = . - 0x0000006010000000;
PROVIDE(kernel_data_begin = .);
_image_size = . - 0x0000006040000000;
.bss : {
PROVIDE(kernel_data_begin = .);
PROVIDE(__bss_start__ = .);
*(.bss .bss.* COMMON)
. = ALIGN(0x1000);
PROVIDE(__bss_end__ = .);
PROVIDE(kernel_data_end = .);
} > vir_ddr3
. = ALIGN(0x1000);
PROVIDE(kernel_data_end = .);
}

View File

@ -48,34 +48,12 @@ Modification:
#include <stdint.h>
#define PSCI_CPUON 0xc4000003
struct xizi_smccc_res {
unsigned long a0;
unsigned long a1;
unsigned long a2;
unsigned long a3;
};
extern void _boot_start();
extern void __print();
extern void __xizi_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
unsigned long a6, unsigned long a7, struct xizi_smccc_res* res);
static struct xizi_smccc_res __invoke_sip_fn_smc(unsigned long function_id,
unsigned long arg0,
unsigned long arg1,
unsigned long arg2)
{
struct xizi_smccc_res res;
__xizi_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
return res;
}
void psci_call(uint64_t fn, uint8_t cpuid, uint64_t entry, uint64_t ctxid);
void cpu_start_secondary(uint8_t cpu_id)
{
__invoke_sip_fn_smc(PSCI_CPUON, cpu_id, (uintptr_t)0xa00000, 0);
psci_call(PSCI_CPUON, cpu_id, (uintptr_t)&_boot_start, 0);
}
void start_smp_cache_broadcast(int cpu_id)

View File

@ -1,8 +1,8 @@
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )
SRC_DIR := cortex-a9
endif
ifneq ($(findstring $(BOARD), 3568), )
SRC_DIR := cortex-a55
ifneq ($(findstring $(BOARD), ok1028a-c), )
SRC_DIR := cortex-a72
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,336 +0,0 @@
/*
* (C) Copyright 2013
* David Feng <fenghua@phytium.com.cn>
*
* This file is based on sample code from ARMv8 ARM.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#define ASM_NL ;
#define SYMBOL_NAME(X) X
// #define SYMBOL_NAME_LABEL(X) X##:
#define SYMBOL_NAME_LABEL(X) X:
#ifndef __ALIGN
#define __ALIGN .align 4
#endif
#ifndef __ALIGN_STR
#define __ALIGN_STR ".align 4"
#endif
#define ALIGN __ALIGN
#define ALIGN_STR __ALIGN_STR
#define LENTRY(name) \
ALIGN ASM_NL \
SYMBOL_NAME_LABEL(name)
#define ENTRY(name) \
.globl SYMBOL_NAME(name) ASM_NL \
LENTRY(name)
#define WEAK(name) \
.weak SYMBOL_NAME(name) ASM_NL \
LENTRY(name)
#define END(name) \
.size name, .-name
#define ENDPROC(name) \
.type name STT_FUNC ASM_NL \
END(name)
#define CR_M (1 << 0) /* MMU enable */
#define CR_A (1 << 1) /* Alignment abort enable */
#define CR_C (1 << 2) /* Dcache enable */
#define CR_SA (1 << 3) /* Stack Alignment Check Enable */
#define CR_I (1 << 12) /* Icache enable */
#define CR_WXN (1 << 19) /* Write Permision Imply XN */
#define CR_EE (1 << 25) /* Exception (Big) Endian */
.macro switch_el, xreg, el3_label, el2_label, el1_label
mrs \xreg, CurrentEL
cmp \xreg, 0xc
b.eq \el3_label
cmp \xreg, 0x8
b.eq \el2_label
cmp \xreg, 0x4
b.eq \el1_label
.endm
/*
* void __asm_dcache_level(level)
* flush or invalidate one level cache.
*
* x0: cache level
* x1: 0 clean & invalidate, 1 invalidate only
* x2~x9: clobbered
*/
ENTRY(__asm_dcache_level)
lsl x12, x0, #1
msr csselr_el1, x12 /* select cache level */
isb /* sync change of cssidr_el1 */
mrs x6, ccsidr_el1 /* read the new cssidr_el1 */
and x2, x6, #7 /* x2 <- log2(cache line size)-4 */
add x2, x2, #4 /* x2 <- log2(cache line size) */
mov x3, #0x3ff
and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */
clz w5, w3 /* bit position of #ways */
mov x4, #0x7fff
and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */
/* x12 <- cache level << 1 */
/* x2 <- line length offset */
/* x3 <- number of cache ways - 1 */
/* x4 <- number of cache sets - 1 */
/* x5 <- bit position of #ways */
loop_set:
mov x6, x3 /* x6 <- working copy of #ways */
loop_way:
lsl x7, x6, x5
orr x9, x12, x7 /* map way and level to cisw value */
lsl x7, x4, x2
orr x9, x9, x7 /* map set number to cisw value */
tbz w1, #0, 1f
dc isw, x9
b 2f
1: dc cisw, x9 /* clean & invalidate by set/way */
2: subs x6, x6, #1 /* decrement the way */
b.ge loop_way
subs x4, x4, #1 /* decrement the set */
b.ge loop_set
ret
ENDPROC(__asm_dcache_level)
/*
* void __asm_flush_dcache_all(int invalidate_only)
*
* x0: 0 clean & invalidate, 1 invalidate only
*
* flush or invalidate all data cache by SET/WAY.
*/
ENTRY(__asm_dcache_all)
mov x1, x0
dsb sy
mrs x10, clidr_el1 /* read clidr_el1 */
lsr x11, x10, #24
and x11, x11, #0x7 /* x11 <- loc */
cbz x11, finished /* if loc is 0, exit */
mov x15, lr
mov x0, #0 /* start flush at cache level 0 */
/* x0 <- cache level */
/* x10 <- clidr_el1 */
/* x11 <- loc */
/* x15 <- return address */
loop_level:
lsl x12, x0, #1
add x12, x12, x0 /* x0 <- tripled cache level */
lsr x12, x10, x12
and x12, x12, #7 /* x12 <- cache type */
cmp x12, #2
b.lt skip /* skip if no cache or icache */
bl __asm_dcache_level /* x1 = 0 flush, 1 invalidate */
skip:
add x0, x0, #1 /* increment cache level */
cmp x11, x0
b.gt loop_level
mov x0, #0
msr csselr_el1, x0 /* restore csselr_el1 */
dsb sy
isb
mov lr, x15
finished:
ret
ENDPROC(__asm_dcache_all)
ENTRY(__asm_flush_dcache_all)
mov x0, #0
b __asm_dcache_all
ENDPROC(__asm_flush_dcache_all)
ENTRY(__asm_invalidate_dcache_all)
mov x0, #0x1
b __asm_dcache_all
ENDPROC(__asm_invalidate_dcache_all)
/*
* void __asm_flush_dcache_range(start, end)
*
* clean & invalidate data cache in the range
*
* x0: start address
* x1: end address
*/
ENTRY(__asm_flush_dcache_range)
isb
mrs x3, ctr_el0
lsr x3, x3, #16
and x3, x3, #0xf
mov x2, #4
lsl x2, x2, x3 /* cache line size */
/* x2 <- minimal cache line size in cache system */
sub x3, x2, #1
bic x0, x0, x3
1: dc civac, x0 /* clean & invalidate data or unified cache */
add x0, x0, x2
cmp x0, x1
b.lo 1b
dsb sy
isb
ret
ENDPROC(__asm_flush_dcache_range)
/*
* void __asm_invalidate_dcache_range(start, end)
*
* invalidate data cache in the range
*
* x0: start address
* x1: end address
*/
ENTRY(__asm_invalidate_dcache_range)
mrs x3, ctr_el0
ubfm x3, x3, #16, #19
mov x2, #4
lsl x2, x2, x3 /* cache line size */
/* x2 <- minimal cache line size in cache system */
sub x3, x2, #1
bic x0, x0, x3
1: dc ivac, x0 /* invalidate data or unified cache */
add x0, x0, x2
cmp x0, x1
b.lo 1b
dsb sy
isb
ret
ENDPROC(__asm_invalidate_dcache_range)
/*
* void __asm_invalidate_icache_all(void)
*
* invalidate all tlb entries.
*/
ENTRY(__asm_invalidate_icache_all)
ic ialluis
isb sy
ret
ENDPROC(__asm_invalidate_icache_all)
ENTRY(__asm_invalidate_l3_dcache)
mov x0, #0 /* return status as success */
ret
ENDPROC(__asm_invalidate_l3_dcache)
.weak __asm_invalidate_l3_dcache
ENTRY(__asm_flush_l3_dcache)
mov x0, #0 /* return status as success */
ret
ENDPROC(__asm_flush_l3_dcache)
.weak __asm_flush_l3_dcache
ENTRY(__asm_invalidate_l3_icache)
mov x0, #0 /* return status as success */
ret
ENDPROC(__asm_invalidate_l3_icache)
.weak __asm_invalidate_l3_icache
/*
* void __asm_switch_ttbr(ulong new_ttbr)
*
* Safely switches to a new page table.
*/
ENTRY(__asm_switch_ttbr)
/* x2 = SCTLR (alive throghout the function) */
switch_el x4, 3f, 2f, 1f
3: mrs x2, sctlr_el3
b 0f
2: mrs x2, sctlr_el2
b 0f
1: mrs x2, sctlr_el1
0:
/* Unset CR_M | CR_C | CR_I from SCTLR to disable all caches */
movn x1, #(CR_M | CR_C | CR_I)
and x1, x2, x1
switch_el x4, 3f, 2f, 1f
3: msr sctlr_el3, x1
b 0f
2: msr sctlr_el2, x1
b 0f
1: msr sctlr_el1, x1
0: isb
/* This call only clobbers x30 (lr) and x9 (unused) */
mov x3, x30
bl __asm_invalidate_tlb_all
/* From here on we're running safely with caches disabled */
/* Set TTBR to our first argument */
switch_el x4, 3f, 2f, 1f
3: msr ttbr0_el3, x0
b 0f
2: msr ttbr0_el2, x0
b 0f
1: msr ttbr0_el1, x0
0: isb
/* Restore original SCTLR and thus enable caches again */
switch_el x4, 3f, 2f, 1f
3: msr sctlr_el3, x2
b 0f
2: msr sctlr_el2, x2
b 0f
1: msr sctlr_el1, x2
0: isb
ret x3
ENDPROC(__asm_switch_ttbr)
ENTRY(__asm_invalidate_tlb_all)
switch_el x9, 3f, 2f, 1f
3: tlbi alle3
dsb sy
isb
b 0f
2: tlbi alle2
dsb sy
isb
b 0f
1: tlbi vmalle1
dsb sy
isb
0:
ret
ENDPROC(__asm_invalidate_tlb_all)

View File

@ -1,3 +1,3 @@
SRC_FILES := uart.c ns16550.c
SRC_FILES := l1_cache.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -20,10 +20,6 @@ Modification:
*************************************************/
#include "l1_cache.h"
extern void __asm_flush_dcache_all();
extern void __asm_flush_l3_dcache();
extern void __asm_invalidate_icache_all();
extern void __asm_invalidate_l3_icache();
void InvalidateL1Dcache(uintptr_t start, uintptr_t end)
{
@ -157,14 +153,34 @@ void FlushL1Dcache(uintptr_t start, uintptr_t end)
void FlushL1DcacheAll(void)
{
__asm_flush_dcache_all();
__asm_flush_l3_dcache();
uint64_t ccsidr_el1; // Cache Size ID
int num_sets; // number of sets
int num_ways; // number of ways
uint32_t wayset; // wayset parameter
__asm__ __volatile__("mrs %0, ccsidr_el1" : "=r"(ccsidr_el1)); // Read Cache Size ID
// Fill number of sets and number of ways from ccsidr_el1 register This walues are decremented by 1
num_sets = ((ccsidr_el1 >> 32) & 0x7FFF) + 1;
num_ways = ((ccsidr_el1 >> 0) & 0x7FFF) + 1;
// clean and invalidate all lines (all Sets in all ways)
for (int way = 0; way < num_ways; way++) {
for (int set = 0; set < num_sets; set++) {
wayset = (way << 30) | (set << 5);
__asm__ __volatile__("dc cisw, %0" : : "r"(wayset));
}
}
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
DSB();
}
void InvalidateL1IcacheAll()
{
__asm_invalidate_icache_all();
__asm_invalidate_l3_icache();
__asm__ __volatile__("ic iallu\n\t");
// synchronize context on this processor
ISB();
}
void InvalidateL1Icache(uintptr_t start, uintptr_t end)

View File

@ -92,7 +92,7 @@ static inline void invalidate_icache(uintptr_t start, uintptr_t end)
static inline void invalidate_icache_all(void)
{
InvalidateL1IcacheAll();
// InvalidateL1IcacheAll();
}
/****************************************************************************
@ -151,7 +151,7 @@ static inline void flush_dcache(uintptr_t start, uintptr_t end)
static inline void flush_dcache_all(void)
{
FlushL1DcacheAll();
// FlushL1DcacheAll();
// FlushL2CacheAll();
}

View File

@ -1,4 +1,4 @@
ifneq ($(findstring $(BOARD), 3568), )
ifneq ($(findstring $(BOARD), ok1028a-c), )
SRC_DIR := armv8-a
endif
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )

View File

@ -1,5 +1,5 @@
ifneq ($(findstring $(BOARD), 3568), )
SRC_DIR := cortex-a55
ifneq ($(findstring $(BOARD), ok1028a-c), )
SRC_DIR := cortex-a72
endif

View File

@ -22,27 +22,27 @@
static void enable_timer()
{
uint32_t c = r_cntp_ctl_el0();
uint32_t c = r_cntv_ctl_el0();
c |= CNTV_CTL_ENABLE;
c &= ~CNTV_CTL_IMASK;
w_cntp_ctl_el0(c);
w_cntv_ctl_el0(c);
}
static void disable_timer()
{
uint32_t c = r_cntp_ctl_el0();
uint32_t c = r_cntv_ctl_el0();
c |= CNTV_CTL_IMASK;
c &= ~CNTV_CTL_ENABLE;
w_cntp_ctl_el0(c);
w_cntv_ctl_el0(c);
}
static void reload_timer()
{
// interval 1ms
static uint32_t ms = 1;
// interval 100ms
static uint32_t ms = 10;
uint32_t interval = ms * 1000;
uint32_t interval_clk = interval * (r_cntfrq_el0() / 1000000);
w_cntp_tval_el0(interval_clk);
w_cntv_tval_el0(interval_clk);
}
void _sys_clock_init()
@ -54,7 +54,7 @@ void _sys_clock_init()
static uint32_t _get_clock_int()
{
return 30;
return 27;
}
static uint64_t _get_tick()
@ -64,7 +64,7 @@ static uint64_t _get_tick()
static uint64_t _get_second()
{
return _get_tick() / r_cntfrq_el0();
return 0;
}
static bool _is_timer_expired()

View File

@ -15,28 +15,28 @@
#include <stdint.h>
// armv8 generic timer
static inline uint32_t r_cntp_ctl_el0()
static inline uint32_t r_cntv_ctl_el0()
{
uint32_t x;
__asm__ volatile("mrs %0, cntp_ctl_el0" : "=r"(x));
__asm__ volatile("mrs %0, cntv_ctl_el0" : "=r"(x));
return x;
}
static inline void w_cntp_ctl_el0(uint32_t x)
static inline void w_cntv_ctl_el0(uint32_t x)
{
__asm__ volatile("msr cntp_ctl_el0, %0" : : "r"(x));
__asm__ volatile("msr cntv_ctl_el0, %0" : : "r"(x));
}
static inline uint32_t r_cntp_tval_el0()
static inline uint32_t r_cntv_tval_el0()
{
uint32_t x;
__asm__ volatile("mrs %0, cntp_tval_el0" : "=r"(x));
__asm__ volatile("mrs %0, cntv_tval_el0" : "=r"(x));
return x;
}
static inline void w_cntp_tval_el0(uint32_t x)
static inline void w_cntv_tval_el0(uint32_t x)
{
__asm__ volatile("msr cntp_tval_el0, %0" : : "r"(x));
__asm__ volatile("msr cntv_tval_el0, %0" : : "r"(x));
}
static inline uint64_t r_cntvct_el0()

View File

@ -129,7 +129,7 @@ static bool xizi_gpt_init()
return false;
}
// register clock handler to intr
struct XiziTrapDriver* p_intr_driver = GetSysObject(struct XiziTrapDriver, &intr_driver_tag);
struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&intr_driver_tag);
p_intr_driver->bind_irq_handler(p_clock_driver->get_clock_int(), xizi_clock_handler);
p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), 0, 0);
return true;
@ -220,7 +220,6 @@ bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag)
p_icache_driver->enable();
p_dcache_driver->enable();
// clock
p_clock_driver->sys_clock_init();
p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0);
// mmu
secondary_cpu_load_kern_pgdir(&init_mmu_tag, &init_intr_tag);

View File

@ -1,4 +1,4 @@
ifneq ($(findstring $(BOARD), 3568), )
ifneq ($(findstring $(BOARD), ok1028a-c), )
SRC_DIR := armv8-a
endif
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )

View File

@ -1,3 +1,3 @@
SRC_DIR := cortex-a55
SRC_DIR := cortex-a72
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,6 +1,6 @@
SRC_FILES := trampoline.S $(BOARD)/trap_common.c $(BOARD)/trap.c error_debug.c hard_spinlock.S
ifeq ($(BOARD), 3568)
ifeq ($(BOARD), ok1028a-c)
SRC_DIR := gicv3
SRC_FILES += $(BOARD)/
endif

View File

@ -39,53 +39,51 @@ Modification:
2. Modify iabort and dabort handler(in dabort_handler() and iabort_handler())
*************************************************/
#include <stddef.h>
#include <stdint.h>
#include "exception_registers.h"
#include "assert.h"
#include "core.h"
#include "log.h"
#include "multicores.h"
#include "spinlock.h"
#include "task.h"
#include "trap_common.h"
void dump_tf(struct trapframe* tf)
{
KPrintf(" sp: 0x%016lx\n", tf->sp);
KPrintf(" pc: 0x%016lx\n", tf->pc);
KPrintf(" spsr: 0x%016lx\n", tf->spsr);
KPrintf(" x0: 0x%016lx\n", tf->x0);
KPrintf(" x1: 0x%016lx\n", tf->x1);
KPrintf(" x2: 0x%016lx\n", tf->x2);
KPrintf(" x3: 0x%016lx\n", tf->x3);
KPrintf(" x4: 0x%016lx\n", tf->x4);
KPrintf(" x5: 0x%016lx\n", tf->x5);
KPrintf(" x6: 0x%016lx\n", tf->x6);
KPrintf(" x7: 0x%016lx\n", tf->x7);
KPrintf(" x8: 0x%016lx\n", tf->x8);
KPrintf(" x9: 0x%016lx\n", tf->x9);
KPrintf(" x10: 0x%016lx\n", tf->x10);
KPrintf(" x11: 0x%016lx\n", tf->x11);
KPrintf(" x12: 0x%016lx\n", tf->x12);
KPrintf(" x13: 0x%016lx\n", tf->x13);
KPrintf(" x14: 0x%016lx\n", tf->x14);
KPrintf(" x15: 0x%016lx\n", tf->x15);
KPrintf(" x16: 0x%016lx\n", tf->x16);
KPrintf(" x17: 0x%016lx\n", tf->x17);
KPrintf(" x18: 0x%016lx\n", tf->x18);
KPrintf(" x19: 0x%016lx\n", tf->x19);
KPrintf(" x20: 0x%016lx\n", tf->x20);
KPrintf(" x21: 0x%016lx\n", tf->x21);
KPrintf(" x22: 0x%016lx\n", tf->x22);
KPrintf(" x23: 0x%016lx\n", tf->x23);
KPrintf(" x24: 0x%016lx\n", tf->x24);
KPrintf(" x25: 0x%016lx\n", tf->x25);
KPrintf(" x26: 0x%016lx\n", tf->x26);
KPrintf(" x27: 0x%016lx\n", tf->x27);
KPrintf(" x28: 0x%016lx\n", tf->x28);
KPrintf(" x29: 0x%016lx\n", tf->x29);
KPrintf(" x30: 0x%016lx\n", tf->x30);
KPrintf(" sp: 0x%x\n", tf->sp);
KPrintf(" pc: 0x%x\n", tf->pc);
KPrintf(" spsr: 0x%x\n", tf->spsr);
KPrintf(" x0: 0x%x\n", tf->x0);
KPrintf(" x1: 0x%x\n", tf->x1);
KPrintf(" x2: 0x%x\n", tf->x2);
KPrintf(" x3: 0x%x\n", tf->x3);
KPrintf(" x4: 0x%x\n", tf->x4);
KPrintf(" x5: 0x%x\n", tf->x5);
KPrintf(" x6: 0x%x\n", tf->x6);
KPrintf(" x7: 0x%x\n", tf->x7);
KPrintf(" x8: 0x%x\n", tf->x8);
KPrintf(" x9: 0x%x\n", tf->x9);
KPrintf(" x10: 0x%x\n", tf->x10);
KPrintf(" x11: 0x%x\n", tf->x11);
KPrintf(" x12: 0x%x\n", tf->x12);
KPrintf(" x13: 0x%x\n", tf->x13);
KPrintf(" x14: 0x%x\n", tf->x14);
KPrintf(" x15: 0x%x\n", tf->x15);
KPrintf(" x16: 0x%x\n", tf->x16);
KPrintf(" x17: 0x%x\n", tf->x17);
KPrintf(" x18: 0x%x\n", tf->x18);
KPrintf(" x19: 0x%x\n", tf->x19);
KPrintf(" x20: 0x%x\n", tf->x20);
KPrintf(" x21: 0x%x\n", tf->x21);
KPrintf(" x22: 0x%x\n", tf->x22);
KPrintf(" x23: 0x%x\n", tf->x23);
KPrintf(" x24: 0x%x\n", tf->x24);
KPrintf(" x25: 0x%x\n", tf->x25);
KPrintf(" x26: 0x%x\n", tf->x26);
KPrintf(" x27: 0x%x\n", tf->x27);
KPrintf(" x28: 0x%x\n", tf->x28);
KPrintf(" x29: 0x%x\n", tf->x29);
KPrintf(" x30: 0x%x\n", tf->x30);
}
void dabort_reason(struct trapframe* r)
@ -93,9 +91,8 @@ void dabort_reason(struct trapframe* r)
uint32_t fault_status, fault_address;
__asm__ __volatile__("mrs %0, esr_el1" : "=r"(fault_status));
__asm__ __volatile__("mrs %0, far_el1" : "=r"(fault_address));
w_esr_el1(0);
LOG("program counter: 0x%016lx caused\n", r->pc);
LOG("data abort at 0x%016lx, status 0x%016lx\n", fault_address, fault_status);
LOG("program counter: 0x%x caused\n", r->pc);
LOG("data abort at 0x%x, status 0x%x\n", fault_address, fault_status);
if ((fault_status & 0x3f) == 0x21) // Alignment failure
KPrintf("reason: alignment\n");
else if ((fault_status & 0x3f) == 0x4) // Translation fault, level 0
@ -134,9 +131,8 @@ void iabort_reason(struct trapframe* r)
uint32_t fault_status, fault_address;
__asm__ __volatile__("mrs %0, esr_el1" : "=r"(fault_status));
__asm__ __volatile__("mrs %0, far_el1" : "=r"(fault_address));
LOG("program counter: 0x%016lx caused\n", r->pc);
LOG("data abort at 0x%016lx, status 0x%016lx\n", fault_address, fault_status);
w_esr_el1(0);
LOG("program counter: 0x%x caused\n", r->pc);
LOG("data abort at 0x%x, status 0x%x\n", fault_address, fault_status);
if ((fault_status & 0x3f) == 0x21) // Alignment failure
KPrintf("reason: alignment\n");
else if ((fault_status & 0x3f) == 0x4) // Translation fault, level 0

View File

@ -30,8 +30,8 @@ Modification:
// clang-format off
// interrupt controller GICv3
#define GICV3 MMIO_P2V_WO(0xFD400000ULL)
#define GICV3_REDIST MMIO_P2V_WO(0xFD460000ULL)
#define GICV3 MMIO_P2V_WO(0x08000000ULL)
#define GICV3_REDIST MMIO_P2V_WO(0x080a0000ULL)
#define D_CTLR 0x0
#define D_TYPER 0x4

View File

@ -55,56 +55,62 @@ Modification:
#define UNLOCKED 0xFF
// int spinlock_lock(spinlock_t * lock, uint64_t timeout)
.global _spinlock_lock
.func _spinlock_lock
.func _spinlock_lock
_spinlock_lock:
mov w2, #1
sevl
1:
wfe
mov w2, #1
2:
ldaxrb w1, [x0] // check if the spinlock is currently unlocked
cmp w1, #UNLOCKED
bne 1b
sevl
wfe
mrs x1, mpidr_el1 // get our CPU ID
and x1, x1, #0xFFF
lsr x1, x1, #8
stxrb w2, w1, [x0]
cmp x2, #0
bne 2b // check if the write was successful, if the write failed, start over
ldaxrb w1, [x0] // check if the spinlock is currently unlocked
cmp w1, #UNLOCKED
bne _spinlock_lock
dmb ish // Ensure that accesses to shared resource have completed
mrs x1, mpidr_el1 // get our CPU ID
and x1, x1, #3
stxrb w2, w1, [x0]
cmp x2, #0
bne _spinlock_lock // check if the write was successful, if the write failed, start over
mov x0, #0
ret
.endfunc
dmb ish // Ensure that accesses to shared resource have completed
mov x0, #0
ret
.endfunc
// void spinlock_unlock(spinlock_t * lock)
.global _spinlock_unlock
.func _spinlock_unlock
_spinlock_unlock:
mrs x1, mpidr_el1 // get our CPU ID
and x1, x1, #0xFFF
lsr x1, x1, #8
ldr w2, [x0]
cmp w1, w2
bne 1f //doesn't match,jump to 1
mrs x1, mpidr_el1 // get our CPU ID
and x1, x1, #3
dmb ish
mov w1, #UNLOCKED
str w1, [x0]
dsb ish //Ensure that no instructions following the barrier execute until
// all memory accesses prior to the barrier have completed.
sevl // send event to wake up other cores waiting on spinlock
ldr w2, [x0]
cmp w1, w2
bne 1f //doesn't match,jump to 1
dmb ish
mov w1, #UNLOCKED
str w1, [x0]
dsb ish //Ensure that no instructions following the barrier execute until
// all memory accesses prior to the barrier have completed.
sevl // send event to wake up other cores waiting on spinlock
mov x0, #0 // return success
ret
mov x0, #0 // return success
ret
1:
mov x0, #1 //doesn't match, so exit with failure
ret
mov x0, #1 //doesn't match, so exit with failure
ret
.endfunc
.end

View File

@ -28,16 +28,13 @@ Modification:
*************************************************/
#include <stdint.h>
#include "exception_registers.h"
#include "assert.h"
#include "core.h"
#include "exception_registers.h"
#include "multicores.h"
#include "syscall.h"
#include "task.h"
#include "mmu.h"
extern void dabort_handler(struct trapframe* r);
extern void iabort_handler(struct trapframe* r);
@ -76,6 +73,7 @@ void syscall_arch_handler(struct trapframe* tf)
uint64_t esr = r_esr_el1();
uint64_t ec = (esr >> 0x1A) & 0x3F;
w_esr_el1(0);
switch (ec) {
case 0B010101:
software_irq_dispatch(tf);
@ -89,30 +87,11 @@ void syscall_arch_handler(struct trapframe* tf)
iabort_handler(tf);
break;
default: {
ERROR("USYSCALL: unexpected\n");
ERROR(" esr: %016lx\n", esr);
ERROR("USYSCALL: unexpected ec: %016lx", esr);
ERROR(" elr = %016lx far = %016lx\n", r_elr_el1(), r_far_el1());
w_esr_el1(0);
extern void dump_tf(struct trapframe * tf);
dump_tf(tf);
uint32_t sctlr = 0;
SCTLR_R(sctlr);
DEBUG("SCTLR: %x\n", sctlr);
uint32_t spsr = 0;
__asm__ volatile("mrs %0, spsr_el1" : "=r"(spsr)::"memory");
DEBUG("SPSR: %x\n", spsr);
uint64_t tcr = 0;
__asm__ volatile("mrs %0, tcr_el1" : "=r"(tcr)::"memory");
DEBUG("TCR: %x\n", tcr);
uint64_t mair = 0;
__asm__ volatile("mrs %0, mair_el1" : "=r"(mair)::"memory");
DEBUG("MAIR: %x\n", mair);
// kill error task
xizi_enter_kernel();
assert(cur_cpu()->task != NULL);
ERROR("Error Task: %s\n", cur_cpu()->task->name);
sys_exit(cur_cpu()->task);
context_switch(&cur_cpu()->task->thread_context.context, cur_cpu()->scheduler);
panic("dabort end should never be reashed.\n");

View File

@ -29,7 +29,7 @@ Modification:
#include <string.h>
#include "core.h"
#include "cortex_a55.h"
#include "cortex_a72.h"
#include "exception_registers.h"
#include "gicv3_common_opa.h"
#include "trap_common.h"
@ -70,12 +70,7 @@ static void _cpu_irq_disable(void)
static void _single_irq_enable(int irq, int cpu, int prio)
{
if (irq < 32) {
gic_setup_ppi((uint32_t)cpu, (uint32_t)irq);
}
else {
gic_setup_spi((uint32_t)cpu, (uint32_t)irq);
}
gic_setup_ppi((uint32_t)cpu, (uint32_t)irq);
}
static void _single_irq_disable(int irq, int cpu)

View File

@ -143,13 +143,13 @@ Modification:
.balign 0x800
alltraps:
// Current EL with sp0
b badtrap
b .
.balign 0x80
b badtrap
b .
.balign 0x80
b badtrap
b .
.balign 0x80
b badtrap
b .
// Current EL with spx
.balign 0x80
@ -157,9 +157,9 @@ alltraps:
.balign 0x80
b el1irq
.balign 0x80
b badtrap
b .
.balign 0x80
b badtrap
b .
// Lower EL using aarch64
.balign 0x80
@ -167,34 +167,32 @@ alltraps:
.balign 0x80
b el0irq
.balign 0x80
b badtrap
b .
.balign 0x80
b badtrap
b .
// Lower EL using aarch32
.balign 0x80
b badtrap
b .
.balign 0x80
b badtrap
b .
.balign 0x80
b badtrap
b .
.balign 0x80
b badtrap
badtrap:
savereg
mov x0, sp
bl kernel_intr_handler
b .
b .
el1sync:
msr daifset, #0xf
savereg
mov x0, sp
bl kernel_abort_handler
b .
el1irq:
msr daifset, #0xf
usavereg
mov x0, sp
bl intr_irq_dispatch
@ -203,7 +201,9 @@ el1irq:
eret
el0sync:
msr daifset, #0xf
usavereg
mov x0, sp
bl syscall_arch_handler
@ -212,7 +212,9 @@ el0sync:
eret
el0irq:
msr daifset, #0xf
usavereg
mov x0, sp
bl intr_irq_dispatch

View File

@ -59,7 +59,7 @@ __attribute__((optimize("O0"))) void spinlock_init(struct spinlock* lock, char*
}
extern int _spinlock_lock(struct spinlock* lock, uint32_t timeout);
extern int _spinlock_unlock(struct spinlock* lock);
extern void _spinlock_unlock(struct spinlock* lock);
__attribute__((optimize("O0"))) void spinlock_lock(struct spinlock* lock)
{
@ -88,9 +88,7 @@ __attribute__((optimize("O0"))) void spinlock_unlock(struct spinlock* lock)
_double_list_del(p_lock_node->prev, p_lock_node->next);
_spinlock_unlock(&request_lock);
if (_spinlock_unlock(lock) != 0) {
ERROR("Core %d trying to unlock a lock belongs to %d.\n", cur_cpuid(), lock->owner_cpu);
}
_spinlock_unlock(lock);
}
__attribute__((optimize("O0"))) bool spinlock_try_lock(struct spinlock* lock)

View File

@ -1,4 +1,4 @@
ifneq ($(findstring $(BOARD), 3568), )
ifneq ($(findstring $(BOARD), ok1028a-c), )
SRC_DIR := armv8-a
endif
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )

View File

@ -48,7 +48,7 @@ uint32_t boot_pgdir[NR_PDE_ENTRIES] __attribute__((aligned(0x4000))) = { 0 };
static void build_boot_pgdir()
{
// dev mem
uint32_t dev_mem_end_idx = (DEV_PHYMEM_BASE + DEV_MEM_SIZE) >> LEVEL3_PDE_SHIFT;
uint32_t dev_mem_end_idx = (DEV_PHYMEM_BASE + DEV_MEM_SZ) >> LEVEL3_PDE_SHIFT;
for (uint32_t i = DEV_PHYMEM_BASE >> LEVEL3_PDE_SHIFT; i < dev_mem_end_idx; i++) {
boot_pgdir[i] = (i << LEVEL3_PDE_SHIFT) | L1_TYPE_SEC | L1_SECT_DEV | L1_SECT_AP0;
boot_pgdir[MMIO_P2V_WO(i << LEVEL3_PDE_SHIFT) >> LEVEL3_PDE_SHIFT] = (i << LEVEL3_PDE_SHIFT) | L1_TYPE_SEC | L1_SECT_DEV | L1_SECT_AP0;

View File

@ -67,17 +67,10 @@ Modification:
/* Deivce memory layout */
#define DEV_PHYMEM_BASE (0x00000000)
#define DEV_VRTMEM_BASE (0x80000000)
#define DEV_MEM_SIZE (0x10000000)
#define DEV_MEM_SZ (0x10000000)
/* Kernel memory layout */
#define KERN_MEM_BASE (0x90000000) // First kernel virtual address
#define KERN_OFFSET (KERN_MEM_BASE - PHY_MEM_BASE)
/* virtual and physical addr translate */
#define V2P(a) ((uint32_t)((uint32_t)(a)-KERN_OFFSET))
#define P2V(a) ((void*)((void*)(a) + KERN_OFFSET))
#define V2P_WO(x) ((x)-KERN_OFFSET) // same as V2P, but without casts
#define P2V_WO(x) ((x) + KERN_OFFSET) // same as V2P, but without casts
// clang-format on

View File

@ -92,6 +92,13 @@ When the process switches, the flush TLB is no longer required anymore.
#define CONTEXTIDR_R(val) __asm__ volatile("mrc p15, 0, %0, c13, c0, 1" : "=r"(val))
#define CONTEXTIDR_W(val) __asm__ volatile("mcr p15, 0, %0, c13, c0, 1" ::"r"(val))
/* virtual and physical addr translate */
#define V2P(a) ((uint32_t)((uint32_t)(a)-KERN_OFFSET))
#define P2V(a) ((void*)((void*)(a) + KERN_OFFSET))
#define V2P_WO(x) ((x)-KERN_OFFSET) // same as V2P, but without casts
#define P2V_WO(x) ((x) + KERN_OFFSET) // same as V2P, but without casts
#ifndef __ASSEMBLER__
#include <stdint.h>
__attribute__((always_inline)) static inline uint32_t v2p(void* a) { return ((uint32_t)(a)) - KERN_MEM_BASE; }

View File

@ -66,7 +66,7 @@ Modification:
/* Deivce memory layout */
#define DEV_PHYMEM_BASE (0xE0000000)
#define DEV_VRTMEM_BASE (0x80000000)
#define DEV_MEM_SIZE (0x1FFFFFFF)
#define DEV_MEM_SZ (0x1FFFFFFF)
/* Kernel memory layout */
#define KERN_MEM_BASE (0xA0000000) // First kernel virtual address

View File

@ -1,3 +1,3 @@
SRC_DIR := cortex-a55
SRC_DIR := cortex-a72
include $(KERNEL_ROOT)/compiler.mk

View File

@ -51,9 +51,9 @@ extern uint64_t kernel_data_begin[];
#define L4_PTE_NORMAL ((0b01) << 2) // Device memory
#define L4_PTE_AF (1 << 10) // Data Access Permissions
#define L4_PTE_PXN (1UL << 53) // Privileged eXecute Never
#define L4_PTE_UXN (1UL << 54) // Unprivileged(user) eXecute Never
#define L4_PTE_XN (PTE_PXN|PTE_UXN) // eXecute Never
#define L4_PTE_PXN (1UL << 53) // Privileged eXecute Never
#define L4_PTE_UXN (1UL << 54) // Unprivileged(user) eXecute Never
#define L4_PTE_XN (PTE_PXN|PTE_UXN) // eXecute Never
#define IDX_MASK (0b111111111)
#define L3_PDE_INDEX(idx) ((idx << LEVEL3_PDE_SHIFT) & L3_IDX_MASK)
@ -62,69 +62,64 @@ extern uint64_t kernel_data_begin[];
uint64_t boot_l2pgdir[NUM_LEVEL2_PDE] __attribute__((aligned(0x1000))) = { 0 };
uint64_t boot_dev_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 };
uint64_t boot_virt_dev_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 };
uint64_t boot_kern_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 };
uint64_t boot_virt_kern_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 };
uint64_t boot_dev_l4pgdirs[NUM_LEVEL3_PDE][NUM_LEVEL4_PTE] __attribute__((aligned(0x1000))) = { 0 };
uint64_t boot_kern_l4pgdirs[NUM_LEVEL3_PDE][NUM_LEVEL4_PTE] __attribute__((aligned(0x1000))) = { 0 };
static void build_boot_pgdir()
{
static bool built = false;
if (!built) {
uint64_t dev_phy_mem_base = DEV_PHYMEM_BASE;
uint64_t dev_phy_mem_base = DEV_PHYMEM_BASE;
// dev mem
boot_l2pgdir[(dev_phy_mem_base >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_dev_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
boot_l2pgdir[(MMIO_P2V_WO(dev_phy_mem_base) >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_dev_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
// dev mem
boot_l2pgdir[(dev_phy_mem_base >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_dev_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
boot_l2pgdir[(MMIO_P2V_WO(dev_phy_mem_base) >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_dev_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
uint64_t cur_mem_paddr = ALIGNDOWN((uint64_t)DEV_PHYMEM_BASE, PAGE_SIZE);
for (size_t i = 0; i < NUM_LEVEL3_PDE; i++) {
boot_dev_l3pgdir[i] = (uint64_t)boot_dev_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
uint64_t cur_mem_paddr = ALIGNDOWN((uint64_t)DEV_PHYMEM_BASE, LEVEL2_PDE_SIZE);
for (size_t i = 0; i < NUM_LEVEL3_PDE; i++) {
boot_dev_l3pgdir[i] = (uint64_t)boot_dev_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
for (size_t j = 0; j < NUM_LEVEL4_PTE; j++) {
boot_dev_l4pgdirs[i][j] = cur_mem_paddr | L4_TYPE_PAGE | L4_PTE_DEV | L4_PTE_AF | L4_PTE_XN;
for (size_t j = 0; j < NUM_LEVEL4_PTE; j++) {
boot_dev_l4pgdirs[i][j] = cur_mem_paddr | L4_TYPE_PAGE | L4_PTE_DEV | L4_PTE_AF | L4_PTE_XN;
if (cur_mem_paddr >= DEV_PHYMEM_BASE && cur_mem_paddr < DEV_PHYMEM_BASE + DEV_MEM_SIZE) {
boot_dev_l4pgdirs[i][j] = cur_mem_paddr | 0x403;
} else {
boot_dev_l4pgdirs[i][j] = cur_mem_paddr | 0x403;
}
cur_mem_paddr += PAGE_SIZE;
}
cur_mem_paddr += PAGE_SIZE;
}
}
// identical mem
boot_l2pgdir[(PHY_MEM_BASE >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_kern_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
boot_l2pgdir[(P2V_WO(PHY_MEM_BASE) >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_kern_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
// identical mem
boot_l2pgdir[(PHY_MEM_BASE >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_kern_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
boot_l2pgdir[(P2V_WO(PHY_MEM_BASE) >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_kern_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
cur_mem_paddr = ALIGNDOWN((uint64_t)0x00000000ULL, PAGE_SIZE);
for (size_t i = 0; i < NUM_LEVEL3_PDE; i++) {
boot_kern_l3pgdir[i] = (uint64_t)boot_kern_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
cur_mem_paddr = ALIGNDOWN((uint64_t)PHY_MEM_BASE, PAGE_SIZE);
for (size_t i = 0; i < NUM_LEVEL3_PDE; i++) {
boot_kern_l3pgdir[i] = (uint64_t)boot_kern_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
for (size_t j = 0; j < NUM_LEVEL4_PTE; j++) {
boot_kern_l4pgdirs[i][j] = cur_mem_paddr | 0x713;
for (size_t j = 0; j < NUM_LEVEL4_PTE; j++) {
boot_kern_l4pgdirs[i][j] = cur_mem_paddr | L4_TYPE_PAGE | L4_PTE_NORMAL | L4_PTE_AF;
cur_mem_paddr += PAGE_SIZE;
}
cur_mem_paddr += PAGE_SIZE;
}
built = true;
}
}
static void load_boot_pgdir()
{
uint64_t val;
TTBR0_W((uintptr_t)boot_l2pgdir);
TTBR1_W(0);
#define TCR_TRUE_VALUE (0x0000000080813519ULL)
uint64_t tcr = 0;
TCR_R(tcr);
tcr &= (uint64_t)~0xFF;
tcr |= 0x19;
TCR_W(tcr);
TCR_W(TCR_VALUE);
MAIR_W((MT_DEVICE_nGnRnE << (8 * AI_DEVICE_nGnRnE_IDX)) | (MT_NORMAL_NC << (8 * AI_NORMAL_NC_IDX)));
// Enable paging using read/modify/write
SCTLR_R(val);
val |= (1 << 0); // EL1 and EL0 stage 1 address translation enabled.
SCTLR_W(val);
// flush all TLB
DSB();
CLEARTLB(0);
ISB();
}
@ -135,7 +130,7 @@ void bootmain()
{
build_boot_pgdir();
load_boot_pgdir();
__asm__ __volatile__("add sp, sp, %0" ::"r"(KERN_OFFSET));
__asm__ __volatile__("add sp, sp, %0" ::"r"(KERN_MEM_BASE - PHY_MEM_BASE));
if (!_bss_inited) {
memset(&kernel_data_begin, 0x00, (size_t)((uint64_t)kernel_data_end - (uint64_t)kernel_data_begin));
_bss_inited = true;

View File

@ -61,36 +61,35 @@ void GetPdeAttr(uintptr_t* attr);
/*
Enable MMU, cache, write buffer, etc.
*/
#define SCTLR_R(val) __asm__ volatile("mrs %0, sctlr_el1" : "=r"(val)::"memory")
#define SCTLR_W(val) __asm__ volatile("msr sctlr_el1, %0" ::"r"(val) : "memory")
#define SCTLR_R(val) __asm__ volatile("mrs %0, sctlr_el1" : "=r"(val))
#define SCTLR_W(val) __asm__ volatile("msr sctlr_el1, %0" ::"r"(val))
/*
Read and write mmu pagetable register base addr
*/
#define TTBR0_R(val) __asm__ volatile("mrs %0, ttbr0_el1" : "=r"(val)::"memory")
#define TTBR0_W(val) __asm__ volatile("msr ttbr0_el1, %0" ::"r"(val) : "memory")
#define TTBR0_R(val) __asm__ volatile("mrs %0, ttbr0_el1" : "=r"(val))
#define TTBR0_W(val) __asm__ volatile("msr ttbr0_el1, %0" ::"r"(val))
/*
Read and write mmu pagetable register base addr
*/
#define TTBR1_R(val) __asm__ volatile("mrs %0, ttbr1_el1" : "=r"(val)::"memory")
#define TTBR1_W(val) __asm__ volatile("msr ttbr1_el1, %0" ::"r"(val) : "memory")
#define TTBR1_R(val) __asm__ volatile("mrs %0, ttbr1_el1" : "=r"(val))
#define TTBR1_W(val) __asm__ volatile("msr ttbr1_el1, %0" ::"r"(val))
/*
Translation Control RegisterTCR
*/
#define TCR_R(val) __asm__ volatile("mrs %0, tcr_el1" : "=r"(val)::"memory")
#define TCR_W(val) __asm__ volatile("msr tcr_el1, %0" ::"r"(val) : "memory")
#define TCR_R(val) __asm__ volatile("mrs %0, tcr_el1" : "=r"(val))
#define TCR_W(val) __asm__ volatile("msr tcr_el1, %0" ::"r"(val))
#define MAIR_R(val) __asm__ volatile("mrs %0, mair_el1" : "=r"(val)::"memory")
#define MAIR_W(val) __asm__ volatile("msr mair_el1, %0" ::"r"(val) : "memory")
#define MAIR_R(val) __asm__ volatile("mrs %0, mair_el1" : "=r"(val))
#define MAIR_W(val) __asm__ volatile("msr mair_el1, %0" ::"r"(val))
/*
Flush TLB when loading a new page table.
@note If nG is not set in the pte attribute, process switching need flush tlb.
*/
// #define CLEARTLB(val) __asm__ volatile("tlbi vmalle1" ::: "memory")
#define CLEARTLB(val) __asm__ volatile("tlbi vmalle1is" ::: "memory")
#define CLEARTLB(val) __asm__ volatile("tlbi vmalle1")
/*
When nG is set in the pte attribute, the process is assigned an ASID, which is stored in the lower 8 bits of the CONTEXTIDR register.

View File

@ -45,9 +45,7 @@ void load_pgdir(uintptr_t pgdir_paddr)
struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag);
TTBR0_W((uint64_t)pgdir_paddr);
DSB();
CLEARTLB(0);
ISB();
p_icache_done->invalidateall();
p_dcache_done->flushall();
}

View File

@ -33,11 +33,11 @@ Modification:
#define ARCH_BIT 64
/* A55 physical memory layout */
#define PHY_MEM_BASE (0x0000000010000000ULL)
#define PHY_USER_FREEMEM_BASE (0x0000000040000000ULL)
#define PHY_USER_FREEMEM_TOP (0x00000000E0000000ULL)
#define PHY_MEM_STOP (0x00000000E0000000ULL)
/* A72 physical memory layout */
#define PHY_MEM_BASE (0x0000000040000000ULL)
#define PHY_USER_FREEMEM_BASE (0x0000000046000000ULL)
#define PHY_USER_FREEMEM_TOP (0x0000000048000000ULL)
#define PHY_MEM_STOP (0x0000000048000000ULL)
/* PTE-PAGE_SIZE */
#define LEVEL4_PTE_SHIFT 12
@ -58,23 +58,23 @@ Modification:
#define NUM_TOPLEVEL_PDE NUM_LEVEL2_PDE
#define PAGE_SIZE LEVEL4_PTE_SIZE
#define MAX_NR_FREE_PAGES ((PHY_USER_FREEMEM_BASE - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT)
#define MAX_NR_FREE_PAGES ((PHY_MEM_STOP - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT)
/* Deivce memory layout */
#define DEV_PHYMEM_BASE (0x00000000F0000000ULL)
#define DEV_VRTMEM_BASE (0x00000040F0000000ULL)
#define DEV_MEM_SIZE (0x0000000010000000ULL)
#define DEV_PHYMEM_BASE (0x0000000000000000ULL)
#define DEV_VRTMEM_BASE (0x0000004000000000ULL)
#define DEV_MEM_SZ (0x0000000010000000ULL)
/* User memory layout */
#define USER_STACK_SIZE PAGE_SIZE
#define USER_MEM_BASE (0x0000000000000000ULL)
#define USER_MEM_TOP (0x0000004000000000ULL)
#define USER_MEM_TOP DEV_VRTMEM_BASE
#define USER_IPC_SPACE_BASE (0x0000003000000000ULL)
#define USER_IPC_USE_ALLOCATOR_WATERMARK (0x0000003000010000ULL)
#define USER_IPC_SPACE_TOP (USER_IPC_SPACE_BASE + 0x10000000ULL)
/* Kernel memory layout */
#define KERN_MEM_BASE (0x0000006010000000ULL) // First kernel virtual address
#define KERN_MEM_BASE (0x0000006040000000ULL) // First kernel virtual address
#define KERN_OFFSET (KERN_MEM_BASE - PHY_MEM_BASE)
#define V2P(a) (((uint64_t)(a)) - KERN_OFFSET)

View File

@ -52,26 +52,22 @@ Modification:
void GetUsrPteAttr(uintptr_t* attr)
{
// *attr = ARMV8_PTE_AP_U | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_NORMAL | ARMV8_PTE_VALID;
*attr = 0x713 | ARMV8_PTE_AP_U;
*attr = ARMV8_PTE_AP_U | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_NORMAL | ARMV8_PTE_VALID;
}
void GetUsrDevPteAttr(uintptr_t* attr)
{
// *attr = ARMV8_PTE_AP_U | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_DEVICE | ARMV8_PTE_XN | ARMV8_PTE_VALID;
*attr = 0x403 | ARMV8_PTE_AP_U;
*attr = ARMV8_PTE_AP_U | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_DEVICE | ARMV8_PTE_XN | ARMV8_PTE_VALID;
}
void GetDevPteAttr(uintptr_t* attr)
{
// *attr = ARMV8_PTE_AP_K | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_DEVICE | ARMV8_PTE_XN | ARMV8_PTE_VALID;
*attr = 0x403ULL;
*attr = ARMV8_PTE_AP_K | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_DEVICE | ARMV8_PTE_XN | ARMV8_PTE_VALID;
}
void GetKernPteAttr(uintptr_t* attr)
{
// *attr = ARMV8_PTE_AP_K | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_NORMAL | ARMV8_PTE_VALID;
*attr = 0x713ULL;
*attr = ARMV8_PTE_AP_K | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_NORMAL | ARMV8_PTE_VALID;
}
void GetPdeAttr(uintptr_t* attr)

View File

@ -1,5 +1,5 @@
# The following three platforms support compatiable instructions.
ifneq ($(findstring $(BOARD), 3568), )
ifneq ($(findstring $(BOARD), ok1028a-c), )
SRC_DIR := armv8-a
endif
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )

View File

@ -1,4 +1,4 @@
# The following three platforms support compatiable instructions.
SRC_DIR := cortex-a55
SRC_DIR := cortex-a72
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,198 +0,0 @@
/*
* NS16550 Serial Port
* originally from linux source (arch/powerpc/boot/ns16550.h)
*
* Cleanup and unification
* (C) 2009 by Detlev Zundel, DENX Software Engineering GmbH
*
* modified slightly to
* have addresses as offsets from CONFIG_SYS_ISA_BASE
* added a few more definitions
* added prototypes for ns16550.c
* reduced no of com ports to 2
* modifications (c) Rob Taylor, Flying Pig Systems. 2000.
*
* added support for port on 64-bit bus
* by Richard Danter (richard.danter@windriver.com), (C) 2005 Wind River Systems
*/
/*
* Note that the following macro magic uses the fact that the compiler
* will not allocate storage for arrays of size 0
*/
#include <stdint.h>
/*
* For driver model we always use one byte per register, and sort out the
* differences in the driver
*/
#define CONFIG_SYS_NS16550_REG_SIZE (-1)
#define UART_REG(x) \
unsigned char x; \
unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
/**
* struct ns16550_platdata - information about a NS16550 port
*
* @base: Base register address
* @reg_shift: Shift size of registers (0=byte, 1=16bit, 2=32bit...)
* @clock: UART base clock speed in Hz
*/
struct ns16550_platdata {
unsigned long base;
int reg_shift;
int clock;
int reg_offset;
uint32_t fcr;
};
struct udevice;
struct NS16550 {
UART_REG(rbr); /* 0 */
UART_REG(ier); /* 1 */
UART_REG(fcr); /* 2 */
UART_REG(lcr); /* 3 */
UART_REG(mcr); /* 4 */
UART_REG(lsr); /* 5 */
UART_REG(msr); /* 6 */
UART_REG(spr); /* 7 */
#ifdef CONFIG_SOC_DA8XX
UART_REG(reg8); /* 8 */
UART_REG(reg9); /* 9 */
UART_REG(revid1); /* A */
UART_REG(revid2); /* B */
UART_REG(pwr_mgmt); /* C */
UART_REG(mdr1); /* D */
#else
UART_REG(mdr1); /* 8 */
UART_REG(reg9); /* 9 */
UART_REG(regA); /* A */
UART_REG(regB); /* B */
UART_REG(regC); /* C */
UART_REG(regD); /* D */
UART_REG(regE); /* E */
UART_REG(uasr); /* F */
UART_REG(scr); /* 10*/
UART_REG(ssr); /* 11*/
#endif
#ifdef CONFIG_DM_SERIAL
struct ns16550_platdata* plat;
#endif
};
#define thr rbr
#define iir fcr
#define dll rbr
#define dlm ier
typedef struct NS16550* NS16550_t;
/*
* These are the definitions for the FIFO Control Register
*/
#define UART_FCR_FIFO_EN 0x01 /* Fifo enable */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */
#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */
#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */
#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
#define UART_FCR_RXSR 0x02 /* Receiver soft reset */
#define UART_FCR_TXSR 0x04 /* Transmitter soft reset */
/* Ingenic JZ47xx specific UART-enable bit. */
#define UART_FCR_UME 0x10
/* Clear & enable FIFOs */
#define UART_FCR_DEFVAL (UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR)
/*
* These are the definitions for the Modem Control Register
*/
#define UART_MCR_DTR 0x01 /* DTR */
#define UART_MCR_RTS 0x02 /* RTS */
#define UART_MCR_OUT1 0x04 /* Out 1 */
#define UART_MCR_OUT2 0x08 /* Out 2 */
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS */
#define UART_MCR_DMA_EN 0x04
#define UART_MCR_TX_DFR 0x08
/*
* These are the definitions for the Line Control Register
*
* Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
* UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
*/
#define UART_LCR_WLS_MSK 0x03 /* character length select mask */
#define UART_LCR_WLS_5 0x00 /* 5 bit character length */
#define UART_LCR_WLS_6 0x01 /* 6 bit character length */
#define UART_LCR_WLS_7 0x02 /* 7 bit character length */
#define UART_LCR_WLS_8 0x03 /* 8 bit character length */
#define UART_LCR_STB 0x04 /* # stop Bits, off=1, on=1.5 or 2) */
#define UART_LCR_PEN 0x08 /* Parity eneble */
#define UART_LCR_EPS 0x10 /* Even Parity Select */
#define UART_LCR_STKP 0x20 /* Stick Parity */
#define UART_LCR_SBRK 0x40 /* Set Break */
#define UART_LCR_BKSE 0x80 /* Bank select enable */
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
/*
* These are the definitions for the Line Status Register
*/
#define UART_LSR_DR 0x01 /* Data ready */
#define UART_LSR_OE 0x02 /* Overrun */
#define UART_LSR_PE 0x04 /* Parity error */
#define UART_LSR_FE 0x08 /* Framing error */
#define UART_LSR_BI 0x10 /* Break */
#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
#define UART_LSR_TEMT 0x40 /* Xmitter empty */
#define UART_LSR_ERR 0x80 /* Error */
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
#define UART_MSR_RI 0x40 /* Ring Indicator */
#define UART_MSR_DSR 0x20 /* Data Set Ready */
#define UART_MSR_CTS 0x10 /* Clear to Send */
#define UART_MSR_DDCD 0x08 /* Delta DCD */
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
#define UART_MSR_DDSR 0x02 /* Delta DSR */
#define UART_MSR_DCTS 0x01 /* Delta CTS */
/*
* These are the definitions for the Interrupt Identification Register
*/
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
/*
* These are the definitions for the Interrupt Enable Register
*/
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
/* useful defaults for LCR */
#define UART_LCR_8N1 0x03
void NS16550_init(NS16550_t com_port, int baud_divisor);
void NS16550_putc(NS16550_t com_port, char c);
char NS16550_getc(NS16550_t com_port);
int NS16550_tstc(NS16550_t com_port);
void NS16550_reinit(NS16550_t com_port, int baud_divisor);
void _debug_uart_init(void);
void _debug_uart_putc(int ch);
int _debug_uart_getc(void);

View File

@ -1,103 +0,0 @@
/*
* COM1 NS16550 support
* originally from linux source (arch/powerpc/boot/ns16550.c)
* modified to use CONFIG_SYS_ISA_MEM and new defines
*/
#include <stdint.h>
#include "mmio_access.h"
#include "ns16550.h"
#define UART_ADDR MMIO_P2V_WO(0xFE660000)
// #define UART_ADDR (0xFE660000)
#define UART_LCRVAL UART_LCR_8N1 /* 8 data, 1 stop, no parity */
#define UART_MCRVAL (UART_MCR_DTR | UART_MCR_RTS) /* RTS/DTR */
#define out_le32(a, v) (*(volatile uint32_t*)(a) = (v))
#define in_le32(a) (*(volatile uint32_t*)(a))
#ifndef CONFIG_SYS_NS16550_IER
#define CONFIG_SYS_NS16550_IER 0x00
#endif /* CONFIG_SYS_NS16550_IER */
#define serial_dout(reg, value) \
serial_out_shift((char*)com_port + ((char*)reg - (char*)com_port) * (1 << 2), \
2, value)
#define serial_din(reg) \
serial_in_shift((char*)com_port + ((char*)reg - (char*)com_port) * (1 << 2), \
2)
static inline void serial_out_shift(void* addr, int shift, int value)
{
out_le32(addr, value);
}
static inline int serial_in_shift(void* addr, int shift)
{
return in_le32(addr);
}
#ifndef CONFIG_SYS_NS16550_CLK
#define CONFIG_SYS_NS16550_CLK 0
#endif
#define DIV_ROUND_CLOSEST(x, divisor) ( \
{ \
typeof(x) __x = x; \
typeof(divisor) __d = divisor; \
(((typeof(x))-1) > 0 || ((typeof(divisor))-1) > 0 || (__x) > 0) ? (((__x) + ((__d) / 2)) / (__d)) : (((__x) - ((__d) / 2)) / (__d)); \
})
int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate)
{
const unsigned int mode_x_div = 16;
return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate);
}
void _debug_uart_init(void)
{
struct NS16550* com_port = (struct NS16550*)UART_ADDR;
/*
* We copy the code from above because it is already horribly messy.
* Trying to refactor to nicely remove the duplication doesn't seem
* feasible. The better fix is to move all users of this driver to
* driver model.
*/
int baud_divisor = ns16550_calc_divisor(com_port, 24000000,
1500000);
serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
serial_dout(&com_port->mcr, UART_MCRVAL);
serial_dout(&com_port->fcr, UART_FCR_DEFVAL);
serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
serial_dout(&com_port->dll, baud_divisor & 0xff);
serial_dout(&com_port->dlm, (baud_divisor >> 8) & 0xff);
serial_dout(&com_port->lcr, UART_LCRVAL);
}
void _debug_uart_putc(int ch)
{
static struct NS16550* com_port = (struct NS16550*)UART_ADDR;
if (ch == '\n') {
_debug_uart_putc('\r');
}
while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
;
serial_dout(&com_port->thr, ch);
}
int _debug_uart_getc(void)
{
static struct NS16550* com_port = (struct NS16550*)UART_ADDR;
while (!(serial_din(&com_port->lsr) & UART_LSR_DR))
;
return serial_din(&com_port->rbr);
}

View File

@ -1,45 +0,0 @@
//
// low-level driver routines for pl011 UART.
//
#include "uart.h"
#include "actracer.h"
#include "ns16550.h"
#include "uart_common_ope.h"
// the UART control registers are memory-mapped
// at address UART0. this macro returns the
// address of one of the registers.
void uartinit(void)
{
_debug_uart_init();
}
void uartputc(uint8_t c)
{
_debug_uart_putc((int)c);
}
static uint8_t uartgetc(void)
{
return (uint8_t)_debug_uart_getc();
}
static uint32_t UartGetIrqnum()
{
return 0;
}
static struct XiziSerialDriver hardkernel_serial_driver = {
.sys_serial_init = uartinit,
.get_serial_irqnum = UartGetIrqnum,
.putc = uartputc,
.getc = uartgetc,
};
struct XiziSerialDriver* hardkernel_uart_init(struct TraceTag* hardkernel_tag)
{
hardkernel_serial_driver.sys_serial_init();
return &hardkernel_serial_driver;
}

View File

@ -1,4 +1,3 @@
SRC_DIR := hal
SRC_FILES := uart.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,128 @@
//
// low-level driver routines for pl011 UART.
//
#include "uart.h"
#include "actracer.h"
#include "uart_common_ope.h"
// the UART control registers are memory-mapped
// at address UART0. this macro returns the
// address of one of the registers.
// the transmit output buffer.
#define UART_TX_BUF_SIZE 32
static char uart_tx_buf[UART_TX_BUF_SIZE];
uint64_t uart_tx_w; // write next to uart_tx_buf[uart_tx_w % UART_TX_BUF_SIZE]
uint64_t uart_tx_r; // read next from uart_tx_buf[uart_tx_r % UART_TX_BUF_SIZE]
void uartinit(void)
{
// disable uart
UART_WRITE_REG(CR, 0);
// disable interrupts.
UART_WRITE_REG(IMSC, 0);
// in qemu, it is not necessary to set baudrate.
// enable FIFOs.
// set word length to 8 bits, no parity.
UART_WRITE_REG(LCRH, LCRH_FEN | LCRH_WLEN_8BIT);
// enable RXE, TXE and enable uart.
UART_WRITE_REG(CR, 0x301);
// enable transmit and receive interrupts.
UART_WRITE_REG(IMSC, INT_RX_ENABLE | INT_TX_ENABLE);
}
// if the UART is idle, and a character is waiting
// in the transmit buffer, send it.
// caller must hold uart_tx_lock.
// called from both the top- and bottom-half.
void uartstart()
{
while (1) {
if (uart_tx_w == uart_tx_r) {
// transmit buffer is empty.
return;
}
if (UART_READ_REG(FR) & FR_TXFF) {
// the UART transmit holding register is full,
// so we cannot give it another byte.
// it will interrupt when it's ready for a new byte.
return;
}
int c = uart_tx_buf[uart_tx_r % UART_TX_BUF_SIZE];
uart_tx_r += 1;
// maybe uartputc() is waiting for space in the buffer.
UART_WRITE_REG(DR, c);
}
}
// add a character to the output buffer and tell the
// UART to start sending if it isn't already.
// blocks if the output buffer is full.
// because it may block, it can't be called
// from interrupts; it's only suitable for use
// by write().
void uartputc(uint8_t c)
{
while (uart_tx_w == uart_tx_r + UART_TX_BUF_SIZE)
;
uart_tx_buf[uart_tx_w % UART_TX_BUF_SIZE] = c;
uart_tx_w += 1;
uartstart();
return;
}
// read one input character from the UART.
// return -1 if none is waiting.
static uint8_t uartgetc(void)
{
if (UART_READ_REG(FR) & FR_RXFE)
return 0xFF;
else
return UART_READ_REG(DR);
}
// handle a uart interrupt, raised because input has
// arrived, or the uart is ready for more output, or
// both. called from trap.c.
void uartintr(void)
{
// read and process incoming characters.
while (1) {
int c = uartgetc();
if (c == 0xFF)
break;
}
// send buffered characters.
uartstart();
// clear transmit and receive interrupts.
UART_WRITE_REG(ICR, INT_RX_ENABLE | INT_TX_ENABLE);
}
static uint32_t UartGetIrqnum()
{
return 0;
}
static struct XiziSerialDriver hardkernel_serial_driver = {
.sys_serial_init = uartinit,
.get_serial_irqnum = UartGetIrqnum,
.putc = uartputc,
.getc = uartgetc,
};
struct XiziSerialDriver* hardkernel_uart_init(struct TraceTag* hardkernel_tag)
{
hardkernel_serial_driver.sys_serial_init();
return &hardkernel_serial_driver;
}

View File

@ -41,16 +41,15 @@ static void tracer_init_node(TracerNode* node, char* name, tracemeta_ac_type typ
node->parent = NULL;
if (name != NULL) {
char* p_name = (char*)slab_alloc(&sys_tracer.node_name_allocator);
if (!p_name) {
p_name = "BAD_NAME(NOMEM)";
} else {
strcpy(p_name, name);
p_name[TRACER_NODE_NAME_LEN - 1] = '\0';
node->name = p_name;
}
strcpy(p_name, name);
p_name[TRACER_NODE_NAME_LEN - 1] = '\0';
node->name = p_name;
}
if (node->type == TRACER_OWNER) {
doubleListNodeInit(&node->children_guard);
} else {
node->p_resource = p_resource;
}
doubleListNodeInit(&node->children_guard);
node->p_resource = p_resource;
doubleListNodeInit(&node->list_node);
}
@ -59,16 +58,16 @@ void sys_tracer_init()
// set sys_tracer resource identity
tracer_init_node(&sys_tracer.root_node, NULL, TRACER_OWNER, NULL);
sys_tracer.root_node.name = root_name;
sys_tracer.sys_tracer_tag.inner_node = &sys_tracer.root_node;
sys_tracer.sys_tracer_tag.meta = &sys_tracer.root_node;
// init memory allocator
slab_init(&sys_tracer.node_allocator, sizeof(TracerNode), "TracerNodeAllocator");
slab_init(&sys_tracer.node_name_allocator, sizeof(char[TRACER_NODE_NAME_LEN]), "TracerNodeNameAllocator");
slab_init(&sys_tracer.node_allocator, sizeof(TracerNode));
slab_init(&sys_tracer.node_name_allocator, sizeof(char[TRACER_NODE_NAME_LEN]));
}
static char* parse_path(char* path, char* const name)
{
// Skip extra '/'
// skip extra '/'
while (*path == '/') {
path++;
}
@ -76,19 +75,21 @@ static char* parse_path(char* path, char* const name)
return NULL;
}
// Start of current name
// start of current name
char* cur_start = path;
while (*path != '/' && *path != '\0') {
path++;
}
// Handle current name
size_t len = path - cur_start;
// handle current name
int len = path - cur_start;
if (len >= TRACER_NODE_NAME_LEN) {
len = TRACER_NODE_NAME_LEN - 1;
strncpy(name, cur_start, TRACER_NODE_NAME_LEN);
name[TRACER_NODE_NAME_LEN - 1] = '\0';
} else {
strncpy(name, cur_start, len);
name[len] = '\0';
}
memcpy(name, cur_start, len);
name[len] = '\0';
return path;
}
@ -120,40 +121,39 @@ bool AchieveResourceTag(TraceTag* target, TraceTag* owner, char* name)
{
static char name_buffer[TRACER_NODE_NAME_LEN];
TracerNode* inner_node = owner->inner_node;
TracerNode* inner_node = owner->meta;
assert(inner_node != NULL && inner_node->type == TRACER_OWNER);
while ((name = parse_path(name, name_buffer)) != NULL) {
if ((inner_node = tracer_find_node_onestep(inner_node, name_buffer)) == NULL) {
DEBUG("Tracer: No such object, owner: %s, child: %s\n", //
owner->inner_node->name == NULL ? "NULL" : owner->inner_node->name, name == NULL ? "NULL" : name_buffer);
owner->meta->name == NULL ? "NULL" : owner->meta->name, name == NULL ? "NULL" : name_buffer);
return false;
}
}
target->inner_node = inner_node;
target->meta = inner_node;
return true;
}
void* AchieveResource(TraceTag* tag)
{
assert(tag != NULL);
if (tag->inner_node == NULL || tag->inner_node->type == TRACER_OWNER) {
if (tag->meta == NULL || tag->meta->type == TRACER_OWNER) {
return NULL;
}
return tag->inner_node->p_resource;
return tag->meta->p_resource;
}
bool CreateResourceTag(TraceTag* new_tag, TraceTag* owner, char* name, tracemeta_ac_type type, void* p_resource)
{
assert(owner != NULL);
if (owner->inner_node == NULL) {
ERROR("Tracer: Empty owner, node name: %s\n", name);
assert(new_tag != NULL && owner != NULL);
if (owner->meta == NULL) {
ERROR("Tracer: Empty owner\n");
return false;
}
// assert(owner->inner_node->type == TRACER_OWNER);
if (type == TRACER_SERVER_IDENTITY_AC_RESOURCE && //
tracer_find_node_onestep(owner->inner_node, name) != NULL) {
assert(owner->meta->type == TRACER_OWNER);
if (tracer_find_node_onestep(owner->meta, name) != NULL) {
return false;
}
@ -165,76 +165,34 @@ bool CreateResourceTag(TraceTag* new_tag, TraceTag* owner, char* name, tracemeta
tracer_init_node(new_node, name, type, p_resource);
// new node add to owner's children list
doubleListAddOnHead(&new_node->list_node, &owner->inner_node->children_guard);
new_node->parent = owner->inner_node;
doubleListAddOnHead(&new_node->list_node, &owner->meta->children_guard);
new_node->parent = owner->meta;
if (new_tag != NULL) {
new_tag->inner_node = new_node;
}
new_tag->meta = new_node;
return true;
}
bool DeleteResource(TraceTag* target, TraceTag* owner)
{
assert(target != NULL && owner != NULL);
assert(owner->inner_node != NULL && owner->inner_node->type == TRACER_OWNER);
if (target->inner_node == NULL) {
ERROR("Tracer: Delete a empty resource, owner: %s\n", owner->inner_node->name);
assert(owner->meta != NULL && owner->meta->type == TRACER_OWNER);
if (target->meta == NULL) {
ERROR("Tracer: Delete a empty resource\n");
return false;
}
assert(target->inner_node->parent == owner->inner_node);
doubleListDel(&target->inner_node->list_node);
assert(target->meta->parent == owner->meta);
doubleListDel(&target->meta->list_node);
// delete name
if (target->inner_node->name != NULL) {
slab_free(&sys_tracer.node_name_allocator, target->inner_node->name);
if (target->meta->name != NULL) {
slab_free(&sys_tracer.node_name_allocator, target->meta->name);
}
// delete all children
if (target->inner_node->type == TRACER_OWNER) {
while (!IS_DOUBLE_LIST_EMPTY(&target->inner_node->children_guard)) {
TraceTag tmp_node = {
.inner_node = DOUBLE_LIST_ENTRY(target->inner_node->children_guard.next, TracerNode, list_node),
};
DeleteResource(&tmp_node, target);
}
/// @attention currently donot allow multilevel resource deletion
if (target->meta->type == TRACER_OWNER) {
assert(IS_DOUBLE_LIST_EMPTY(&target->meta->children_guard));
}
slab_free(&sys_tracer.node_allocator, target->inner_node);
target->inner_node = NULL;
slab_free(&sys_tracer.node_allocator, target->meta);
target->meta = NULL;
return true;
}
#define debug_print_blanks(n) \
for (int __i = 0; __i < n; __i++) { \
DEBUG_PRINTF(" "); \
}
void debug_list_tracetree_inner(TracerNode* cur_node, int nr_blanks)
{
debug_print_blanks(nr_blanks);
if (cur_node->name == NULL) {
DEBUG_PRINTF("[ANON %d] ", cur_node->type);
} else {
DEBUG_PRINTF("[%s %d] ", cur_node->name, cur_node->type);
}
TracerNode* tmp = NULL;
DOUBLE_LIST_FOR_EACH_ENTRY(tmp, &cur_node->children_guard, list_node)
{
if (tmp->name != NULL) {
DEBUG_PRINTF("%s ", tmp->name);
} else {
DEBUG_PRINTF("ANON ");
}
}
DEBUG_PRINTF("\n");
DOUBLE_LIST_FOR_EACH_ENTRY(tmp, &cur_node->children_guard, list_node)
{
debug_list_tracetree_inner(tmp, nr_blanks + 1);
}
}
void debug_list_tracetree()
{
TracerNode* ref_root = RequireRootTag()->inner_node;
debug_list_tracetree_inner(ref_root, 0);
}

View File

@ -30,12 +30,35 @@ Modification:
#include <stdbool.h>
#include <stdint.h>
#include "actracer_tag.h"
#include "list.h"
#include "object_allocator.h"
#define TRACER_NODE_NAME_LEN 32
#define GetSysObject(type, target_tag) (type*)AchieveResource(target_tag)
typedef enum {
TRACER_INVALID = 0,
TRACER_OWNER,
TRACER_HARDKERNEL_AC_RESOURCE,
TRACER_TASK_DESCRIPTOR_AC_RESOURCE,
TRACER_SERVER_IDENTITY_AC_RESOURCE,
TRACER_MEM_FROM_BUDDY_AC_RESOURCE,
} tracemeta_ac_type;
typedef struct TracerNode {
tracemeta_ac_type type;
char* name;
union {
struct double_list_node children_guard;
void* p_resource;
};
struct TracerNode* parent;
struct double_list_node list_node;
} TracerNode;
/// @brief tag for other module to reference trace meta
typedef struct TraceTag {
TracerNode* meta;
} TraceTag;
struct SysTracer {
TracerNode root_node;
@ -49,6 +72,4 @@ TraceTag* const RequireRootTag();
bool AchieveResourceTag(struct TraceTag* target, struct TraceTag* owner, char* name);
void* AchieveResource(struct TraceTag* tag);
bool CreateResourceTag(struct TraceTag* new_tag, struct TraceTag* owner, char* name, tracemeta_ac_type type, void* p_resource);
bool DeleteResource(struct TraceTag* target, struct TraceTag* owner);
void debug_list_tracetree();
bool DeleteResource(struct TraceTag* target, struct TraceTag* owner);

View File

@ -1,27 +0,0 @@
#pragma once
#include "list.h"
typedef enum {
TRACER_INVALID = 0,
TRACER_OWNER,
TRACER_HARDKERNEL_AC_RESOURCE,
TRACER_TASK_DESCRIPTOR_AC_RESOURCE,
TRACER_SERVER_IDENTITY_AC_RESOURCE,
TRACER_MEM_SIGNATURE,
TRACER_SYSOBJECT,
} tracemeta_ac_type;
typedef struct TracerNode {
tracemeta_ac_type type;
char* name;
void* p_resource;
struct TracerNode* parent;
struct double_list_node list_node;
struct double_list_node children_guard;
} TracerNode;
/// @brief tag for other module to reference trace inner_node
typedef struct TraceTag {
TracerNode* inner_node;
uint32_t authority;
} TraceTag;

View File

@ -38,20 +38,20 @@ KERNELPATHS += \
-I$(KERNEL_ROOT)/hardkernel/cache/L2/pl310/
endif
ifeq ($(BOARD), 3568)
ifeq ($(BOARD), ok1028a-c)
KERNELPATHS += \
-I$(KERNEL_ROOT)/hardkernel/clock/arm/armv8-a/cortex-a55/$(BOARD)/include \
-I$(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_$(BOARD)/include \
-I$(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a55/ \
-I$(KERNEL_ROOT)/hardkernel/mmu/arm/armv8-a/cortex-a55/$(BOARD) \
-I$(KERNEL_ROOT)/hardkernel/mmu/arm/armv8-a/cortex-a55/include \
-I$(KERNEL_ROOT)/hardkernel/clock/arm/armv8-a/cortex-a55/include \
-I$(KERNEL_ROOT)/hardkernel/intr/arm/armv8-a/cortex-a55/ \
-I$(KERNEL_ROOT)/hardkernel/intr/arm/armv8-a/cortex-a55/$(BOARD) \
-I$(KERNEL_ROOT)/hardkernel/intr/arm/armv8-a/cortex-a55/gicv3 \
-I$(KERNEL_ROOT)/hardkernel/uart/arm/armv8-a/cortex-a55/uart_io_for_$(BOARD)/include \
-I$(KERNEL_ROOT)/hardkernel/uart/arm/armv8-a/cortex-a55/ \
-I$(KERNEL_ROOT)/hardkernel/cache/L1/arm/cortex-a55/
-I$(KERNEL_ROOT)/hardkernel/clock/arm/armv8-a/cortex-a72/$(BOARD)/include \
-I$(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a72/preboot_for_$(BOARD)/include \
-I$(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a72/ \
-I$(KERNEL_ROOT)/hardkernel/mmu/arm/armv8-a/cortex-a72/$(BOARD) \
-I$(KERNEL_ROOT)/hardkernel/mmu/arm/armv8-a/cortex-a72/include \
-I$(KERNEL_ROOT)/hardkernel/clock/arm/armv8-a/cortex-a72/include \
-I$(KERNEL_ROOT)/hardkernel/intr/arm/armv8-a/cortex-a72/ \
-I$(KERNEL_ROOT)/hardkernel/intr/arm/armv8-a/cortex-a72/$(BOARD) \
-I$(KERNEL_ROOT)/hardkernel/intr/arm/armv8-a/cortex-a72/gicv3 \
-I$(KERNEL_ROOT)/hardkernel/uart/arm/armv8-a/cortex-a72/uart_io_for_$(BOARD)/include \
-I$(KERNEL_ROOT)/hardkernel/uart/arm/armv8-a/cortex-a72/ \
-I$(KERNEL_ROOT)/hardkernel/cache/L1/arm/cortex-a72/
endif
KERNELPATHS += \

View File

@ -1,5 +1,4 @@
SRC_DIR := fs shell lib boards semaphore drivers tools net app
SRC_DIR := fs shell lib boards semaphore drivers tools app
include $(KERNEL_ROOT)/compiler.mk

View File

@ -10,10 +10,10 @@ cflags = -std=c11 -O2 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -
board_specs = stub.o
#cflags = -Wall -g -std=c11
endif
ifeq ($(BOARD), 3568)
ifeq ($(BOARD), ok1028a-c)
toolchain ?= aarch64-none-elf-
user_ldflags = -N -Ttext 0
cflags = -Wall -O2 -std=c11 -mtune=cortex-a55 -nostdlib -nodefaultlibs -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
cflags = -Wall -g -std=c11 -mtune=cortex-a72 -nostdlib -nodefaultlibs -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
board_specs = stub.o
endif
@ -28,24 +28,14 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \
-I$(KERNEL_ROOT)/services/lib/serial \
-I$(KERNEL_ROOT)/services/lib/usyscall \
-I$(KERNEL_ROOT)/services/fs/libfs \
-I$(KERNEL_ROOT)/services/net/libnet \
-I$(KERNEL_ROOT)/services/net/net_server \
-I$(KERNEL_ROOT)/services/net/net_server/arch \
-I$(KERNEL_ROOT)/services/net/net_server/include \
-I$(KERNEL_ROOT)/services/net/net_server/include/lwip \
-I$(KERNEL_ROOT)/services/net/net_server/include/lwip/apps \
-I$(KERNEL_ROOT)/services/net/net_server/include/lwip/priv \
-I$(KERNEL_ROOT)/services/net/net_server/include/lwip/prot \
-I$(KERNEL_ROOT)/services/net/net_server/include/netif \
-I$(KERNEL_ROOT)/services/net/net_server/include/compat \
-I$(KERNEL_ROOT)/services/semaphore \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app
ifeq ($(BOARD), imx6q-sabrelite)
all: test_fault simple_client simple_server shell fs_server semaphore_server test_semaphore test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server test_net lwip readme.txt | bin
all: init test_fault simple_client simple_server shell fs_server semaphore_server test_semaphore test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server readme.txt | bin
else
all: test_fault simple_client simple_server shell fs_server semaphore_server test_ipc_null test_thread test_semaphore test_net lwip readme.txt eth_hal usb_driver_service | bin
all: init test_fault simple_client simple_server shell fs_server semaphore_server test_ipc_null test_thread test_semaphore readme.txt | bin
endif
../tools/mkfs/mkfs ./fs.img $^
@mv $(filter-out readme.txt, $^) bin
@ -69,10 +59,6 @@ epit_server: timer.o epit.o ccm_pll.o usyscall.o arch_usyscall.o libserial.o pri
@${objdump} -S $@ > $@.asm
endif
test_sleep: test_sleep.o libserial.o printf.o usyscall.o arch_usyscall.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
test_semaphore: test_semaphore.o libserial.o printf.o usyscall.o arch_usyscall.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
@ -101,6 +87,10 @@ shell: shell_port.o libserial.o printf.o shell_cmd_list.o shell.o shell_ext.o li
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
init: init.o libfs.o libipc.o session.o libserial.o printf.o usyscall.o arch_usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
test_fault: test_fault.o libserial.o printf.o usyscall.o arch_usyscall.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
@ -121,16 +111,8 @@ test_priority: test_priority.o libserial.o printf.o usyscall.o arch_usyscall.o l
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
test_net: test_net.o lwip_service.o libipc.o session.o libserial.o printf.o usyscall.o arch_usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} -llwip -L$(KERNEL_ROOT)/services/net/net_server
@${objdump} -S $@ > $@.asm
%.o: %.c
@${cc} ${cflags} ${c_useropts} ${INC_DIR} -o $@ -c $<
%.o: %.S
@${cc} ${cflags} ${c_useropts} -o $@ -c $<
eth_hal: test_gmac.o hal_gmac.o hal_gmac_3568.o hal_base.o hal_bsp.o hal_pinctrl_v2.o hal_cru.o hal_gpio.o hal_timer.o hal_cru_rk3568.o system_rk3568.o hal_debug.o libserial.o printf.o libmem.o usyscall.o arch_usyscall.o session.o libipc.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
@${cc} ${cflags} ${c_useropts} -o $@ -c $<

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
// init: The initial user-level program
#include <stdbool.h>
#include "libfs.h"
#include "libserial.h"
#include "usyscall.h"
int main(int argc, char* argv[])
{
struct Session session;
printf("init: connecting MemFS\n");
while (connect_session(&session, "MemFS", 8092) < 0)
;
printf("init: connect MemFS success\n");
int fd;
char* shell_task_param[2] = { "/shell", 0 };
if ((fd = open(&session, shell_task_param[0])) < 0) {
printf("Open %s failed\n", shell_task_param[0]);
exit(1);
}
if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) {
printf("Syscall Spawn shell failed\n");
}
close(&session, fd);
exit(0);
return 0;
}

View File

@ -50,7 +50,7 @@ int main(void)
shellInit(&shell, shellBuffer, 512);
while (connect_session(&session_fs, "MemFS", 0x10000) < 0)
while (connect_session(&session_fs, "MemFS", 8092) < 0)
;
if (!session_fs.buf) {
printf("session connect faield\n");

View File

@ -108,7 +108,7 @@ int main(int argc, char** argv)
struct Session fs_session;
static char id_buf[33] = { 0 };
if (id > 1) {
if (connect_session(&fs_session, "MemFS", 0x4000) < 0) {
if (connect_session(&fs_session, "MemFS", 8192) < 0) {
printf("connect fs_session failed\n");
} else {
int fd;

View File

@ -30,7 +30,8 @@ int IPC_DO_SERVE_FUNC(Ipc_hello_string)(char* buf, int* len)
return 0;
}
IPC_SERVER_INTERFACE(Ipc_add, 2);
// IPC_SERVER_INTERFACE(Ipc_add, 2);
IPC_SERVER_THREAD_INTERFACE(Ipc_add, 2);
IPC_SERVER_INTERFACE(Ipc_hello_string, 2);
IPC_SERVER_REGISTER_INTERFACES(IpcSimpleServer, 2, Ipc_hello_string, Ipc_add);

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
// test_net: Test the lwip network stack
#include "libserial.h"
#include "lwip_service.h"
#include "usyscall.h"
static char udp_ip_str[128] = {0};
static uint16_t udp_socket_port = 8888;
#define UDP_DEMO_SEND_TIMES 3
int main(int argc, char* argv[])
{
printf("lwip network stack test \n");
int cnt = UDP_DEMO_SEND_TIMES;
char send_str[128];
int fd = -1;
memset(send_str, 0, sizeof(send_str));
struct Session sess;
connect_session(&sess, "LWIPServer", 4096);
printf("%s %d\n", __func__, __LINE__);
fd = ipc_socket(&sess, AF_INET, SOCK_DGRAM, 0);
if(fd < 0) {
printf("Socket error\n");
return 0;
}
printf("%s %d\n", __func__, __LINE__);
struct sockaddr_in udp_sock;
udp_sock.sin_family = AF_INET;
udp_sock.sin_port = htons(udp_socket_port);
udp_sock.sin_addr.s_addr = inet_addr(udp_ip_str);
memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero));
printf("%s %d\n", __func__, __LINE__);
if(ipc_connect(&sess, fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)) < 0) {
printf("Unable to connect %s:%d\n", udp_ip_str, udp_socket_port);
ipc_close(&sess,fd);
return 0;
}
printf("%s %d\n", __func__, __LINE__);
printf("UDP connect %s:%d success, start to send.\n",
udp_ip_str,
udp_socket_port);
while(cnt --) {
snprintf(send_str, sizeof(send_str), "UDP test package times %d\r\n", cnt);
ipc_send(&sess, fd, send_str, strlen(send_str), 0);
printf("Send UDP msg: %s ", send_str);
}
ipc_close(&sess,fd);
free_session(&sess);
exit(0);
return 0;
}

View File

@ -1,24 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "libserial.h"
#include "usyscall.h"
int main(int argc, char* argv[])
{
while (true) {
printf("sleep for 2 seconds\n");
sleep(2000);
}
exit(0);
}

View File

@ -1,250 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/// this file is only used for debug
#include <stddef.h>
#include <stdint.h>
#include "libserial.h"
#include "usyscall.h"
/*
* For driver model we always use one byte per register, and sort out the
* differences in the driver
*/
#define CONFIG_SYS_NS16550_REG_SIZE (-1)
#define UART_REG(x) \
unsigned char x; \
unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
/**
* struct ns16550_platdata - information about a NS16550 port
*
* @base: Base register address
* @reg_shift: Shift size of registers (0=byte, 1=16bit, 2=32bit...)
* @clock: UART base clock speed in Hz
*/
struct ns16550_platdata {
unsigned long base;
int reg_shift;
int clock;
int reg_offset;
uint32_t fcr;
};
struct udevice;
struct NS16550 {
UART_REG(rbr); /* 0 */
UART_REG(ier); /* 1 */
UART_REG(fcr); /* 2 */
UART_REG(lcr); /* 3 */
UART_REG(mcr); /* 4 */
UART_REG(lsr); /* 5 */
UART_REG(msr); /* 6 */
UART_REG(spr); /* 7 */
#ifdef CONFIG_SOC_DA8XX
UART_REG(reg8); /* 8 */
UART_REG(reg9); /* 9 */
UART_REG(revid1); /* A */
UART_REG(revid2); /* B */
UART_REG(pwr_mgmt); /* C */
UART_REG(mdr1); /* D */
#else
UART_REG(mdr1); /* 8 */
UART_REG(reg9); /* 9 */
UART_REG(regA); /* A */
UART_REG(regB); /* B */
UART_REG(regC); /* C */
UART_REG(regD); /* D */
UART_REG(regE); /* E */
UART_REG(uasr); /* F */
UART_REG(scr); /* 10*/
UART_REG(ssr); /* 11*/
#endif
#ifdef CONFIG_DM_SERIAL
struct ns16550_platdata* plat;
#endif
};
#define thr rbr
#define iir fcr
#define dll rbr
#define dlm ier
typedef struct NS16550* NS16550_t;
/*
* These are the definitions for the FIFO Control Register
*/
#define UART_FCR_FIFO_EN 0x01 /* Fifo enable */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */
#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */
#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */
#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
#define UART_FCR_RXSR 0x02 /* Receiver soft reset */
#define UART_FCR_TXSR 0x04 /* Transmitter soft reset */
/* Ingenic JZ47xx specific UART-enable bit. */
#define UART_FCR_UME 0x10
/* Clear & enable FIFOs */
#define UART_FCR_DEFVAL (UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR)
/*
* These are the definitions for the Modem Control Register
*/
#define UART_MCR_DTR 0x01 /* DTR */
#define UART_MCR_RTS 0x02 /* RTS */
#define UART_MCR_OUT1 0x04 /* Out 1 */
#define UART_MCR_OUT2 0x08 /* Out 2 */
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS */
#define UART_MCR_DMA_EN 0x04
#define UART_MCR_TX_DFR 0x08
/*
* These are the definitions for the Line Control Register
*
* Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
* UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
*/
#define UART_LCR_WLS_MSK 0x03 /* character length select mask */
#define UART_LCR_WLS_5 0x00 /* 5 bit character length */
#define UART_LCR_WLS_6 0x01 /* 6 bit character length */
#define UART_LCR_WLS_7 0x02 /* 7 bit character length */
#define UART_LCR_WLS_8 0x03 /* 8 bit character length */
#define UART_LCR_STB 0x04 /* # stop Bits, off=1, on=1.5 or 2) */
#define UART_LCR_PEN 0x08 /* Parity eneble */
#define UART_LCR_EPS 0x10 /* Even Parity Select */
#define UART_LCR_STKP 0x20 /* Stick Parity */
#define UART_LCR_SBRK 0x40 /* Set Break */
#define UART_LCR_BKSE 0x80 /* Bank select enable */
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
/*
* These are the definitions for the Line Status Register
*/
#define UART_LSR_DR 0x01 /* Data ready */
#define UART_LSR_OE 0x02 /* Overrun */
#define UART_LSR_PE 0x04 /* Parity error */
#define UART_LSR_FE 0x08 /* Framing error */
#define UART_LSR_BI 0x10 /* Break */
#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
#define UART_LSR_TEMT 0x40 /* Xmitter empty */
#define UART_LSR_ERR 0x80 /* Error */
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
#define UART_MSR_RI 0x40 /* Ring Indicator */
#define UART_MSR_DSR 0x20 /* Data Set Ready */
#define UART_MSR_CTS 0x10 /* Clear to Send */
#define UART_MSR_DDCD 0x08 /* Delta DCD */
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
#define UART_MSR_DDSR 0x02 /* Delta DSR */
#define UART_MSR_DCTS 0x01 /* Delta CTS */
/*
* These are the definitions for the Interrupt Identification Register
*/
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
#define UART_IIR_MSI 0x00 /* Modem status interrupt */
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
/*
* These are the definitions for the Interrupt Enable Register
*/
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
/* useful defaults for LCR */
#define UART_LCR_8N1 0x03
#define UART_ADDR (0xFE660000)
#define UART_LCRVAL UART_LCR_8N1 /* 8 data, 1 stop, no parity */
#define UART_MCRVAL (UART_MCR_DTR | UART_MCR_RTS) /* RTS/DTR */
#define out_le32(a, v) (*(volatile uint32_t*)(a) = (v))
#define in_le32(a) (*(volatile uint32_t*)(a))
#ifndef CONFIG_SYS_NS16550_IER
#define CONFIG_SYS_NS16550_IER 0x00
#endif /* CONFIG_SYS_NS16550_IER */
#define serial_dout(reg, value) \
serial_out_shift((char*)com_port + ((char*)reg - (char*)com_port) * (1 << 2), \
2, value)
#define serial_din(reg) \
serial_in_shift((char*)com_port + ((char*)reg - (char*)com_port) * (1 << 2), \
2)
static inline void serial_out_shift(void* addr, int shift, int value)
{
out_le32(addr, value);
}
static inline int serial_in_shift(void* addr, int shift)
{
return in_le32(addr);
}
#ifndef CONFIG_SYS_NS16550_CLK
#define CONFIG_SYS_NS16550_CLK 0
#endif
bool init_uart_mmio()
{
static int mapped = 0;
if (mapped == 0) {
if (-1 == mmap(UART_ADDR, UART_ADDR, 4096, true)) {
return false;
}
mapped = 1;
}
return true;
}
void putc(char ch)
{
static struct NS16550* com_port = (struct NS16550*)UART_ADDR;
if (ch == '\n') {
putc('\r');
}
while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
;
serial_dout(&com_port->thr, ch);
}
char getc(void)
{
static struct NS16550* com_port = (struct NS16550*)UART_ADDR;
while (!(serial_din(&com_port->lsr) & UART_LSR_DR))
;
return serial_din(&com_port->rbr);
}

View File

@ -8,10 +8,10 @@ toolchain ?= arm-xilinx-eabi-
user_ldflags = -N -Ttext 0
cflags = -march=armv7-a -std=c11 -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
endif
ifeq ($(BOARD), 3568)
ifeq ($(BOARD), ok1028a-c)
toolchain ?= aarch64-none-elf-
user_ldflags = -N -Ttext 0
cflags = -Wall -O0 -g -std=c11 -mtune=cortex-a55 -nostdlib -nodefaultlibs -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
cflags = -Wall -g -std=c11 -mtune=cortex-a72 -nostdlib -nodefaultlibs -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
endif
cc = ${toolchain}gcc

View File

@ -8,10 +8,10 @@ toolchain ?= arm-xilinx-eabi-
user_ldflags = -N -Ttext 0
cflags = -march=armv7-a -std=c11 -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
endif
ifeq ($(BOARD), 3568)
ifeq ($(BOARD), ok1028a-c)
toolchain ?= aarch64-none-elf-
user_ldflags = -N -Ttext 0
cflags = -Wall -O0 -g -std=c11 -mtune=cortex-a55 -nostdlib -nodefaultlibs -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
cflags = -Wall -g -std=c11 -mtune=cortex-a72 -nostdlib -nodefaultlibs -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
endif
cc = ${toolchain}gcc

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/// this file is only used for debug
#include "libserial.h"
#include "usyscall.h"
#define USER_UART_BASE 0x6FFFF000
#define UART0_BASE (0x09000000ULL)
#define UART0_REG(reg) ((volatile uint32_t*)(USER_UART_BASE + reg))
// the UART control registers.
// pl011
#define DR 0x00
#define FR 0x18
#define FR_RXFE (1 << 4) // recieve fifo empty
#define FR_TXFF (1 << 5) // transmit fifo full
#define FR_RXFF (1 << 6) // recieve fifo full
#define FR_TXFE (1 << 7) // transmit fifo empty
#define IBRD 0x24
#define FBRD 0x28
#define LCRH 0x2c
#define LCRH_FEN (1 << 4)
#define LCRH_WLEN_8BIT (3 << 5)
#define CR 0x30
#define IMSC 0x38
#define INT_RX_ENABLE (1 << 4)
#define INT_TX_ENABLE (1 << 5)
#define ICR 0x44
#define UART_READ_REG(reg) (*(UART0_REG(reg)))
#define UART_WRITE_REG(reg, v) (*(UART0_REG(reg)) = (v))
#define UART_TX_BUF_SIZE 32
static char uart_tx_buf[UART_TX_BUF_SIZE];
uint64_t uart_tx_w; // write next to uart_tx_buf[uart_tx_w % UART_TX_BUF_SIZE]
uint64_t uart_tx_r; // read next from uart_tx_buf[uart_tx_r % UART_TX_BUF_SIZE]
bool init_uart_mmio()
{
static int mapped = 0;
if (mapped == 0) {
if (-1 == mmap(USER_UART_BASE, UART0_BASE, 4096, true)) {
return false;
}
mapped = 1;
}
return true;
}
// if the UART is idle, and a character is waiting
// in the transmit buffer, send it.
// caller must hold uart_tx_lock.
// called from both the top- and bottom-half.
void uartstart()
{
while (1) {
if (uart_tx_w == uart_tx_r) {
// transmit buffer is empty.
return;
}
if (UART_READ_REG(FR) & FR_TXFF) {
// the UART transmit holding register is full,
// so we cannot give it another byte.
// it will interrupt when it's ready for a new byte.
return;
}
int c = uart_tx_buf[uart_tx_r % UART_TX_BUF_SIZE];
uart_tx_r += 1;
// maybe uartputc() is waiting for space in the buffer.
UART_WRITE_REG(DR, c);
}
}
// add a character to the output buffer and tell the
// UART to start sending if it isn't already.
// blocks if the output buffer is full.
// because it may block, it can't be called
// from interrupts; it's only suitable for use
// by write().
void putc(char c)
{
while (uart_tx_w == uart_tx_r + UART_TX_BUF_SIZE)
;
uart_tx_buf[uart_tx_w % UART_TX_BUF_SIZE] = c;
uart_tx_w += 1;
uartstart();
return;
}
// read one input character from the UART.
// return -1 if none is waiting.
char getc(void)
{
if (UART_READ_REG(FR) & FR_RXFE)
return 0xFF;
else
return UART_READ_REG(DR);
}

Some files were not shown because too many files have changed in this diff Show More