Merge branch rk3568_dev of https://www.gitlink.org.cn/tuyuyang/xiuos with commit 6bc856b7a6 into local

This commit is contained in:
songyanguang 2024-08-15 19:26:02 +08:00
parent 059da067df
commit a9273b9879
155 changed files with 2734 additions and 2127 deletions

View File

@ -4,7 +4,7 @@ MAKEFLAGS += --no-print-directory
.PHONY:COMPILE_APP COMPILE_KERNEL .PHONY:COMPILE_APP COMPILE_KERNEL
riscv_support := riscv_support :=
arm_support += imx6q-sabrelite zynq7000-zc702 ok1028a-c arm_support += imx6q-sabrelite zynq7000-zc702 3568
emulator_support += emulator_support +=
support := $(riscv_support) $(arm_support) $(emulator_support) support := $(riscv_support) $(arm_support) $(emulator_support)
SRC_DIR := SRC_DIR :=
@ -34,8 +34,8 @@ export UBIQUITOUS_ROOT ?= ..
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), ) ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )
include $(KERNEL_ROOT)/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_$(BOARD)/config.mk include $(KERNEL_ROOT)/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_$(BOARD)/config.mk
endif endif
ifneq ($(findstring $(BOARD), ok1028a-c), ) ifneq ($(findstring $(BOARD), 3568), )
include $(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a72/preboot_for_$(BOARD)/config.mk include $(KERNEL_ROOT)/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_$(BOARD)/config.mk
endif endif
export BSP_BUILD_DIR := $(KERNEL_ROOT) export BSP_BUILD_DIR := $(KERNEL_ROOT)
export HOSTTOOLS_DIR ?= $(KERNEL_ROOT)/services/tools/hosttools export HOSTTOOLS_DIR ?= $(KERNEL_ROOT)/services/tools/hosttools

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,120 @@
/*
* 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)
.section ".text", "ax"
.global _boot_start
.global primary_cpu_init
.global el2_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 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 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
.end

View File

@ -1,8 +1,7 @@
export CROSS_COMPILE ?= aarch64-none-elf- export CROSS_COMPILE ?= aarch64-none-elf-
export DEVICE = -mtune=cortex-a72 -ffreestanding -fno-common -fno-stack-protector -fno-pie -no-pie 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 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-a55/preboot_for_3568/3568.lds -Wl,--start-group,-lgcc,-lc,--end-group
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 CXXFLAGS :=
export DEFINES := -DHAVE_CCONFIG_H -DCHIP_LS1028 export DEFINES := -DHAVE_CCONFIG_H -DCHIP_LS1028

View File

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

View File

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

View File

@ -48,12 +48,34 @@ Modification:
#include <stdint.h> #include <stdint.h>
#define PSCI_CPUON 0xc4000003 #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 _boot_start();
void psci_call(uint64_t fn, uint8_t cpuid, uint64_t entry, uint64_t ctxid); 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 cpu_start_secondary(uint8_t cpu_id) void cpu_start_secondary(uint8_t cpu_id)
{ {
psci_call(PSCI_CPUON, cpu_id, (uintptr_t)&_boot_start, 0); __invoke_sip_fn_smc(PSCI_CPUON, cpu_id, (uintptr_t)0xa00000, 0);
} }
void start_smp_cache_broadcast(int cpu_id) void start_smp_cache_broadcast(int cpu_id)

View File

@ -0,0 +1,27 @@
/*
* 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

@ -1,81 +0,0 @@
// #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,8 +1,8 @@
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), ) ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )
SRC_DIR := cortex-a9 SRC_DIR := cortex-a9
endif endif
ifneq ($(findstring $(BOARD), ok1028a-c), ) ifneq ($(findstring $(BOARD), 3568), )
SRC_DIR := cortex-a72 SRC_DIR := cortex-a55
endif endif
include $(KERNEL_ROOT)/compiler.mk include $(KERNEL_ROOT)/compiler.mk

View File

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

View File

@ -0,0 +1,336 @@
/*
* (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

@ -20,6 +20,10 @@ Modification:
*************************************************/ *************************************************/
#include "l1_cache.h" #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) void InvalidateL1Dcache(uintptr_t start, uintptr_t end)
{ {
@ -153,34 +157,14 @@ void FlushL1Dcache(uintptr_t start, uintptr_t end)
void FlushL1DcacheAll(void) void FlushL1DcacheAll(void)
{ {
uint64_t ccsidr_el1; // Cache Size ID __asm_flush_dcache_all();
int num_sets; // number of sets __asm_flush_l3_dcache();
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() void InvalidateL1IcacheAll()
{ {
__asm__ __volatile__("ic iallu\n\t"); __asm_invalidate_icache_all();
// synchronize context on this processor __asm_invalidate_l3_icache();
ISB();
} }
void InvalidateL1Icache(uintptr_t start, uintptr_t end) 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) 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) static inline void flush_dcache_all(void)
{ {
// FlushL1DcacheAll(); FlushL1DcacheAll();
// FlushL2CacheAll(); // FlushL2CacheAll();
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -220,6 +220,7 @@ bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag)
p_icache_driver->enable(); p_icache_driver->enable();
p_dcache_driver->enable(); p_dcache_driver->enable();
// clock // clock
p_clock_driver->sys_clock_init();
p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0); p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0);
// mmu // mmu
secondary_cpu_load_kern_pgdir(&init_mmu_tag, &init_intr_tag); secondary_cpu_load_kern_pgdir(&init_mmu_tag, &init_intr_tag);

View File

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

View File

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

View File

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

View File

@ -29,7 +29,7 @@ Modification:
#include <string.h> #include <string.h>
#include "core.h" #include "core.h"
#include "cortex_a72.h" #include "cortex_a55.h"
#include "exception_registers.h" #include "exception_registers.h"
#include "gicv3_common_opa.h" #include "gicv3_common_opa.h"
#include "trap_common.h" #include "trap_common.h"

View File

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

View File

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

View File

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

View File

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

View File

@ -143,13 +143,13 @@ Modification:
.balign 0x800 .balign 0x800
alltraps: alltraps:
// Current EL with sp0 // Current EL with sp0
b . b badtrap
.balign 0x80 .balign 0x80
b . b badtrap
.balign 0x80 .balign 0x80
b . b badtrap
.balign 0x80 .balign 0x80
b . b badtrap
// Current EL with spx // Current EL with spx
.balign 0x80 .balign 0x80
@ -157,9 +157,9 @@ alltraps:
.balign 0x80 .balign 0x80
b el1irq b el1irq
.balign 0x80 .balign 0x80
b . b badtrap
.balign 0x80 .balign 0x80
b . b badtrap
// Lower EL using aarch64 // Lower EL using aarch64
.balign 0x80 .balign 0x80
@ -167,32 +167,34 @@ alltraps:
.balign 0x80 .balign 0x80
b el0irq b el0irq
.balign 0x80 .balign 0x80
b . b badtrap
.balign 0x80 .balign 0x80
b . b badtrap
// Lower EL using aarch32 // Lower EL using aarch32
.balign 0x80 .balign 0x80
b . b badtrap
.balign 0x80 .balign 0x80
b . b badtrap
.balign 0x80 .balign 0x80
b . b badtrap
.balign 0x80 .balign 0x80
b . b badtrap
badtrap:
savereg
mov x0, sp
bl kernel_intr_handler
b .
el1sync: el1sync:
msr daifset, #0xf
savereg savereg
mov x0, sp mov x0, sp
bl kernel_abort_handler bl kernel_abort_handler
b . b .
el1irq: el1irq:
msr daifset, #0xf
usavereg usavereg
mov x0, sp mov x0, sp
bl intr_irq_dispatch bl intr_irq_dispatch
@ -201,9 +203,7 @@ el1irq:
eret eret
el0sync: el0sync:
msr daifset, #0xf
usavereg usavereg
mov x0, sp mov x0, sp
bl syscall_arch_handler bl syscall_arch_handler
@ -212,9 +212,7 @@ el0sync:
eret eret
el0irq: el0irq:
msr daifset, #0xf
usavereg usavereg
mov x0, sp mov x0, sp
bl intr_irq_dispatch 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_lock(struct spinlock* lock, uint32_t timeout);
extern void _spinlock_unlock(struct spinlock* lock); extern int _spinlock_unlock(struct spinlock* lock);
__attribute__((optimize("O0"))) void spinlock_lock(struct spinlock* lock) __attribute__((optimize("O0"))) void spinlock_lock(struct spinlock* lock)
{ {
@ -88,7 +88,9 @@ __attribute__((optimize("O0"))) void spinlock_unlock(struct spinlock* lock)
_double_list_del(p_lock_node->prev, p_lock_node->next); _double_list_del(p_lock_node->prev, p_lock_node->next);
_spinlock_unlock(&request_lock); _spinlock_unlock(&request_lock);
_spinlock_unlock(lock); if (_spinlock_unlock(lock) != 0) {
ERROR("Core %d trying to unlock a lock belongs to %d.\n", cur_cpuid(), lock->owner_cpu);
}
} }
__attribute__((optimize("O0"))) bool spinlock_try_lock(struct spinlock* lock) __attribute__((optimize("O0"))) bool spinlock_try_lock(struct spinlock* lock)

View File

@ -1,4 +1,4 @@
ifneq ($(findstring $(BOARD), ok1028a-c), ) ifneq ($(findstring $(BOARD), 3568), )
SRC_DIR := armv8-a SRC_DIR := armv8-a
endif endif
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), ) 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() static void build_boot_pgdir()
{ {
// dev mem // dev mem
uint32_t dev_mem_end_idx = (DEV_PHYMEM_BASE + DEV_MEM_SZ) >> LEVEL3_PDE_SHIFT; uint32_t dev_mem_end_idx = (DEV_PHYMEM_BASE + DEV_MEM_SIZE) >> LEVEL3_PDE_SHIFT;
for (uint32_t i = DEV_PHYMEM_BASE >> LEVEL3_PDE_SHIFT; i < dev_mem_end_idx; i++) { 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[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; 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,7 +67,7 @@ Modification:
/* Deivce memory layout */ /* Deivce memory layout */
#define DEV_PHYMEM_BASE (0x00000000) #define DEV_PHYMEM_BASE (0x00000000)
#define DEV_VRTMEM_BASE (0x80000000) #define DEV_VRTMEM_BASE (0x80000000)
#define DEV_MEM_SZ (0x10000000) #define DEV_MEM_SIZE (0x10000000)
/* Kernel memory layout */ /* Kernel memory layout */
#define KERN_MEM_BASE (0x90000000) // First kernel virtual address #define KERN_MEM_BASE (0x90000000) // First kernel virtual address

View File

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

View File

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

View File

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

View File

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

View File

@ -61,35 +61,36 @@ void GetPdeAttr(uintptr_t* attr);
/* /*
Enable MMU, cache, write buffer, etc. Enable MMU, cache, write buffer, etc.
*/ */
#define SCTLR_R(val) __asm__ volatile("mrs %0, sctlr_el1" : "=r"(val)) #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)) #define SCTLR_W(val) __asm__ volatile("msr sctlr_el1, %0" ::"r"(val) : "memory")
/* /*
Read and write mmu pagetable register base addr Read and write mmu pagetable register base addr
*/ */
#define TTBR0_R(val) __asm__ volatile("mrs %0, ttbr0_el1" : "=r"(val)) #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)) #define TTBR0_W(val) __asm__ volatile("msr ttbr0_el1, %0" ::"r"(val) : "memory")
/* /*
Read and write mmu pagetable register base addr Read and write mmu pagetable register base addr
*/ */
#define TTBR1_R(val) __asm__ volatile("mrs %0, ttbr1_el1" : "=r"(val)) #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)) #define TTBR1_W(val) __asm__ volatile("msr ttbr1_el1, %0" ::"r"(val) : "memory")
/* /*
Translation Control RegisterTCR Translation Control RegisterTCR
*/ */
#define TCR_R(val) __asm__ volatile("mrs %0, tcr_el1" : "=r"(val)) #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)) #define TCR_W(val) __asm__ volatile("msr tcr_el1, %0" ::"r"(val) : "memory")
#define MAIR_R(val) __asm__ volatile("mrs %0, mair_el1" : "=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)) #define MAIR_W(val) __asm__ volatile("msr mair_el1, %0" ::"r"(val) : "memory")
/* /*
Flush TLB when loading a new page table. Flush TLB when loading a new page table.
@note If nG is not set in the pte attribute, process switching need flush tlb. @note If nG is not set in the pte attribute, process switching need flush tlb.
*/ */
#define CLEARTLB(val) __asm__ volatile("tlbi vmalle1") // #define CLEARTLB(val) __asm__ volatile("tlbi vmalle1" ::: "memory")
#define CLEARTLB(val) __asm__ volatile("tlbi vmalle1is" ::: "memory")
/* /*
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. 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,7 +45,9 @@ void load_pgdir(uintptr_t pgdir_paddr)
struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag); struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag);
TTBR0_W((uint64_t)pgdir_paddr); TTBR0_W((uint64_t)pgdir_paddr);
DSB();
CLEARTLB(0); CLEARTLB(0);
ISB();
p_icache_done->invalidateall(); p_icache_done->invalidateall();
p_dcache_done->flushall(); p_dcache_done->flushall();
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,198 @@
/*
* 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

@ -0,0 +1,103 @@
/*
* 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

@ -0,0 +1,45 @@
//
// 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,3 +0,0 @@
SRC_FILES := uart.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,128 +0,0 @@
//
// 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

@ -147,7 +147,7 @@ void* AchieveResource(TraceTag* tag)
bool CreateResourceTag(TraceTag* new_tag, TraceTag* owner, char* name, tracemeta_ac_type type, void* p_resource) bool CreateResourceTag(TraceTag* new_tag, TraceTag* owner, char* name, tracemeta_ac_type type, void* p_resource)
{ {
assert(new_tag != NULL && owner != NULL); assert(owner != NULL);
if (owner->meta == NULL) { if (owner->meta == NULL) {
ERROR("Tracer: Empty owner\n"); ERROR("Tracer: Empty owner\n");
return false; return false;
@ -168,7 +168,9 @@ bool CreateResourceTag(TraceTag* new_tag, TraceTag* owner, char* name, tracemeta
doubleListAddOnHead(&new_node->list_node, &owner->meta->children_guard); doubleListAddOnHead(&new_node->list_node, &owner->meta->children_guard);
new_node->parent = owner->meta; new_node->parent = owner->meta;
new_tag->meta = new_node; if (new_tag != NULL) {
new_tag->meta = new_node;
}
return true; return true;
} }
@ -187,12 +189,42 @@ bool DeleteResource(TraceTag* target, TraceTag* owner)
if (target->meta->name != NULL) { if (target->meta->name != NULL) {
slab_free(&sys_tracer.node_name_allocator, target->meta->name); slab_free(&sys_tracer.node_name_allocator, target->meta->name);
} }
// delete all children // delete all children
/// @attention currently donot allow multilevel resource deletion
if (target->meta->type == TRACER_OWNER) { if (target->meta->type == TRACER_OWNER) {
assert(IS_DOUBLE_LIST_EMPTY(&target->meta->children_guard)); while (!IS_DOUBLE_LIST_EMPTY(&target->meta->children_guard)) {
TraceTag tmp_node = {
.meta = DOUBLE_LIST_ENTRY(target->meta->children_guard.next, TracerNode, list_node),
};
DeleteResource(&tmp_node, target);
}
} }
slab_free(&sys_tracer.node_allocator, target->meta); slab_free(&sys_tracer.node_allocator, target->meta);
target->meta = NULL; target->meta = NULL;
return true; return true;
}
void debug_list_tracetree_inner(TracerNode* cur_node)
{
DEBUG("[%s] ", cur_node->name);
TracerNode* tmp = NULL;
DOUBLE_LIST_FOR_EACH_ENTRY(tmp, &cur_node->children_guard, list_node)
{
if (tmp->name != NULL) {
DEBUG("%s ", tmp->name);
} else {
DEBUG("ANON ");
}
}
DEBUG("\n");
DOUBLE_LIST_FOR_EACH_ENTRY(tmp, &cur_node->children_guard, list_node)
{
debug_list_tracetree_inner(tmp);
}
}
void debug_list_tracetree()
{
TracerNode* ref_root = RequireRootTag()->meta;
debug_list_tracetree_inner(ref_root);
} }

View File

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

View File

@ -10,10 +10,10 @@ cflags = -std=c11 -O2 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -
board_specs = stub.o board_specs = stub.o
#cflags = -Wall -g -std=c11 #cflags = -Wall -g -std=c11
endif endif
ifeq ($(BOARD), ok1028a-c) ifeq ($(BOARD), 3568)
toolchain ?= aarch64-none-elf- toolchain ?= aarch64-none-elf-
user_ldflags = -N -Ttext 0 user_ldflags = -N -Ttext 0
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 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
board_specs = stub.o board_specs = stub.o
endif endif
@ -43,9 +43,9 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \
-I$(KERNEL_ROOT)/services/app -I$(KERNEL_ROOT)/services/app
ifeq ($(BOARD), imx6q-sabrelite) ifeq ($(BOARD), imx6q-sabrelite)
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 test_net lwip readme.txt | bin 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
else else
all: init 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 | bin 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 | bin
endif endif
../tools/mkfs/mkfs ./fs.img $^ ../tools/mkfs/mkfs ./fs.img $^
@mv $(filter-out readme.txt, $^) bin @mv $(filter-out readme.txt, $^) bin
@ -97,10 +97,6 @@ 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} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${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 test_fault: test_fault.o libserial.o printf.o usyscall.o arch_usyscall.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm @${objdump} -S $@ > $@.asm

View File

@ -1,42 +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.
*/
// 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); shellInit(&shell, shellBuffer, 512);
while (connect_session(&session_fs, "MemFS", 8092) < 0) while (connect_session(&session_fs, "MemFS", 0x10000) < 0)
; ;
if (!session_fs.buf) { if (!session_fs.buf) {
printf("session connect faield\n"); printf("session connect faield\n");

View File

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

View File

@ -30,8 +30,7 @@ int IPC_DO_SERVE_FUNC(Ipc_hello_string)(char* buf, int* len)
return 0; 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_INTERFACE(Ipc_hello_string, 2);
IPC_SERVER_REGISTER_INTERFACES(IpcSimpleServer, 2, Ipc_hello_string, Ipc_add); IPC_SERVER_REGISTER_INTERFACES(IpcSimpleServer, 2, Ipc_hello_string, Ipc_add);

View File

@ -8,10 +8,10 @@ toolchain ?= arm-xilinx-eabi-
user_ldflags = -N -Ttext 0 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 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 endif
ifeq ($(BOARD), ok1028a-c) ifeq ($(BOARD), 3568)
toolchain ?= aarch64-none-elf- toolchain ?= aarch64-none-elf-
user_ldflags = -N -Ttext 0 user_ldflags = -N -Ttext 0
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 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
endif endif
cc = ${toolchain}gcc cc = ${toolchain}gcc

View File

@ -0,0 +1,250 @@
/*
* 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 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 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 endif
ifeq ($(BOARD), ok1028a-c) ifeq ($(BOARD), 3568)
toolchain ?= aarch64-none-elf- toolchain ?= aarch64-none-elf-
user_ldflags = -N -Ttext 0 user_ldflags = -N -Ttext 0
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 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
endif endif
cc = ${toolchain}gcc cc = ${toolchain}gcc

View File

@ -1,113 +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 "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);
}

View File

@ -9,10 +9,10 @@ user_ldflags = --start-group,-lgcc,-lc,--end-group
cflags = -std=c11 -march=armv7-a -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 cflags = -std=c11 -march=armv7-a -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
#cflags = -Wall -g -std=c11 #cflags = -Wall -g -std=c11
endif endif
ifeq ($(BOARD), ok1028a-c) ifeq ($(BOARD), 3568)
toolchain ?= aarch64-none-elf- toolchain ?= aarch64-none-elf-
user_ldflags = -N -Ttext 0 user_ldflags = -N -Ttext 0
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 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
endif endif
cc = ${toolchain}gcc cc = ${toolchain}gcc

View File

@ -19,6 +19,13 @@ cflags = -g -std=c11 -mtune=cortex-a72 -nostdlib -nodefaultlibs -fno-pic -stati
board_specs = stub.o board_specs = stub.o
endif endif
ifeq ($(BOARD), 3568)
toolchain ?= aarch64-none-elf-
user_ldflags = -N -Ttext 0
cflags = -Wall -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
board_specs = $(KERNEL_ROOT)/services/app/stub.o
endif
cc = ${toolchain}gcc cc = ${toolchain}gcc
ld = ${toolchain}g++ ld = ${toolchain}g++
objdump = ${toolchain}objdump objdump = ${toolchain}objdump
@ -28,7 +35,7 @@ c_useropts = -O2
INC_DIR = -I$(KERNEL_ROOT)/services/app \ INC_DIR = -I$(KERNEL_ROOT)/services/app \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/lib/serial \ -I$(KERNEL_ROOT)/services/lib/serial \
-I$(KERNEL_ROOT)/services/drivers/rk-3568/include \ -I$(KERNEL_ROOT)/services/drivers/3568/include \
-I$(KERNEL_ROOT)/services/lib/usyscall \ -I$(KERNEL_ROOT)/services/lib/usyscall \
-I$(KERNEL_ROOT)/services/lib/ipc \ -I$(KERNEL_ROOT)/services/lib/ipc \
-I$(KERNEL_ROOT)/services/lib/memory -I$(KERNEL_ROOT)/services/lib/memory

View File

@ -122,12 +122,10 @@ __attribute__((always_inline)) static inline HAL_Status TimerDelayUs(uint32_t us
from = HAL_TIMER_GetCount(SYS_TIMER); from = HAL_TIMER_GetCount(SYS_TIMER);
count = PLL_INPUT_OSC_RATE / 1000000 * us; count = PLL_INPUT_OSC_RATE / 1000000 * us;
do { do {
now = HAL_TIMER_GetCount(SYS_TIMER); now = HAL_TIMER_GetCount(SYS_TIMER);
pass = now > from ? now - from : from - now; pass = now > from ? now - from : from - now;
} while (pass < count); } while (pass < count);
return HAL_OK; return HAL_OK;
} }
#endif #endif
@ -314,13 +312,13 @@ __attribute__((weak)) HAL_Status HAL_DelayMs(uint32_t ms)
*/ */
HAL_Status HAL_DelayUs(uint32_t us) HAL_Status HAL_DelayUs(uint32_t us)
{ {
#if defined(SYS_TIMER) && defined(HAL_TIMER_MODULE_ENABLED) // #if defined(SYS_TIMER) && defined(HAL_TIMER_MODULE_ENABLED)
return TimerDelayUs(us); // return TimerDelayUs(us);
#else // #else
return HAL_CPUDelayUs(us); return HAL_CPUDelayUs(us);
#endif // #endif
} }
/** /**

View File

@ -956,268 +956,6 @@ HAL_Status HAL_CRU_SetPllPowerDown(struct PLL_SETUP *pSetup)
} }
#endif #endif
#ifdef CRU_CLK_USE_CON_BANK
static const struct HAL_CRU_DEV *CRU_GetInfo(void)
{
return &g_cruDev;
}
HAL_Check HAL_CRU_ClkIsEnabled(uint32_t clk)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
uint32_t shift = CLK_GATE_GET_BITS_SHIFT(clk);
uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
uint32_t reg;
HAL_Check ret;
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].gateOffset + index * 4;
ret = (HAL_Check)(!((CRU_READ(reg) & (1 << shift)) >> shift));
return ret;
}
HAL_Status HAL_CRU_ClkEnable(uint32_t clk)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
uint32_t shift = CLK_GATE_GET_BITS_SHIFT(clk);
uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
uint32_t reg;
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].gateOffset + index * 4;
CRU_WRITE(reg, shift, 1U << shift, 0U);
return HAL_OK;
}
HAL_Status HAL_CRU_ClkDisable(uint32_t clk)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
uint32_t shift = CLK_GATE_GET_BITS_SHIFT(clk);
uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
uint32_t reg;
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].gateOffset + index * 4;
CRU_WRITE(reg, shift, 1U << shift, 1U);
return HAL_OK;
}
HAL_Status HAL_CRU_ClkDisableUnused(uint32_t bank, uint32_t index, uint32_t val)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t reg;
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].gateOffset + index * 4;
CRU_WRITE(reg, 0, 0, val);
return HAL_OK;
}
HAL_Check HAL_CRU_ClkIsReset(uint32_t clk)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
uint32_t shift = CLK_GATE_GET_BITS_SHIFT(clk);
uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
uint32_t reg;
HAL_Check ret;
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
ret = (HAL_Check)((CRU_READ(reg) & (1 << shift)) >> shift);
return ret;
}
HAL_Status HAL_CRU_ClkResetAssert(uint32_t clk)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t index = CLK_RESET_GET_REG_OFFSET(clk);
uint32_t shift = CLK_RESET_GET_BITS_SHIFT(clk);
uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
uint32_t reg;
HAL_ASSERT(shift < 16);
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
CRU_WRITE(reg, shift, 1U << shift, 1U);
return HAL_OK;
}
HAL_Status HAL_CRU_ClkResetDeassert(uint32_t clk)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t index = CLK_RESET_GET_REG_OFFSET(clk);
uint32_t shift = CLK_RESET_GET_BITS_SHIFT(clk);
uint32_t bank = CLK_GATE_GET_REG_BANK(clk);
uint32_t reg;
HAL_ASSERT(shift < 16);
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
CRU_WRITE(reg, shift, 1U << shift, 0U);
return HAL_OK;
}
HAL_Status HAL_CRU_ClkResetSyncAssert(int numClks, uint32_t *clks)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t index = CLK_RESET_GET_REG_OFFSET(clks[0]);
uint32_t bank = CLK_GATE_GET_REG_BANK(clks[0]);
uint32_t val = 0;
uint32_t reg;
int i;
for (i = 0; i < numClks; i++) {
val |= HAL_BIT(CLK_RESET_GET_BITS_SHIFT(clks[i]));
if (index != CLK_RESET_GET_REG_OFFSET(clks[i])) {
return HAL_ERROR;
}
}
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
CRU_WRITE(reg, 0, val, val);
HAL_DBG("%s: index: 0x%lx, val: 0x%lx\n", __func__, index, val);
return HAL_OK;
}
HAL_Status HAL_CRU_ClkResetSyncDeassert(int numClks, uint32_t *clks)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t index = CLK_RESET_GET_REG_OFFSET(clks[0]);
uint32_t bank = CLK_GATE_GET_REG_BANK(clks[0]);
uint32_t val = 0;
uint32_t reg;
int i;
for (i = 0; i < numClks; i++) {
val |= HAL_BIT(CLK_RESET_GET_BITS_SHIFT(clks[i]));
if (index != CLK_RESET_GET_REG_OFFSET(clks[i])) {
return HAL_ERROR;
}
}
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].softOffset + index * 4;
CRU_WRITE(reg, 0, val, 0);
HAL_DBG("%s: index: 0x%lx, val: 0x%lx\n", __func__, index, val);
return HAL_OK;
}
HAL_Status HAL_CRU_ClkSetDiv(uint32_t divName, uint32_t divValue)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t shift, mask, index;
uint32_t reg, bank;
index = CLK_DIV_GET_REG_OFFSET(divName);
shift = CLK_DIV_GET_BITS_SHIFT(divName);
HAL_ASSERT(shift < 16);
mask = CLK_DIV_GET_MASK(divName);
if (divValue > mask) {
divValue = mask;
}
bank = CLK_DIV_GET_BANK(divName);
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
CRU_WRITE(reg, shift, mask, (divValue - 1U));
return HAL_OK;
}
uint32_t HAL_CRU_ClkGetDiv(uint32_t divName)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t shift, mask, index, divValue;
uint32_t reg, bank;
index = CLK_DIV_GET_REG_OFFSET(divName);
shift = CLK_DIV_GET_BITS_SHIFT(divName);
HAL_ASSERT(shift < 16);
mask = CLK_DIV_GET_MASK(divName);
bank = CLK_DIV_GET_BANK(divName);
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
divValue = ((CRU_READ(reg) & mask) >> shift) + 1;
return divValue;
}
HAL_SECTION_SRAM_CODE
HAL_Status HAL_CRU_ClkSetMux(uint32_t muxName, uint32_t muxValue)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t shift, mask, index;
uint32_t reg, bank;
index = CLK_MUX_GET_REG_OFFSET(muxName);
shift = CLK_MUX_GET_BITS_SHIFT(muxName);
HAL_ASSERT(shift < 16);
mask = CLK_MUX_GET_MASK(muxName);
bank = CLK_MUX_GET_BANK(muxName);
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
CRU_WRITE(reg, shift, mask, muxValue);
return HAL_OK;
}
HAL_SECTION_SRAM_CODE
uint32_t HAL_CRU_ClkGetMux(uint32_t muxName)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t shift, mask, index, muxValue;
uint32_t reg, bank;
index = CLK_MUX_GET_REG_OFFSET(muxName);
shift = CLK_MUX_GET_BITS_SHIFT(muxName);
HAL_ASSERT(shift < 16);
mask = CLK_MUX_GET_MASK(muxName);
bank = CLK_MUX_GET_BANK(muxName);
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
muxValue = ((CRU_READ(reg) & mask) >> shift);
return muxValue;
}
HAL_Status HAL_CRU_ClkSetFracDiv(uint32_t fracDivName,
uint32_t numerator,
uint32_t denominator)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t reg, bank;
uint32_t index;
index = CLK_DIV_GET_REG_OFFSET(fracDivName);
bank = CLK_DIV_GET_BANK(fracDivName);
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
CRU_WRITE(reg, 0, 0, ((numerator << 16) | denominator));
return HAL_OK;
}
HAL_Status HAL_CRU_ClkGetFracDiv(uint32_t fracDivName,
uint32_t *numerator,
uint32_t *denominator)
{
const struct HAL_CRU_DEV *ctrl = CRU_GetInfo();
uint32_t reg, bank;
uint32_t index;
uint32_t val;
index = CLK_DIV_GET_REG_OFFSET(fracDivName);
bank = CLK_DIV_GET_BANK(fracDivName);
reg = ctrl->banks[bank].cruBase + ctrl->banks[bank].selOffset + index * 4;
val = CRU_READ(reg);
*numerator = (val & 0xffff0000) >> 16;
*denominator = (val & 0x0000ffff);
return HAL_OK;
}
#else /* CRU_CLK_USE_CON_BANK */
HAL_Check HAL_CRU_ClkIsEnabled(uint32_t clk) HAL_Check HAL_CRU_ClkIsEnabled(uint32_t clk)
{ {
uint32_t index = CLK_GATE_GET_REG_OFFSET(clk); uint32_t index = CLK_GATE_GET_REG_OFFSET(clk);
@ -1575,7 +1313,7 @@ HAL_Status HAL_CRU_ClkGetFracDiv(uint32_t fracDivName,
return HAL_OK; return HAL_OK;
} }
#endif /* CRU_CLK_USE_CON_BANK */
HAL_Status HAL_CRU_FracdivGetConfig(uint32_t rateOut, uint32_t rate, HAL_Status HAL_CRU_FracdivGetConfig(uint32_t rateOut, uint32_t rate,
uint32_t *numerator, uint32_t *numerator,

View File

@ -284,7 +284,6 @@
#define GMAC_DESC3_LD (0x1 << 28) #define GMAC_DESC3_LD (0x1 << 28)
#define GMAC_DESC3_BUF1V (0x1 << 24) #define GMAC_DESC3_BUF1V (0x1 << 24)
#define DES3_ERROR_SUMMARY (1 << 15)
#define DES3_ERROR_SUMMARY (1 << 15) #define DES3_ERROR_SUMMARY (1 << 15)
/* Generic MII registers. */ /* Generic MII registers. */
@ -1515,19 +1514,24 @@ void HAL_GMAC_DisableDmaIRQ(struct GMAC_HANDLE *pGMAC)
*/ */
HAL_Status HAL_GMAC_DMATxDescInit(struct GMAC_HANDLE *pGMAC, HAL_Status HAL_GMAC_DMATxDescInit(struct GMAC_HANDLE *pGMAC,
struct GMAC_Desc *txDescs, struct GMAC_Desc *txDescs,
uint8_t *txBuff, uint32_t count) struct GMAC_Desc *txDescs_dma,
uint8_t *txBuff, uint8_t *txBuff_dma, uint32_t count)
{ {
struct GMAC_Desc *desc; struct GMAC_Desc *desc;
uint32_t i = 0; uint32_t i = 0;
HAL_ASSERT(pGMAC != NULL); HAL_ASSERT(pGMAC != NULL);
HAL_ASSERT(txDescs != NULL); HAL_ASSERT(txDescs != NULL);
HAL_ASSERT(txDescs_dma != NULL);
HAL_ASSERT(txBuff != NULL); HAL_ASSERT(txBuff != NULL);
HAL_ASSERT(txBuff_dma != NULL);
pGMAC->txDescIdx = 0; pGMAC->txDescIdx = 0;
pGMAC->txDescs = txDescs; pGMAC->txDescs = txDescs;
pGMAC->txDescs_dma = txDescs_dma;
pGMAC->txBuf = txBuff; pGMAC->txBuf = txBuff;
pGMAC->txBuf_dma = txBuff_dma;
pGMAC->txSize = count; pGMAC->txSize = count;
/* Fill each DMATxDesc descriptor with the right values */ /* Fill each DMATxDesc descriptor with the right values */
@ -1557,19 +1561,24 @@ HAL_Status HAL_GMAC_DMATxDescInit(struct GMAC_HANDLE *pGMAC,
*/ */
HAL_Status HAL_GMAC_DMARxDescInit(struct GMAC_HANDLE *pGMAC, HAL_Status HAL_GMAC_DMARxDescInit(struct GMAC_HANDLE *pGMAC,
struct GMAC_Desc *rxDescs, struct GMAC_Desc *rxDescs,
uint8_t *rxBuff, uint32_t count) struct GMAC_Desc *rxDescs_dma,
uint8_t *rxBuff, uint8_t *rxBuff_dma, uint32_t count)
{ {
struct GMAC_Desc *desc; struct GMAC_Desc *desc;
uint32_t i = 0; uint32_t i = 0;
HAL_ASSERT(pGMAC != NULL); HAL_ASSERT(pGMAC != NULL);
HAL_ASSERT(rxDescs != NULL); HAL_ASSERT(rxDescs != NULL);
HAL_ASSERT(rxDescs_dma != NULL);
HAL_ASSERT(rxBuff != NULL); HAL_ASSERT(rxBuff != NULL);
HAL_ASSERT(rxBuff_dma != NULL);
pGMAC->rxDescIdx = 0; pGMAC->rxDescIdx = 0;
pGMAC->rxDescs = rxDescs; pGMAC->rxDescs = rxDescs;
pGMAC->rxDescs_dma = rxDescs_dma;
pGMAC->rxBuf = rxBuff; pGMAC->rxBuf = rxBuff;
pGMAC->rxBuf_dma = rxBuff_dma;
pGMAC->rxSize = count; pGMAC->rxSize = count;
/* Fill each DMARxDesc descriptor with the right values */ /* Fill each DMARxDesc descriptor with the right values */
@ -1577,7 +1586,7 @@ HAL_Status HAL_GMAC_DMARxDescInit(struct GMAC_HANDLE *pGMAC,
/* Get the pointer on the ith member of the Rx Desc list */ /* Get the pointer on the ith member of the Rx Desc list */
desc = rxDescs + i; desc = rxDescs + i;
desc->des0 = (uint64_t)(rxBuff + i * HAL_GMAC_MAX_PACKET_SIZE); desc->des0 = (uint32_t)(uint64_t)(rxBuff_dma + i * HAL_GMAC_MAX_PACKET_SIZE);
desc->des1 = 0; desc->des1 = 0;
desc->des2 = 0; desc->des2 = 0;
desc->des3 = GMAC_DESC3_OWN | GMAC_DESC3_BUF1V | GMAC_DESC3_IOC; desc->des3 = GMAC_DESC3_OWN | GMAC_DESC3_BUF1V | GMAC_DESC3_IOC;
@ -1771,7 +1780,7 @@ HAL_Status HAL_GMAC_Start(struct GMAC_HANDLE *pGMAC, uint8_t *addr)
/* DMA init */ /* DMA init */
WRITE_REG(pGMAC->pReg->DMA_SYSBUS_MODE, DMA_SYSBUS_MODE_BLEN16 | WRITE_REG(pGMAC->pReg->DMA_SYSBUS_MODE, DMA_SYSBUS_MODE_BLEN16 |
DMA_SYSBUS_MODE_BLEN8 | DMA_SYSBUS_MODE_BLEN4); DMA_SYSBUS_MODE_BLEN8 | DMA_SYSBUS_MODE_BLEN4 | 1 << 12 | 1 << 14);
/* Mask interrupts by writing to CSR7 */ /* Mask interrupts by writing to CSR7 */
WRITE_REG(pGMAC->pReg->DMA_CH0_INTERRUPT_ENABLE, DMA_CHAN_INTR_DEFAULT_MASK); WRITE_REG(pGMAC->pReg->DMA_CH0_INTERRUPT_ENABLE, DMA_CHAN_INTR_DEFAULT_MASK);
@ -1787,9 +1796,9 @@ HAL_Status HAL_GMAC_Start(struct GMAC_HANDLE *pGMAC, uint8_t *addr)
value |= (rxFifosz << DMA_CH0_RX_CONTROL_RBSZ_SHIFT) & DMA_CH0_RX_CONTROL_RBSZ_MASK; value |= (rxFifosz << DMA_CH0_RX_CONTROL_RBSZ_SHIFT) & DMA_CH0_RX_CONTROL_RBSZ_MASK;
value = value | (8 << DMA_CH0_RX_CONTROL_RXPBL_SHIFT); value = value | (8 << DMA_CH0_RX_CONTROL_RXPBL_SHIFT);
WRITE_REG(pGMAC->pReg->DMA_CH0_RX_CONTROL, value); WRITE_REG(pGMAC->pReg->DMA_CH0_RX_CONTROL, value);
WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_LIST_ADDRESS, (uint64_t)pGMAC->rxDescs); WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_LIST_ADDRESS, (uint32_t)(uint64_t)pGMAC->rxDescs_dma);
WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_TAIL_POINTER, WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_TAIL_POINTER,
(uint64_t)(pGMAC->rxDescs + pGMAC->rxSize)); (uint32_t)(uint64_t)(pGMAC->rxDescs_dma + pGMAC->rxSize));
/* init tx chan */ /* init tx chan */
value = READ_REG(pGMAC->pReg->DMA_CH0_TX_CONTROL); value = READ_REG(pGMAC->pReg->DMA_CH0_TX_CONTROL);
@ -1797,8 +1806,8 @@ HAL_Status HAL_GMAC_Start(struct GMAC_HANDLE *pGMAC, uint8_t *addr)
value |= DMA_CH0_TX_CONTROL_OSF; value |= DMA_CH0_TX_CONTROL_OSF;
WRITE_REG(pGMAC->pReg->DMA_CH0_TX_CONTROL, value); WRITE_REG(pGMAC->pReg->DMA_CH0_TX_CONTROL, value);
WRITE_REG(pGMAC->pReg->DMA_CH0_TXDESC_LIST_ADDRESS, (uint64_t)pGMAC->txDescs); WRITE_REG(pGMAC->pReg->DMA_CH0_TXDESC_LIST_ADDRESS, (uint32_t)(uint64_t)pGMAC->txDescs_dma);
WRITE_REG(pGMAC->pReg->DMA_CH0_TXDESC_TAIL_POINTER, (uint64_t)pGMAC->txDescs); WRITE_REG(pGMAC->pReg->DMA_CH0_TXDESC_TAIL_POINTER, (uint32_t)(uint64_t)pGMAC->txDescs_dma);
HAL_GMAC_WriteHWAddr(pGMAC, addr); HAL_GMAC_WriteHWAddr(pGMAC, addr);
@ -1935,6 +1944,12 @@ uint8_t *HAL_GMAC_GetTXBuffer(struct GMAC_HANDLE *pGMAC)
return pGMAC->txBuf + pGMAC->txDescIdx * HAL_GMAC_MAX_PACKET_SIZE; return pGMAC->txBuf + pGMAC->txDescIdx * HAL_GMAC_MAX_PACKET_SIZE;
} }
uint8_t *HAL_GMAC_GetTXBufferDMA(struct GMAC_HANDLE *pGMAC)
{
HAL_ASSERT(pGMAC != NULL);
return pGMAC->txBuf_dma + pGMAC->txDescIdx * HAL_GMAC_MAX_PACKET_SIZE;
}
/** /**
* @brief Get current RX buffer. * @brief Get current RX buffer.
* @param pGMAC: pointer to a GMAC_HANDLE structure that contains * @param pGMAC: pointer to a GMAC_HANDLE structure that contains
@ -1949,6 +1964,13 @@ uint8_t *HAL_GMAC_GetRXBuffer(struct GMAC_HANDLE *pGMAC)
return pGMAC->rxBuf + pGMAC->rxDescIdx * HAL_GMAC_MAX_PACKET_SIZE; return pGMAC->rxBuf + pGMAC->rxDescIdx * HAL_GMAC_MAX_PACKET_SIZE;
} }
uint8_t *HAL_GMAC_GetRXBufferDMA(struct GMAC_HANDLE *pGMAC)
{
HAL_ASSERT(pGMAC != NULL);
return pGMAC->rxBuf_dma + pGMAC->rxDescIdx * HAL_GMAC_MAX_PACKET_SIZE;
}
/** /**
* @brief Send a packet with the length, clean packet' dcached memory before send. * @brief Send a packet with the length, clean packet' dcached memory before send.
* @param pGMAC: pointer to a GMAC_HANDLE structure that contains * @param pGMAC: pointer to a GMAC_HANDLE structure that contains
@ -1977,8 +1999,8 @@ HAL_Status HAL_GMAC_Send(struct GMAC_HANDLE *pGMAC, void *packet,
pGMAC->txDescIdx++; pGMAC->txDescIdx++;
pGMAC->txDescIdx %= pGMAC->txSize; pGMAC->txDescIdx %= pGMAC->txSize;
desc->des0 = (uint64_t)packet; desc->des0 = (uint32_t)(uint64_t)packet;
desc->des1 = 0; desc->des1 = 0;
desc->des2 = length; desc->des2 = length;
/* /*
@ -1986,9 +2008,8 @@ HAL_Status HAL_GMAC_Send(struct GMAC_HANDLE *pGMAC, void *packet,
* writes to the rest of the descriptor too. * writes to the rest of the descriptor too.
*/ */
desc->des3 = GMAC_DESC3_OWN | GMAC_DESC3_FD | GMAC_DESC3_LD; desc->des3 = GMAC_DESC3_OWN | GMAC_DESC3_FD | GMAC_DESC3_LD;
WRITE_REG(pGMAC->pReg->DMA_CH0_TXDESC_TAIL_POINTER, WRITE_REG(pGMAC->pReg->DMA_CH0_TXDESC_TAIL_POINTER,
(uint64_t)(pGMAC->txDescs + pGMAC->txDescIdx)); (uint32_t)(uint64_t)(pGMAC->txDescs_dma + pGMAC->txDescIdx));
for (i = 0; i < 1000000; i++) { for (i = 0; i < 1000000; i++) {
if (!(desc->des3 & GMAC_DESC3_OWN)) { if (!(desc->des3 & GMAC_DESC3_OWN)) {
@ -2025,6 +2046,7 @@ uint8_t *HAL_GMAC_Recv(struct GMAC_HANDLE *pGMAC, int32_t *length)
*length = 0; *length = 0;
desc = pGMAC->rxDescs + pGMAC->rxDescIdx; desc = pGMAC->rxDescs + pGMAC->rxDescIdx;
HAL_DBG("Rx at %p\n", desc->des0);
des3 = desc->des3; des3 = desc->des3;
if (des3 & GMAC_DESC3_OWN) { if (des3 & GMAC_DESC3_OWN) {
HAL_DBG("%s: RX packet not available\n", __func__); HAL_DBG("%s: RX packet not available\n", __func__);
@ -2072,18 +2094,22 @@ uint8_t *HAL_GMAC_Recv(struct GMAC_HANDLE *pGMAC, int32_t *length)
void HAL_GMAC_CleanRX(struct GMAC_HANDLE *pGMAC) void HAL_GMAC_CleanRX(struct GMAC_HANDLE *pGMAC)
{ {
struct GMAC_Desc *desc; struct GMAC_Desc *desc;
struct GMAC_Desc *desc_dma;
HAL_ASSERT(pGMAC != NULL); HAL_ASSERT(pGMAC != NULL);
/* Get the pointer on the ith member of the Tx Desc list */ /* Get the pointer on the ith member of the Tx Desc list */
desc = pGMAC->rxDescs + pGMAC->rxDescIdx; desc = pGMAC->rxDescs + pGMAC->rxDescIdx;
desc->des0 = (uint64_t)(pGMAC->rxBuf + (pGMAC->rxDescIdx * desc->des0 = (uint32_t)(uint64_t)(pGMAC->rxBuf_dma + (pGMAC->rxDescIdx *
HAL_GMAC_MAX_PACKET_SIZE)); HAL_GMAC_MAX_PACKET_SIZE));
desc->des1 = 0; desc->des1 = 0;
desc->des2 = 0; desc->des2 = 0;
desc->des3 = GMAC_DESC3_OWN | GMAC_DESC3_BUF1V | GMAC_DESC3_IOC; desc->des3 = GMAC_DESC3_OWN | GMAC_DESC3_BUF1V | GMAC_DESC3_IOC;
WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_TAIL_POINTER, (uint64_t)desc); HAL_DBG("Clean buff %p\n", desc->des0);
desc_dma = pGMAC->rxDescs_dma + pGMAC->rxDescIdx;
HAL_DBG("Clean desc %p\n", desc_dma);
WRITE_REG(pGMAC->pReg->DMA_CH0_RXDESC_TAIL_POINTER, (uint32_t)(uint64_t)desc_dma);
pGMAC->rxDescIdx++; pGMAC->rxDescIdx++;
pGMAC->rxDescIdx %= pGMAC->rxSize; pGMAC->rxDescIdx %= pGMAC->rxSize;

View File

@ -6,7 +6,7 @@
#include "hal_bsp.h" #include "hal_bsp.h"
#include "hal_base.h" #include "hal_base.h"
#include "hal_gmac.h" #include "hal_gmac.h"
#include "usyscall.h"
#if (defined(HAL_GMAC_MODULE_ENABLED) || defined(HAL_GMAC1000_MODULE_ENABLED)) #if (defined(HAL_GMAC_MODULE_ENABLED) || defined(HAL_GMAC1000_MODULE_ENABLED))
/*************************** GMAC DRIVER ****************************/ /*************************** GMAC DRIVER ****************************/
@ -14,11 +14,6 @@
/***************************** MACRO Definition ******************************/ /***************************** MACRO Definition ******************************/
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
#define CONFIG_SYS_NONCACHED_MEMORY (4 << 20) /* 4M */
/* 1MB granularity */
#define MMU_SECTION_SIZE (1 << 20)
/***************************** Structure Definition **************************/ /***************************** Structure Definition **************************/
/***************************** Function Declare ******************************/ /***************************** Function Declare ******************************/
@ -51,7 +46,7 @@
#define BMCR_RESET 0x8000 /* Reset to default state */ #define BMCR_RESET 0x8000 /* Reset to default state */
#define BMCR_SPEED10 0x0000 /* Select 10Mbps */ #define BMCR_SPEED10 0x0000 /* Select 10Mbps */
#define GMAC_TEST_TIMES 1600 #define GMAC_TEST_TIMES 16
/********************* Private Structure Definition **************************/ /********************* Private Structure Definition **************************/
/* GMAC consumer config data. */ /* GMAC consumer config data. */
@ -74,33 +69,23 @@ struct GMAC_ETH_CONFIG {
int32_t rxDelay; int32_t rxDelay;
struct GMAC_Desc *txDescs; struct GMAC_Desc *txDescs;
struct GMAC_Desc *txDescs_dma;
struct GMAC_Desc *rxDescs; struct GMAC_Desc *rxDescs;
struct GMAC_Desc *rxDescs_dma;
uint8_t *txBuff; uint8_t *txBuff;
uint8_t *txBuff_dma;
uint8_t *rxBuff; uint8_t *rxBuff;
uint8_t *rxBuff_dma;
/* MAC address info, hw address */ /* MAC address info, hw address */
uint8_t macAddr[6]; uint8_t macAddr[6];
}; };
/********************* Private Variable Definition ***************************/ /********************* Private Variable Definition ***************************/
#ifdef NC_MEM_BASE
static const unsigned long os_no_cache_start = (unsigned long)NC_MEM_BASE;
#else
static const unsigned long os_no_cache_start = 0;
#endif
/*
* Reserve one MMU section worth of address space below the malloc() area that
* will be mapped uncached.
*/
static unsigned long noncached_start;
static unsigned long noncached_end;
static unsigned long noncached_next;
static unsigned int m_nocachemem_inited = 0; static uint8_t dstAddr[6] = { 0x00, 0x0C, 0x29, 0xf8, 0x7a, 0x6b };
static uint8_t dstAddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#if defined(HAL_GMAC_MODULE_ENABLED) && defined(SOC_RK3568) #if defined(HAL_GMAC_MODULE_ENABLED) && defined(SOC_RK3568)
static struct GMAC_ETH_CONFIG ethConfigTable[] = static struct GMAC_ETH_CONFIG ethConfigTable[] =
@ -113,31 +98,30 @@ static struct GMAC_ETH_CONFIG ethConfigTable[] =
.extClk = false, .extClk = false,
.resetGpioBank = GPIO2, .resetGpioBank = GPIO3,
.resetGpioNum = GPIO_PIN_D3, .resetGpioNum = GPIO_PIN_A4,
.resetDelayMs = { 0, 20, 100 }, .resetDelayMs = { 0, 20, 100 },
.txDelay = 0x3C, .txDelay = 0x2f,
.rxDelay = 0x2f, .rxDelay = 0x00,
}, },
#ifdef HAL_GMAC1
{
.halDev = &g_gmac1Dev,
.mode = PHY_INTERFACE_MODE_RGMII,
.maxSpeed = 1000,
.phyAddr = 1,
.extClk = false, // {
// .halDev = &g_gmac1Dev,
// .mode = PHY_INTERFACE_MODE_RGMII,
// .maxSpeed = 1000,
// .phyAddr = 1,
.resetGpioBank = GPIO2, // .extClk = false,
.resetGpioNum = GPIO_PIN_D1,
.resetDelayMs = { 0, 20, 100 },
.txDelay = 0x4f, // .resetGpioBank = GPIO4,
.rxDelay = 0x26, // .resetGpioNum = GPIO_PIN_B6,
}, // .resetDelayMs = { 0, 20, 100 },
#endif
// .txDelay = 0x4f,
// .rxDelay = 0x26,
// },
}; };
#endif #endif
@ -223,31 +207,6 @@ static void Dump_Regs(struct GMAC_HANDLE *pGMAC)
} }
} }
static void PHY_Read(struct GMAC_HANDLE *pGMAC, uint32_t phyReg)
{
int data;
data = HAL_GMAC_MDIORead(pGMAC, pGMAC->phyConfig.phyAddress, phyReg);
if (data >= 0) {
printf("PHY_Read: %02lX --> %08X\n", phyReg, data);
} else {
printf("PHY_Read: %02lX --> faild\n", phyReg);
}
}
static void PHY_Write(struct GMAC_HANDLE *pGMAC, uint32_t phyReg, uint32_t data)
{
// struct GMAC_HANDLE *pGMAC;
int status;
status = HAL_GMAC_MDIOWrite(pGMAC, pGMAC->phyConfig.phyAddress, phyReg, data);
if (!status) {
printf("PHY_Write: %02lX --> %08lX\n", phyReg, data);
} else {
printf("PHY_Write: %02lX --> faild\n", phyReg);
}
}
static void PHY_Dump(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE *pGMAC) static void PHY_Dump(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE *pGMAC)
{ {
int data, i; int data, i;
@ -277,14 +236,11 @@ static void GMAC_PHY_Reset(struct GMAC_ETH_CONFIG *config)
HAL_GPIO_SetPinLevel(config->resetGpioBank, HAL_GPIO_SetPinLevel(config->resetGpioBank,
config->resetGpioNum, config->resetGpioNum,
GPIO_HIGH); GPIO_HIGH);
HAL_DelayMs(config->resetDelayMs[0]); HAL_DelayMs(config->resetDelayMs[0]);
HAL_GPIO_SetPinLevel(config->resetGpioBank, HAL_GPIO_SetPinLevel(config->resetGpioBank,
config->resetGpioNum, config->resetGpioNum,
GPIO_LOW); GPIO_LOW);
HAL_DelayMs(config->resetDelayMs[1]); HAL_DelayMs(config->resetDelayMs[1]);
HAL_GPIO_SetPinLevel(config->resetGpioBank, HAL_GPIO_SetPinLevel(config->resetGpioBank,
config->resetGpioNum, config->resetGpioNum,
GPIO_HIGH); GPIO_HIGH);
@ -294,15 +250,12 @@ static void GMAC_PHY_Reset(struct GMAC_ETH_CONFIG *config)
static inline void NET_Random_ETHAddr(uint8_t *addr) static inline void NET_Random_ETHAddr(uint8_t *addr)
{ {
unsigned int seed = HAL_TIMER_GetCount(SYS_TIMER) | 0xffffffff; addr[0] = 0xe6;
uint8_t i; addr[1] = 0x47;
addr[2] = 0xcd;
for (i = 0; i < 6; i++) { addr[3] = 0x20;
addr[i] = rand(); addr[4] = 0xcf;
} addr[5] = 0xd9;
addr[0] &= 0xfe; /* clear multicast bit */
addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
} }
static inline void NET_Random_Package(uint8_t *addr, uint16_t len) static inline void NET_Random_Package(uint8_t *addr, uint16_t len)
@ -326,7 +279,7 @@ static void PHY_Update_Links(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE *pG
return; return;
} }
HAL_DelayMs(7000); HAL_DelayMs(10000);
status = HAL_GMAC_PHYUpdateLink(pGMAC); status = HAL_GMAC_PHYUpdateLink(pGMAC);
if (status == HAL_OK) { if (status == HAL_OK) {
@ -383,74 +336,42 @@ static HAL_Status GMAC_ETH_IRQ(struct GMAC_HANDLE *pGMAC)
/* rt_interrupt_leave(); */ /* rt_interrupt_leave(); */
} }
static HAL_Status noncached_init(void)
{
unsigned long start, end;
size_t size;
if (os_no_cache_start <= 0) { static void *malloc_align(size_t size, size_t align, uintptr_t va, uintptr_t *pa)
printf("Noncached_init failed, plase defined no cached memort\n");
return -1;
}
start = HAL_GMAC_ALIGN(os_no_cache_start, 64);
size = HAL_GMAC_ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE);
end = start + size;
noncached_start = start;
noncached_end = end;
noncached_next = start;
m_nocachemem_inited = 1;
return 0;
}
static unsigned long noncached_alloc(size_t size, size_t align)
{
if (!m_nocachemem_inited) {
if (noncached_init())
return (unsigned long)NULL;
}
unsigned long next = HAL_GMAC_ALIGN(noncached_next, align);
if (next >= noncached_end || (noncached_end - next) < size) {
return 0;
}
noncached_next = next + size;
return next;
}
static void *malloc_align(size_t size, size_t align)
{ {
void *align_ptr; void *align_ptr;
void *ptr; // void *ptr;
size_t align_size; size_t align_size;
/* align the alignment size to 4 byte */ /* align the alignment size to 4 byte */
align = ((align + 0x03) & ~0x03); align = ((align + 0x03) & ~0x03);
/* get total aligned size */ /* get total aligned size */
align_size = ((size + 0x03) & ~0x03) + align; align_size = ((size + 0x03) & ~0x03);
/* allocate memory block from heap */ /* allocate memory block from heap */
ptr = malloc(align_size); HAL_DBG("size: %d, align:%d\n",align_size, align);
if (ptr != NULL) { // ptr = malloc(align_size);
/* the allocated memory block is aligned */
if (((uint64_t)ptr & (align - 1)) == 0) {
align_ptr = (void *)((uint64_t)ptr + align);
} else {
align_ptr = (void *)(((uint64_t)ptr + (align - 1)) & ~(align - 1));
}
/* set the pointer before alignment pointer to the real pointer */ if (naive_mmap(&va, pa, align_size, true) < 0){
*((uint64_t *)((uint64_t)align_ptr - sizeof(void *))) = (uint64_t)ptr; HAL_DBG("Alloc failed\n");
ptr = align_ptr;
} }
// printf("%p,%p\n",(void *)va, *pa);
// void* ptr = (void *)va;
// if (ptr != 0) {
// /* the allocated memory block is aligned */
// if (((uint64_t)ptr & (align - 1)) == 0) {
// align_ptr = (void *)((uint64_t)ptr + align);
// } else {
// align_ptr = (void *)(((uint64_t)ptr + (align - 1)) & ~(align - 1));
// }
return ptr; // /* set the pointer before alignment pointer to the real pointer */
// *((uint64_t *)((uint64_t)align_ptr - sizeof(void *))) = (uint64_t)ptr;
// ptr = align_ptr;
// }
return (void *)va;
} }
static void free_align(void *ptr) static void free_align(void *ptr)
@ -459,6 +380,7 @@ static void free_align(void *ptr)
real_ptr = (void *)*(uint64_t *)((uint64_t)ptr - sizeof(void *)); real_ptr = (void *)*(uint64_t *)((uint64_t)ptr - sizeof(void *));
free(real_ptr); free(real_ptr);
} }
/********************* Public Function Definition ****************************/ /********************* Public Function Definition ****************************/
@ -470,6 +392,7 @@ static HAL_Status GMAC_Send_Test(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE
HAL_Status status; HAL_Status status;
if (!pGMAC->phyStatus.link) { if (!pGMAC->phyStatus.link) {
HAL_DBG("pGMAC->phyStatus.link: %d", pGMAC->phyStatus.link);
return -1; return -1;
} }
@ -479,6 +402,7 @@ static HAL_Status GMAC_Send_Test(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE
} }
ptr = (uint8_t *)HAL_GMAC_GetTXBuffer(pGMAC); ptr = (uint8_t *)HAL_GMAC_GetTXBuffer(pGMAC);
HAL_DBG("txPtr:%p\n", ptr);
memcpy(ptr, dstAddr, 6); memcpy(ptr, dstAddr, 6);
memcpy(ptr + 6, eth->macAddr, 6); memcpy(ptr + 6, eth->macAddr, 6);
ptr[12] = 0x40; ptr[12] = 0x40;
@ -493,14 +417,16 @@ static HAL_Status GMAC_Send_Test(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE
} }
/* dump packages */ /* dump packages */
Dump_Hex("Tx", ptr, len); // Dump_Hex("Tx", ptr, len);
// HAL_DCACHE_CleanByRange((uint64_t)ptr, len); // HAL_DCACHE_CleanByRange((uint64_t)ptr, len);
status = HAL_GMAC_Send(pGMAC, ptr, len); uint8_t * ptr_dma = (uint8_t *)HAL_GMAC_GetTXBufferDMA(pGMAC);
status = HAL_GMAC_Send(pGMAC, ptr_dma, len);
if (status) { if (status) {
printf("GMAC send failed: %d\n", status); printf("GMAC send failed: %d\n", status);
} }
print_desc(pGMAC);
return status; return status;
} }
@ -511,12 +437,14 @@ static uint16_t GMAC_Recv_Test(struct GMAC_HANDLE *pGMAC)
int32_t size; int32_t size;
if (!pGMAC->phyStatus.link) { if (!pGMAC->phyStatus.link) {
HAL_DBG("pGMAC->phyStatus.link: %d", pGMAC->phyStatus.link);
return -1; return -1;
} }
status = GMAC_ETH_IRQ(pGMAC); status = GMAC_ETH_IRQ(pGMAC);
ptr = HAL_GMAC_Recv(pGMAC, &size); ptr = HAL_GMAC_Recv(pGMAC, &size);
while (status && ptr) { while (status && ptr) {
print_desc(pGMAC);
if (size > 0 && ptr) { if (size > 0 && ptr) {
/* dump packages */ /* dump packages */
Dump_Hex("Rx", ptr, size); Dump_Hex("Rx", ptr, size);
@ -529,35 +457,59 @@ static uint16_t GMAC_Recv_Test(struct GMAC_HANDLE *pGMAC)
} }
ptr = HAL_GMAC_Recv(pGMAC, &size); ptr = HAL_GMAC_Recv(pGMAC, &size);
} }
return 0; return 0;
} }
static HAL_Status GMAC_Memory_Init(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE *pGMAC) static HAL_Status GMAC_Memory_Init(struct GMAC_ETH_CONFIG *eth, struct GMAC_HANDLE *pGMAC)
{ {
eth->rxDescs = (struct GMAC_Desc *)noncached_alloc(GMAC_DESC_RX_SIZE, ARCH_DMA_MINALIGN); uintptr_t rx_va = 0x1000000000, rx_pa = 0;
eth->txDescs = (struct GMAC_Desc *)noncached_alloc(GMAC_DESC_TX_SIZE, ARCH_DMA_MINALIGN); if (naive_mmap(&rx_va, &rx_pa, GMAC_DESC_RX_SIZE, true) < 0){
HAL_DBG("RX Desc alloc failed\n");
}
eth->rxDescs = (struct GMAC_Desc *)0x1000000000;
eth->rxDescs_dma = (struct GMAC_Desc *)rx_pa;
if (!eth->rxDescs || !eth->txDescs) uintptr_t tx_va = 0x1000400000, tx_pa = 0;
if (naive_mmap(&tx_va, &tx_pa, GMAC_DESC_TX_SIZE, true) < 0){
HAL_DBG("TX Desc alloc failed\n");
}
eth->txDescs = (struct GMAC_Desc *)0x1000400000;
eth->txDescs_dma = (struct GMAC_Desc *)tx_pa;
if (!eth->rxDescs || !eth->txDescs_dma ||
!eth->txDescs || !eth->txDescs_dma){
return -1; return -1;
}
HAL_DBG("rx:%p, %p\n",eth->rxDescs, eth->rxDescs_dma);
HAL_DBG("tx:%p, %p\n",eth->txDescs, eth->txDescs_dma);
eth->rxBuff = malloc_align(GMAC_RX_BUFFER_SIZE, ARCH_DMA_MINALIGN); uintptr_t rxbuf_va = 0x1000800000, rxbuf_pa = 0;
eth->txBuff = malloc_align(GMAC_TX_BUFFER_SIZE, ARCH_DMA_MINALIGN); uintptr_t txbuf_va = 0x1000C00000, txbuf_pa = 0;
eth->rxBuff = malloc_align(GMAC_RX_BUFFER_SIZE, ARCH_DMA_MINALIGN, rxbuf_va, &rxbuf_pa);
if (!eth->rxBuff || !eth->txBuff) eth->rxBuff = (void *)0x1000800000;
eth->rxBuff_dma = (void *)rxbuf_pa;
eth->txBuff = malloc_align(GMAC_TX_BUFFER_SIZE, ARCH_DMA_MINALIGN, txbuf_va, &txbuf_pa);
eth->txBuff = (void *)0x1000C00000;
eth->txBuff_dma = (void *)txbuf_pa;
if (!eth->rxBuff || !eth->txBuff ||
!eth->rxBuff_dma || !eth->txBuff_dma){
return -1; return -1;
}
HAL_DBG("rx_buff:%p,%p\n",eth->rxBuff, eth->rxBuff_dma);
HAL_DBG("tx_buff:%p,%p,\n",eth->txBuff, eth->txBuff_dma);
HAL_DBG("GMAC_DESC_RX_SIZE:%d\n", GMAC_DESC_RX_SIZE);
HAL_DBG("GMAC_RX_BUFFER_SIZE:%d\n", GMAC_RX_BUFFER_SIZE);
memset(eth->rxDescs, 0, GMAC_DESC_RX_SIZE); memset(eth->rxDescs, 0, GMAC_DESC_RX_SIZE);
memset(eth->txDescs, 0, GMAC_DESC_TX_SIZE); memset(eth->txDescs, 0, GMAC_DESC_TX_SIZE);
memset(eth->rxBuff, 0, GMAC_RX_BUFFER_SIZE); memset(eth->rxBuff, 0, GMAC_RX_BUFFER_SIZE);
// HAL_DCACHE_InvalidateByRange((uint64_t)eth->rxBuff, GMAC_RX_BUFFER_SIZE); // HAL_DCACHE_InvalidateByRange((uint64_t)eth->rxBuff, GMAC_RX_BUFFER_SIZE);
memset(eth->txBuff, 0, GMAC_TX_BUFFER_SIZE); memset(eth->txBuff, 0, GMAC_TX_BUFFER_SIZE);
// HAL_DCACHE_CleanByRange((uint64_t)eth->txBuff, GMAC_TX_BUFFER_SIZE); // HAL_DCACHE_CleanByRange((uint64_t)eth->txBuff, GMAC_TX_BUFFER_SIZE);
HAL_GMAC_DMARxDescInit(pGMAC, eth->rxDescs, eth->rxBuff, GMAC_DESCRIPTORS_RX); HAL_GMAC_DMARxDescInit(pGMAC, eth->rxDescs, eth->rxDescs_dma, eth->rxBuff, eth->rxBuff_dma, GMAC_DESCRIPTORS_RX);
HAL_GMAC_DMATxDescInit(pGMAC, eth->txDescs, eth->txBuff, GMAC_DESCRIPTORS_TX); HAL_GMAC_DMATxDescInit(pGMAC, eth->txDescs, eth->txDescs_dma, eth->txBuff, eth->txBuff_dma, GMAC_DESCRIPTORS_TX);
print_desc(pGMAC); print_desc(pGMAC);
@ -619,7 +571,6 @@ static HAL_Status GMAC_Init(uint8_t id)
} }
/*************************** GMAC TEST ****************************/ /*************************** GMAC TEST ****************************/
#define GMAC_MAX_DEVICES 2
#ifdef SOC_RK3568 #ifdef SOC_RK3568
/** /**
@ -631,8 +582,8 @@ static void GMAC0_Iomux_Config(void)
HAL_PINCTRL_SetIOMUX(GPIO_BANK2, HAL_PINCTRL_SetIOMUX(GPIO_BANK2,
GPIO_PIN_B6, /* gmac0_rxd0 */ GPIO_PIN_B6, /* gmac0_rxd0 */
PIN_CONFIG_MUX_FUNC1); PIN_CONFIG_MUX_FUNC1);
HAL_PINCTRL_SetIOMUX(GPIO_BANK2, HAL_PINCTRL_SetIOMUX(GPIO_BANK2,
GPIO_PIN_C0 | ///* eth0_refclko25m */
GPIO_PIN_C3 | /* gmac0_mdc */ GPIO_PIN_C3 | /* gmac0_mdc */
GPIO_PIN_C4 | /* gmac0_mdio */ GPIO_PIN_C4 | /* gmac0_mdio */
GPIO_PIN_C0 | /* gmac0_rxdvcrs */ GPIO_PIN_C0 | /* gmac0_rxdvcrs */
@ -643,7 +594,6 @@ static void GMAC0_Iomux_Config(void)
GPIO_PIN_A7 | /* gmac0_txd3 */ GPIO_PIN_A7 | /* gmac0_txd3 */
GPIO_PIN_A5, /* gmac0_rxclk */ GPIO_PIN_A5, /* gmac0_rxclk */
PIN_CONFIG_MUX_FUNC2); PIN_CONFIG_MUX_FUNC2);
HAL_PINCTRL_SetIOMUX(GPIO_BANK2, HAL_PINCTRL_SetIOMUX(GPIO_BANK2,
GPIO_PIN_B3 | /* gmac0_txd0 */ GPIO_PIN_B3 | /* gmac0_txd0 */
GPIO_PIN_B4 | /* gmac0_txd1 */ GPIO_PIN_B4 | /* gmac0_txd1 */
@ -658,16 +608,6 @@ static void GMAC0_Iomux_Config(void)
GPIO_PIN_B0, GPIO_PIN_B0,
PIN_CONFIG_MUX_FUNC2 | PIN_CONFIG_DRV_LEVEL1); PIN_CONFIG_MUX_FUNC2 | PIN_CONFIG_DRV_LEVEL1);
#if 0
/* io-domian: 1.8v or 3.3v for vccio4 */
WRITE_REG_MASK_WE(GRF->IO_VSEL0,
GRF_IO_VSEL0_POC_VCCIO4_SEL18_MASK,
(1 << GRF_IO_VSEL0_POC_VCCIO4_SEL18_SHIFT));
WRITE_REG_MASK_WE(GRF->IO_VSEL1,
GRF_IO_VSEL1_POC_VCCIO4_SEL33_MASK,
(0 << GRF_IO_VSEL1_POC_VCCIO4_SEL33_SHIFT));
#endif
} }
#endif #endif
@ -682,75 +622,131 @@ static void GMAC_Iomux_Config(uint8_t id)
} }
/*************************** GMAC TEST MAIN ****************************/ /*************************** GMAC TEST MAIN ****************************/
#include "usyscall.h"
// IPC_SERVER_INTERFACE(Ipc_intr, 1);
// IPC_SERVER_REGISTER_INTERFACES(IpIntrHandler, 1, Ipc_intr);
int main() { int main() {
struct GMAC_ETH_CONFIG *eth; struct GMAC_ETH_CONFIG *eth;
struct GMAC_HANDLE *pGMAC; struct GMAC_HANDLE *pGMAC;
int32_t bus, num = 0, i; int32_t bus, num = 0, i;
HAL_DBG("\n"); HAL_DBG("GMAC Test:\n");
HAL_DBG("%s\n", __func__);
HAL_DBG(" GMAC Test:\n");
num = sizeof(ethConfigTable) / sizeof(struct GMAC_ETH_CONFIG); num = sizeof(ethConfigTable) / sizeof(struct GMAC_ETH_CONFIG);
HAL_DBG(" GMAC Num: %ld\n", num); HAL_DBG("GMAC Num: %ld\n", num);
for (bus = 0; bus < num; bus++) { for (bus = 0; bus < num; bus++) {
eth = &ethConfigTable[bus]; eth = &ethConfigTable[bus];
HAL_DBG("new pGmac\n");
if (eth) { if (eth) {
pGMAC = &eth->instance; pGMAC = &eth->instance;
} else { } else {
return -1; return -1;
} }
HAL_DBG("map GMAC0\n");
if (!mmap(0x2000000000ULL+ GMAC0_BASE, GMAC0_BASE, 0x10000, true)) {
printf("eth_hal: mmap GMAC0(%8x) failed\n", GMAC0);
exit(1);
}
HAL_DBG("map GPIO2\n");
if (!mmap(0x2000000000ULL + GPIO2_BASE, GPIO2_BASE, 0x10000, true)) {
printf("eth_hal: mmap GPIO2(%8x) failed\n", GPIO2);
exit(1);
}
HAL_DBG("map GPIO3\n");
if (!mmap(0x2000000000ULL + GPIO3_BASE, GPIO3_BASE, 0x10000, true)) {
printf("eth_hal: mmap GPIO2(%8x) failed\n", GPIO2);
exit(1);
}
if (!mmap(0x2000000000ULL + GRF_BASE, GRF_BASE, 0x50000, true)) {
printf("eth_hal: mmap GRF(%8x) failed\n", GRF);
exit(1);
}
if (!mmap(0x2000000000ULL + CRU_BASE, CRU_BASE, 0x10000, true)) {
printf("eth_hal: mmap GRF(%8x) failed\n", GRF);
exit(1);
}
if (!mmap(0x2000000000ULL + TIMER5_BASE, CRU_BASE, 32, true)) {
printf("eth_hal: mmap GRF(%8x) failed\n", GRF);
exit(1);
}
if (!mmap(0x2000000000ULL + PMUCRU_BASE, PMUCRU_BASE, 0x10000, true)) {
printf("eth_hal: mmap GRF(%8x) failed\n", GRF);
exit(1);
}
HAL_DBG("config iomux\n");
/* ionmux */ /* ionmux */
GMAC_Iomux_Config(bus); GMAC_Iomux_Config(bus);
HAL_DBG("config cru\n");
HAL_CRU_ClkEnable(eth->halDev->pclkGateID); HAL_CRU_ClkEnable(eth->halDev->pclkGateID);
HAL_CRU_ClkEnable(eth->halDev->clkGateID); HAL_CRU_ClkEnable(eth->halDev->clkGateID);
/* Register irq */ /* Register irq */
// register_irq(eth->halDev->irqNum, );
/* PHY reset */ /* PHY reset */
HAL_DBG("reset phy\n");
GMAC_PHY_Reset(eth); GMAC_PHY_Reset(eth);
/* GMAC Init */ /* GMAC Init */
HAL_DBG("init gmac\n");
GMAC_Init(bus); GMAC_Init(bus);
HAL_DBG("init memory\n");
GMAC_Memory_Init(eth, pGMAC); GMAC_Memory_Init(eth, pGMAC);
/* Enable GMAC and DMA transmission and reception */ /* Enable GMAC and DMA transmission and reception */
HAL_DBG("start gmac\n");
HAL_GMAC_Start(pGMAC, eth->macAddr); HAL_GMAC_Start(pGMAC, eth->macAddr);
// print_desc(pGMAC);
/* Update links information */ /* Update links information */
HAL_DBG("phy update link\n");
PHY_Update_Links(eth, pGMAC, bus); PHY_Update_Links(eth, pGMAC, bus);
// print_desc(pGMAC);
/* Dump MAC Regs */ /* Dump MAC Regs */
Dump_Regs(pGMAC); Dump_Regs(pGMAC);
/* Dump PHY Regs */ /* Dump PHY Regs */
PHY_Dump(eth, pGMAC); // PHY_Dump(eth, pGMAC);
HAL_DBG("Init Down\n");
for (i = 0; i < GMAC_TEST_TIMES; i++) { for (i = 0; i < GMAC_TEST_TIMES; i++) {
HAL_DBG("TEST Send %d\n", i);
/* GMAC Send 64 bytes */ /* GMAC Send 64 bytes */
GMAC_Send_Test(eth, pGMAC, 64); // GMAC_Send_Test(eth, pGMAC, 64);
/* GMAC Send 1500 bytes */ /* GMAC Send 1500 bytes */
GMAC_Send_Test(eth, pGMAC, 1500); GMAC_Send_Test(eth, pGMAC, 1500);
HAL_DelayMs(1000); HAL_DelayMs(1000);
HAL_DBG("TEST Recv %d\n", i);
/* GMAC Recv */ /* GMAC Recv */
GMAC_Recv_Test(pGMAC); GMAC_Recv_Test(pGMAC);
} }
Dump_Regs(pGMAC);
HAL_CRU_ClkDisable(eth->halDev->pclkGateID); HAL_CRU_ClkDisable(eth->halDev->pclkGateID);
HAL_CRU_ClkDisable(eth->halDev->clkGateID); HAL_CRU_ClkDisable(eth->halDev->clkGateID);
free_align(eth->txBuff); // free_align(eth->txBuff);
free_align(eth->rxBuff); // free_align(eth->rxBuff);
HAL_DBG("done\n");
} }
exit(0);
return 0; return 0;
} }
// typedef void (*isr_handler_t)(int vector, void *param);
// typedef void (*NVIC_IRQHandler)(void);
// isr_handler_t interrupt_install(int vector,
// isr_handler_t handler,
// void *param,
// const char *name)
// {
// HAL_NVIC_SetIRQHandler(vector, (NVIC_IRQHandler)handler);
// return handler;
// }

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