forked from ROMEO/fsw-ws
Compare commits
78
Commits
philipp/docker
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c111ec176c | ||
|
|
081c3a7472 | ||
|
|
4643cce673 | ||
|
|
1f52efecda | ||
|
|
46d8803ab7 | ||
|
|
de2c3dfede | ||
|
|
bcacc493d3 | ||
|
|
a1a5f7c417 | ||
|
|
e2280b138f | ||
|
|
e31b632bc8 | ||
|
|
f3e17fc7a1 | ||
|
|
0d69a52626 | ||
|
|
4769da31b7 | ||
|
|
b5ab8a601f | ||
|
|
825c0d1911 | ||
|
|
f3aa72b1cb | ||
|
|
3379b39105 | ||
|
|
c7062407e0 | ||
|
|
c5d2c65a2e | ||
|
|
84fa8721c2 | ||
|
|
cead8ba50b | ||
|
|
a5267b11bf | ||
|
|
f8dbe305d6 | ||
|
|
f9aacd4c91 | ||
|
|
3af76b93b2 | ||
|
|
556faaba08 | ||
|
|
bb5fbf19cf | ||
|
|
243fd19827 | ||
|
|
20ca676e63 | ||
|
|
1049c40f9d | ||
|
|
6c937fa8b0 | ||
|
|
a5713ac7b8 | ||
|
|
57ecba297b | ||
|
|
e3b7fb48f1 | ||
|
|
6b1fd91a70 | ||
|
|
10b98c3835 | ||
|
|
e0242e515d | ||
|
|
164b8ed6c2 | ||
|
|
7e0d346962 | ||
|
|
35b951597a | ||
|
|
b341a0f7bf | ||
|
|
d3af5e1519 | ||
|
|
242b8e4958 | ||
|
|
6ff33beecc | ||
|
|
fd2c5a544f | ||
|
|
65299e46c4 | ||
|
|
fb4b12c8f9 | ||
|
|
dd9c39af30 | ||
|
|
791428e6c0 | ||
|
|
944e45cad2 | ||
|
|
8fa5cddc23 | ||
|
|
44ffb09ee9 | ||
|
|
5ad8853fef | ||
|
|
8e7424bb2f | ||
|
|
ee06c79bf4 | ||
|
|
8497fe754c | ||
|
|
ae47ca8291 | ||
|
|
497e380860 | ||
|
|
6c556b8fbf | ||
|
|
2d8d8aeb0a | ||
|
|
910553df45 | ||
|
|
fe5629fa85 | ||
|
|
926ef26000 | ||
|
|
cbe8184fab | ||
|
|
49c19ba675 | ||
|
|
02a7d525be | ||
|
|
716fdd7fa0 | ||
|
|
976e079d02 | ||
|
|
c3ae428da7 | ||
|
|
f2b3319973 | ||
|
|
5707c9f8ae | ||
|
|
a7336c7f75 | ||
|
|
c9a81c025f | ||
|
|
5c9df20ed1 | ||
|
|
af95ae60b1 | ||
|
|
6eec534116 | ||
|
|
2aec6c3931 | ||
|
|
8f4782728f |
@@ -0,0 +1,30 @@
|
||||
name: ROMEO CI Builder
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
Build Code:
|
||||
runs-on: romeo-builder
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.ROMEO_NUMALFIX_TOKEN }}
|
||||
submodules: 'recursive'
|
||||
- name: Configure z7
|
||||
run: |
|
||||
mkdir build_z7
|
||||
cd build_z7
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../bsp_z7/cmake/arm-none-eabi.toolchain ..
|
||||
- name: Build z7
|
||||
run: |
|
||||
cd build_z7
|
||||
make -j8
|
||||
- name: Configure linux
|
||||
run: |
|
||||
mkdir build_linux
|
||||
cd build_linux
|
||||
cmake ..
|
||||
- name: Build linux
|
||||
run: |
|
||||
cd build_linux
|
||||
make -j8
|
||||
+2
-1
@@ -4,4 +4,5 @@
|
||||
.vscode
|
||||
__pycache__/*
|
||||
**/__pycache__/*
|
||||
*.elf
|
||||
*.elf
|
||||
.cache
|
||||
|
||||
+5
-2
@@ -1,6 +1,9 @@
|
||||
[submodule "FreeRTOS-Kernel"]
|
||||
path = FreeRTOS-Kernel
|
||||
path = contrib/FreeRTOS-Kernel
|
||||
url = https://github.com/FreeRTOS/FreeRTOS-Kernel
|
||||
[submodule "contrib/lwip"]
|
||||
path = contrib/lwip
|
||||
url = https://git.savannah.gnu.org/git/lwip.git
|
||||
url = ../lwip
|
||||
[submodule "fsbl-compiled"]
|
||||
path = fsbl-compiled
|
||||
url = ../fsbl-compiled
|
||||
|
||||
+41
-15
@@ -1,17 +1,15 @@
|
||||
|
||||
## Requirements:
|
||||
|
||||
### Known Issues
|
||||
Ubuntu 22.04 has some version issues with the compile toolchain, consider using a newer version or other distribution or docker. Or solve the issue and add it here.
|
||||
|
||||
### Steps
|
||||
Install
|
||||
1. `cmake`
|
||||
2. `arm-none-eabi-gcc arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-gdb arm-none-eabi-newlib`
|
||||
3. `doxygen`
|
||||
4. `graphviz`
|
||||
5. `rustup` || Install using your packet manager or alternatively use the rust install script: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
|
||||
|
||||
|
||||
5. `rustup` || Install using your packet manager or alternatively use the rust install script: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh` (confirm default toolchain | nightly | complete | modify path variable: yes)
|
||||
|
||||
6. At last: Satisfy Rust requirements
|
||||
|
||||
@@ -26,10 +24,15 @@ cargo build -Z build-std
|
||||
|
||||
## Build the FSBL
|
||||
|
||||
FSBL is the First Stage Boot Loader and prepares the CPU and FPGA configuration for booting up the Second Stage Bootloader and finally the flight software.
|
||||
FSBL is the First Stage Boot Loader and prepares the CPU and FPGA configuration for booting up the Second Stage Bootloader and finally the flight software.
|
||||
|
||||
Before building, the correct `ps7_init.[c;h]` and some other configuration files need to be copied into the misc folder of the FSBL. The FSBL will run without this step, but some interfaces might not work as expected.
|
||||
|
||||
These files are specific to the actual hardware used and located in the `bsp_z7/ps7_init` folder. The following examples assume the zedboard.
|
||||
|
||||
```sh
|
||||
cd lib/sw_apps/zynq_fsbl/src
|
||||
cp romeo-obsw/bsp_z7/ps7_init/zedboard/* ../misc/zed/
|
||||
make BOARD=zed SHELL=/bin/bash
|
||||
```
|
||||
|
||||
@@ -49,26 +52,49 @@ cp embeddedsw/lib/sw_apps/zynq_fsbl/src/fsbl.elf .
|
||||
|
||||
##### Clone the submodules (FreeRTOS and lwIP):
|
||||
```sh
|
||||
git submodule init
|
||||
git submodule update
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
##### To build the obsw, run the following command
|
||||
|
||||
Once:
|
||||
Configure and generate using cmake:
|
||||
```sh
|
||||
mkdir -p build
|
||||
cd build
|
||||
mkdir build_z7
|
||||
cd build_z7
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../bsp_z7/cmake/arm-none-eabi.toolchain ..
|
||||
```
|
||||
|
||||
After adding a new .c file:
|
||||
Compile (`-j` count your discretion):
|
||||
```sh
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../bsp_z7/cmake/arm-none-eabi.toolchain ..
|
||||
make -j 8
|
||||
```
|
||||
|
||||
Every time
|
||||
The romeo-obsw binary can now be found in the `build_z7` directory. The next step to deploy it is here: [DEBUG_ON_ZEDBOARD.md](./DEBUG_ON_ZEDBOARD.md).
|
||||
|
||||
## Linux
|
||||
|
||||
The obsw can also be compiled and run on linux using the `gcc-posix` port of FreeRTOS.
|
||||
|
||||
### build
|
||||
|
||||
Configure and generate using cmake:
|
||||
```sh
|
||||
make -j 8"
|
||||
mkdir build_linux
|
||||
cd build_linux
|
||||
cmake ..
|
||||
```
|
||||
|
||||
The romeo-obsw binary can now be found in the `build` directory. The next step to deploy it is here: [DEBUG_ON_ZEDBOARD.md](./DEBUG_ON_ZEDBOARD.md).
|
||||
Compile (`-j` count your discretion):
|
||||
```sh
|
||||
make -j 8
|
||||
```
|
||||
|
||||
### run
|
||||
|
||||
Run the binary:
|
||||
|
||||
```sh
|
||||
./romeo-obsw
|
||||
```
|
||||
|
||||
The linux binary is supposed to be run against a simulator listening on UDP Ports. Command line options configure this connection (`./romeo-obsw --help`). A lightweight test simulator is at https://egit.irs.uni-stuttgart.de/ROMEO/obsw_dev_sim.
|
||||
+38
-7
@@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
## Prerequisits for build with Docker
|
||||
##### Info
|
||||
## Prerequisites for building with Docker
|
||||
##### Please Note
|
||||
IRS wireguard VPN can cause network issues with docker.
|
||||
|
||||
##### Install Docker
|
||||
@@ -9,6 +9,11 @@ If you are using macOS or Windows, please use this tutorial:
|
||||
- https://www.docker.com/get-started/
|
||||
|
||||
On Linux simply use your package manager to install ```docker``` and prepare everything using these commands, to avoid permission denied errors:
|
||||
On Arch Linux this would look like
|
||||
```sh
|
||||
sudo apt-get install docker # Ubuntu
|
||||
sudo packman -Syy docker # Arch
|
||||
```
|
||||
|
||||
```sh
|
||||
sudo systemctl start docker
|
||||
@@ -16,9 +21,9 @@ sudo groupadd docker
|
||||
sudo usermod -aG docker $USER
|
||||
sudo reboot
|
||||
```
|
||||
Congratulations, you installed docker. Please proceed.
|
||||
|
||||
|
||||
## FSBL
|
||||
## First Stage Boot Loader (FSBL)
|
||||
|
||||
FSBL is the First Stage Boot Loader and prepares the CPU and FPGA configuration for booting up the Second Stage Bootloader and finally the flight software.
|
||||
|
||||
@@ -27,7 +32,7 @@ FSBL is the First Stage Boot Loader and prepares the CPU and FPGA configuration
|
||||
```sh
|
||||
cd docker/compile_fsbl/
|
||||
git clone https://github.com/Xilinx/embeddedsw/
|
||||
docker build -t compile_fsbl .
|
||||
docker build -t compile_fsbl . # Legacy builder is deprecated and will be removed in future release. TODO
|
||||
```
|
||||
|
||||
##### To build the FSBL, run the following command in the `docker/compile-fsbl` directory:
|
||||
@@ -35,14 +40,23 @@ docker build -t compile_fsbl .
|
||||
docker run -v ./embeddedsw:/fsbl compile_fsbl /bin/bash -c "cd lib/sw_apps/zynq_fsbl/src && make BOARD=zed SHELL=/bin/bash"
|
||||
```
|
||||
|
||||
## Requirements [TBC]:
|
||||
```sh
|
||||
sudo apt-get install cdoxygen graphviz make arm-none-eabi-gcc # Ubuntu
|
||||
sudo packman -Syy cmake adoxygen graphviz rm-none-eabi-gcc # Arch
|
||||
```
|
||||
1. `doxygen` - tool to generate documentation for C++, C, ...
|
||||
2. `graphviz` - graph visualisation
|
||||
3. `cmake` - cross-platform build system
|
||||
4. `arm-none-eabi-gcc` - precompiled GNU toolchain for certain ARM processors including GCC and GNU Debugger (GDB)
|
||||
|
||||
If you want, copy the fsbl.elf to the docker/compile_fsbl directory for easier access:
|
||||
If you want, copy the `fsbl.elf` to the `docker/compile_fsbl` directory for easier access:
|
||||
```sh
|
||||
cp embeddedsw/lib/sw_apps/zynq_fsbl/src/fsbl.elf .
|
||||
```
|
||||
|
||||
## Steps
|
||||
1. Configure doxygen:
|
||||
1. Configure `doxygen`:
|
||||
|
||||
## mission_rust
|
||||
|
||||
@@ -50,6 +64,23 @@ cp embeddedsw/lib/sw_apps/zynq_fsbl/src/fsbl.elf .
|
||||
```sh
|
||||
export DOT_PATH=/usr/local/bin
|
||||
```
|
||||
2. Satisfy Rust requirements
|
||||
```sh
|
||||
cd ../mission_rust
|
||||
cargo update
|
||||
rustup toolchain install nightly
|
||||
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||
rustup override set nightly
|
||||
cargo build -Z build-std
|
||||
cd docker/compile_mission/
|
||||
docker build -t compile_mission .
|
||||
```
|
||||
|
||||
3. Configure the ROMEO OBSW repository in `.../obsw/`
|
||||
##### To build the mission_rust, run the following command in the `docker/compile_mission` directory:
|
||||
```sh
|
||||
docker run -v $(pwd)/../../mission_rust:/mission_rust compile_mission /bin/bash -c "cargo build -Z build-std"
|
||||
```
|
||||
|
||||
|
||||
## obsw
|
||||
|
||||
+105
-86
@@ -1,113 +1,132 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
# Project Name
|
||||
project(romeo-obsw C CXX ASM)
|
||||
|
||||
|
||||
# ##############################################################################
|
||||
# Pre-Sources preparation
|
||||
# ##############################################################################
|
||||
|
||||
|
||||
|
||||
# Specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
# Set names and variables
|
||||
set(TARGET_NAME ${CMAKE_PROJECT_NAME})
|
||||
project(romeo-obsw C ASM)
|
||||
|
||||
# Set path names
|
||||
set(FreeRTOS_PATH FreeRTOS-Kernel/)
|
||||
set(MISSION_PATH mission/)
|
||||
set(FreeRTOS_CONFIG_PATH bsp_z7/freeRTOS)
|
||||
set(BSP_PATH bsp_z7)
|
||||
set(OBSW_NAME romeo-obsw)
|
||||
set(FreeRTOS_PATH contrib/FreeRTOS-Kernel/)
|
||||
|
||||
set (LWIP_DIR contrib/lwip)
|
||||
# Compiler Options
|
||||
set(ROMEO_Z7_COMPILE_OPTIONS -c -fmessage-length=0 -g -O0 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -ffunction-sections -fdata-sections)
|
||||
set(ROMEO_LINUX_COMPILE_OPTIONS -c -fmessage-length=0 -g -O0 -ffunction-sections -fdata-sections)
|
||||
set(ROMEO_Z7_LINK_OPTIONS -Wl,--cref -Wl,-Map=${OBSW_NAME}.map -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -T${CMAKE_SOURCE_DIR}/bsp_z7/freeRTOS/lscript.ld -specs=${CMAKE_SOURCE_DIR}/bsp_z7/freeRTOS/Xilinx.spec )
|
||||
set(ROMEO_WARNING_FLAGS
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
-Werror) # TODO so far, this only affects mission code, not bsp
|
||||
|
||||
# CMake options which are only available when crosscompiling
|
||||
if (${CMAKE_CROSSCOMPILING})
|
||||
set(ZYNQ_UART UART1 CACHE STRING "Which PS UART to use for stdout")
|
||||
set_property(CACHE ZYNQ_UART PROPERTY STRINGS UART0 UART1)
|
||||
|
||||
# ##############################################################################
|
||||
# Configuration
|
||||
# ##############################################################################
|
||||
if(${ZYNQ_UART} STREQUAL UART0)
|
||||
add_compile_definitions(ZYNQ_USE_UART0)
|
||||
endif()
|
||||
|
||||
set(ZYNQ_UART UART1 CACHE STRING "Which PS UART to use for stdout")
|
||||
set_property(CACHE ZYNQ_UART PROPERTY STRINGS UART0 UART1)
|
||||
option(ARM_SEMIHOSTING "enable semihosting for emulation" OFF)
|
||||
|
||||
if(${ZYNQ_UART} STREQUAL UART0)
|
||||
add_compile_definitions(ZYNQ_USE_UART0)
|
||||
if(${ARM_SEMIHOSTING})
|
||||
add_compile_definitions(ARM_SEMIHOSTING)
|
||||
endif()
|
||||
else()
|
||||
unset(ZYNQ_UART)
|
||||
unset(ZYNQ_UART CACHE)
|
||||
unset(ARM_SEMIHOSTING)
|
||||
unset(ARM_SEMIHOSTING CACHE)
|
||||
endif()
|
||||
|
||||
# Add main executable
|
||||
add_executable(${OBSW_NAME})
|
||||
|
||||
# ##############################################################################
|
||||
# Executable and Sources
|
||||
# ##############################################################################
|
||||
# export lwip path, so the bsp can find it
|
||||
if(${CMAKE_CROSSCOMPILING})
|
||||
set (LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/lwip)
|
||||
endif()
|
||||
|
||||
# Add executable
|
||||
add_executable(${TARGET_NAME})
|
||||
# Platform dependend configuration
|
||||
# Includes setting the FreeRTOS port, compiler options and
|
||||
# selecting the bsp
|
||||
if(${CMAKE_CROSSCOMPILING})
|
||||
#TODO: this somewhat hardcodes zynq as the only cross target
|
||||
set(FREERTOS_PORT GCC_ARM_CA9 CACHE STRING "")
|
||||
set(FREERTOS_HEAP ${CMAKE_CURRENT_SOURCE_DIR}/bsp_z7/freeRTOS/no_heap.c CACHE STRING "")
|
||||
|
||||
# lwip
|
||||
set (LWIP_INCLUDE_DIRS
|
||||
"${LWIP_DIR}/src/include"
|
||||
"${BSP_PATH}/lwip"
|
||||
)
|
||||
include(${LWIP_DIR}/src/Filelists.cmake)
|
||||
set(lwip_SRCS
|
||||
${lwipcore_SRCS}
|
||||
${lwipcore4_SRCS}
|
||||
${lwipcore6_SRCS}
|
||||
${LWIP_DIR}/src/netif/slipif.c
|
||||
${LWIP_DIR}/src/apps/tftp/tftp.c
|
||||
)
|
||||
add_library(lwip ${lwip_SRCS})
|
||||
target_include_directories(lwip PUBLIC ${LWIP_INCLUDE_DIRS})
|
||||
# config library for FreeRTOS
|
||||
add_library(freertos_config INTERFACE)
|
||||
|
||||
#target_compile_options(${TARGET_NAME} PUBLIC -g -O0 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard)
|
||||
# The config file directory
|
||||
target_include_directories(freertos_config SYSTEM
|
||||
INTERFACE bsp_z7/freeRTOS)
|
||||
|
||||
# Add freeRTOS
|
||||
set(FREERTOS_PORT GCC_ARM_CA9 CACHE STRING "")
|
||||
set(FREERTOS_HEAP 1 CACHE STRING "")
|
||||
add_library(freertos_config INTERFACE)
|
||||
target_include_directories(freertos_config SYSTEM
|
||||
INTERFACE ${FreeRTOS_CONFIG_PATH}) # The config file directory
|
||||
target_compile_definitions(freertos_config
|
||||
INTERFACE
|
||||
projCOVERAGE_TEST=0)
|
||||
target_include_directories(
|
||||
freertos_config INTERFACE ${BSP_PATH}/ps7_cortexa9_0/include)
|
||||
# our compiler options, will trickle down through the project
|
||||
target_compile_options(freertos_config INTERFACE -c -fmessage-length=0 -g -O0 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -ffunction-sections -fdata-sections)
|
||||
# no coverage tests
|
||||
target_compile_definitions(freertos_config
|
||||
INTERFACE
|
||||
projCOVERAGE_TEST=0)
|
||||
|
||||
# FreeRTOS config depends on bsp headers
|
||||
target_include_directories(
|
||||
freertos_config INTERFACE bsp_z7/ps7_cortexa9_0/include)
|
||||
|
||||
# Compiler options, we set them on the FreeRTOS config, will trickle down from there
|
||||
target_compile_options(freertos_config INTERFACE ${ROMEO_Z7_COMPILE_OPTIONS})
|
||||
|
||||
# add the bsp
|
||||
add_subdirectory(bsp_z7)
|
||||
|
||||
# Link options for cross build
|
||||
target_link_options(${OBSW_NAME} PRIVATE ${ROMEO_Z7_LINK_OPTIONS})
|
||||
else()
|
||||
# So far, only unix port supported when not crosscompiling
|
||||
set(FREERTOS_PORT GCC_POSIX CACHE STRING "")
|
||||
|
||||
# config library for FreeRTOS
|
||||
add_library(freertos_config INTERFACE)
|
||||
|
||||
# The config file directory
|
||||
target_include_directories(freertos_config SYSTEM
|
||||
INTERFACE bsp_linux/freeRTOS)
|
||||
|
||||
# Compiler options, we set them on the FreeRTOS config, will trickle down from there
|
||||
target_compile_options(freertos_config INTERFACE ${ROMEO_LINUX_COMPILE_OPTIONS})
|
||||
|
||||
# No coverage tests, no tracing
|
||||
target_compile_definitions(freertos_config
|
||||
INTERFACE
|
||||
projCOVERAGE_TEST=0
|
||||
projENABLE_TRACING=0)
|
||||
|
||||
# add the bsp
|
||||
add_subdirectory(bsp_linux)
|
||||
endif()
|
||||
|
||||
# Add FreeRTOS
|
||||
add_subdirectory(${FreeRTOS_PATH})
|
||||
|
||||
add_subdirectory(bsp_z7)
|
||||
|
||||
|
||||
# Common stuff that is not mission code, mostly code shared between bsps
|
||||
add_subdirectory(common)
|
||||
|
||||
add_subdirectory(${MISSION_PATH})
|
||||
# Mission code, in our case C glue between rust and bsp
|
||||
add_subdirectory(mission)
|
||||
|
||||
# The actual mission code, in rust, exported as library `mission_rust`
|
||||
add_subdirectory(mission_rust)
|
||||
|
||||
# ##############################################################################
|
||||
# Post-Sources preparation
|
||||
# ##############################################################################
|
||||
|
||||
# Add libraries for all sources.
|
||||
target_link_libraries(lwip PUBLIC freertos_kernel)
|
||||
target_link_libraries(${TARGET_NAME} PUBLIC freertos_kernel mission_rust lwip)
|
||||
|
||||
target_include_directories(
|
||||
${TARGET_NAME} PUBLIC ${BSP_PATH})
|
||||
|
||||
|
||||
target_link_options(${TARGET_NAME} PRIVATE -Wl,--cref -Wl,-Map=${TARGET_NAME}.map -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -T${CMAKE_SOURCE_DIR}/${FreeRTOS_CONFIG_PATH}/lscript.ld -specs=${CMAKE_SOURCE_DIR}/${FreeRTOS_CONFIG_PATH}/Xilinx.spec )
|
||||
|
||||
# Removed unused sections.
|
||||
target_link_options(${TARGET_NAME} PRIVATE "-Wl,--gc-sections")
|
||||
|
||||
if(CMAKE_VERBOSE)
|
||||
message(STATUS "Warning flags: ${WARNING_FLAGS}")
|
||||
# We provide a firmware image for an interface board as part of the z7 build
|
||||
# This is a second executable, excluded from `all` builds
|
||||
if(${CMAKE_CROSSCOMPILING})
|
||||
add_subdirectory(sim_interface)
|
||||
endif()
|
||||
|
||||
# Compile options for all sources.
|
||||
target_compile_options(${TARGET_NAME} PRIVATE ${WARNING_FLAGS})
|
||||
# Link all libraries into the binary
|
||||
# bsp depends on FreeRTOS, so we do not need to link it again
|
||||
target_link_libraries(${OBSW_NAME} PUBLIC bsp mission_rust )
|
||||
|
||||
# Common link options
|
||||
target_link_options(${OBSW_NAME} PRIVATE "-Wl,--gc-sections")
|
||||
|
||||
|
||||
# Common compile options
|
||||
target_compile_options(${OBSW_NAME} PRIVATE ${ROMEO_WARNING_FLAGS})
|
||||
@@ -0,0 +1,42 @@
|
||||
# Qemu
|
||||
|
||||
qemu is an emulator which can be used to run code compiled for a different architecture (say ARMv7 as on zynq) on the host architecture (the PC you are using).
|
||||
|
||||
This is mainly useful for testing platform dependent code, in our case the operating system abstraction. This code can not be tested on linux, as the FreeRTOS port used is a different one.
|
||||
|
||||
By selecting the `ZYNQ_SEMIHOSTING` in cmake, the semihosting interface is enabled. This allows the software to signal an exit condition to qemu, which in turn makes qemu exit with the corresponding exit code. This functionality is used for unit testing, where the exit condition is needed to signal success or failure of the unit tests.
|
||||
|
||||
# Run on qemu
|
||||
|
||||
The full call to run the romeo-obsw on qemu is:
|
||||
|
||||
`qemu-system-arm -semihosting -nographic -monitor none -serial null -serial stdio -machine xilinx-zynq-a9 -m 500M -kernel romeo-obsw`
|
||||
|
||||
Where the arguments are the following:
|
||||
* `qemu-system-arm`: the qemu emulating arm processors
|
||||
* `-semihosting`: enables the emulated software to communicate with the host. This is only used to allow the software to exit including returning an exit code
|
||||
* `-nographic`: disable qemus graphical interface
|
||||
* `-monitor none`: disable qemu monitoring (not used)
|
||||
* `-serial null`: add first UART, do not connect it.
|
||||
* `-serial stdio`: add second UART, connect it to the console of the host
|
||||
* `-machine xilinx-zynq-a9`: select zynq as emulation target
|
||||
* `-m 500M`: set RAM size
|
||||
* `-device loader,addr=0x0000012c,data=0x00001234,data-len=4`: set data at the memory location `data`. This is used by the FSW to detect if it is runing on qemu or on a real zynq (where this memory location will not be 0x00001234)
|
||||
* `-kernel romeo-obsw`: which program to run
|
||||
|
||||
The first UART can be connected to a serial device on the host. Add `-chardev serial,id=serial0,path="/dev/ttyUSB0"` where `"/dev/ttyUSB0"` is the path to the serial device. Then, change the first invocation of `-serial` from `-serial null` to `-serial chardev:serial0`
|
||||
|
||||
|
||||
# Debug on qemu
|
||||
|
||||
Basically the same call as above, only `-kernel` is replaced by `-s -S`, which enables debugging and halts the CPU.
|
||||
|
||||
`qemu-system-arm -semihosting -nographic -monitor none -serial null -serial stdio -machine xilinx-zynq-a9 -m 500M -device loader,addr=0x0000012c,data=0x00001234,data-len=4 -s -S`
|
||||
|
||||
After qemu is started, connect to the gdb server:
|
||||
```sh
|
||||
arm-none-eabi-gdb romeo-obsw
|
||||
>target remote :1234
|
||||
>load
|
||||
>cont
|
||||
```
|
||||
+15
-2
@@ -13,15 +13,26 @@ TODO: what is which port, use distinct name/add a graphic
|
||||
```sh
|
||||
openocd -f board/digilent_zedboard.cfg
|
||||
```
|
||||
_Note: The board path is from the openocd tool, it is not a local path within this project._
|
||||
|
||||
If you have one around, load bitstream at startup (go get a coffee, takes time with onboard JTAG, blue LED lights up when done):
|
||||
```sh
|
||||
openocd -f board/digilent_zedboard.cfg -c "init" -c "pld load 0 system.bit"
|
||||
```
|
||||
|
||||
If multiple zedboards are connected, openocd takes parameters to select which zedboard to use, as well as to configure the gdb port and disable telnet and tcl:
|
||||
```sh
|
||||
openocd -f board/digilent_zedboard.cfg -c "adapter serial #####; gdb_port 3334; telnet_port disabled; tcl_port disabled"
|
||||
```
|
||||
|
||||
The adapter serial can be found by running `lsusb -vvv`, looking for the FTDI FT232H device with `iManufacturer: Digilent`. The serial is reported as `iSerial`.
|
||||
```sh
|
||||
lsusb -vvv | grep Digilent -A1 -B2
|
||||
```
|
||||
|
||||
3. To use JTAG Boot for the OBSW, you first need to run the FSBL once.
|
||||
|
||||
On build PC (adapt IP if different from debugging PC) in the folder where you build the FSBL as above:
|
||||
On build PC (adapt IP if different from debugging PC) in the folder where you build the FSBL / in the fsbl-compiled repository/submodule folder:
|
||||
```sh
|
||||
arm-none-eabi-gdb fsbl.elf
|
||||
>target extended-remote localhost:3333
|
||||
@@ -50,4 +61,6 @@ Again, `Command Line Interface (CLI) commands` can be moved to the GNU Debugger
|
||||
arm-none-eabi-gdb romeo-obsw -iex "target extended-remote localhost:3333" -ex "set pagination off" -ex "load" -ex "break done" -ex "cont" -ex="set confirm off" -ex "exit"
|
||||
```
|
||||
|
||||
UART USB port should output something at `115200baud`, (I use moserial to monitor).
|
||||
_Consider removing the `-ex "cont"` to start the software manually when you have et up your serial monitor.
|
||||
|
||||
UART USB port should output something at `115200baud`, (I use moserial to monitor). If using our project's `ps7_init.c` USB UART1 is configured to `230400baud`, UART0 to `1000000baud`.
|
||||
|
||||
@@ -15,7 +15,7 @@ The Onboard Software (OBSW) is written in Rust for run-time stability. The imple
|
||||
|
||||
|
||||
# First Stage Bootloader (FSBL)
|
||||
FSBL code is at https://github.com/Xilinx/embeddedsw/
|
||||
FSBL code is at https://github.com/Xilinx/embeddedsw/tree/xilinx_v2024.1/lib/sw_apps/zynq_fsbl
|
||||
|
||||
## Scope
|
||||
This is the central repository for the flight software of the ROMEO satellite.
|
||||
@@ -43,6 +43,22 @@ The current working steps are:
|
||||
Consider using Docker or setting up a local compile toolchain.
|
||||
Please refer to [BUILD_WITH_DOCKER.md](./BUILD_WITH_DOCKER.md) or [BUILD_WITH_CMAKE.md](./BUILD_WITH_CMAKE.md).
|
||||
|
||||
### Compiling Annotations
|
||||
Bare metal rust on the Zynq requires the use of C-libraries, which affects the compilation.
|
||||
The current setup includes `cmake` which calls `cargo`to compile the rust `mission` and `framework` creates as `static libraries`.
|
||||
Then, `gcc` is used to link those two libraries , the `Xilinx Board Support Packages (BSP)` (incl. all hardware drivers), and supplier libraries in the final binary.
|
||||
|
||||
The canocial compiler is debian bookkworm's `arm-none-eabi-gcc 12.2` using `newlib 3.3.0`.
|
||||
|
||||
The **minimum** set of **compiler** (not linker) **flags** (as used by Xilinx to build the First Stage Bootloader (FSBL)) are
|
||||
+ hardware (HW) type: `-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard`
|
||||
+ function and data sections, to be able to garbage-collect unused code: `-ffunction-sections -fdata-sections`
|
||||
+ optimization for release: `-O2`
|
||||
|
||||
Link Time Optimization (LTO) TBD
|
||||
<!--Currently LTO is not enabled, as it might break linkage with the static STR library, TBC with STR supplier.
|
||||
|
||||
... to be completed ... TODO PAUL-->
|
||||
## How to debug on hardware?
|
||||
|
||||
Please refer to [DEBUG_ON_ZEDBOARD.md](./DEBUG_ON_ZEDBOARD.md)
|
||||
@@ -0,0 +1,8 @@
|
||||
add_library(bsp STATIC)
|
||||
|
||||
add_subdirectory(hardware)
|
||||
|
||||
target_sources(bsp PRIVATE main.c)
|
||||
|
||||
# bsp depends on FreeRTOS
|
||||
target_link_libraries(bsp PUBLIC freertos_kernel)
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* FreeRTOS V202212.00
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
|
||||
* https://www.FreeRTOS.org/a00110.html
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) PTHREAD_STACK_MIN ) /* The stack size being passed is equal to the minimum stack size needed by pthread_create(). */
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 200 * 1024 * 1024 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 12 )
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 20
|
||||
#define configUSE_APPLICATION_TASK_TAG 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_ALTERNATIVE_API 0
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 1
|
||||
|
||||
/* The following 2 memory allocation schemes are possible for this demo:
|
||||
*
|
||||
* 1. Dynamic Only.
|
||||
* #define configSUPPORT_STATIC_ALLOCATION 0
|
||||
* #define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
*
|
||||
* 2. Static and Dynamic.
|
||||
* #define configSUPPORT_STATIC_ALLOCATION 1
|
||||
* #define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
*
|
||||
* Static only configuration is not possible for this demo as it utilizes
|
||||
* dynamic allocation.
|
||||
*/
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
|
||||
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||
|
||||
/* Software timer related configuration options. The maximum possible task
|
||||
* priority is configMAX_PRIORITIES - 1. The priority of the timer task is
|
||||
* deliberately set higher to ensure it is correctly capped back to
|
||||
* configMAX_PRIORITIES - 1. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||
#define configTIMER_QUEUE_LENGTH 20
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
|
||||
#define configMAX_PRIORITIES ( 10 )
|
||||
|
||||
/* Run time stats gathering configuration options. */
|
||||
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
|
||||
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
|
||||
/* Co-routine related configuration options. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* This demo can use of one or more example stats formatting functions. These
|
||||
* format the raw data provided by the uxTaskGetSystemState() function in to human
|
||||
* readable ASCII form. See the notes in the implementation of vTaskList() within
|
||||
* FreeRTOS/Source/tasks.c for limitations. */
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/* Enables the test whereby a stack larger than the total heap size is
|
||||
* requested. */
|
||||
#define configSTACK_DEPTH_TYPE uint32_t
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
* to exclude the API function. In most cases the linker will remove unused
|
||||
* functions anyway. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 0
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark2 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
#define INCLUDE_xTaskGetHandle 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
|
||||
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
|
||||
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
|
||||
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
|
||||
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
|
||||
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
|
||||
|
||||
extern void vAssertCalled( const char * const pcFileName,
|
||||
unsigned long ulLine );
|
||||
|
||||
|
||||
|
||||
/* projCOVERAGE_TEST should be defined on the command line so this file can be
|
||||
* used with multiple project configurations. If it is
|
||||
*/
|
||||
#ifndef projCOVERAGE_TEST
|
||||
#error projCOVERAGE_TEST should be defined to 1 or 0 on the command line.
|
||||
#endif
|
||||
|
||||
#ifndef projENABLE_TRACING
|
||||
#error projENABLE_TRACING should be defined to 1 or 0 on the command line.
|
||||
#endif
|
||||
|
||||
#if ( projCOVERAGE_TEST == 1 )
|
||||
|
||||
/* Insert NOPs in empty decision paths to ensure both true and false paths
|
||||
* are being tested. */
|
||||
#define mtCOVERAGE_TEST_MARKER() __asm volatile ( "NOP" )
|
||||
|
||||
/* Ensure the tick count overflows during the coverage test. */
|
||||
#define configINITIAL_TICK_COUNT 0xffffd800UL
|
||||
|
||||
/* Allows tests of trying to allocate more than the heap has free. */
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
|
||||
/* To test builds that remove the static qualifier for debug builds. */
|
||||
#define portREMOVE_STATIC_QUALIFIER
|
||||
#else /* if ( projCOVERAGE_TEST == 1 ) */
|
||||
|
||||
/* It is a good idea to define configASSERT() while developing. configASSERT()
|
||||
* uses the same semantics as the standard C assert() macro. Don't define
|
||||
* configASSERT() when performing code coverage tests though, as it is not
|
||||
* intended to asserts() to fail, some some code is intended not to run if no
|
||||
* errors are present. */
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
|
||||
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
|
||||
/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
|
||||
#if( projENABLE_TRACING == 1 )
|
||||
#include "trcRecorder.h"
|
||||
#endif /* if ( projENABLE_TRACING == 1 ) */
|
||||
#endif /* if ( projCOVERAGE_TEST == 1 ) */
|
||||
|
||||
/* networking definitions */
|
||||
#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||
|
||||
/* Prototype for the function used to print out. In this case it prints to the
|
||||
* console before the network is connected then a UDP port after the network has
|
||||
* connected. */
|
||||
extern void vLoggingPrintf( const char * pcFormatString,
|
||||
... );
|
||||
|
||||
/* Set to 1 to print out debug messages. If ipconfigHAS_DEBUG_PRINTF is set to
|
||||
* 1 then FreeRTOS_debug_printf should be defined to the function used to print
|
||||
* out the debugging messages. */
|
||||
#define ipconfigHAS_DEBUG_PRINTF 1
|
||||
#if ( ipconfigHAS_DEBUG_PRINTF == 1 )
|
||||
#define FreeRTOS_debug_printf( X ) vLoggingPrintf X
|
||||
#endif
|
||||
|
||||
/* Set to 1 to print out non debugging messages, for example the output of the
|
||||
* FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1
|
||||
* then FreeRTOS_printf should be set to the function used to print out the
|
||||
* messages. */
|
||||
#define ipconfigHAS_PRINTF 0
|
||||
#if ( ipconfigHAS_PRINTF == 1 )
|
||||
#define FreeRTOS_printf( X ) vLoggingPrintf X
|
||||
#endif
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
@@ -0,0 +1 @@
|
||||
target_sources(bsp PRIVATE hardware.c serial.c)
|
||||
@@ -0,0 +1,100 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <hardware/interfaces.h>
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
extern const char *sim_ip;
|
||||
extern int ai_family;
|
||||
|
||||
int compare_string_chars(const char *c_string, const char *chars,
|
||||
size_t chars_len) {
|
||||
for (int i = 0; i < chars_len; i++) {
|
||||
if (c_string[i] == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (c_string[i] != chars[i]) {
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *get_port_number(const char *path, size_t path_len) {
|
||||
if (compare_string_chars("uart0", path, path_len) == 1) {
|
||||
return "8100";
|
||||
}
|
||||
if (compare_string_chars("uart1", path, path_len) == 1) {
|
||||
return "8101";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int hw_device_open(const char *path, size_t path_len) {
|
||||
|
||||
int serial_fd = serial_open(path, path_len);
|
||||
|
||||
if (serial_fd >= -1) {
|
||||
return serial_fd;
|
||||
}
|
||||
|
||||
const char *port_number = get_port_number(path, path_len);
|
||||
if (port_number == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct addrinfo addrinfo_hint;
|
||||
addrinfo_hint.ai_flags = AI_ADDRCONFIG;
|
||||
addrinfo_hint.ai_family = ai_family;
|
||||
addrinfo_hint.ai_socktype = SOCK_DGRAM;
|
||||
addrinfo_hint.ai_protocol = 0;
|
||||
addrinfo_hint.ai_addrlen = 0;
|
||||
addrinfo_hint.ai_addr = NULL;
|
||||
addrinfo_hint.ai_canonname = NULL;
|
||||
addrinfo_hint.ai_next = NULL;
|
||||
|
||||
int sock;
|
||||
struct addrinfo *addr_candidates, *current_candidate;
|
||||
|
||||
int result =
|
||||
getaddrinfo(sim_ip, port_number, &addrinfo_hint, &addr_candidates);
|
||||
if (result != 0) {
|
||||
fprintf(stderr, "hw_device_open, reading sim address: %s\n",
|
||||
gai_strerror(result));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (current_candidate = addr_candidates; current_candidate != NULL;
|
||||
current_candidate = current_candidate->ai_next) {
|
||||
sock = socket(current_candidate->ai_family, current_candidate->ai_socktype | SOCK_NONBLOCK,
|
||||
current_candidate->ai_protocol);
|
||||
if (sock == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connect(sock, current_candidate->ai_addr,
|
||||
current_candidate->ai_addrlen) != -1) {
|
||||
break; /* Success */
|
||||
}
|
||||
|
||||
// Connect failed, close socket
|
||||
close(sock);
|
||||
}
|
||||
|
||||
if (current_candidate == NULL) { /* No address succeeded */
|
||||
fprintf(stderr, "hw_device_open, invalid sim address\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// TODO FIXME
|
||||
int compare_string_chars(const char *c_string, const char *chars,
|
||||
size_t chars_len);
|
||||
|
||||
int convert_errno(int errno_value) {
|
||||
// errno on linux will always be >0
|
||||
if (errno <= 0) {
|
||||
// something is very wrong
|
||||
return -1;
|
||||
} else {
|
||||
return -errno - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: can we extend errno safely?
|
||||
// returns fd if ok, -1 on error 0 if no match
|
||||
int serial_open_actual(const char *path, speed_t speed) {
|
||||
// open serial
|
||||
int fd = open(path, O_RDWR | O_NOCTTY | O_SYNC);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct termios termios;
|
||||
|
||||
// initialize termios struct
|
||||
int ret = tcgetattr(fd, &termios);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// configure for raw input
|
||||
cfmakeraw(&termios);
|
||||
|
||||
// make it non-blocking
|
||||
termios.c_cc[VMIN] = 0;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
|
||||
// set speed
|
||||
ret = cfsetspeed(&termios, speed);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = tcsetattr(fd, TCSANOW, &termios);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
// returns fd if success, -1 on error, -2 if no match
|
||||
int serial_open(const char *path, size_t path_len) {
|
||||
if (compare_string_chars("ps/uart_mtg", path, path_len) == 1) {
|
||||
return serial_open_actual("/dev/ttyUSB0", B921600);
|
||||
}
|
||||
if (compare_string_chars("debug/uart🚀", path, path_len) == 1) {
|
||||
return serial_open_actual("/dev/ttyUSB0", B115200);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// returns fd if success, -1 if no path match <-1 if error
|
||||
int serial_open(const char *path, size_t path_len);
|
||||
@@ -0,0 +1,66 @@
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char *sim_ip = "localhost";
|
||||
int ai_family = AF_UNSPEC;
|
||||
|
||||
void mission(void);
|
||||
|
||||
void done() { exit(0); }
|
||||
|
||||
void done_error() { exit(1); }
|
||||
|
||||
int test_socket();
|
||||
|
||||
// TODO link to GCC's personality or make the linux build not use it?
|
||||
void rust_eh_personality() { puts("eh_personality"); }
|
||||
|
||||
void print_usage(const char *name) {
|
||||
fprintf(stderr, "Usage: %s [-s sim_ip] [-4|6]\n", name);
|
||||
}
|
||||
|
||||
#include <hardware/interfaces.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
hw_device_open(
|
||||
"invalidpath",
|
||||
11); // TODO for some weird linker behaviour, if this function is not used
|
||||
// here, it will not be found by the linker when linking the rust lib
|
||||
static struct option long_options[] = {
|
||||
/* NAME ARGUMENT FLAG SHORTNAME */
|
||||
{"sim_ip", required_argument, NULL, 's'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{NULL, 0, NULL, 0}};
|
||||
int c;
|
||||
int option_index = 0;
|
||||
while ((c = getopt_long(argc, argv, "46hs:", long_options, &option_index)) !=
|
||||
-1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
if (optarg != NULL) {
|
||||
sim_ip = optarg;
|
||||
break;
|
||||
case '4':
|
||||
ai_family = AF_INET;
|
||||
break;
|
||||
case '6':
|
||||
ai_family = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mission();
|
||||
return 0;
|
||||
}
|
||||
+22
-1
@@ -1,2 +1,23 @@
|
||||
# export all code as a static library
|
||||
add_library(bsp)
|
||||
|
||||
# Add code to the bsp
|
||||
add_subdirectory(freeRTOS)
|
||||
add_subdirectory(ps7_cortexa9_0)
|
||||
add_subdirectory(ps7_cortexa9_0)
|
||||
add_subdirectory(newlib)
|
||||
add_subdirectory(hardware)
|
||||
|
||||
# this exports two libraries
|
||||
# `lwip` for embedded use
|
||||
# `lwip_xil` to use the ps eth
|
||||
# the subdirectory contains mostly configuration code
|
||||
# actual lwip is at ${LWIP_DIR}, to be set in main CMakeLists.txt
|
||||
add_subdirectory(lwip)
|
||||
|
||||
target_sources(bsp PRIVATE main.c)
|
||||
|
||||
# bsp depends on FreeRTOS
|
||||
target_link_libraries(bsp PUBLIC freertos_kernel)
|
||||
|
||||
# export lwip as part of bsp
|
||||
target_link_libraries(bsp INTERFACE lwip)
|
||||
@@ -1,9 +1,10 @@
|
||||
# the name of the target operating system
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR armv7a-none-eabihf)
|
||||
|
||||
set(CMAKE_C_COMPILER /usr/bin/arm-none-eabi-gcc)
|
||||
set(CMAKE_CXX_COMPILER /usr/bin/arm-none-eabi-g++)
|
||||
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
|
||||
set(CMAKE_ASM_COMPILER /usr/bin/arm-none-eabi-gcc)
|
||||
|
||||
# built in tests fail
|
||||
set(CMAKE_C_COMPILER_WORKS 1)
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
target_sources(${TARGET_NAME} PRIVATE FreeRTOS_asm_vectors.S FreeRTOS_tick_config.c)
|
||||
target_sources(bsp PRIVATE FreeRTOS_asm_vectors.S)
|
||||
|
||||
# Needs to be INTERFACE'd so it is build as part of the main application and can be found by the linker
|
||||
# Otherwise, we have a circular dependency between FreeRTOS and bsp which needs single file libraries to
|
||||
# resolve
|
||||
target_sources(bsp INTERFACE FreeRTOS_tick_config.c)
|
||||
@@ -75,7 +75,7 @@
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 1
|
||||
#define configMAX_PRIORITIES ( 7 )
|
||||
#define configMAX_PRIORITIES ( 10 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 250 ) /* Large in case configUSE_TASK_FPU_SUPPORT is 2 in which case all tasks have an FPU context. */
|
||||
#define configTOTAL_HEAP_SIZE ( 204800 )
|
||||
#define configMAX_TASK_NAME_LEN ( 10 )
|
||||
@@ -89,8 +89,9 @@
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 1
|
||||
|
||||
/* Include the query-heap CLI command to query the free heap space. */
|
||||
#define configINCLUDE_QUERY_HEAP_COMMAND 0
|
||||
@@ -127,6 +128,8 @@ to exclude the API function. */
|
||||
#define INCLUDE_xTaskGetTaskHandle 1
|
||||
#define INCLUDE_xTaskGetHandle 1
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark2 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
|
||||
|
||||
/* The private watchdog is used to generate run time stats. */
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// FreeRTOS build system needs to have a heap implementation, even if no dynamic allocation is used.
|
||||
// So we provide one:
|
||||
|
||||
void no_heap() {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
target_sources(bsp PRIVATE interfaces.c uart.c)
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int hw_interface_write(int fd, const char *ptr, size_t len);
|
||||
|
||||
int hw_interface_read(int fd, char *ptr, size_t len);
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
enum InterfaceFileDescriptors {
|
||||
UART_0 = 3,
|
||||
UART_1,
|
||||
INTERFACE_FDS_NEXT
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
#include <hardware/interfaces.h>
|
||||
#include <xparameters_ps.h>
|
||||
#include <xuartps.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "interface_access.h"
|
||||
#include "interface_fds.h"
|
||||
#include "uart.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <reent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int compare_string_chars(const char *c_string, const char *chars,
|
||||
size_t chars_len) {
|
||||
for(int i = 0; i < chars_len; i++) {
|
||||
if (c_string[i] == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (c_string[i] != chars[i]) {;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//TODO no dual open
|
||||
int hw_device_open(const char *path, size_t path_len) {
|
||||
if (compare_string_chars("uart0", path, path_len) == 1) {
|
||||
uart0_enable_receiver();
|
||||
return UART_0;
|
||||
}
|
||||
if (compare_string_chars("debug/uart🚀", path, path_len) == 1) {
|
||||
uart0_enable_receiver();
|
||||
return UART_0;
|
||||
}
|
||||
if (compare_string_chars("uart1", path, path_len) == 1) {
|
||||
uart1_enable_receiver();
|
||||
return UART_1;
|
||||
}
|
||||
|
||||
// _REENT_ERRNO(_REENT) = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t hw_device_transfer(int fd, void *sendbuffer, void *receivebuffer,
|
||||
size_t buffer_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// TODO move into uart.c
|
||||
// we could implement interrupt based nonblocking sending using a queue
|
||||
// like we do receiving (where we need it for the small hw buffer)
|
||||
// but in the end, we do not want too many interrupts, so we do it blocking
|
||||
void uart_send(uint32_t BaseAddress, const char *data, size_t data_len) {
|
||||
int todo;
|
||||
for (todo = 0; todo < data_len; todo++) {
|
||||
XUartPs_SendByte(BaseAddress, *data++);
|
||||
}
|
||||
}
|
||||
|
||||
int hw_interface_write(int fd, const char *ptr, size_t len) {
|
||||
enum InterfaceFileDescriptors fd_enum = fd;
|
||||
switch (fd) {
|
||||
case UART_0:
|
||||
uart_send(XPS_UART0_BASEADDR, ptr, len);
|
||||
return len;
|
||||
case UART_1:
|
||||
uart_send(XPS_UART1_BASEADDR, ptr, len);
|
||||
return len;
|
||||
}
|
||||
// _REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int hw_interface_read(int fd, char *ptr, size_t len) {
|
||||
enum InterfaceFileDescriptors fd_enum = fd;
|
||||
switch (fd) {
|
||||
case UART_0:
|
||||
return uart0_read(ptr,len);
|
||||
case UART_1:
|
||||
return uart1_read(ptr,len);;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
#include <xscugic.h>
|
||||
#include <xuartps.h>
|
||||
|
||||
// TODO deduplicate calls
|
||||
// TODO add semaphore to make QueueSets smaller
|
||||
|
||||
#undef XUARTPS_IXR_RXOVR
|
||||
#define XUARTPS_IXR_RXOVR 0x00000020U /**< Rx Overrun error interrupt */
|
||||
#define XUARTPS_IXR_RTRIG 0x00000001U /**< RX FIFO trigger interrupt. */
|
||||
|
||||
extern XScuGic xInterruptController; /* Interrupt controller instance */
|
||||
|
||||
uint8_t uart0_receive_buffer[1024 * 1];
|
||||
StaticQueue_t uart0_static_queue;
|
||||
QueueHandle_t uart0_receive_queue;
|
||||
|
||||
uint8_t uart1_receive_buffer[1024 * 1];
|
||||
StaticQueue_t uart1_static_queue;
|
||||
QueueHandle_t uart1_receive_queue;
|
||||
|
||||
/** this is based on XUartPs_InterruptHandler() in xuartps_intr.c*/
|
||||
void uart0_handle_interrupt(void *) {
|
||||
u32 IsrStatus;
|
||||
|
||||
/*
|
||||
* Read the interrupt ID register to determine which
|
||||
* interrupt is active
|
||||
*/
|
||||
IsrStatus = XUartPs_ReadReg(XPS_UART0_BASEADDR, XUARTPS_IMR_OFFSET);
|
||||
|
||||
IsrStatus &= XUartPs_ReadReg(XPS_UART0_BASEADDR, XUARTPS_ISR_OFFSET);
|
||||
|
||||
// Onlx RX intterupts are enabled
|
||||
// We do not care which interrupt actually triggered, just get all bytes
|
||||
// available into the stack
|
||||
uint8_t RecievedByte;
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
while (XUartPs_IsReceiveData(XPS_UART0_BASEADDR)) {
|
||||
RecievedByte = XUartPs_ReadReg(XPS_UART0_BASEADDR, XUARTPS_FIFO_OFFSET);
|
||||
xQueueSendToBackFromISR(uart0_receive_queue, &RecievedByte,
|
||||
&xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
/* Clear the interrupt status. */
|
||||
XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_ISR_OFFSET, IsrStatus);
|
||||
|
||||
/* directly yield if sending to the queue woke something in ourselves */
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void uart1_handle_interrupt(void *) {
|
||||
u32 IsrStatus;
|
||||
|
||||
/*
|
||||
* Read the interrupt ID register to determine which
|
||||
* interrupt is active
|
||||
*/
|
||||
IsrStatus = XUartPs_ReadReg(XPS_UART1_BASEADDR, XUARTPS_IMR_OFFSET);
|
||||
|
||||
IsrStatus &= XUartPs_ReadReg(XPS_UART1_BASEADDR, XUARTPS_ISR_OFFSET);
|
||||
|
||||
// Onlx RX intterupts are enabled
|
||||
// We do not care which interrupt actually triggered, just get all bytes
|
||||
// available into the stack
|
||||
uint8_t RecievedByte;
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
|
||||
while (XUartPs_IsReceiveData(XPS_UART1_BASEADDR)) {
|
||||
RecievedByte = XUartPs_ReadReg(XPS_UART1_BASEADDR, XUARTPS_FIFO_OFFSET);
|
||||
xQueueSendToBackFromISR(uart1_receive_queue, &RecievedByte,
|
||||
&xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
/* Clear the interrupt status. */
|
||||
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_ISR_OFFSET, IsrStatus);
|
||||
|
||||
/* directly yield if sending to the queue woke something in ourselves */
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void uart0_enable_receiver() {
|
||||
uart0_receive_queue =
|
||||
xQueueCreateStatic(sizeof(uart0_receive_buffer), 1, uart0_receive_buffer,
|
||||
&uart0_static_queue);
|
||||
|
||||
/* Install the UART Interrupt handler. */
|
||||
BaseType_t xStatus =
|
||||
XScuGic_Connect(&xInterruptController, XPAR_XUARTPS_0_INTR,
|
||||
(Xil_ExceptionHandler)uart0_handle_interrupt, NULL);
|
||||
configASSERT(xStatus == XST_SUCCESS);
|
||||
(void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */
|
||||
|
||||
// Set trigger level to 62 of 64 bytes, giving interrupt some time to react
|
||||
XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_RXWM_OFFSET, 62);
|
||||
|
||||
// Setting the rx timeout to n*4 -1 bits
|
||||
XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_RXTOUT_OFFSET, 50);
|
||||
|
||||
// enable UART Interrupts
|
||||
u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL |
|
||||
XUARTPS_IXR_TOUT;
|
||||
/* Write the mask to the IER Register */
|
||||
XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_IER_OFFSET, mask);
|
||||
/* Write the inverse of the Mask to the IDR register */
|
||||
XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_IDR_OFFSET, (~mask));
|
||||
|
||||
/* Enable the interrupt for the UART0 in the interrupt controller. */
|
||||
XScuGic_Enable(&xInterruptController, XPAR_XUARTPS_0_INTR);
|
||||
}
|
||||
|
||||
void uart1_enable_receiver() {
|
||||
uart1_receive_queue =
|
||||
xQueueCreateStatic(sizeof(uart1_receive_buffer), 1, uart1_receive_buffer,
|
||||
&uart1_static_queue);
|
||||
|
||||
/* Install the UART Interrupt handler. */
|
||||
BaseType_t xStatus =
|
||||
XScuGic_Connect(&xInterruptController, XPAR_XUARTPS_1_INTR,
|
||||
(Xil_ExceptionHandler)uart1_handle_interrupt, NULL);
|
||||
configASSERT(xStatus == XST_SUCCESS);
|
||||
(void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */
|
||||
|
||||
// Set trigger level to 62 of 64 bytes, giving interrupt some time to react
|
||||
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_RXWM_OFFSET, 62);
|
||||
|
||||
// Setting the rx timeout to n*4 -1 bits
|
||||
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_RXTOUT_OFFSET, 50);
|
||||
|
||||
// enable UART Interrupts
|
||||
u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL |
|
||||
XUARTPS_IXR_TOUT;
|
||||
/* Write the mask to the IER Register */
|
||||
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_IER_OFFSET, mask);
|
||||
/* Write the inverse of the Mask to the IDR register */
|
||||
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_IDR_OFFSET, (~mask));
|
||||
|
||||
/* Enable the interrupt for the UART1 in the interrupt controller. */
|
||||
XScuGic_Enable(&xInterruptController, XPAR_XUARTPS_1_INTR);
|
||||
}
|
||||
|
||||
int uart0_read(char *ptr, size_t len) {
|
||||
// TODO for blocking, if first call was successfull, further calls need to be
|
||||
// delay=0
|
||||
int received = 0;
|
||||
while (len > 0) {
|
||||
BaseType_t result = xQueueReceive(uart0_receive_queue, ptr, 0);
|
||||
if (result == pdFAIL) {
|
||||
return received;
|
||||
}
|
||||
received++;
|
||||
ptr++;
|
||||
len--;
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
int uart1_read(char *ptr, size_t len) {
|
||||
// TODO for blocking, if first call was successfull, further calls need to be
|
||||
// delay=0
|
||||
int received = 0;
|
||||
while (len > 0) {
|
||||
BaseType_t result = xQueueReceive(uart1_receive_queue, ptr, 0);
|
||||
if (result == pdFAIL) {
|
||||
return received;
|
||||
}
|
||||
received++;
|
||||
ptr++;
|
||||
len--;
|
||||
}
|
||||
return received;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
void uart0_enable_receiver();
|
||||
int uart0_read(char *ptr, int size_t);
|
||||
void uart1_enable_receiver();
|
||||
int uart1_read(char *ptr, int size_t);
|
||||
@@ -0,0 +1,11 @@
|
||||
# LWIP_DIR should point to the lwip source, to be set in main CMakeLists.txt
|
||||
include(${LWIP_DIR}/src/Filelists.cmake)
|
||||
|
||||
|
||||
add_subdirectory(xilinx_eth)
|
||||
add_subdirectory(bare)
|
||||
|
||||
target_link_libraries(lwip_xil PUBLIC freertos_kernel)
|
||||
|
||||
# should not need freeRTOS as it is NO_SYS
|
||||
#target_link_libraries(lwip PUBLIC freertos_kernel)
|
||||
@@ -0,0 +1,9 @@
|
||||
We provide two lwip configurations, bare and xilinx_eth.
|
||||
|
||||
Bare is the bare-metal minimal implementation. It tries to reduce code size and system complexity, using the bare API and a custom networking thread, handling all networking aspects.
|
||||
This configuration is meant to be run on the satellite obsw. It is exported as library `lwip`.
|
||||
|
||||
Xilinx_eth supports the xilinx ethernet core of the Zynq PS, inlcuding DMA. Unfortunately, the xilinx drivers require a custom sys_arch port and run a lot of additionals threads. Also, some code seems to be rather improvised. In sum, this code is not considered fit for orbit and kept out of the actual obsw except for special test cases.
|
||||
The xilinx_eth configuration is meant to be used with posix compatible calls, using the lwip sockets api.
|
||||
This configuration is mainly used for the simulation interface which relies on an eth interface to communicate with the simulator.
|
||||
This code is exported as library `lwip_xil`.
|
||||
@@ -0,0 +1,19 @@
|
||||
set (LWIP_INCLUDE_DIRS
|
||||
"${LWIP_DIR}/src/include"
|
||||
"${LWIP_DIR}/src/include/compat/posix"
|
||||
"include"
|
||||
)
|
||||
|
||||
set(lwip_SRCS
|
||||
${lwipcore_SRCS}
|
||||
${lwipcore4_SRCS}
|
||||
${lwipcore6_SRCS}
|
||||
${lwipnetif_SRCS}
|
||||
${lwipapi_SRCS}
|
||||
#${LWIP_DIR}/contrib/ports/freertos/sys_arch.c
|
||||
#${LWIP_DIR}/src/netif/slipif.c
|
||||
#${LWIP_DIR}/src/apps/tftp/tftp.c
|
||||
)
|
||||
|
||||
add_library(lwip ${lwip_SRCS})
|
||||
target_include_directories(lwip PUBLIC ${LWIP_INCLUDE_DIRS})
|
||||
@@ -36,9 +36,9 @@
|
||||
#define LWIP_IPV6 0
|
||||
|
||||
#define NO_SYS 1
|
||||
#define LWIP_SOCKET (NO_SYS==0)
|
||||
#define LWIP_NETCONN (NO_SYS==0)
|
||||
#define LWIP_NETIF_API (NO_SYS==0)
|
||||
#define LWIP_SOCKET 0
|
||||
#define LWIP_NETCONN 0
|
||||
#define LWIP_NETIF_API 0
|
||||
|
||||
#define LWIP_IGMP 0
|
||||
#define LWIP_ICMP LWIP_IPV4
|
||||
@@ -60,9 +60,17 @@
|
||||
|
||||
#define TCP_LISTEN_BACKLOG 0
|
||||
|
||||
#define LWIP_COMPAT_SOCKETS 0
|
||||
#define LWIP_SO_RCVTIMEO 0
|
||||
#define LWIP_SO_RCVBUF 0
|
||||
#define LWIP_COMPAT_SOCKETS 0
|
||||
//TODO put this into the OS
|
||||
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
|
||||
#define LWIP_SO_RCVTIMEO 0
|
||||
#define LWIP_SO_RCVBUF 0
|
||||
//TODO use this with LWIP_POSIX_SOCKETS_IO_NAMES
|
||||
// TODO why is 100 not working...
|
||||
#define LWIP_SOCKET_OFFSET 10
|
||||
|
||||
#define LWIP_SOCKET_SELECT 0
|
||||
#define LWIP_SOCKET_POLL 0
|
||||
|
||||
#define LWIP_TCPIP_CORE_LOCKING 0
|
||||
|
||||
@@ -78,7 +86,7 @@
|
||||
#define PPP_DEBUG LWIP_DBG_OFF
|
||||
#define MEM_DEBUG LWIP_DBG_OFF
|
||||
#define MEMP_DEBUG LWIP_DBG_OFF
|
||||
#define PBUF_DEBUG LWIP_DBG_OFF
|
||||
#define PBUF_DEBUG LWIP_DBG_ON
|
||||
#define API_LIB_DEBUG LWIP_DBG_ON
|
||||
#define API_MSG_DEBUG LWIP_DBG_ON
|
||||
#define TCPIP_DEBUG LWIP_DBG_ON
|
||||
@@ -114,14 +122,16 @@
|
||||
byte alignment -> define MEM_ALIGNMENT to 2. */
|
||||
/* MSVC port: intel processors don't need 4-byte alignment,
|
||||
but are faster that way! */
|
||||
#define MEM_ALIGNMENT 8U
|
||||
//TODO documentation
|
||||
//Zynq needs 32 for DMA to work (something about cache I guess...)
|
||||
#define MEM_ALIGNMENT 32U
|
||||
|
||||
#define MEM_USE_POOLS 1
|
||||
#define MEMP_USE_CUSTOM_POOLS MEM_USE_POOLS
|
||||
|
||||
/* MEM_SIZE: the size of the heap memory. If the application will send
|
||||
a lot of data that needs to be copied, this should be set high. */
|
||||
#define MEM_SIZE 10240
|
||||
#define MEM_SIZE 102400
|
||||
|
||||
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||
sends a lot of data out of ROM (or other static memory), this
|
||||
@@ -166,14 +176,15 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#define PBUF_POOL_SIZE 120
|
||||
|
||||
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
|
||||
#define PBUF_POOL_BUFSIZE 256
|
||||
/* Needs to be large enough to fit eth MTU to be able to use DMA for xemacps rx*/
|
||||
#define PBUF_POOL_BUFSIZE 1600
|
||||
|
||||
/** SYS_LIGHTWEIGHT_PROT
|
||||
* define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
|
||||
* for certain critical regions during buffer allocation, deallocation and memory
|
||||
* allocation and deallocation.
|
||||
*/
|
||||
#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0)
|
||||
#define SYS_LIGHTWEIGHT_PROT 0
|
||||
|
||||
|
||||
/* ---------- TCP options ---------- */
|
||||
@@ -219,7 +230,7 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#define TCPIP_MBOX_SIZE 5
|
||||
|
||||
/* ---------- ARP options ---------- */
|
||||
#define LWIP_ARP 0
|
||||
#define LWIP_ARP 1
|
||||
#define ARP_TABLE_SIZE 10
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_QUEUE_LEN 10
|
||||
@@ -288,7 +299,7 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#endif /* LWIP_STATS */
|
||||
|
||||
/* ---------- NETBIOS options ---------- */
|
||||
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1
|
||||
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 0
|
||||
|
||||
/* ---------- PPP options ---------- */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
LWIP_MALLOC_MEMPOOL_START
|
||||
LWIP_MALLOC_MEMPOOL(50, 256)
|
||||
LWIP_MALLOC_MEMPOOL(50, 512)
|
||||
LWIP_MALLOC_MEMPOOL(50, 1512)
|
||||
LWIP_MALLOC_MEMPOOL(50, 1550)
|
||||
LWIP_MALLOC_MEMPOOL_END
|
||||
@@ -0,0 +1,27 @@
|
||||
set (LWIP_INCLUDE_DIRS_XIL
|
||||
"${LWIP_DIR}/src/include"
|
||||
"${LWIP_DIR}/src/include/compat/posix"
|
||||
"include"
|
||||
)
|
||||
|
||||
set(lwip_SRCS_XIL
|
||||
${lwipcore_SRCS}
|
||||
${lwipcore4_SRCS}
|
||||
${lwipcore6_SRCS}
|
||||
${lwipnetif_SRCS}
|
||||
${lwipapi_SRCS}
|
||||
#${LWIP_DIR}/contrib/ports/freertos/sys_arch.c
|
||||
#${LWIP_DIR}/src/netif/slipif.c
|
||||
#${LWIP_DIR}/src/apps/tftp/tftp.c
|
||||
)
|
||||
|
||||
|
||||
add_library(lwip_xil EXCLUDE_FROM_ALL ${lwip_SRCS_XIL})
|
||||
|
||||
target_include_directories(lwip_xil PUBLIC ${LWIP_INCLUDE_DIRS_XIL})
|
||||
|
||||
target_sources(lwip_xil PRIVATE xethernet.c)
|
||||
|
||||
add_subdirectory(netif)
|
||||
add_subdirectory(port)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
This folder contains mostly code from https://github.com/Xilinx/embeddedsw/tree/xilinx_v2024.1/ThirdParty/sw_services/lwip220/src/lwip-2.2.0/contrib/ports/xilinx
|
||||
|
||||
Some files were added or modified to work with our setup. See git history for details, first clean import ist at `fd2c5a544fa1139c5123c35c83ca6b886bae2e6f`.
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_CC_H__
|
||||
#define __ARCH_CC_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lwipopts.h"
|
||||
|
||||
/** if you want to use the struct timeval provided
|
||||
* by your system, set this to 0 and include <sys/time.h> in cc.h */
|
||||
#define LWIP_TIMEVAL_PRIVATE 0
|
||||
#include <sys/time.h>
|
||||
#include "cpu.h"
|
||||
|
||||
#include "xil_printf.h"
|
||||
|
||||
|
||||
// errno is a macro. If we define LWIP_ERRNO_INCLUDE to errno.h the preprocessor will replace it,
|
||||
// breaking the include. Instead we supply a helper include which in turn includes errno.h
|
||||
#define LWIP_ERRNO_INCLUDE <onrre.h>
|
||||
|
||||
// /* As per new design of lwip-2.0.2,
|
||||
// * LWIP_NO_STDINT_H should be defined as 1 in cc.h */
|
||||
// #define LWIP_NO_STDINT_H 1
|
||||
|
||||
// typedef unsigned char u8_t;
|
||||
// typedef signed char s8_t;
|
||||
// typedef unsigned short u16_t;
|
||||
// typedef signed short s16_t;
|
||||
// typedef unsigned int u32_t;
|
||||
// typedef signed int s32_t;
|
||||
// typedef unsigned long long u64_t;
|
||||
// typedef signed long long s64_t;
|
||||
|
||||
// #define S16_F "d"
|
||||
// #define U16_F "d"
|
||||
// #define S32_F "d"
|
||||
// #define U32_F "x"
|
||||
|
||||
// #define X16_F "x"
|
||||
// #define X32_F "x"
|
||||
|
||||
#define LWIP_RAND rand
|
||||
|
||||
// typedef unsigned long mem_ptr_t;
|
||||
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
#define PACK_STRUCT_STRUCT __attribute__((packed))
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_END
|
||||
|
||||
#define LWIP_PLATFORM_ASSERT(x)
|
||||
#define LWIP_PLATFORM_DIAG(x) do { xil_printf x; } while(0)
|
||||
|
||||
#endif /* __ARCH_CC_H__ */
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_CPU_H__
|
||||
#define __ARCH_CPU_H__
|
||||
|
||||
#include "lwipopts.h"
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
#ifdef PROCESSOR_LITTLE_ENDIAN
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#else
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_CPU_H__ */
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_PERF_H__
|
||||
#define __ARCH_PERF_H__
|
||||
|
||||
#define PERF_START /* null definition */
|
||||
#define PERF_STOP(x) /* null definition */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void perf_init(char *fname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_PERF_H__ */
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SYS_XILINX_ARCH_H__
|
||||
#define __SYS_XILINX_ARCH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "lwipopts.h"
|
||||
|
||||
|
||||
#if !NO_SYS
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
#include "timers.h"
|
||||
|
||||
#define SYS_MBOX_NULL ( ( xQueueHandle ) NULL )
|
||||
#define SYS_SEM_NULL ( ( xSemaphoreHandle ) NULL )
|
||||
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
|
||||
typedef xSemaphoreHandle sys_sem_t;
|
||||
typedef xSemaphoreHandle sys_mutex_t;
|
||||
typedef xQueueHandle sys_mbox_t;
|
||||
typedef xTaskHandle sys_thread_t;
|
||||
|
||||
typedef unsigned long sys_prot_t;
|
||||
|
||||
#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL )
|
||||
#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define sys_sem_set_invalid( x ) ( ( *x ) = NULL )
|
||||
#endif /* !NO_SYS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYS_XILINX_ARCH_H__ */
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_LWIPOPTS_H
|
||||
#define LWIP_LWIPOPTS_H
|
||||
|
||||
#define LWIP_IPV4 1
|
||||
#define LWIP_IPV6 0
|
||||
|
||||
#define NO_SYS 0
|
||||
#define LWIP_SOCKET 1
|
||||
#define LWIP_NETCONN 1
|
||||
#define LWIP_NETIF_API 0
|
||||
|
||||
#define LWIP_IGMP 0
|
||||
#define LWIP_ICMP LWIP_IPV4
|
||||
|
||||
#define LWIP_SNMP 0
|
||||
//#define MIB2_STATS LWIP_SNMP
|
||||
#ifdef LWIP_HAVE_MBEDTLS
|
||||
#define LWIP_SNMP_V3 (LWIP_SNMP)
|
||||
#endif
|
||||
|
||||
#define LWIP_DNS 0
|
||||
#define LWIP_MDNS_RESPONDER 0
|
||||
|
||||
#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER)
|
||||
|
||||
#define LWIP_HAVE_LOOPIF 0
|
||||
#define LWIP_NETIF_LOOPBACK 0
|
||||
#define LWIP_LOOPBACK_MAX_PBUFS 0
|
||||
|
||||
#define TCP_LISTEN_BACKLOG 0
|
||||
|
||||
#define LWIP_COMPAT_SOCKETS 2
|
||||
//TODO put this into the OS
|
||||
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
|
||||
#define LWIP_SO_RCVTIMEO 0
|
||||
#define LWIP_SO_RCVBUF 0
|
||||
//TODO use this with LWIP_POSIX_SOCKETS_IO_NAMES
|
||||
// TODO why is 100 not working...
|
||||
#define LWIP_SOCKET_OFFSET 10
|
||||
|
||||
#define LWIP_SOCKET_SELECT 1
|
||||
#define LWIP_SOCKET_POLL 1
|
||||
|
||||
#define LWIP_TCPIP_CORE_LOCKING 0
|
||||
|
||||
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||
#define LWIP_NETIF_STATUS_CALLBACK 1
|
||||
#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
|
||||
|
||||
//#define LWIP_DEBUG
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
|
||||
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
|
||||
#define PPP_DEBUG LWIP_DBG_OFF
|
||||
#define MEM_DEBUG LWIP_DBG_OFF
|
||||
#define MEMP_DEBUG LWIP_DBG_OFF
|
||||
#define PBUF_DEBUG LWIP_DBG_ON
|
||||
#define API_LIB_DEBUG LWIP_DBG_ON
|
||||
#define API_MSG_DEBUG LWIP_DBG_ON
|
||||
#define TCPIP_DEBUG LWIP_DBG_ON
|
||||
#define NETIF_DEBUG LWIP_DBG_ON
|
||||
#define SOCKETS_DEBUG LWIP_DBG_ON
|
||||
#define DNS_DEBUG LWIP_DBG_ON
|
||||
#define AUTOIP_DEBUG LWIP_DBG_ON
|
||||
#define DHCP_DEBUG LWIP_DBG_ON
|
||||
#define IP_DEBUG LWIP_DBG_ON
|
||||
#define IP_REASS_DEBUG LWIP_DBG_ON
|
||||
#define ICMP_DEBUG LWIP_DBG_ON
|
||||
#define IGMP_DEBUG LWIP_DBG_ON
|
||||
#define UDP_DEBUG LWIP_DBG_ON
|
||||
#define TCP_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_RTO_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_CWND_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_WND_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_FR_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_RST_DEBUG LWIP_DBG_OFF
|
||||
#define TIMERS_DEBUG LWIP_DBG_OFF
|
||||
#define LWIP_DEBUG_TIMERNAMES LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
|
||||
|
||||
|
||||
/* ---------- Memory options ---------- */
|
||||
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
|
||||
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
|
||||
byte alignment -> define MEM_ALIGNMENT to 2. */
|
||||
/* MSVC port: intel processors don't need 4-byte alignment,
|
||||
but are faster that way! */
|
||||
//TODO documentation
|
||||
//Zynq needs 32 for DMA to work (something about cache I guess...)
|
||||
#define MEM_ALIGNMENT 32U
|
||||
|
||||
#define MEM_USE_POOLS 1
|
||||
#define MEMP_USE_CUSTOM_POOLS MEM_USE_POOLS
|
||||
|
||||
/* MEM_SIZE: the size of the heap memory. If the application will send
|
||||
a lot of data that needs to be copied, this should be set high. */
|
||||
#define MEM_SIZE 102400
|
||||
|
||||
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||
sends a lot of data out of ROM (or other static memory), this
|
||||
should be set high. */
|
||||
#define MEMP_NUM_PBUF 16
|
||||
/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One
|
||||
per active RAW "connection". */
|
||||
#define MEMP_NUM_RAW_PCB 3
|
||||
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
|
||||
per active UDP "connection". */
|
||||
#define MEMP_NUM_UDP_PCB 8
|
||||
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
|
||||
connections. */
|
||||
#define MEMP_NUM_TCP_PCB 5
|
||||
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
|
||||
connections. */
|
||||
#define MEMP_NUM_TCP_PCB_LISTEN 8
|
||||
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
|
||||
segments. */
|
||||
#define MEMP_NUM_TCP_SEG 16
|
||||
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
|
||||
timeouts. */
|
||||
#define MEMP_NUM_SYS_TIMEOUT 17
|
||||
|
||||
/* The following four are used only with the sequential API and can be
|
||||
set to 0 if the application only will use the raw API. */
|
||||
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
|
||||
#define MEMP_NUM_NETBUF 2
|
||||
/* MEMP_NUM_NETCONN: the number of struct netconns. */
|
||||
#define MEMP_NUM_NETCONN 12
|
||||
/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
|
||||
for sequential API communication and incoming packets. Used in
|
||||
src/api/tcpip.c. */
|
||||
#define MEMP_NUM_TCPIP_MSG_API 16
|
||||
#define MEMP_NUM_TCPIP_MSG_INPKT 16
|
||||
|
||||
#define TCPIP_THREAD_STACKSIZE 10240
|
||||
|
||||
|
||||
/* ---------- Pbuf options ---------- */
|
||||
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
|
||||
#define PBUF_POOL_SIZE 120
|
||||
|
||||
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
|
||||
/* Needs to be large enough to fit eth MTU to be able to use DMA for xemacps rx*/
|
||||
#define PBUF_POOL_BUFSIZE 1600
|
||||
|
||||
/** SYS_LIGHTWEIGHT_PROT
|
||||
* define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
|
||||
* for certain critical regions during buffer allocation, deallocation and memory
|
||||
* allocation and deallocation.
|
||||
*/
|
||||
#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0)
|
||||
|
||||
|
||||
/* ---------- TCP options ---------- */
|
||||
#define LWIP_TCP 0
|
||||
#define TCP_TTL 255
|
||||
|
||||
#define LWIP_ALTCP (LWIP_TCP)
|
||||
#ifdef LWIP_HAVE_MBEDTLS
|
||||
#define LWIP_ALTCP_TLS (LWIP_TCP)
|
||||
#define LWIP_ALTCP_TLS_MBEDTLS (LWIP_TCP)
|
||||
#endif
|
||||
|
||||
|
||||
/* Controls if TCP should queue segments that arrive out of
|
||||
order. Define to 0 if your device is low on memory. */
|
||||
#define TCP_QUEUE_OOSEQ 1
|
||||
|
||||
/* TCP Maximum segment size. */
|
||||
#define TCP_MSS 1024
|
||||
|
||||
/* TCP sender buffer space (bytes). */
|
||||
#define TCP_SND_BUF 2048
|
||||
|
||||
/* TCP sender buffer space (pbufs). This must be at least = 2 *
|
||||
TCP_SND_BUF/TCP_MSS for things to work. */
|
||||
#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS)
|
||||
|
||||
/* TCP writable space (bytes). This must be less than or equal
|
||||
to TCP_SND_BUF. It is the amount of space which must be
|
||||
available in the tcp snd_buf for select to return writable */
|
||||
#define TCP_SNDLOWAT (TCP_SND_BUF/2)
|
||||
|
||||
/* TCP receive window. */
|
||||
#define TCP_WND (20 * 1024)
|
||||
|
||||
/* Maximum number of retransmissions of data segments. */
|
||||
#define TCP_MAXRTX 12
|
||||
|
||||
/* Maximum number of retransmissions of SYN segments. */
|
||||
#define TCP_SYNMAXRTX 4
|
||||
|
||||
|
||||
#define TCPIP_MBOX_SIZE 5
|
||||
|
||||
/* ---------- ARP options ---------- */
|
||||
#define LWIP_ARP 1
|
||||
#define ARP_TABLE_SIZE 10
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_QUEUE_LEN 10
|
||||
|
||||
|
||||
/* ---------- IP options ---------- */
|
||||
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
|
||||
IP packets across network interfaces. If you are going to run lwIP
|
||||
on a device with only one network interface, define this to 0. */
|
||||
#define IP_FORWARD 1
|
||||
|
||||
/* IP reassembly and segmentation.These are orthogonal even
|
||||
* if they both deal with IP fragments */
|
||||
#define IP_REASSEMBLY 1
|
||||
#define IP_REASS_MAX_PBUFS (10 * ((1500 + PBUF_POOL_BUFSIZE - 1) / PBUF_POOL_BUFSIZE))
|
||||
#define MEMP_NUM_REASSDATA IP_REASS_MAX_PBUFS
|
||||
#define IP_FRAG 1
|
||||
#define IPV6_FRAG_COPYHEADER 1
|
||||
|
||||
/* ---------- ICMP options ---------- */
|
||||
#define ICMP_TTL 255
|
||||
|
||||
|
||||
/* ---------- DHCP options ---------- */
|
||||
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
|
||||
interfaces. */
|
||||
#define LWIP_DHCP 0
|
||||
|
||||
/* 1 if you want to do an ARP check on the offered address
|
||||
(recommended). */
|
||||
#define DHCP_DOES_ARP_CHECK (LWIP_DHCP)
|
||||
|
||||
|
||||
/* ---------- AUTOIP options ------- */
|
||||
#define LWIP_AUTOIP (LWIP_DHCP)
|
||||
#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP)
|
||||
|
||||
|
||||
/* ---------- UDP options ---------- */
|
||||
#define LWIP_UDP 1
|
||||
#define LWIP_UDPLITE 0
|
||||
#define UDP_TTL 255
|
||||
#define DEFAULT_UDP_RECVMBOX_SIZE 4
|
||||
|
||||
/* ---------- RAW options ---------- */
|
||||
#define LWIP_RAW 0
|
||||
#define DEFAULT_TCP_RECVMBOX_SIZE 2
|
||||
|
||||
/* ---------- Statistics options ---------- */
|
||||
|
||||
#define LWIP_STATS 0
|
||||
#define LWIP_STATS_DISPLAY 0
|
||||
|
||||
#if LWIP_STATS
|
||||
#define LINK_STATS 1
|
||||
#define IP_STATS 1
|
||||
#define ICMP_STATS 1
|
||||
#define IGMP_STATS 1
|
||||
#define IPFRAG_STATS 1
|
||||
#define UDP_STATS 1
|
||||
#define TCP_STATS 1
|
||||
#define MEM_STATS 1
|
||||
#define MEMP_STATS 1
|
||||
#define PBUF_STATS 1
|
||||
#define SYS_STATS 1
|
||||
#endif /* LWIP_STATS */
|
||||
|
||||
/* ---------- NETBIOS options ---------- */
|
||||
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 0
|
||||
|
||||
/* ---------- PPP options ---------- */
|
||||
|
||||
#define PPP_SUPPORT 0 /* Set > 0 for PPP */
|
||||
|
||||
#if PPP_SUPPORT
|
||||
|
||||
#define NUM_PPP 1 /* Max PPP sessions. */
|
||||
|
||||
|
||||
/* Select modules to enable. Ideally these would be set in the makefile but
|
||||
* we're limited by the command line length so you need to modify the settings
|
||||
* in this file.
|
||||
*/
|
||||
#define PPPOE_SUPPORT 1
|
||||
#define PPPOS_SUPPORT 1
|
||||
|
||||
#define PAP_SUPPORT 1 /* Set > 0 for PAP. */
|
||||
#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */
|
||||
#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP */
|
||||
#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
|
||||
#define CCP_SUPPORT 0 /* Set > 0 for CCP */
|
||||
#define VJ_SUPPORT 0 /* Set > 0 for VJ header compression. */
|
||||
#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */
|
||||
|
||||
#endif /* PPP_SUPPORT */
|
||||
|
||||
|
||||
// Disable slip task
|
||||
#define SLIP_USE_RX_THREAD 0
|
||||
|
||||
|
||||
|
||||
#endif /* LWIP_LWIPOPTS_H */
|
||||
@@ -0,0 +1,5 @@
|
||||
LWIP_MALLOC_MEMPOOL_START
|
||||
LWIP_MALLOC_MEMPOOL(50, 256)
|
||||
LWIP_MALLOC_MEMPOOL(50, 512)
|
||||
LWIP_MALLOC_MEMPOOL(50, 1550)
|
||||
LWIP_MALLOC_MEMPOOL_END
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XADAPTER_H_
|
||||
#define __XADAPTER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwipopts.h"
|
||||
|
||||
#if !NO_SYS
|
||||
#include "lwip/sys.h"
|
||||
//TODO this is not portable:
|
||||
#include "FreeRTOS.h"
|
||||
#include "timers.h"
|
||||
#endif
|
||||
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/ip.h"
|
||||
|
||||
#include "netif/xtopology.h"
|
||||
|
||||
struct xemac_s {
|
||||
enum xemac_types type;
|
||||
int topology_index;
|
||||
void *state;
|
||||
#if !NO_SYS
|
||||
sys_sem_t sem_rx_data_available;
|
||||
#if defined(__arm__) && !defined(ARMR5)
|
||||
TimerHandle_t xTimer;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
enum ethernet_link_status {
|
||||
ETH_LINK_UNDEFINED = 0,
|
||||
ETH_LINK_UP,
|
||||
ETH_LINK_DOWN,
|
||||
ETH_LINK_NEGOTIATING
|
||||
};
|
||||
|
||||
void eth_link_detect(struct netif *netif);
|
||||
void lwip_raw_init();
|
||||
int xemacif_input(struct netif *netif);
|
||||
void xemacif_input_thread(struct netif *netif);
|
||||
struct netif * xemac_add(struct netif *netif,
|
||||
ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw,
|
||||
unsigned char *mac_ethernet_address,
|
||||
UINTPTR mac_baseaddr);
|
||||
#if defined (__arm__) || defined (__aarch64__)
|
||||
void xemacpsif_resetrx_on_no_rxdata(struct netif *netif);
|
||||
#endif
|
||||
|
||||
/* global lwip debug variable used for debugging */
|
||||
extern int lwip_runtime_debug;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NETIF_XAXIEMACIF_H__
|
||||
#define __NETIF_XAXIEMACIF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "xlwipconfig.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/xadapter.h"
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
#include "xaxiethernet.h"
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO
|
||||
#include "xllfifo.h"
|
||||
#elif XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_MCDMA
|
||||
#include "xmcdma.h"
|
||||
#else
|
||||
#include "xaxidma.h"
|
||||
#include "xaxidma_hw.h"
|
||||
#endif
|
||||
|
||||
#include "netif/xpqueue.h"
|
||||
#include "xlwipconfig.h"
|
||||
|
||||
#if XLWIP_CONFIG_INCLUDE_AXIETH_ON_ZYNQ == 1
|
||||
#define AXIDMA_TX_INTR_PRIORITY_SET_IN_GIC 0xA0
|
||||
#define AXIDMA_RX_INTR_PRIORITY_SET_IN_GIC 0xA0
|
||||
#define AXIETH_INTR_PRIORITY_SET_IN_GIC 0xA0
|
||||
#define TRIG_TYPE_RISING_EDGE_SENSITIVE 0x3
|
||||
|
||||
#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_0_DIST_BASEADDR
|
||||
#endif
|
||||
|
||||
void xaxiemacif_setmac(u32_t index, u8_t *addr);
|
||||
u8_t* xaxiemacif_getmac(u32_t index);
|
||||
err_t xaxiemacif_init(struct netif *netif);
|
||||
int xaxiemacif_input(struct netif *netif);
|
||||
|
||||
unsigned get_IEEE_phy_speed(XAxiEthernet *xaxiemacp);
|
||||
void enable_sgmii_clock(XAxiEthernet *xaxiemacp);
|
||||
unsigned configure_IEEE_phy_speed(XAxiEthernet *xaxiemacp, unsigned speed);
|
||||
unsigned phy_setup_axiemac (XAxiEthernet *xaxiemacp);
|
||||
|
||||
/* xaxiemacif_hw.c */
|
||||
void xaxiemac_error_handler(XAxiEthernet * Temac);
|
||||
|
||||
/* structure within each netif, encapsulating all information required for
|
||||
* using a particular temac instance
|
||||
*/
|
||||
typedef struct {
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO
|
||||
XLlFifo axififo;
|
||||
#elif defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_MCDMA)
|
||||
XMcdma aximcdma;
|
||||
#else
|
||||
XAxiDma axidma;
|
||||
#endif
|
||||
XAxiEthernet axi_ethernet;
|
||||
|
||||
/* queue to store overflow packets */
|
||||
pq_queue_t *recv_q;
|
||||
pq_queue_t *send_q;
|
||||
|
||||
/* pointers to memory holding buffer descriptors (used only with SDMA) */
|
||||
void *rx_bdspace;
|
||||
void *tx_bdspace;
|
||||
|
||||
enum ethernet_link_status eth_link_status;
|
||||
} xaxiemacif_s;
|
||||
|
||||
extern xaxiemacif_s xaxiemacif;
|
||||
|
||||
#ifndef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO
|
||||
s32_t xaxiemac_is_tx_space_available(xaxiemacif_s *emac);
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_MCDMA
|
||||
s32_t process_sent_bds(XMcdma_ChanCtrl *Tx_Chan);
|
||||
#else
|
||||
s32_t process_sent_bds(XAxiDma_BdRing *txring);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* xaxiemacif_dma.c/xaxiemacif_mcdma.c */
|
||||
#ifndef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_MCDMA
|
||||
XStatus init_axi_mcdma(struct xemac_s *xemac);
|
||||
XStatus axi_mcdma_sgsend(xaxiemacif_s *xaxiemacif, struct pbuf *p);
|
||||
#else
|
||||
XStatus init_axi_dma(struct xemac_s *xemac);
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
XStatus axidma_sgsend(xaxiemacif_s *xaxiemacif, struct pbuf *p,
|
||||
u32_t block_till_tx_complete, u32_t *to_block_index);
|
||||
#else
|
||||
XStatus axidma_sgsend(xaxiemacif_s *xaxiemacif, struct pbuf *p);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETIF_XAXIEMACIF_H__ */
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NETIF_XEMACLITEIF_H__
|
||||
#define __NETIF_XEMACLITEIF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwip/netif.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/xpqueue.h"
|
||||
#include "xemaclite.h"
|
||||
#include "xemaclite_i.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
/* structure within each netif, encapsulating all information required for
|
||||
* using a particular emaclite instance
|
||||
*/
|
||||
typedef struct {
|
||||
XEmacLite *instance;
|
||||
|
||||
/* queue to store overflow packets */
|
||||
pq_queue_t *recv_q;
|
||||
pq_queue_t *send_q;
|
||||
|
||||
enum ethernet_link_status eth_link_status;
|
||||
} xemacliteif_s;
|
||||
|
||||
void xemacliteif_setmac(u32_t index, u8_t *addr);
|
||||
u8_t* xemacliteif_getmac(u32_t index);
|
||||
err_t xemacliteif_init(struct netif *netif);
|
||||
int xemacliteif_input(struct netif *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETIF_XEMACLITEIF_H__ */
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NETIF_XEMACPSIF_H__
|
||||
#define __NETIF_XEMACPSIF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "xlwipconfig.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "netif/xadapter.h"
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "sleep.h"
|
||||
#include "xparameters.h"
|
||||
#include "xparameters_ps.h" /* defines XPAR values */
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xil_io.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xpseudo_asm.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xscugic.h"
|
||||
#include "xemacps.h" /* defines XEmacPs API */
|
||||
|
||||
#include "netif/xpqueue.h"
|
||||
#include "xlwipconfig.h"
|
||||
|
||||
#if defined (__aarch64__) && (EL1_NONSECURE == 1)
|
||||
#include "xil_smc.h"
|
||||
#endif
|
||||
|
||||
#define ZYNQ_EMACPS_0_BASEADDR 0xE000B000
|
||||
#define ZYNQ_EMACPS_1_BASEADDR 0xE000C000
|
||||
|
||||
#define ZYNQMP_EMACPS_0_BASEADDR 0xFF0B0000
|
||||
#define ZYNQMP_EMACPS_1_BASEADDR 0xFF0C0000
|
||||
#define ZYNQMP_EMACPS_2_BASEADDR 0xFF0D0000
|
||||
#define ZYNQMP_EMACPS_3_BASEADDR 0xFF0E0000
|
||||
|
||||
#define CRL_APB_GEM0_REF_CTRL 0xFF5E0050
|
||||
#define CRL_APB_GEM1_REF_CTRL 0xFF5E0054
|
||||
#define CRL_APB_GEM2_REF_CTRL 0xFF5E0058
|
||||
#define CRL_APB_GEM3_REF_CTRL 0xFF5E005C
|
||||
|
||||
#define CRL_APB_GEM_DIV0_MASK 0x00003F00
|
||||
#define CRL_APB_GEM_DIV0_SHIFT 8
|
||||
#define CRL_APB_GEM_DIV1_MASK 0x003F0000
|
||||
#define CRL_APB_GEM_DIV1_SHIFT 16
|
||||
|
||||
#define VERSAL_EMACPS_0_BASEADDR 0xFF0C0000
|
||||
#define VERSAL_EMACPS_1_BASEADDR 0xFF0D0000
|
||||
|
||||
#define VERSAL_CRL_GEM0_REF_CTRL 0xFF5E0118
|
||||
#define VERSAL_CRL_GEM1_REF_CTRL 0xFF5E011C
|
||||
|
||||
#define VERSAL_CRL_GEM_DIV_MASK 0x0003FF00
|
||||
#define VERSAL_CRL_APB_GEM_DIV_SHIFT 8
|
||||
|
||||
#define VERSAL_NET_EMACPS_0_BASEADDR 0xF19E0000
|
||||
#define VERSAL_NET_EMACPS_1_BASEADDR 0xF19F0000
|
||||
|
||||
#ifdef XPAR_PSX_CRL_0_S_AXI_BASEADDR
|
||||
#define VERSAL_NET_CRL_GEM0_REF_CTRL ( XPAR_PSX_CRL_0_S_AXI_BASEADDR + 0x118)
|
||||
#define VERSAL_NET_CRL_GEM1_REF_CTRL ( XPAR_PSX_CRL_0_S_AXI_BASEADDR + 0x11C)
|
||||
#endif
|
||||
|
||||
#define VERSAL_NET_CRL_GEM_DIV_MASK VERSAL_CRL_GEM_DIV_MASK
|
||||
#define VERSAL_NET_CRL_APB_GEM_DIV_SHIFT VERSAL_CRL_APB_GEM_DIV_SHIFT
|
||||
|
||||
#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) || (__MICROBLAZE__)
|
||||
#if defined (USE_JUMBO_FRAMES)
|
||||
#define ZYNQMP_USE_JUMBO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define GEM_VERSION_ZYNQMP 7
|
||||
#define GEM_VERSION_VERSAL 0x107
|
||||
|
||||
#define MAX_FRAME_SIZE_JUMBO (XEMACPS_MTU_JUMBO + XEMACPS_HDR_SIZE + XEMACPS_TRL_SIZE)
|
||||
|
||||
void xemacpsif_setmac(u32_t index, u8_t *addr);
|
||||
u8_t* xemacpsif_getmac(u32_t index);
|
||||
err_t xemacpsif_init(struct netif *netif);
|
||||
s32_t xemacpsif_input(struct netif *netif);
|
||||
|
||||
/* xaxiemacif_hw.c */
|
||||
void xemacps_error_handler(XEmacPs * Temac);
|
||||
|
||||
/* structure within each netif, encapsulating all information required for
|
||||
* using a particular temac instance
|
||||
*/
|
||||
typedef struct {
|
||||
XEmacPs emacps;
|
||||
|
||||
/* queue to store overflow packets */
|
||||
pq_queue_t *recv_q;
|
||||
pq_queue_t *send_q;
|
||||
|
||||
/* pointers to memory holding buffer descriptors (used only with SDMA) */
|
||||
void *rx_bdspace;
|
||||
void *tx_bdspace;
|
||||
|
||||
unsigned int last_rx_frms_cntr;
|
||||
enum ethernet_link_status eth_link_status;
|
||||
} xemacpsif_s;
|
||||
|
||||
extern xemacpsif_s xemacpsif;
|
||||
|
||||
s32_t xemacps_is_tx_space_available(xemacpsif_s *emac);
|
||||
|
||||
/* xemacpsif_dma.c */
|
||||
|
||||
void xemacps_process_sent_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *txring);
|
||||
u32_t phy_setup_emacps (XEmacPs *xemacpsp, u32_t phy_addr);
|
||||
#ifdef SGMII_FIXED_LINK
|
||||
u32_t pcs_setup_emacps (XEmacPs *xemacps);
|
||||
#endif
|
||||
void detect_phy(XEmacPs *xemacpsp);
|
||||
void emacps_send_handler(void *arg);
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p,
|
||||
u32_t block_till_tx_complete, u32_t *to_block_index);
|
||||
#else
|
||||
XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p);
|
||||
#endif
|
||||
void emacps_recv_handler(void *arg);
|
||||
void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
|
||||
void setup_rx_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *rxring);
|
||||
void HandleTxErrors(struct xemac_s *xemac);
|
||||
void HandleEmacPsError(struct xemac_s *xemac);
|
||||
XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
|
||||
void init_emacps(xemacpsif_s *xemacps, struct netif *netif);
|
||||
void setup_isr (struct xemac_s *xemac);
|
||||
XStatus init_dma(struct xemac_s *xemac);
|
||||
void start_emacps (xemacpsif_s *xemacps);
|
||||
void free_txrx_pbufs(xemacpsif_s *xemacpsif);
|
||||
void free_onlytx_pbufs(xemacpsif_s *xemacpsif);
|
||||
void init_emacps_on_error (xemacpsif_s *xemacps, struct netif *netif);
|
||||
void clean_dma_txdescs(struct xemac_s *xemac);
|
||||
void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
|
||||
void reset_dma(struct xemac_s *xemac);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETIF_XAXIEMACIF_H__ */
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NETIF_XLLTEMACIF_H__
|
||||
#define __NETIF_XLLTEMACIF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwip/netif.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/xadapter.h"
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xstatus.h"
|
||||
#include "xlltemac.h"
|
||||
#include "xlldma.h"
|
||||
#include "xllfifo.h"
|
||||
#include "xlldma_bdring.h"
|
||||
|
||||
#include "netif/xpqueue.h"
|
||||
#include "xlwipconfig.h"
|
||||
|
||||
void xlltemacif_setmac(u32_t index, u8_t *addr);
|
||||
u8_t* xlltemacif_getmac(u32_t index);
|
||||
err_t xlltemacif_init(struct netif *netif);
|
||||
int xlltemacif_input(struct netif *netif);
|
||||
unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
|
||||
unsigned Phy_Setup (XLlTemac *xlltemacp);
|
||||
unsigned configure_IEEE_phy_speed(XLlTemac *xlltemacp, unsigned speed);
|
||||
|
||||
/* xlltemacif_hw.c */
|
||||
void xlltemac_error_handler(XLlTemac * Temac);
|
||||
|
||||
/* structure within each netif, encapsulating all information required for
|
||||
* using a particular temac instance
|
||||
*/
|
||||
typedef struct {
|
||||
XLlDma lldma;
|
||||
XLlFifo llfifo;
|
||||
XLlTemac lltemac;
|
||||
|
||||
/* queue to store overflow packets */
|
||||
pq_queue_t *recv_q;
|
||||
pq_queue_t *send_q;
|
||||
|
||||
/* pointers to memory holding buffer descriptors (used only with SDMA) */
|
||||
void *rx_bdspace;
|
||||
void *tx_bdspace;
|
||||
|
||||
enum ethernet_link_status eth_link_status;
|
||||
} xlltemacif_s;
|
||||
|
||||
extern xlltemacif_s xlltemacif;
|
||||
|
||||
/* xlltemacif_sdma.c */
|
||||
XStatus init_sdma(struct xemac_s *xemac);
|
||||
int process_sent_bds(XLlDma_BdRing *txring);
|
||||
void lldma_send_handler(void *arg);
|
||||
XStatus lldma_sgsend(xlltemacif_s *xlltemacif, struct pbuf *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETIF_XLLTEMACIF_H__ */
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LWIP_PBUF_QUEUE_H_
|
||||
#define __LWIP_PBUF_QUEUE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwip/debug.h"
|
||||
|
||||
#define PQ_QUEUE_SIZE 4096
|
||||
|
||||
typedef struct {
|
||||
void *data[PQ_QUEUE_SIZE];
|
||||
int head, tail, len;
|
||||
} pq_queue_t;
|
||||
|
||||
pq_queue_t* pq_create_queue();
|
||||
int pq_enqueue(pq_queue_t *q, void *p);
|
||||
void* pq_dequeue(pq_queue_t *q);
|
||||
int pq_qlength(pq_queue_t *q);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XTOPOLOGY_H_
|
||||
#define __XTOPOLOGY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "xil_types.h"
|
||||
|
||||
enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
|
||||
|
||||
struct xtopology_t {
|
||||
UINTPTR emac_baseaddr;
|
||||
enum xemac_types emac_type;
|
||||
#ifndef SDT
|
||||
UINTPTR intc_baseaddr;
|
||||
unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
|
||||
UINTPTR scugic_baseaddr; /* valid only for Zynq */
|
||||
unsigned scugic_emac_intr; /* valid only for GEM */
|
||||
#endif
|
||||
};
|
||||
|
||||
extern int xtopology_n_emacs;
|
||||
extern struct xtopology_t xtopology[];
|
||||
|
||||
int xtopology_find_index(unsigned base);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
#include <errno.h>
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void xethernet_init();
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XLWIPCONFIG_H_
|
||||
#define __XLWIPCONFIG_H_
|
||||
|
||||
#define XLWIP_CONFIG_INCLUDE_GEM
|
||||
#define XLWIP_CONFIG_N_TX_DESC 64
|
||||
#define XLWIP_CONFIG_N_RX_DESC 64
|
||||
|
||||
//#define CONFIG_LINKSPEED100
|
||||
#define CONFIG_LINKSPEED_AUTODETECT
|
||||
|
||||
//TODO defines
|
||||
/*
|
||||
#cmakedefine XLWIP_CONFIG_INCLUDE_AXIETH_ON_ZYNQ @XLWIP_CONFIG_INCLUDE_AXIETH_ON_ZYNQ@
|
||||
#cmakedefine XLWIP_CONFIG_INCLUDE_EMACLITE_ON_ZYNQ @XLWIP_CONFIG_INCLUDE_EMACLITE_ON_ZYNQ@
|
||||
#cmakedefine XLWIP_CONFIG_INCLUDE_EMACLITE @XLWIP_CONFIG_INCLUDE_EMACLITE@
|
||||
#cmakedefine XLWIP_CONFIG_INCLUDE_AXI_ETHERNET @XLWIP_CONFIG_INCLUDE_AXI_ETHERNET@
|
||||
#cmakedefine XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_DMA @XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_DMA@
|
||||
#cmakedefine XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO @XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO@
|
||||
#cmakedefine XLWIP_CONFIG_AXI_ETHERNET_ENABLE_1588 @XLWIP_CONFIG_AXI_ETHERNET_ENABLE_1588@
|
||||
#cmakedefine XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_MCDMA @XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_MCDMA@
|
||||
#cmakedefine XLWIP_CONFIG_INCLUDE_GEM @XLWIP_CONFIG_INCLUDE_GEM@
|
||||
#cmakedefine XLWIP_CONFIG_N_TX_DESC @XLWIP_CONFIG_N_TX_DESC@
|
||||
#cmakedefine XLWIP_CONFIG_N_RX_DESC @XLWIP_CONFIG_N_RX_DESC@
|
||||
#cmakedefine XLWIP_CONFIG_N_TX_COALESCE @XLWIP_CONFIG_N_TX_COALESCE@
|
||||
#cmakedefine XLWIP_CONFIG_N_RX_COALESCE @XLWIP_CONFIG_N_RX_COALESCE@
|
||||
#cmakedefine XLWIP_CONFIG_EMAC_NUMBER @XLWIP_CONFIG_EMAC_NUMBER@
|
||||
#cmakedefine XLWIP_CONFIG_PCS_PMA_1000BASEX_CORE_PRESENT @XLWIP_CONFIG_PCS_PMA_1000BASEX_CORE_PRESENT@
|
||||
#cmakedefine XLWIP_CONFIG_PCS_PMA_SGMII_CORE_PRESENT @XLWIP_CONFIG_PCS_PMA_SGMII_CORE_PRESENT@
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
target_sources(lwip_xil PRIVATE
|
||||
xadapter.c
|
||||
xpqueue.c
|
||||
xemacpsif_dma.c
|
||||
xemacpsif_physpeed.c
|
||||
xemacpsif_hw.c
|
||||
xemacpsif.c
|
||||
topology.c
|
||||
)
|
||||
|
||||
target_include_directories(lwip_xil PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "netif/xtopology.h"
|
||||
|
||||
// struct xtopology_t {
|
||||
// UINTPTR emac_baseaddr;
|
||||
// enum xemac_types emac_type;
|
||||
// #ifndef SDT
|
||||
// UINTPTR intc_baseaddr;
|
||||
// unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
|
||||
// UINTPTR scugic_baseaddr; /* valid only for Zynq */
|
||||
// unsigned scugic_emac_intr; /* valid only for GEM */
|
||||
// #endif
|
||||
// };
|
||||
|
||||
|
||||
int xtopology_n_emacs = 2;
|
||||
struct xtopology_t xtopology[] = {
|
||||
{
|
||||
0xE000B000,
|
||||
xemac_type_emacps,
|
||||
#ifndef SDT
|
||||
0,
|
||||
0,
|
||||
0xF8F00100,
|
||||
0x36
|
||||
#endif
|
||||
},
|
||||
{
|
||||
0xE000C000,
|
||||
xemac_type_emacps,
|
||||
#ifndef SDT
|
||||
0,
|
||||
0,
|
||||
0xF8F00100,
|
||||
0x4D
|
||||
#endif
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwipopts.h"
|
||||
#include "xlwipconfig.h"
|
||||
#include "xemac_ieee_reg.h"
|
||||
|
||||
#if !NO_SYS
|
||||
#endif
|
||||
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/priv/tcp_priv.h"
|
||||
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/xadapter.h"
|
||||
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
|
||||
#include "netif/xemacliteif.h"
|
||||
#endif
|
||||
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
|
||||
#include "netif/xaxiemacif.h"
|
||||
#endif
|
||||
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_GEM
|
||||
#include "netif/xemacpsif.h"
|
||||
#endif
|
||||
|
||||
#if !NO_SYS
|
||||
#include "lwip/tcpip.h"
|
||||
|
||||
#define THREAD_STACKSIZE 256
|
||||
#define LINK_DETECT_THREAD_INTERVAL 1000 /* one second */
|
||||
|
||||
void link_detect_thread(void *p);
|
||||
#endif
|
||||
|
||||
/* global lwip debug variable used for debugging */
|
||||
int lwip_runtime_debug = 0;
|
||||
|
||||
u32_t phyaddrforemac;
|
||||
|
||||
void
|
||||
lwip_raw_init()
|
||||
{
|
||||
ip_init(); /* Doesn't do much, it should be called to handle future changes. */
|
||||
#if LWIP_UDP
|
||||
udp_init(); /* Clears the UDP PCB list. */
|
||||
#endif
|
||||
#if LWIP_TCP
|
||||
tcp_init(); /* Clears the TCP PCB list and clears some internal TCP timers. */
|
||||
/* Note: you must call tcp_fasttmr() and tcp_slowtmr() at the */
|
||||
/* predefined regular intervals after this initialization. */
|
||||
#endif
|
||||
}
|
||||
|
||||
static enum xemac_types
|
||||
find_mac_type(unsigned base)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef SDT
|
||||
for (i = 0; xtopology[i].emac_baseaddr != NULL; i++) {
|
||||
#else
|
||||
for (i = 0; i < xtopology_n_emacs; i++) {
|
||||
#endif
|
||||
if (xtopology[i].emac_baseaddr == base)
|
||||
return xtopology[i].emac_type;
|
||||
}
|
||||
|
||||
return xemac_type_unknown;
|
||||
}
|
||||
|
||||
int
|
||||
xtopology_find_index(unsigned base)
|
||||
{
|
||||
int i;
|
||||
#ifdef SDT
|
||||
for (i = 0; xtopology[i].emac_baseaddr != NULL; i++) {
|
||||
#else
|
||||
for (i = 0; i < xtopology_n_emacs; i++) {
|
||||
#endif
|
||||
if (xtopology[i].emac_baseaddr == base)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* xemac_add: this is a wrapper around lwIP's netif_add function.
|
||||
* The objective is to provide portability between the different Xilinx MAC's
|
||||
* This function can be used to add both xps_ethernetlite and xps_ll_temac
|
||||
* based interfaces
|
||||
*/
|
||||
struct netif *
|
||||
xemac_add(struct netif *netif,
|
||||
ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw,
|
||||
unsigned char *mac_ethernet_address,
|
||||
UINTPTR mac_baseaddr)
|
||||
{
|
||||
int i;
|
||||
struct netif * nif = NULL;
|
||||
|
||||
/* set mac address */
|
||||
netif->hwaddr_len = 6;
|
||||
for (i = 0; i < 6; i++)
|
||||
netif->hwaddr[i] = mac_ethernet_address[i];
|
||||
|
||||
/* initialize based on MAC type */
|
||||
switch (find_mac_type(mac_baseaddr)) {
|
||||
case xemac_type_xps_emaclite:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
|
||||
nif = netif_add(netif, ipaddr, netmask, gw,
|
||||
(void*)(UINTPTR)mac_baseaddr,
|
||||
xemacliteif_init,
|
||||
#if NO_SYS
|
||||
ethernet_input
|
||||
#else
|
||||
tcpip_input
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
nif = NULL;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case xemac_type_axi_ethernet:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
|
||||
nif = netif_add(netif, ipaddr, netmask, gw,
|
||||
(void*)(UINTPTR)mac_baseaddr,
|
||||
xaxiemacif_init,
|
||||
#if NO_SYS
|
||||
ethernet_input
|
||||
#else
|
||||
tcpip_input
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
nif = NULL;
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined (__arm__) || defined (__aarch64__)
|
||||
case xemac_type_emacps:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_GEM
|
||||
nif = netif_add(netif, ipaddr, netmask, gw,
|
||||
(void*)(UINTPTR)mac_baseaddr,
|
||||
xemacpsif_init,
|
||||
#if NO_SYS
|
||||
ethernet_input
|
||||
#else
|
||||
tcpip_input
|
||||
#endif
|
||||
|
||||
);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
xil_printf("unable to determine type of EMAC with baseaddress 0x%08lx\r\n",
|
||||
(UINTPTR)mac_baseaddr);
|
||||
}
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
/* Start thread to detect link periodically for Hot Plug autodetect */
|
||||
sys_thread_new("link_detect_thread", link_detect_thread, netif,
|
||||
THREAD_STACKSIZE, tskIDLE_PRIORITY);
|
||||
#endif
|
||||
|
||||
return nif;
|
||||
}
|
||||
|
||||
#if !NO_SYS
|
||||
/*
|
||||
* The input thread calls lwIP to process any received packets.
|
||||
* This thread waits until a packet is received (sem_rx_data_available),
|
||||
* and then calls xemacif_input which processes 1 packet at a time.
|
||||
*/
|
||||
void
|
||||
xemacif_input_thread(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *emac = (struct xemac_s *)netif->state;
|
||||
while (1) {
|
||||
/* sleep until there are packets to process
|
||||
* This semaphore is set by the packet receive interrupt
|
||||
* routine.
|
||||
*/
|
||||
sys_sem_wait(&emac->sem_rx_data_available);
|
||||
|
||||
/* move all received packets to lwIP */
|
||||
xemacif_input(netif);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
xemacif_input(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *emac = (struct xemac_s *)netif->state;
|
||||
|
||||
int n_packets = 0;
|
||||
|
||||
switch (emac->type) {
|
||||
case xemac_type_xps_emaclite:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
|
||||
n_packets = xemacliteif_input(netif);
|
||||
break;
|
||||
#else
|
||||
xil_printf("incorrect configuration: xps_ethernetlite drivers not present?");
|
||||
while(1);
|
||||
return 0;
|
||||
#endif
|
||||
case xemac_type_axi_ethernet:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
|
||||
n_packets = xaxiemacif_input(netif);
|
||||
break;
|
||||
#else
|
||||
xil_printf("incorrect configuration: axi_ethernet drivers not present?");
|
||||
while(1);
|
||||
return 0;
|
||||
#endif
|
||||
#if defined (__arm__) || defined (__aarch64__)
|
||||
case xemac_type_emacps:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_GEM
|
||||
n_packets = xemacpsif_input(netif);
|
||||
break;
|
||||
#else
|
||||
xil_printf("incorrect configuration: ps7_ethernet drivers not present?\r\n");
|
||||
while(1);
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
xil_printf("incorrect configuration: unknown temac type");
|
||||
while(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return n_packets;
|
||||
}
|
||||
|
||||
#ifdef SGMII_FIXED_LINK
|
||||
static u32_t pcs_link_detect(XEmacPs *xemacp)
|
||||
{
|
||||
u16_t status;
|
||||
|
||||
status = XEmacPs_ReadReg(xemacp->Config.BaseAddress, XEMACPS_PCS_STATUS_OFFSET);
|
||||
status = XEmacPs_ReadReg(xemacp->Config.BaseAddress, XEMACPS_PCS_STATUS_OFFSET);
|
||||
status &= XEMACPS_PCS_STATUS_LINK_STATUS_MASK;
|
||||
if (status)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_GEM)
|
||||
void emacps_link_status(struct netif *netif, xemacpsif_s *xemacs, XEmacPs *xemacp)
|
||||
{
|
||||
u32_t link_speed, phy_link_status, phy_autoneg_status;
|
||||
u16_t status;
|
||||
|
||||
if ((xemacp->IsReady != (u32)XIL_COMPONENT_IS_READY) ||
|
||||
(xemacs->eth_link_status == ETH_LINK_UNDEFINED))
|
||||
return;
|
||||
#ifndef SGMII_FIXED_LINK
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XEmacPs_PhyRead(xemacp, phyaddrforemac, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XEmacPs_PhyRead(xemacp, phyaddrforemac, IEEE_STATUS_REG_OFFSET, &status);
|
||||
if (status & IEEE_STAT_LINK_STATUS)
|
||||
phy_link_status = 1;
|
||||
else
|
||||
phy_link_status = 0;
|
||||
|
||||
if (status & IEEE_STAT_AUTONEGOTIATE_COMPLETE)
|
||||
phy_autoneg_status = 1;
|
||||
else
|
||||
phy_autoneg_status = 0;
|
||||
|
||||
#else
|
||||
phy_link_status = pcs_link_detect(xemacp);
|
||||
#endif
|
||||
|
||||
if ((xemacs->eth_link_status == ETH_LINK_UP) && (!phy_link_status))
|
||||
xemacs->eth_link_status = ETH_LINK_DOWN;
|
||||
|
||||
switch (xemacs->eth_link_status) {
|
||||
case ETH_LINK_UNDEFINED:
|
||||
case ETH_LINK_UP:
|
||||
return;
|
||||
case ETH_LINK_DOWN:
|
||||
netif_set_link_down(netif);
|
||||
xemacs->eth_link_status = ETH_LINK_NEGOTIATING;
|
||||
xil_printf("Ethernet Link down\r\n");
|
||||
break;
|
||||
case ETH_LINK_NEGOTIATING:
|
||||
if (phy_link_status && phy_autoneg_status) {
|
||||
|
||||
link_speed = phy_setup_emacps(xemacp,
|
||||
phyaddrforemac);
|
||||
XEmacPs_SetOperatingSpeed(xemacp, link_speed);
|
||||
netif_set_link_up(netif);
|
||||
xemacs->eth_link_status = ETH_LINK_UP;
|
||||
xil_printf("Ethernet Link up\r\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)
|
||||
void axieth_link_status(struct netif *netif, xaxiemacif_s *xemacs, XAxiEthernet *xemacp)
|
||||
{
|
||||
u32_t link_speed, phy_link_status, phy_autoneg_status;
|
||||
u16_t status;
|
||||
|
||||
if ((xemacp->IsReady != (u32)XIL_COMPONENT_IS_READY) ||
|
||||
(xemacs->eth_link_status == ETH_LINK_UNDEFINED))
|
||||
return;
|
||||
#ifndef SGMII_FIXED_LINK
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XAxiEthernet_PhyRead(xemacp, phyaddrforemac, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XAxiEthernet_PhyRead(xemacp, phyaddrforemac, IEEE_STATUS_REG_OFFSET, &status);
|
||||
if (status & IEEE_STAT_LINK_STATUS)
|
||||
phy_link_status = 1;
|
||||
else
|
||||
phy_link_status = 0;
|
||||
|
||||
if (status & IEEE_STAT_AUTONEGOTIATE_COMPLETE)
|
||||
phy_autoneg_status = 1;
|
||||
else
|
||||
phy_autoneg_status = 0;
|
||||
#else
|
||||
phy_link_status = pcs_link_detect(xemacp);
|
||||
#endif
|
||||
|
||||
if ((xemacs->eth_link_status == ETH_LINK_UP) && (!phy_link_status))
|
||||
xemacs->eth_link_status = ETH_LINK_DOWN;
|
||||
|
||||
switch (xemacs->eth_link_status) {
|
||||
case ETH_LINK_UNDEFINED:
|
||||
case ETH_LINK_UP:
|
||||
return;
|
||||
case ETH_LINK_DOWN:
|
||||
netif_set_link_down(netif);
|
||||
xemacs->eth_link_status = ETH_LINK_NEGOTIATING;
|
||||
xil_printf("Ethernet Link down\r\n");
|
||||
break;
|
||||
case ETH_LINK_NEGOTIATING:
|
||||
if (phy_link_status && phy_autoneg_status) {
|
||||
|
||||
link_speed = phy_setup_axiemac(xemacp);
|
||||
XAxiEthernet_SetOperatingSpeed(xemacp,link_speed);
|
||||
netif_set_link_up(netif);
|
||||
xemacs->eth_link_status = ETH_LINK_UP;
|
||||
xil_printf("Ethernet Link up\r\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_EMACLITE)
|
||||
void emaclite_link_status(struct netif *netif, xemacliteif_s *xemacs, XEmacLite *xemacp)
|
||||
{
|
||||
u32_t phy_link_status, status, phy_autoneg_status;
|
||||
|
||||
if ((xemacp->IsReady != (u32)XIL_COMPONENT_IS_READY) ||
|
||||
(xemacs->eth_link_status == ETH_LINK_UNDEFINED))
|
||||
return;
|
||||
#ifndef SGMII_FIXED_LINK
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XEmacLite_PhyRead(xemacp, phyaddrforemac, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XEmacLite_PhyRead(xemacp, phyaddrforemac, IEEE_STATUS_REG_OFFSET, &status);
|
||||
if (status & IEEE_STAT_LINK_STATUS)
|
||||
phy_link_status = 1;
|
||||
else
|
||||
phy_link_status = 0;
|
||||
|
||||
if (status & IEEE_STAT_AUTONEGOTIATE_COMPLETE)
|
||||
phy_autoneg_status = 1;
|
||||
else
|
||||
phy_autoneg_status = 0;
|
||||
#else
|
||||
phy_link_status = pcs_link_detect(xemacp);
|
||||
#endif
|
||||
|
||||
if ((xemacs->eth_link_status == ETH_LINK_UP) && (!phy_link_status))
|
||||
xemacs->eth_link_status = ETH_LINK_DOWN;
|
||||
|
||||
switch (xemacs->eth_link_status) {
|
||||
case ETH_LINK_UNDEFINED:
|
||||
case ETH_LINK_UP:
|
||||
return;
|
||||
case ETH_LINK_DOWN:
|
||||
netif_set_link_down(netif);
|
||||
xemacs->eth_link_status = ETH_LINK_NEGOTIATING;
|
||||
xil_printf("Ethernet Link down\r\n");
|
||||
break;
|
||||
case ETH_LINK_NEGOTIATING:
|
||||
if (phy_link_status && phy_autoneg_status) {
|
||||
netif_set_link_up(netif);
|
||||
xemacs->eth_link_status = ETH_LINK_UP;
|
||||
xil_printf("Ethernet Link up\r\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void eth_link_detect(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
|
||||
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_GEM)
|
||||
xemacpsif_s *xemacps = (xemacpsif_s *)(xemac->state);
|
||||
XEmacPs *xemacpsp = &xemacps->emacps;
|
||||
#endif
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)
|
||||
xaxiemacif_s *xaxiemac = (xaxiemacif_s *)(xemac->state);
|
||||
XAxiEthernet *xaxiemacp = &xaxiemac->axi_ethernet;
|
||||
#endif
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_EMACLITE)
|
||||
xemacliteif_s *xemaclite = (xemacliteif_s *)(xemac->state);
|
||||
XEmacLite *xemaclitep = xemaclite->instance;
|
||||
#endif
|
||||
|
||||
switch (xemac->type) {
|
||||
case xemac_type_emacps:
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_GEM)
|
||||
emacps_link_status(netif, xemacps, xemacpsp);
|
||||
#endif
|
||||
break;
|
||||
case xemac_type_xps_emaclite:
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_EMACLITE)
|
||||
emaclite_link_status(netif, xemaclite, xemaclitep);
|
||||
#endif
|
||||
break;
|
||||
case xemac_type_axi_ethernet:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
|
||||
axieth_link_status(netif, xaxiemac, xaxiemacp);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if !NO_SYS
|
||||
void link_detect_thread(void *p)
|
||||
{
|
||||
struct netif *netif = (struct netif *) p;
|
||||
|
||||
while (1) {
|
||||
/* Call eth_link_detect() every second to detect Ethernet link
|
||||
* change.
|
||||
*/
|
||||
eth_link_detect(netif);
|
||||
vTaskDelay(LINK_DETECT_THREAD_INTERVAL / portTICK_RATE_MS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2018 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XEMAC_IEEE_REGS_H_
|
||||
#define __XEMAC_IEEE_REGS_H_
|
||||
|
||||
/* Advertisement control register. */
|
||||
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
|
||||
#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
|
||||
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
|
||||
#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
|
||||
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
|
||||
#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
|
||||
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
|
||||
#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
|
||||
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
|
||||
|
||||
|
||||
#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | \
|
||||
ADVERTISE_10HALF | ADVERTISE_100HALF)
|
||||
#define ADVERTISE_100 (ADVERTISE_100FULL | ADVERTISE_100HALF)
|
||||
#define ADVERTISE_10 (ADVERTISE_10FULL | ADVERTISE_10HALF)
|
||||
|
||||
#define ADVERTISE_1000 0x0300
|
||||
|
||||
|
||||
#define IEEE_CONTROL_REG_OFFSET 0
|
||||
#define IEEE_STATUS_REG_OFFSET 1
|
||||
#define IEEE_AUTONEGO_ADVERTISE_REG 4
|
||||
#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
|
||||
#define IEEE_PARTNER_ABILITIES_2_REG_OFFSET 8
|
||||
#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
|
||||
#define IEEE_1000_ADVERTISE_REG_OFFSET 9
|
||||
#define IEEE_MMD_ACCESS_CONTROL_REG 13
|
||||
#define IEEE_MMD_ACCESS_ADDRESS_DATA_REG 14
|
||||
#define IEEE_COPPER_SPECIFIC_CONTROL_REG 16
|
||||
#define IEEE_SPECIFIC_STATUS_REG 17
|
||||
#define IEEE_COPPER_SPECIFIC_STATUS_REG_2 19
|
||||
#define IEEE_EXT_PHY_SPECIFIC_CONTROL_REG 20
|
||||
#define IEEE_CONTROL_REG_MAC 21
|
||||
#define IEEE_PAGE_ADDRESS_REGISTER 22
|
||||
|
||||
#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
|
||||
#define IEEE_CTRL_LINKSPEED_MASK 0x0040
|
||||
#define IEEE_CTRL_LINKSPEED_1000M 0x0040
|
||||
#define IEEE_CTRL_LINKSPEED_100M 0x2000
|
||||
#define IEEE_CTRL_LINKSPEED_10M 0x0000
|
||||
#define IEEE_CTRL_FULL_DUPLEX 0x100
|
||||
#define IEEE_CTRL_RESET_MASK 0x8000
|
||||
#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
|
||||
#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
|
||||
#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
|
||||
#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
|
||||
#define IEEE_STAT_LINK_STATUS 0x0004
|
||||
#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
|
||||
#define IEEE_AN1_ABILITY_MASK 0x1FE0
|
||||
#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
|
||||
#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
|
||||
#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
|
||||
#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK 0x0030
|
||||
|
||||
#define IEEE_SPEED_MASK 0xC000
|
||||
#define IEEE_SPEED_1000 0x8000
|
||||
#define IEEE_SPEED_100 0x4000
|
||||
|
||||
#define IEEE_ASYMMETRIC_PAUSE_MASK 0x0800
|
||||
#define IEEE_PAUSE_MASK 0x0400
|
||||
#define IEEE_AUTONEG_ERROR_MASK 0x8000
|
||||
|
||||
#define IEEE_MMD_ACCESS_CTRL_DEVAD_MASK 0x1F
|
||||
#define IEEE_MMD_ACCESS_CTRL_PIDEVAD_MASK 0x801F
|
||||
#define IEEE_MMD_ACCESS_CTRL_NOPIDEVAD_MASK 0x401F
|
||||
|
||||
#endif /* __XEMAC_IEEE_REGS_H_ */
|
||||
@@ -0,0 +1,796 @@
|
||||
/*
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xparameters.h>
|
||||
#include "lwipopts.h"
|
||||
#include "xlwipconfig.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/igmp.h"
|
||||
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "netif/xpqueue.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
#include "xemacps.h"
|
||||
|
||||
#if LWIP_IPV6
|
||||
#include "lwip/ethip6.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
#define IFNAME0 't'
|
||||
#define IFNAME1 'e'
|
||||
|
||||
#if LWIP_IGMP
|
||||
static err_t xemacpsif_mac_filter_update (struct netif *netif,
|
||||
ip_addr_t *group, u8_t action);
|
||||
|
||||
static u8_t xemacps_mcast_entry_mask = 0;
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
static err_t xemacpsif_mld6_mac_filter_update (struct netif *netif,
|
||||
ip_addr_t *group, u8_t action);
|
||||
|
||||
static u8_t xemacps_mld6_mcast_entry_mask;
|
||||
#endif
|
||||
|
||||
XEmacPs_Config *mac_config;
|
||||
struct netif *NetIf;
|
||||
|
||||
#if !NO_SYS
|
||||
#if defined(__arm__) && !defined(ARMR5)
|
||||
int32_t lExpireCounter = 0;
|
||||
#define RESETRXTIMEOUT 10
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
extern volatile u32_t notifyinfo[4*XLWIP_CONFIG_N_TX_DESC];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* this function is always called with interrupts off
|
||||
* this function also assumes that there are available BD's
|
||||
*/
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
static err_t _unbuffered_low_level_output(xemacpsif_s *xemacpsif,
|
||||
struct pbuf *p, u32_t block_till_tx_complete, u32_t *to_block_index )
|
||||
#else
|
||||
static err_t _unbuffered_low_level_output(xemacpsif_s *xemacpsif,
|
||||
struct pbuf *p)
|
||||
#endif
|
||||
{
|
||||
XStatus status = 0;
|
||||
err_t err = ERR_MEM;
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||
#endif
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
if (block_till_tx_complete == 1) {
|
||||
status = emacps_sgsend(xemacpsif, p, 1, to_block_index);
|
||||
} else {
|
||||
status = emacps_sgsend(xemacpsif, p, 0, to_block_index);
|
||||
}
|
||||
#else
|
||||
status = emacps_sgsend(xemacpsif, p);
|
||||
#endif
|
||||
if (status != XST_SUCCESS) {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
} else {
|
||||
err = ERR_OK;
|
||||
}
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||
#endif
|
||||
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.xmit++;
|
||||
#endif /* LINK_STATS */
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* low_level_output():
|
||||
*
|
||||
* Should do the actual transmission of the packet. The packet is
|
||||
* contained in the pbuf that is passed to the function. This pbuf
|
||||
* might be chained.
|
||||
*
|
||||
*/
|
||||
|
||||
static err_t low_level_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
err_t err = ERR_MEM;
|
||||
s32_t freecnt;
|
||||
XEmacPs_BdRing *txring;
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
u32_t notfifyblocksleepcntr;
|
||||
u32_t to_block_index;
|
||||
#endif
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
/* check if space is available to send */
|
||||
freecnt = xemacps_is_tx_space_available(xemacpsif);
|
||||
if (freecnt <= 5) {
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
xemacps_process_sent_bds(xemacpsif, txring);
|
||||
}
|
||||
|
||||
if (xemacps_is_tx_space_available(xemacpsif)) {
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
if (netif_is_opt_block_tx_set(netif, NETIF_ENABLE_BLOCKING_TX_FOR_PACKET)) {
|
||||
err = _unbuffered_low_level_output(xemacpsif, p, 1, &to_block_index);
|
||||
} else {
|
||||
err = _unbuffered_low_level_output(xemacpsif, p, 0, &to_block_index);
|
||||
}
|
||||
#else
|
||||
err = _unbuffered_low_level_output(xemacpsif, p);
|
||||
#endif
|
||||
} else {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
xil_printf("pack dropped, no space\r\n");
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
goto return_pack_dropped;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
if (netif_is_opt_block_tx_set(netif, NETIF_ENABLE_BLOCKING_TX_FOR_PACKET)) {
|
||||
/* Wait for approx 1 second before timing out */
|
||||
notfifyblocksleepcntr = 900000;
|
||||
while(notifyinfo[to_block_index] == 1) {
|
||||
usleep(1);
|
||||
notfifyblocksleepcntr--;
|
||||
if (notfifyblocksleepcntr <= 0) {
|
||||
err = ERR_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
netif_clear_opt_block_tx(netif, NETIF_ENABLE_BLOCKING_TX_FOR_PACKET);
|
||||
#endif
|
||||
return_pack_dropped:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* low_level_input():
|
||||
*
|
||||
* Should allocate a pbuf and transfer the bytes of the incoming
|
||||
* packet from the interface into the pbuf.
|
||||
*
|
||||
*/
|
||||
static struct pbuf * low_level_input(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
struct pbuf *p;
|
||||
|
||||
/* see if there is data to process */
|
||||
if (pq_qlength(xemacpsif->recv_q) == 0)
|
||||
return NULL;
|
||||
|
||||
/* return one packet from receive q */
|
||||
p = (struct pbuf *)pq_dequeue(xemacpsif->recv_q);
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* xemacpsif_output():
|
||||
*
|
||||
* This function is called by the TCP/IP stack when an IP packet
|
||||
* should be sent. It calls the function called low_level_output() to
|
||||
* do the actual transmission of the packet.
|
||||
*
|
||||
*/
|
||||
|
||||
static err_t xemacpsif_output(struct netif *netif, struct pbuf *p,
|
||||
const ip_addr_t *ipaddr)
|
||||
{
|
||||
/* resolve hardware address, then send (or queue) packet */
|
||||
return etharp_output(netif, p, ipaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* xemacpsif_input():
|
||||
*
|
||||
* This function should be called when a packet is ready to be read
|
||||
* from the interface. It uses the function low_level_input() that
|
||||
* should handle the actual reception of bytes from the network
|
||||
* interface.
|
||||
*
|
||||
* Returns the number of packets read (max 1 packet on success,
|
||||
* 0 if there are no packets)
|
||||
*
|
||||
*/
|
||||
|
||||
s32_t xemacpsif_input(struct netif *netif)
|
||||
{
|
||||
struct eth_hdr *ethhdr;
|
||||
struct pbuf *p;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
#if !NO_SYS
|
||||
while (1)
|
||||
#endif
|
||||
{
|
||||
/* move received packet into a new pbuf */
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
p = low_level_input(netif);
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
/* no packet could be read, silently ignore this */
|
||||
if (p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* points to packet payload, which starts with an Ethernet header */
|
||||
ethhdr = p->payload;
|
||||
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.recv++;
|
||||
#endif /* LINK_STATS */
|
||||
|
||||
switch (htons(ethhdr->type)) {
|
||||
/* IP or ARP packet? */
|
||||
case ETHTYPE_IP:
|
||||
case ETHTYPE_ARP:
|
||||
#if LWIP_IPV6
|
||||
/*IPv6 Packet?*/
|
||||
case ETHTYPE_IPV6:
|
||||
#endif
|
||||
#if PPPOE_SUPPORT
|
||||
/* PPPoE packet? */
|
||||
case ETHTYPE_PPPOEDISC:
|
||||
case ETHTYPE_PPPOE:
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (netif->input(p, netif) != ERR_OK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_input: IP input error\r\n"));
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if !NO_SYS
|
||||
#if defined(__arm__) && !defined(ARMR5)
|
||||
void vTimerCallback( TimerHandle_t pxTimer )
|
||||
{
|
||||
/* Do something if the pxTimer parameter is NULL */
|
||||
configASSERT(pxTimer);
|
||||
|
||||
lExpireCounter++;
|
||||
/* If the timer has expired 100 times then reset RX */
|
||||
if(lExpireCounter >= RESETRXTIMEOUT) {
|
||||
lExpireCounter = 0;
|
||||
xemacpsif_resetrx_on_no_rxdata(NetIf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static err_t low_level_init(struct netif *netif)
|
||||
{
|
||||
UINTPTR mac_address = (UINTPTR)(netif->state);
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
u32 dmacrreg;
|
||||
|
||||
s32_t status = XST_SUCCESS;
|
||||
|
||||
NetIf = netif;
|
||||
|
||||
xemacpsif = mem_malloc(sizeof *xemacpsif);
|
||||
if (xemacpsif == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_init: out of memory\r\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
xemac = mem_malloc(sizeof *xemac);
|
||||
if (xemac == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_init: out of memory\r\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
xemac->state = (void *)xemacpsif;
|
||||
xemac->topology_index = xtopology_find_index(mac_address);
|
||||
xemac->type = xemac_type_emacps;
|
||||
|
||||
xemacpsif->send_q = NULL;
|
||||
xemacpsif->recv_q = pq_create_queue();
|
||||
if (!xemacpsif->recv_q)
|
||||
return ERR_MEM;
|
||||
|
||||
/* maximum transfer unit */
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
netif->mtu = XEMACPS_MTU_JUMBO - XEMACPS_HDR_SIZE;
|
||||
#else
|
||||
netif->mtu = XEMACPS_MTU - XEMACPS_HDR_SIZE;
|
||||
#endif
|
||||
|
||||
#if LWIP_IGMP
|
||||
netif->igmp_mac_filter = xemacpsif_mac_filter_update;
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
netif->mld_mac_filter = xemacpsif_mld6_mac_filter_update;
|
||||
#endif
|
||||
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
|
||||
NETIF_FLAG_LINK_UP;
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
netif->flags |= NETIF_FLAG_MLD6;
|
||||
#endif
|
||||
|
||||
#if LWIP_IGMP
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
#endif
|
||||
|
||||
#if !NO_SYS
|
||||
sys_sem_new(&xemac->sem_rx_data_available, 0);
|
||||
#endif
|
||||
/* obtain config of this emac */
|
||||
mac_config = (XEmacPs_Config *)xemacps_lookup_config((unsigned)(UINTPTR)netif->state);
|
||||
|
||||
#if defined (__aarch64__) && (EL1_NONSECURE == 1)
|
||||
/* Request device to indicate that this library is using it */
|
||||
if (mac_config->BaseAddress == VERSAL_EMACPS_0_BASEADDR) {
|
||||
Xil_Smc(PM_REQUEST_DEVICE_SMC_FID, DEV_GEM_0, 1, 0, 100, 1, 0, 0);
|
||||
}
|
||||
if (mac_config->BaseAddress == VERSAL_EMACPS_0_BASEADDR) {
|
||||
Xil_Smc(PM_REQUEST_DEVICE_SMC_FID, DEV_GEM_1, 1, 0, 100, 1, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
status = XEmacPs_CfgInitialize(&xemacpsif->emacps, mac_config,
|
||||
mac_config->BaseAddress);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("In %s:EmacPs Configuration Failed....\r\n", __func__));
|
||||
}
|
||||
|
||||
/* initialize the mac */
|
||||
init_emacps(xemacpsif, netif);
|
||||
|
||||
dmacrreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET);
|
||||
dmacrreg = dmacrreg | (0x00000010);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET, dmacrreg);
|
||||
#if !NO_SYS
|
||||
#if defined(__arm__) && !defined(ARMR5)
|
||||
/* Freertos tick is 10ms by default; set period to the same */
|
||||
xemac->xTimer = xTimerCreate("Timer", 10, pdTRUE, ( void * ) 1, vTimerCallback);
|
||||
if (xemac->xTimer == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("In %s:Timer creation failed....\r\n", __func__));
|
||||
} else {
|
||||
if(xTimerStart(xemac->xTimer, 0) != pdPASS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("In %s:Timer start failed....\r\n", __func__));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
setup_isr(xemac);
|
||||
init_dma(xemac);
|
||||
start_emacps(xemacpsif);
|
||||
|
||||
/* replace the state in netif (currently the emac baseaddress)
|
||||
* with the mac instance pointer.
|
||||
*/
|
||||
netif->state = (void *)xemac;
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void HandleEmacPsError(struct xemac_s *xemac)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
s32_t status = XST_SUCCESS;
|
||||
u32 dmacrreg;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
free_txrx_pbufs(xemacpsif);
|
||||
status = XEmacPs_CfgInitialize(&xemacpsif->emacps, mac_config,
|
||||
mac_config->BaseAddress);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("In %s:EmacPs Configuration Failed....\r\n", __func__));
|
||||
}
|
||||
/* initialize the mac */
|
||||
init_emacps_on_error(xemacpsif, NetIf);
|
||||
dmacrreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET);
|
||||
dmacrreg = dmacrreg | (0x01000000);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET, dmacrreg);
|
||||
setup_isr(xemac);
|
||||
init_dma(xemac);
|
||||
start_emacps(xemacpsif);
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
void HandleTxErrors(struct xemac_s *xemac)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
u32 netctrlreg;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, netctrlreg);
|
||||
free_onlytx_pbufs(xemacpsif);
|
||||
|
||||
clean_dma_txdescs(xemac);
|
||||
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, netctrlreg);
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
static u8_t xemacpsif_ip6_addr_ismulticast(ip6_addr_t* ip_addr)
|
||||
{
|
||||
if(ip6_addr_ismulticast_linklocal(ip_addr)||
|
||||
ip6_addr_ismulticast_iflocal(ip_addr) ||
|
||||
ip6_addr_ismulticast_adminlocal(ip_addr)||
|
||||
ip6_addr_ismulticast_sitelocal(ip_addr) ||
|
||||
ip6_addr_ismulticast_orglocal(ip_addr) ||
|
||||
ip6_addr_ismulticast_global(ip_addr)) {
|
||||
/*Return TRUE if IPv6 is Multicast type*/
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void xemacpsif_mld6_mac_hash_update (struct netif *netif, u8_t *ip_addr,
|
||||
u8_t action)
|
||||
{
|
||||
u8_t multicast_mac_addr[6];
|
||||
struct xemac_s *xemac = (struct xemac_s *) (netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *) (xemac->state);
|
||||
XEmacPs_BdRing *txring;
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
|
||||
multicast_mac_addr[0] = LL_IP6_MULTICAST_ADDR_0;
|
||||
multicast_mac_addr[1] = LL_IP6_MULTICAST_ADDR_1;
|
||||
multicast_mac_addr[2] = ip_addr[12];
|
||||
multicast_mac_addr[3] = ip_addr[13];
|
||||
multicast_mac_addr[4] = ip_addr[14];
|
||||
multicast_mac_addr[5] = ip_addr[15];
|
||||
|
||||
/* Wait till all sent packets are acknowledged from HW */
|
||||
while(txring->HwCnt);
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
|
||||
/* Stop Ethernet */
|
||||
XEmacPs_Stop(&xemacpsif->emacps);
|
||||
|
||||
if (action == NETIF_ADD_MAC_FILTER) {
|
||||
/* Set Mulitcast mac address in hash table */
|
||||
XEmacPs_SetHash(&xemacpsif->emacps, multicast_mac_addr);
|
||||
|
||||
} else if (action == NETIF_DEL_MAC_FILTER) {
|
||||
/* Remove Mulitcast mac address in hash table */
|
||||
XEmacPs_DeleteHash(&xemacpsif->emacps, multicast_mac_addr);
|
||||
}
|
||||
|
||||
/* Reset DMA */
|
||||
reset_dma(xemac);
|
||||
|
||||
/* Start Ethernet */
|
||||
XEmacPs_Start(&xemacpsif->emacps);
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
static err_t xemacpsif_mld6_mac_filter_update (struct netif *netif, ip_addr_t *group,
|
||||
u8_t action)
|
||||
{
|
||||
u8_t temp_mask;
|
||||
unsigned int i;
|
||||
u8_t * ip_addr = (u8_t *) group;
|
||||
|
||||
if(!(xemacpsif_ip6_addr_ismulticast((ip6_addr_t*) ip_addr))) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: The requested MAC address is not a multicast address.\r\n", __func__)); LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast address add operation failure !!\r\n"));
|
||||
return ERR_ARG;
|
||||
}
|
||||
if (action == NETIF_ADD_MAC_FILTER) {
|
||||
for (i = 0; i < XEMACPS_MAX_MAC_ADDR; i++) {
|
||||
temp_mask = (0x01) << i;
|
||||
if ((xemacps_mld6_mcast_entry_mask & temp_mask) == temp_mask) {
|
||||
continue;
|
||||
}
|
||||
xemacps_mld6_mcast_entry_mask |= temp_mask;
|
||||
|
||||
/* Update mac address in hash table */
|
||||
xemacpsif_mld6_mac_hash_update(netif, ip_addr, action);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: Multicast MAC address successfully added.\r\n", __func__));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: No multicast address registers left.\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast MAC address add operation failure !!\r\n"));
|
||||
return ERR_MEM;
|
||||
} else if (action == NETIF_DEL_MAC_FILTER) {
|
||||
for (i = 0; i < XEMACPS_MAX_MAC_ADDR; i++) {
|
||||
temp_mask = (0x01) << i;
|
||||
if ((xemacps_mld6_mcast_entry_mask & temp_mask) != temp_mask) {
|
||||
continue;
|
||||
}
|
||||
xemacps_mld6_mcast_entry_mask &= (~temp_mask);
|
||||
|
||||
/* Update mac address in hash table */
|
||||
xemacpsif_mld6_mac_hash_update(netif, ip_addr, action);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: Multicast MAC address successfully removed.\r\n", __func__));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: No multicast address registers present with\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("the requested Multicast MAC address.\r\n"));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast MAC address removal failure!!.\r\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
return ERR_ARG;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IGMP
|
||||
static void xemacpsif_mac_hash_update (struct netif *netif, u8_t *ip_addr,
|
||||
u8_t action)
|
||||
{
|
||||
u8_t multicast_mac_addr[6];
|
||||
struct xemac_s *xemac = (struct xemac_s *) (netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *) (xemac->state);
|
||||
XEmacPs_BdRing *txring;
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
|
||||
multicast_mac_addr[0] = 0x01;
|
||||
multicast_mac_addr[1] = 0x00;
|
||||
multicast_mac_addr[2] = 0x5E;
|
||||
multicast_mac_addr[3] = ip_addr[1] & 0x7F;
|
||||
multicast_mac_addr[4] = ip_addr[2];
|
||||
multicast_mac_addr[5] = ip_addr[3];
|
||||
|
||||
/* Wait till all sent packets are acknowledged from HW */
|
||||
while(txring->HwCnt);
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
|
||||
/* Stop Ethernet */
|
||||
XEmacPs_Stop(&xemacpsif->emacps);
|
||||
|
||||
if (action == IGMP_ADD_MAC_FILTER) {
|
||||
/* Set Mulitcast mac address in hash table */
|
||||
XEmacPs_SetHash(&xemacpsif->emacps, multicast_mac_addr);
|
||||
|
||||
} else if (action == IGMP_DEL_MAC_FILTER) {
|
||||
/* Remove Mulitcast mac address in hash table */
|
||||
XEmacPs_DeleteHash(&xemacpsif->emacps, multicast_mac_addr);
|
||||
}
|
||||
|
||||
/* Reset DMA */
|
||||
reset_dma(xemac);
|
||||
|
||||
/* Start Ethernet */
|
||||
XEmacPs_Start(&xemacpsif->emacps);
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
static err_t xemacpsif_mac_filter_update (struct netif *netif, ip_addr_t *group,
|
||||
u8_t action)
|
||||
{
|
||||
u8_t temp_mask;
|
||||
unsigned int i;
|
||||
u8_t * ip_addr = (u8_t *) group;
|
||||
|
||||
if ((ip_addr[0] < 224) && (ip_addr[0] > 239)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: The requested MAC address is not a multicast address.\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast address add operation failure !!\r\n"));
|
||||
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
if (action == IGMP_ADD_MAC_FILTER) {
|
||||
|
||||
for (i = 0; i < XEMACPS_MAX_MAC_ADDR; i++) {
|
||||
temp_mask = (0x01) << i;
|
||||
if ((xemacps_mcast_entry_mask & temp_mask) == temp_mask) {
|
||||
continue;
|
||||
}
|
||||
xemacps_mcast_entry_mask |= temp_mask;
|
||||
|
||||
/* Update mac address in hash table */
|
||||
xemacpsif_mac_hash_update(netif, ip_addr, action);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: Multicast MAC address successfully added.\r\n", __func__));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
if (i == XEMACPS_MAX_MAC_ADDR) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: No multicast address registers left.\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast MAC address add operation failure !!\r\n"));
|
||||
|
||||
return ERR_MEM;
|
||||
}
|
||||
} else if (action == IGMP_DEL_MAC_FILTER) {
|
||||
for (i = 0; i < XEMACPS_MAX_MAC_ADDR; i++) {
|
||||
temp_mask = (0x01) << i;
|
||||
if ((xemacps_mcast_entry_mask & temp_mask) != temp_mask) {
|
||||
continue;
|
||||
}
|
||||
xemacps_mcast_entry_mask &= (~temp_mask);
|
||||
|
||||
/* Update mac address in hash table */
|
||||
xemacpsif_mac_hash_update(netif, ip_addr, action);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: Multicast MAC address successfully removed.\r\n", __func__));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
if (i == XEMACPS_MAX_MAC_ADDR) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: No multicast address registers present with\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("the requested Multicast MAC address.\r\n"));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast MAC address removal failure!!.\r\n"));
|
||||
|
||||
return ERR_MEM;
|
||||
}
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xemacpsif_init():
|
||||
*
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* network interface. It calls the function low_level_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
*/
|
||||
|
||||
err_t xemacpsif_init(struct netif *netif)
|
||||
{
|
||||
#if LWIP_SNMP
|
||||
/* ifType ethernetCsmacd(6) @see RFC1213 */
|
||||
netif->link_type = 6;
|
||||
/* your link speed here */
|
||||
netif->link_speed = ;
|
||||
netif->ts = 0;
|
||||
netif->ifinoctets = 0;
|
||||
netif->ifinucastpkts = 0;
|
||||
netif->ifinnucastpkts = 0;
|
||||
netif->ifindiscards = 0;
|
||||
netif->ifoutoctets = 0;
|
||||
netif->ifoutucastpkts = 0;
|
||||
netif->ifoutnucastpkts = 0;
|
||||
netif->ifoutdiscards = 0;
|
||||
#endif
|
||||
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
netif->output = xemacpsif_output;
|
||||
netif->linkoutput = low_level_output;
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif
|
||||
|
||||
low_level_init(netif);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* xemacpsif_resetrx_on_no_rxdata():
|
||||
*
|
||||
* Should be called by the user at regular intervals, typically
|
||||
* from a timer (100 msecond). This is to provide a SW workaround
|
||||
* for the HW bug (SI #692601). Please refer to the function header
|
||||
* for the function resetrx_on_no_rxdata in xemacpsif_dma.c to
|
||||
* know more about the SI.
|
||||
*
|
||||
*/
|
||||
|
||||
void xemacpsif_resetrx_on_no_rxdata(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
|
||||
resetrx_on_no_rxdata(xemacpsif);
|
||||
}
|
||||
@@ -0,0 +1,951 @@
|
||||
/*
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwipopts.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
|
||||
#include "netif/xadapter.h"
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
#include "xlwipconfig.h"
|
||||
#include "xparameters.h"
|
||||
#include "xparameters_ps.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xil_mmu.h"
|
||||
#if defined (ARMR5)
|
||||
#include "xreg_cortexr5.h"
|
||||
#endif
|
||||
#ifdef CONFIG_XTRACE
|
||||
#include "xtrace.h"
|
||||
#endif
|
||||
#if !NO_SYS
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "timers.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDT
|
||||
#include "xinterrupt_wrap.h"
|
||||
#else
|
||||
#define INTC_BASE_ADDR XPAR_SCUGIC_0_CPU_BASEADDR
|
||||
#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_0_DIST_BASEADDR
|
||||
#endif
|
||||
|
||||
/* Byte alignment of BDs */
|
||||
#define BD_ALIGNMENT (XEMACPS_DMABD_MINIMUM_ALIGNMENT*2)
|
||||
|
||||
/* A max of 4 different ethernet interfaces are supported */
|
||||
static UINTPTR tx_pbufs_storage[4*XLWIP_CONFIG_N_TX_DESC];
|
||||
static UINTPTR rx_pbufs_storage[4*XLWIP_CONFIG_N_RX_DESC];
|
||||
|
||||
static s32_t emac_intr_num;
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
volatile u32_t notifyinfo[4*XLWIP_CONFIG_N_TX_DESC];
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Each BD is of 8 bytes of size and the BDs (BD chain) need to be put
|
||||
* at uncached memory location. If they are not put at uncached
|
||||
* locations, the user needs to flush or invalidate for each BD/packet.
|
||||
* However, the flush or invalidate can happen over a cache line which can
|
||||
* span multiple BDs. This means a flush or invalidate of one BD can actually
|
||||
* flush/invalidate multiple BDs adjacent to the targeted BD.Assuming that
|
||||
* the user and hardware both update the BD fields, this operation from user
|
||||
* can potentially overwrite the updates done by hardware or user.
|
||||
* To avoid this, it is always safe to put the BD chains for Rx and tx side
|
||||
* at uncached memory location.
|
||||
*
|
||||
* The Xilinx standalone BSP for Cortex A9 implements only primary page tables.
|
||||
* Each table entry corresponds to 1 MB of address map. This means, if a memory
|
||||
* region has to be made uncached, the minimum granularity will be of 1 MB.
|
||||
*
|
||||
* The implementation below allocates a 1 MB of u8 array aligned to 1 MB.
|
||||
* This ensures that this array is put at 1 MB aligned memory (e.g. 0x1200000)
|
||||
* and accupies memory of 1 MB. The init_dma function then changes 1 MB of this
|
||||
* region to make it uncached (strongly ordered).
|
||||
* This increases the bss section of the program significantly and can be a
|
||||
* wastage of memory. The reason beings, BDs will hardly occupy few KBs of
|
||||
* memory and the rest of 1 MB of memory will be unused.
|
||||
*
|
||||
* If a program uses other peripherals that have DMAs/bus masters and need
|
||||
* uncached memory, they may also end of following the same approach. This
|
||||
* definitely aggravates the memory wastage issue. To avoid all this, the user
|
||||
* can create a new 1 MB section in the linker script and reserve it for such
|
||||
* use cases that need uncached memory location. They can then have their own
|
||||
* memory allocation logic in their application that allocates uncached memory
|
||||
* from this 1 MB location. For such a case, changes need to be done in this
|
||||
* file and appropriate uncached memory allocated through other means can be
|
||||
* used.
|
||||
*
|
||||
* The present implementation here allocates 1 MB of uncached memory. It
|
||||
* reserves of 64 KB of memory for each BD chain. 64 KB of memory means 8192 of
|
||||
* BDs for each BD chain which is more than enough for any application.
|
||||
* Assuming that both emac0 and emac1 are present, 256 KB of memory is allocated
|
||||
* for BDs. The rest 768 KB of memory is just unused.
|
||||
*********************************************************************************/
|
||||
|
||||
#if defined __aarch64__
|
||||
u8_t emac_bd_space[0x200000] __attribute__ ((aligned (0x200000)));
|
||||
#else
|
||||
u8_t emac_bd_space[0x100000] __attribute__ ((aligned (0x100000)));
|
||||
#endif
|
||||
static volatile u32_t bd_space_index = 0;
|
||||
static volatile u32_t bd_space_attr_set = 0;
|
||||
|
||||
#if !NO_SYS
|
||||
extern u32 xInsideISR;
|
||||
#endif
|
||||
|
||||
#define XEMACPS_BD_TO_INDEX(ringptr, bdptr) \
|
||||
(((UINTPTR)bdptr - (UINTPTR)(ringptr)->BaseBdAddr) / (ringptr)->Separation)
|
||||
|
||||
|
||||
s32_t xemacps_is_tx_space_available(xemacpsif_s *emac)
|
||||
{
|
||||
XEmacPs_BdRing *txring;
|
||||
s32_t freecnt = 0;
|
||||
|
||||
txring = &(XEmacPs_GetTxRing(&emac->emacps));
|
||||
|
||||
/* tx space is available as long as there are valid BD's */
|
||||
freecnt = XEmacPs_BdRingGetFreeCnt(txring);
|
||||
return freecnt;
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
u32_t get_base_index_txpbufsstorage (xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32_t index;
|
||||
#ifdef XPAR_XEMACPS_0_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
index = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_1_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_1_BASEADDR) {
|
||||
index = XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_2_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_2_BASEADDR) {
|
||||
index = 2 * XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_3_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_3_BASEADDR) {
|
||||
index = 3 * XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
return index;
|
||||
}
|
||||
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
static inline
|
||||
u32_t get_base_index_tasknotifyinfo (xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32_t index;
|
||||
#ifdef XPAR_XEMACPS_0_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
index = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_1_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_1_BASEADDR) {
|
||||
index = XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_2_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_2_BASEADDR) {
|
||||
index = 2 * XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_3_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_3_BASEADDR) {
|
||||
index = 3 * XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
return index;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline
|
||||
u32_t get_base_index_rxpbufsstorage (xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32_t index;
|
||||
#ifdef XPAR_XEMACPS_0_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
index = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_1_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_1_BASEADDR) {
|
||||
index = XLWIP_CONFIG_N_RX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_2_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_2_BASEADDR) {
|
||||
index = 2 * XLWIP_CONFIG_N_RX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_3_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_3_BASEADDR) {
|
||||
index = 3 * XLWIP_CONFIG_N_RX_DESC;
|
||||
}
|
||||
#endif
|
||||
return index;
|
||||
}
|
||||
|
||||
void xemacps_process_sent_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *txring)
|
||||
{
|
||||
XEmacPs_Bd *txbdset;
|
||||
XEmacPs_Bd *curbdpntr;
|
||||
s32_t n_bds;
|
||||
XStatus status;
|
||||
s32_t n_pbufs_freed = 0;
|
||||
u32_t bdindex;
|
||||
struct pbuf *p;
|
||||
u32 *temp;
|
||||
u32_t index;
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
u32_t tx_task_notifier_index;
|
||||
#endif
|
||||
|
||||
index = get_base_index_txpbufsstorage (xemacpsif);
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
tx_task_notifier_index = get_base_index_tasknotifyinfo (xemacpsif);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
/* obtain processed BD's */
|
||||
n_bds = XEmacPs_BdRingFromHwTx(txring,
|
||||
XLWIP_CONFIG_N_TX_DESC, &txbdset);
|
||||
if (n_bds == 0) {
|
||||
return;
|
||||
}
|
||||
/* free the processed BD's */
|
||||
n_pbufs_freed = n_bds;
|
||||
curbdpntr = txbdset;
|
||||
while (n_pbufs_freed > 0) {
|
||||
bdindex = XEMACPS_BD_TO_INDEX(txring, curbdpntr);
|
||||
temp = (u32 *)curbdpntr;
|
||||
*temp = 0;
|
||||
temp++;
|
||||
if (bdindex == (XLWIP_CONFIG_N_TX_DESC - 1)) {
|
||||
*temp = 0xC0000000;
|
||||
} else {
|
||||
*temp = 0x80000000;
|
||||
}
|
||||
dsb();
|
||||
p = (struct pbuf *)tx_pbufs_storage[index + bdindex];
|
||||
if (p != NULL) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
notifyinfo[tx_task_notifier_index + bdindex] = 0;
|
||||
#endif
|
||||
tx_pbufs_storage[index + bdindex] = 0;
|
||||
curbdpntr = XEmacPs_BdRingNext(txring, curbdpntr);
|
||||
n_pbufs_freed--;
|
||||
dsb();
|
||||
}
|
||||
|
||||
status = XEmacPs_BdRingFree(txring, n_bds, txbdset);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Failure while freeing in Tx Done ISR\r\n"));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void emacps_send_handler(void *arg)
|
||||
{
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
XEmacPs_BdRing *txringptr;
|
||||
u32_t regval;
|
||||
#if !NO_SYS
|
||||
xInsideISR++;
|
||||
#endif
|
||||
xemac = (struct xemac_s *)(arg);
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
txringptr = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,XEMACPS_TXSR_OFFSET, regval);
|
||||
|
||||
/* If Transmit done interrupt is asserted, process completed BD's */
|
||||
xemacps_process_sent_bds(xemacpsif, txringptr);
|
||||
#if !NO_SYS
|
||||
xInsideISR--;
|
||||
#endif
|
||||
}
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p,
|
||||
u32_t block_till_tx_complete, u32_t *to_block_index)
|
||||
#else
|
||||
XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p)
|
||||
#endif
|
||||
{
|
||||
struct pbuf *q;
|
||||
s32_t n_pbufs;
|
||||
XEmacPs_Bd *txbdset, *txbd, *last_txbd = NULL;
|
||||
XEmacPs_Bd *temp_txbd;
|
||||
XStatus status;
|
||||
XEmacPs_BdRing *txring;
|
||||
u32_t bdindex = 0;
|
||||
u32_t index;
|
||||
u32_t max_fr_size;
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
u32_t tx_task_notifier_index;
|
||||
#endif
|
||||
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
|
||||
index = get_base_index_txpbufsstorage (xemacpsif);
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
tx_task_notifier_index = get_base_index_tasknotifyinfo (xemacpsif);
|
||||
#endif
|
||||
|
||||
/* first count the number of pbufs */
|
||||
for (q = p, n_pbufs = 0; q != NULL; q = q->next)
|
||||
n_pbufs++;
|
||||
|
||||
/* obtain as many BD's */
|
||||
status = XEmacPs_BdRingAlloc(txring, n_pbufs, &txbdset);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("sgsend: Error allocating TxBD\r\n"));
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
for(q = p, txbd = txbdset; q != NULL; q = q->next) {
|
||||
bdindex = XEMACPS_BD_TO_INDEX(txring, txbd);
|
||||
if (tx_pbufs_storage[index + bdindex] != 0) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("PBUFS not available\r\n"));
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/* Send the data from the pbuf to the interface, one pbuf at a
|
||||
time. The size of the data in each pbuf is kept in the ->len
|
||||
variable. */
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheFlushRange((UINTPTR)q->payload, (UINTPTR)q->len);
|
||||
}
|
||||
|
||||
XEmacPs_BdSetAddressTx(txbd, (UINTPTR)q->payload);
|
||||
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
max_fr_size = MAX_FRAME_SIZE_JUMBO - 18;
|
||||
#else
|
||||
max_fr_size = XEMACPS_MAX_FRAME_SIZE - 18;
|
||||
#endif
|
||||
if (q->len > max_fr_size)
|
||||
XEmacPs_BdSetLength(txbd, max_fr_size & 0x3FFF);
|
||||
else
|
||||
XEmacPs_BdSetLength(txbd, q->len & 0x3FFF);
|
||||
|
||||
tx_pbufs_storage[index + bdindex] = (UINTPTR)q;
|
||||
|
||||
pbuf_ref(q);
|
||||
last_txbd = txbd;
|
||||
XEmacPs_BdClearLast(txbd);
|
||||
txbd = XEmacPs_BdRingNext(txring, txbd);
|
||||
}
|
||||
#if LWIP_UDP_OPT_BLOCK_TX_TILL_COMPLETE
|
||||
if (block_till_tx_complete == 1) {
|
||||
notifyinfo[tx_task_notifier_index + bdindex] = 1;
|
||||
*to_block_index = tx_task_notifier_index + bdindex;
|
||||
}
|
||||
#endif
|
||||
XEmacPs_BdSetLast(last_txbd);
|
||||
/* For fragmented packets, remember the 1st BD allocated for the 1st
|
||||
packet fragment. The used bit for this BD should be cleared at the end
|
||||
after clearing out used bits for other fragments. For packets without
|
||||
just remember the allocated BD. */
|
||||
temp_txbd = txbdset;
|
||||
txbd = txbdset;
|
||||
txbd = XEmacPs_BdRingNext(txring, txbd);
|
||||
q = p->next;
|
||||
for(; q != NULL; q = q->next) {
|
||||
XEmacPs_BdClearTxUsed(txbd);
|
||||
txbd = XEmacPs_BdRingNext(txring, txbd);
|
||||
}
|
||||
XEmacPs_BdClearTxUsed(temp_txbd);
|
||||
dsb();
|
||||
|
||||
status = XEmacPs_BdRingToHw(txring, n_pbufs, txbdset);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("sgsend: Error submitting TxBD\r\n"));
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/* Start transmit */
|
||||
XEmacPs_WriteReg((xemacpsif->emacps).Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET,
|
||||
(XEmacPs_ReadReg((xemacpsif->emacps).Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET) | XEMACPS_NWCTRL_STARTTX_MASK));
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup_rx_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *rxring)
|
||||
{
|
||||
XEmacPs_Bd *rxbd;
|
||||
XStatus status;
|
||||
struct pbuf *p;
|
||||
u32_t freebds;
|
||||
u32_t bdindex;
|
||||
u32 *temp;
|
||||
u32_t index;
|
||||
|
||||
index = get_base_index_rxpbufsstorage (xemacpsif);
|
||||
|
||||
freebds = XEmacPs_BdRingGetFreeCnt (rxring);
|
||||
while (freebds > 0) {
|
||||
freebds--;
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
p = pbuf_alloc(PBUF_RAW, MAX_FRAME_SIZE_JUMBO, PBUF_POOL);
|
||||
#else
|
||||
p = pbuf_alloc(PBUF_RAW, XEMACPS_MAX_FRAME_SIZE, PBUF_POOL);
|
||||
#endif
|
||||
if (!p) {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.memerr++;
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
xil_printf("unable to alloc pbuf in recv_handler\r\n");
|
||||
return;
|
||||
}
|
||||
status = XEmacPs_BdRingAlloc(rxring, 1, &rxbd);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("setup_rx_bds: Error allocating RxBD\r\n"));
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
status = XEmacPs_BdRingToHw(rxring, 1, rxbd);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Error committing RxBD to hardware: "));
|
||||
if (status == XST_DMA_SG_LIST_ERROR) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("XST_DMA_SG_LIST_ERROR: this function was called out of sequence with XEmacPs_BdRingAlloc()\r\n"));
|
||||
}
|
||||
else {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("set of BDs was rejected because the first BD did not have its start-of-packet bit set, or the last BD did not have its end-of-packet bit set, or any one of the BD set has 0 as length value\r\n"));
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
XEmacPs_BdRingUnAlloc(rxring, 1, rxbd);
|
||||
return;
|
||||
}
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, (UINTPTR)MAX_FRAME_SIZE_JUMBO);
|
||||
}
|
||||
#else
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, (UINTPTR)XEMACPS_MAX_FRAME_SIZE);
|
||||
}
|
||||
#endif
|
||||
bdindex = XEMACPS_BD_TO_INDEX(rxring, rxbd);
|
||||
temp = (u32 *)rxbd;
|
||||
temp++;
|
||||
/* Status field should be cleared first to avoid drops */
|
||||
*temp = 0;
|
||||
dsb();
|
||||
|
||||
/* Set high address when required */
|
||||
#ifdef __aarch64__
|
||||
XEmacPs_BdWrite(rxbd, XEMACPS_BD_ADDR_HI_OFFSET,
|
||||
(((UINTPTR)p->payload) & ULONG64_HI_MASK) >> 32U);
|
||||
#endif
|
||||
/* Set address field; add WRAP bit on last descriptor */
|
||||
if (bdindex == (XLWIP_CONFIG_N_RX_DESC - 1)) {
|
||||
XEmacPs_BdWrite(rxbd, XEMACPS_BD_ADDR_OFFSET, ((UINTPTR)p->payload | XEMACPS_RXBUF_WRAP_MASK));
|
||||
} else {
|
||||
XEmacPs_BdWrite(rxbd, XEMACPS_BD_ADDR_OFFSET, (UINTPTR)p->payload);
|
||||
}
|
||||
|
||||
rx_pbufs_storage[index + bdindex] = (UINTPTR)p;
|
||||
}
|
||||
}
|
||||
|
||||
void emacps_recv_handler(void *arg)
|
||||
{
|
||||
struct pbuf *p;
|
||||
XEmacPs_Bd *rxbdset, *curbdptr;
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
XEmacPs_BdRing *rxring;
|
||||
volatile s32_t bd_processed;
|
||||
s32_t rx_bytes, k;
|
||||
u32_t bdindex;
|
||||
u32_t regval;
|
||||
u32_t index;
|
||||
u32_t gigeversion;
|
||||
|
||||
xemac = (struct xemac_s *)(arg);
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps);
|
||||
|
||||
#if !NO_SYS
|
||||
xInsideISR++;
|
||||
#endif
|
||||
|
||||
gigeversion = ((Xil_In32(xemacpsif->emacps.Config.BaseAddress + 0xFC)) >> 16) & 0xFFF;
|
||||
index = get_base_index_rxpbufsstorage (xemacpsif);
|
||||
/*
|
||||
* If Reception done interrupt is asserted, call RX call back function
|
||||
* to handle the processed BDs and then raise the according flag.
|
||||
*/
|
||||
regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET, regval);
|
||||
if (gigeversion <= 2) {
|
||||
resetrx_on_no_rxdata(xemacpsif);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
|
||||
bd_processed = XEmacPs_BdRingFromHwRx(rxring, XLWIP_CONFIG_N_RX_DESC, &rxbdset);
|
||||
if (bd_processed <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (k = 0, curbdptr=rxbdset; k < bd_processed; k++) {
|
||||
|
||||
bdindex = XEMACPS_BD_TO_INDEX(rxring, curbdptr);
|
||||
p = (struct pbuf *)rx_pbufs_storage[index + bdindex];
|
||||
|
||||
/*
|
||||
* Adjust the buffer size to the actual number of bytes received.
|
||||
*/
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
rx_bytes = XEmacPs_GetRxFrameSize(&xemacpsif->emacps, curbdptr);
|
||||
#else
|
||||
rx_bytes = XEmacPs_BdGetLength(curbdptr);
|
||||
#endif
|
||||
pbuf_realloc(p, rx_bytes);
|
||||
|
||||
/* Invalidate RX frame before queuing to handle
|
||||
* L1 cache prefetch conditions on any architecture.
|
||||
*/
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, rx_bytes);
|
||||
}
|
||||
|
||||
/* store it in the receive queue,
|
||||
* where it'll be processed by a different handler
|
||||
*/
|
||||
if (pq_enqueue(xemacpsif->recv_q, (void*)p) < 0) {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.memerr++;
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
pbuf_free(p);
|
||||
}
|
||||
curbdptr = XEmacPs_BdRingNext( rxring, curbdptr);
|
||||
}
|
||||
/* free up the BD's */
|
||||
XEmacPs_BdRingFree(rxring, bd_processed, rxbdset);
|
||||
setup_rx_bds(xemacpsif, rxring);
|
||||
}
|
||||
#if !NO_SYS
|
||||
sys_sem_signal(&xemac->sem_rx_data_available);
|
||||
xInsideISR--;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void clean_dma_txdescs(struct xemac_s *xemac)
|
||||
{
|
||||
XEmacPs_Bd bdtemplate;
|
||||
XEmacPs_BdRing *txringptr;
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
|
||||
txringptr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
|
||||
|
||||
XEmacPs_BdClear(&bdtemplate);
|
||||
XEmacPs_BdSetStatus(&bdtemplate, XEMACPS_TXBUF_USED_MASK);
|
||||
|
||||
/*
|
||||
* Create the TxBD ring
|
||||
*/
|
||||
XEmacPs_BdRingCreate(txringptr, (UINTPTR) xemacpsif->tx_bdspace,
|
||||
(UINTPTR) xemacpsif->tx_bdspace, BD_ALIGNMENT,
|
||||
XLWIP_CONFIG_N_TX_DESC);
|
||||
XEmacPs_BdRingClone(txringptr, &bdtemplate, XEMACPS_SEND);
|
||||
}
|
||||
|
||||
XStatus init_dma(struct xemac_s *xemac)
|
||||
{
|
||||
XEmacPs_Bd bdtemplate;
|
||||
XEmacPs_BdRing *rxringptr, *txringptr;
|
||||
XEmacPs_Bd *rxbd;
|
||||
struct pbuf *p;
|
||||
XStatus status;
|
||||
s32_t i;
|
||||
u32_t bdindex;
|
||||
volatile UINTPTR tempaddress;
|
||||
u32_t index;
|
||||
u32_t gigeversion;
|
||||
XEmacPs_Bd *bdtxterminate = NULL;
|
||||
XEmacPs_Bd *bdrxterminate = NULL;
|
||||
u32 *temp;
|
||||
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
|
||||
|
||||
index = get_base_index_rxpbufsstorage (xemacpsif);
|
||||
gigeversion = ((Xil_In32(xemacpsif->emacps.Config.BaseAddress + 0xFC)) >> 16) & 0xFFF;
|
||||
/*
|
||||
* The BDs need to be allocated in uncached memory. Hence the 1 MB
|
||||
* address range allocated for Bd_Space is made uncached
|
||||
* by setting appropriate attributes in the translation table.
|
||||
* The Bd_Space is aligned to 1MB and has a size of 1 MB. This ensures
|
||||
* a reserved uncached area used only for BDs.
|
||||
*/
|
||||
if (bd_space_attr_set == 0) {
|
||||
#if defined (ARMR5)
|
||||
Xil_SetTlbAttributes((s32_t)emac_bd_space, STRONG_ORDERD_SHARED | PRIV_RW_USER_RW); // addr, attr
|
||||
#else
|
||||
#if defined __aarch64__
|
||||
Xil_SetTlbAttributes((u64)emac_bd_space, NORM_NONCACHE | INNER_SHAREABLE);
|
||||
#else
|
||||
Xil_SetTlbAttributes((s32_t)emac_bd_space, DEVICE_MEMORY); // addr, attr
|
||||
#endif
|
||||
#endif
|
||||
bd_space_attr_set = 1;
|
||||
}
|
||||
|
||||
rxringptr = &XEmacPs_GetRxRing(&xemacpsif->emacps);
|
||||
txringptr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("rxringptr: 0x%08x\r\n", rxringptr));
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("txringptr: 0x%08x\r\n", txringptr));
|
||||
|
||||
/* Allocate 64k for Rx and Tx bds each to take care of extreme cases */
|
||||
tempaddress = (UINTPTR)&(emac_bd_space[bd_space_index]);
|
||||
xemacpsif->rx_bdspace = (void *)tempaddress;
|
||||
bd_space_index += 0x10000;
|
||||
tempaddress = (UINTPTR)&(emac_bd_space[bd_space_index]);
|
||||
xemacpsif->tx_bdspace = (void *)tempaddress;
|
||||
bd_space_index += 0x10000;
|
||||
if (gigeversion > 2) {
|
||||
tempaddress = (UINTPTR)&(emac_bd_space[bd_space_index]);
|
||||
bdrxterminate = (XEmacPs_Bd *)tempaddress;
|
||||
bd_space_index += 0x10000;
|
||||
tempaddress = (UINTPTR)&(emac_bd_space[bd_space_index]);
|
||||
bdtxterminate = (XEmacPs_Bd *)tempaddress;
|
||||
bd_space_index += 0x10000;
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("rx_bdspace: %p \r\n", xemacpsif->rx_bdspace));
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("tx_bdspace: %p \r\n", xemacpsif->tx_bdspace));
|
||||
|
||||
if (!xemacpsif->rx_bdspace || !xemacpsif->tx_bdspace) {
|
||||
xil_printf("%s@%d: Error: Unable to allocate memory for TX/RX buffer descriptors",
|
||||
__FILE__, __LINE__);
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup RxBD space.
|
||||
*
|
||||
* Setup a BD template for the Rx channel. This template will be copied to
|
||||
* every RxBD. We will not have to explicitly set these again.
|
||||
*/
|
||||
XEmacPs_BdClear(&bdtemplate);
|
||||
|
||||
/*
|
||||
* Create the RxBD ring
|
||||
*/
|
||||
|
||||
status = XEmacPs_BdRingCreate(rxringptr, (UINTPTR) xemacpsif->rx_bdspace,
|
||||
(UINTPTR) xemacpsif->rx_bdspace, BD_ALIGNMENT,
|
||||
XLWIP_CONFIG_N_RX_DESC);
|
||||
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Error setting up RxBD space\r\n"));
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
status = XEmacPs_BdRingClone(rxringptr, &bdtemplate, XEMACPS_RECV);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Error initializing RxBD space\r\n"));
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
XEmacPs_BdClear(&bdtemplate);
|
||||
XEmacPs_BdSetStatus(&bdtemplate, XEMACPS_TXBUF_USED_MASK);
|
||||
/*
|
||||
* Create the TxBD ring
|
||||
*/
|
||||
status = XEmacPs_BdRingCreate(txringptr, (UINTPTR) xemacpsif->tx_bdspace,
|
||||
(UINTPTR) xemacpsif->tx_bdspace, BD_ALIGNMENT,
|
||||
XLWIP_CONFIG_N_TX_DESC);
|
||||
|
||||
if (status != XST_SUCCESS) {
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/* We reuse the bd template, as the same one will work for both rx and tx. */
|
||||
status = XEmacPs_BdRingClone(txringptr, &bdtemplate, XEMACPS_SEND);
|
||||
if (status != XST_SUCCESS) {
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate RX descriptors, 1 RxBD at a time.
|
||||
*/
|
||||
for (i = 0; i < XLWIP_CONFIG_N_RX_DESC; i++) {
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
p = pbuf_alloc(PBUF_RAW, MAX_FRAME_SIZE_JUMBO, PBUF_POOL);
|
||||
#else
|
||||
p = pbuf_alloc(PBUF_RAW, XEMACPS_MAX_FRAME_SIZE, PBUF_POOL);
|
||||
#endif
|
||||
if (!p) {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.memerr++;
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
xil_printf("unable to alloc pbuf in init_dma\r\n");
|
||||
return ERR_IF;
|
||||
}
|
||||
status = XEmacPs_BdRingAlloc(rxringptr, 1, &rxbd);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("init_dma: Error allocating RxBD\r\n"));
|
||||
pbuf_free(p);
|
||||
return ERR_IF;
|
||||
}
|
||||
/* Enqueue to HW */
|
||||
status = XEmacPs_BdRingToHw(rxringptr, 1, rxbd);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Error: committing RxBD to HW\r\n"));
|
||||
pbuf_free(p);
|
||||
XEmacPs_BdRingUnAlloc(rxringptr, 1, rxbd);
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
bdindex = XEMACPS_BD_TO_INDEX(rxringptr, rxbd);
|
||||
temp = (u32 *)rxbd;
|
||||
*temp = 0;
|
||||
if (bdindex == (XLWIP_CONFIG_N_RX_DESC - 1)) {
|
||||
*temp = 0x00000002;
|
||||
}
|
||||
temp++;
|
||||
*temp = 0;
|
||||
dsb();
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, (UINTPTR)MAX_FRAME_SIZE_JUMBO);
|
||||
}
|
||||
#else
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, (UINTPTR)XEMACPS_MAX_FRAME_SIZE);
|
||||
}
|
||||
#endif
|
||||
XEmacPs_BdSetAddressRx(rxbd, (UINTPTR)p->payload);
|
||||
|
||||
rx_pbufs_storage[index + bdindex] = (UINTPTR)p;
|
||||
}
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.RxBdRing.BaseBdAddr, 0, XEMACPS_RECV);
|
||||
if (gigeversion > 2) {
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.TxBdRing.BaseBdAddr, 1, XEMACPS_SEND);
|
||||
}else {
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.TxBdRing.BaseBdAddr, 0, XEMACPS_SEND);
|
||||
}
|
||||
if (gigeversion > 2)
|
||||
{
|
||||
/*
|
||||
* This version of GEM supports priority queuing and the current
|
||||
* driver is using tx priority queue 1 and normal rx queue for
|
||||
* packet transmit and receive. The below code ensure that the
|
||||
* other queue pointers are parked to known state for avoiding
|
||||
* the controller to malfunction by fetching the descriptors
|
||||
* from these queues.
|
||||
*/
|
||||
XEmacPs_BdClear(bdrxterminate);
|
||||
XEmacPs_BdSetAddressRx(bdrxterminate, (XEMACPS_RXBUF_NEW_MASK |
|
||||
XEMACPS_RXBUF_WRAP_MASK));
|
||||
XEmacPs_Out32((xemacpsif->emacps.Config.BaseAddress + XEMACPS_RXQ1BASE_OFFSET),
|
||||
(UINTPTR)bdrxterminate);
|
||||
XEmacPs_BdClear(bdtxterminate);
|
||||
XEmacPs_BdSetStatus(bdtxterminate, (XEMACPS_TXBUF_USED_MASK |
|
||||
XEMACPS_TXBUF_WRAP_MASK));
|
||||
XEmacPs_Out32((xemacpsif->emacps.Config.BaseAddress + XEMACPS_TXQBASE_OFFSET),
|
||||
(UINTPTR)bdtxterminate);
|
||||
}
|
||||
// #if !NO_SYS
|
||||
// #ifdef SDT
|
||||
// xPortInstallInterruptHandler(xemacpsif->emacps.Config.IntrId,
|
||||
// ( Xil_InterruptHandler ) XEmacPs_IntrHandler,
|
||||
// (void *)&xemacpsif->emacps);
|
||||
// #else
|
||||
// xPortInstallInterruptHandler(xtopologyp->scugic_emac_intr,
|
||||
// ( Xil_InterruptHandler ) XEmacPs_IntrHandler,
|
||||
// (void *)&xemacpsif->emacps);
|
||||
|
||||
// #endif
|
||||
// #else
|
||||
#ifndef SDT
|
||||
/*
|
||||
* Connect the device driver handler that will be called when an
|
||||
* interrupt for the device occurs, the handler defined above performs
|
||||
* the specific interrupt processing for the device.
|
||||
*/
|
||||
XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
|
||||
(Xil_ExceptionHandler)XEmacPs_IntrHandler,
|
||||
(void *)&xemacpsif->emacps);
|
||||
#endif
|
||||
// #endif
|
||||
/*
|
||||
* Enable the interrupt for emacps.
|
||||
*/
|
||||
#ifdef SDT
|
||||
XSetupInterruptSystem(&xemacpsif->emacps, &XEmacPs_IntrHandler,
|
||||
xemacpsif->emacps.Config.IntrId, xemacpsif->emacps.Config.IntrParent,
|
||||
XINTERRUPT_DEFAULT_PRIORITY);
|
||||
#else
|
||||
XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, (u32) xtopologyp->scugic_emac_intr);
|
||||
emac_intr_num = (u32) xtopologyp->scugic_emac_intr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* resetrx_on_no_rxdata():
|
||||
*
|
||||
* It is called at regular intervals through the API xemacpsif_resetrx_on_no_rxdata
|
||||
* called by the user.
|
||||
* The EmacPs has a HW bug (SI# 692601) on the Rx path for heavy Rx traffic.
|
||||
* Under heavy Rx traffic because of the HW bug there are times when the Rx path
|
||||
* becomes unresponsive. The workaround for it is to check for the Rx path for
|
||||
* traffic (by reading the stats registers regularly). If the stats register
|
||||
* does not increment for sometime (proving no Rx traffic), the function resets
|
||||
* the Rx data path.
|
||||
*
|
||||
*/
|
||||
|
||||
void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32_t regctrl;
|
||||
u32_t tempcntr;
|
||||
u32_t gigeversion;
|
||||
|
||||
gigeversion = ((Xil_In32(xemacpsif->emacps.Config.BaseAddress + 0xFC)) >> 16) & 0xFFF;
|
||||
if (gigeversion == 2) {
|
||||
tempcntr = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET);
|
||||
if ((!tempcntr) && (!(xemacpsif->last_rx_frms_cntr))) {
|
||||
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, regctrl);
|
||||
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET);
|
||||
regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, regctrl);
|
||||
}
|
||||
xemacpsif->last_rx_frms_cntr = tempcntr;
|
||||
}
|
||||
}
|
||||
|
||||
void free_txrx_pbufs(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
s32_t index;
|
||||
s32_t index1;
|
||||
struct pbuf *p;
|
||||
|
||||
index1 = get_base_index_txpbufsstorage (xemacpsif);
|
||||
|
||||
for (index = index1; index < (index1 + XLWIP_CONFIG_N_TX_DESC); index++) {
|
||||
if (tx_pbufs_storage[index] != 0) {
|
||||
p = (struct pbuf *)tx_pbufs_storage[index];
|
||||
pbuf_free(p);
|
||||
tx_pbufs_storage[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
index1 = get_base_index_rxpbufsstorage(xemacpsif);
|
||||
for (index = index1; index < (index1 + XLWIP_CONFIG_N_RX_DESC); index++) {
|
||||
p = (struct pbuf *)rx_pbufs_storage[index];
|
||||
pbuf_free(p);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void free_onlytx_pbufs(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
s32_t index;
|
||||
s32_t index1;
|
||||
struct pbuf *p;
|
||||
|
||||
index1 = get_base_index_txpbufsstorage (xemacpsif);
|
||||
for (index = index1; index < (index1 + XLWIP_CONFIG_N_TX_DESC); index++) {
|
||||
if (tx_pbufs_storage[index] != 0) {
|
||||
p = (struct pbuf *)tx_pbufs_storage[index];
|
||||
pbuf_free(p);
|
||||
tx_pbufs_storage[index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* reset Tx and Rx DMA pointers after XEmacPs_Stop */
|
||||
void reset_dma(struct xemac_s *xemac)
|
||||
{
|
||||
u8 txqueuenum;
|
||||
u32_t gigeversion;
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
XEmacPs_BdRing *txringptr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
|
||||
XEmacPs_BdRing *rxringptr = &XEmacPs_GetRxRing(&xemacpsif->emacps);
|
||||
|
||||
XEmacPs_BdRingPtrReset(txringptr, xemacpsif->tx_bdspace);
|
||||
XEmacPs_BdRingPtrReset(rxringptr, xemacpsif->rx_bdspace);
|
||||
|
||||
gigeversion = ((Xil_In32(xemacpsif->emacps.Config.BaseAddress + 0xFC)) >> 16) & 0xFFF;
|
||||
if (gigeversion > 2) {
|
||||
txqueuenum = 1;
|
||||
} else {
|
||||
txqueuenum = 0;
|
||||
}
|
||||
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.RxBdRing.BaseBdAddr, 0, XEMACPS_RECV);
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.TxBdRing.BaseBdAddr, txqueuenum, XEMACPS_SEND);
|
||||
}
|
||||
|
||||
#ifndef SDT
|
||||
void emac_disable_intr(void)
|
||||
{
|
||||
XScuGic_DisableIntr(INTC_DIST_BASE_ADDR, emac_intr_num);
|
||||
}
|
||||
|
||||
void emac_enable_intr(void)
|
||||
{
|
||||
XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, emac_intr_num);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "lwipopts.h"
|
||||
|
||||
|
||||
u32_t link_speed = 100;
|
||||
extern XEmacPs_Config XEmacPs_ConfigTable[];
|
||||
extern u32_t phymapemac0[32];
|
||||
extern u32_t phymapemac1[32];
|
||||
extern u32_t phyaddrforemac;
|
||||
|
||||
#if !NO_SYS
|
||||
extern long xInsideISR;
|
||||
#endif
|
||||
|
||||
XEmacPs_Config *xemacps_lookup_config(unsigned mac_base)
|
||||
{
|
||||
XEmacPs_Config *cfgptr = NULL;
|
||||
s32_t i;
|
||||
|
||||
for (i = 0; i < XPAR_XEMACPS_NUM_INSTANCES; i++) {
|
||||
if (XEmacPs_ConfigTable[i].BaseAddress == mac_base) {
|
||||
cfgptr = &XEmacPs_ConfigTable[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (cfgptr);
|
||||
}
|
||||
|
||||
void init_emacps(xemacpsif_s *xemacps, struct netif *netif)
|
||||
{
|
||||
XEmacPs *xemacpsp;
|
||||
s32_t status = XST_SUCCESS;
|
||||
u32_t i;
|
||||
u32_t phyfoundforemac0 = FALSE;
|
||||
u32_t phyfoundforemac1 = FALSE;
|
||||
|
||||
xemacpsp = &xemacps->emacps;
|
||||
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
XEmacPs_SetOptions(xemacpsp, XEMACPS_JUMBO_ENABLE_OPTION);
|
||||
#endif
|
||||
|
||||
#ifdef LWIP_IGMP
|
||||
XEmacPs_SetOptions(xemacpsp, XEMACPS_MULTICAST_OPTION);
|
||||
#endif
|
||||
|
||||
#ifdef SGMII_FIXED_LINK
|
||||
XEmacPs_SetOptions(xemacpsp, XEMACPS_SGMII_ENABLE_OPTION);
|
||||
status = XEmacPs_ReadReg(xemacpsp->Config.BaseAddress, XEMACPS_PCS_CONTROL_OFFSET);
|
||||
status &= ~XEMACPS_PCS_CON_AUTO_NEG_MASK;
|
||||
XEmacPs_WriteReg(xemacps->emacps.Config.BaseAddress, XEMACPS_PCS_CONTROL_OFFSET, status);
|
||||
#endif
|
||||
|
||||
/* set mac address */
|
||||
status = XEmacPs_SetMacAddress(xemacpsp, (void*)(netif->hwaddr), 1);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("In %s:Emac Mac Address set failed...\r\n",__func__));
|
||||
}
|
||||
|
||||
XEmacPs_SetMdioDivisor(xemacpsp, MDC_DIV_224);
|
||||
|
||||
/* Please refer to file header comments for the file xemacpsif_physpeed.c
|
||||
* to know more about the PHY programming sequence.
|
||||
* For PCS PMA core, phy_setup_emacps is called with the predefined PHY address
|
||||
* exposed through xaparemeters.h
|
||||
* For RGMII case, assuming multiple PHYs can be present on the MDIO bus,
|
||||
* detect_phy is called to get the addresses of the PHY present on
|
||||
* a particular MDIO bus (emac0 or emac1). This address map is populated
|
||||
* in phymapemac0 or phymapemac1.
|
||||
* phy_setup_emacps is then called for each PHY present on the MDIO bus.
|
||||
*/
|
||||
#ifndef SGMII_FIXED_LINK
|
||||
detect_phy(xemacpsp);
|
||||
for (i = 31; i > 0; i--) {
|
||||
if (xemacpsp->Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
if (phymapemac0[i] == TRUE) {
|
||||
link_speed = phy_setup_emacps(xemacpsp, i);
|
||||
phyfoundforemac0 = TRUE;
|
||||
phyaddrforemac = i;
|
||||
}
|
||||
} else {
|
||||
if (phymapemac1[i] == TRUE) {
|
||||
link_speed = phy_setup_emacps(xemacpsp, i);
|
||||
phyfoundforemac1 = TRUE;
|
||||
phyaddrforemac = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If no PHY was detected, use broadcast PHY address of 0 */
|
||||
if (xemacpsp->Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
if (phyfoundforemac0 == FALSE)
|
||||
link_speed = phy_setup_emacps(xemacpsp, 0);
|
||||
} else {
|
||||
if (phyfoundforemac1 == FALSE)
|
||||
link_speed = phy_setup_emacps(xemacpsp, 0);
|
||||
}
|
||||
#else
|
||||
link_speed = pcs_setup_emacps(xemacpsp);
|
||||
#endif
|
||||
|
||||
if (link_speed == XST_FAILURE) {
|
||||
xemacps->eth_link_status = ETH_LINK_DOWN;
|
||||
xil_printf("Phy setup failure %s \n\r",__func__);
|
||||
return;
|
||||
} else {
|
||||
xemacps->eth_link_status = ETH_LINK_UP;
|
||||
}
|
||||
|
||||
XEmacPs_SetOperatingSpeed(xemacpsp, link_speed);
|
||||
/* Setting the operating speed of the MAC needs a delay. */
|
||||
{
|
||||
volatile s32_t wait;
|
||||
for (wait=0; wait < 20000; wait++);
|
||||
}
|
||||
}
|
||||
|
||||
void init_emacps_on_error (xemacpsif_s *xemacps, struct netif *netif)
|
||||
{
|
||||
XEmacPs *xemacpsp;
|
||||
s32_t status = XST_SUCCESS;
|
||||
|
||||
xemacpsp = &xemacps->emacps;
|
||||
|
||||
/* set mac address */
|
||||
status = XEmacPs_SetMacAddress(xemacpsp, (void*)(netif->hwaddr), 1);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("In %s:Emac Mac Address set failed...\r\n",__func__));
|
||||
}
|
||||
|
||||
XEmacPs_SetOperatingSpeed(xemacpsp, link_speed);
|
||||
|
||||
/* Setting the operating speed of the MAC needs a delay. */
|
||||
{
|
||||
volatile s32_t wait;
|
||||
for (wait=0; wait < 20000; wait++);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_isr (struct xemac_s *xemac)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
/*
|
||||
* Setup callbacks
|
||||
*/
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
|
||||
(void *) emacps_send_handler,
|
||||
(void *) xemac);
|
||||
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
|
||||
(void *) emacps_recv_handler,
|
||||
(void *) xemac);
|
||||
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
|
||||
(void *) emacps_error_handler,
|
||||
(void *) xemac);
|
||||
}
|
||||
|
||||
void start_emacps (xemacpsif_s *xemacps)
|
||||
{
|
||||
/* start the temac */
|
||||
XEmacPs_Start(&xemacps->emacps);
|
||||
}
|
||||
|
||||
void restart_emacps_transmitter (xemacpsif_s *xemacps) {
|
||||
u32_t Reg;
|
||||
Reg = XEmacPs_ReadReg(xemacps->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
Reg = Reg & (~XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacps->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, Reg);
|
||||
|
||||
Reg = XEmacPs_ReadReg(xemacps->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
Reg = Reg | (XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacps->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, Reg);
|
||||
}
|
||||
|
||||
void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord)
|
||||
{
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
XEmacPs_BdRing *rxring;
|
||||
XEmacPs_BdRing *txring;
|
||||
#if !NO_SYS
|
||||
xInsideISR++;
|
||||
#endif
|
||||
|
||||
xemac = (struct xemac_s *)(arg);
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps);
|
||||
txring = &XEmacPs_GetTxRing(&xemacpsif->emacps);
|
||||
|
||||
if (ErrorWord != 0) {
|
||||
switch (Direction) {
|
||||
case XEMACPS_RECV:
|
||||
if (ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Receive DMA error\r\n"));
|
||||
HandleEmacPsError(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_RXSR_RXOVR_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Receive over run\r\n"));
|
||||
emacps_recv_handler(arg);
|
||||
setup_rx_bds(xemacpsif, rxring);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_RXSR_BUFFNA_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Receive buffer not available\r\n"));
|
||||
emacps_recv_handler(arg);
|
||||
setup_rx_bds(xemacpsif, rxring);
|
||||
}
|
||||
break;
|
||||
case XEMACPS_SEND:
|
||||
if (ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit DMA error\r\n"));
|
||||
HandleEmacPsError(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_TXSR_URUN_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit under run\r\n"));
|
||||
HandleTxErrors(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_TXSR_BUFEXH_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit buffer exhausted\r\n"));
|
||||
HandleTxErrors(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_TXSR_RXOVR_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit retry excessed limits\r\n"));
|
||||
HandleTxErrors(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_TXSR_FRAMERX_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit collision\r\n"));
|
||||
xemacps_process_sent_bds(xemacpsif, txring);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if !NO_SYS
|
||||
xInsideISR--;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XEMACPSIF_HW_H_
|
||||
#define __XEMACPSIF_HW_H_
|
||||
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "lwip/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
XEmacPs_Config * lookup_config(unsigned mac_base);
|
||||
|
||||
void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "netif/xpqueue.h"
|
||||
|
||||
#define NUM_QUEUES 2
|
||||
|
||||
pq_queue_t pq_queue[NUM_QUEUES];
|
||||
|
||||
pq_queue_t *
|
||||
pq_create_queue()
|
||||
{
|
||||
static int i;
|
||||
pq_queue_t *q = NULL;
|
||||
|
||||
if (i >= NUM_QUEUES) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ERR: Max Queues allocated\n\r"));
|
||||
return q;
|
||||
}
|
||||
|
||||
q = &pq_queue[i++];
|
||||
|
||||
if (!q)
|
||||
return q;
|
||||
|
||||
q->head = q->tail = q->len = 0;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
int
|
||||
pq_enqueue(pq_queue_t *q, void *p)
|
||||
{
|
||||
if (q->len == PQ_QUEUE_SIZE)
|
||||
return -1;
|
||||
|
||||
q->data[q->head] = p;
|
||||
q->head = (q->head + 1)%PQ_QUEUE_SIZE;
|
||||
q->len++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
pq_dequeue(pq_queue_t *q)
|
||||
{
|
||||
int ptail;
|
||||
|
||||
if (q->len == 0)
|
||||
return NULL;
|
||||
|
||||
ptail = q->tail;
|
||||
q->tail = (q->tail + 1)%PQ_QUEUE_SIZE;
|
||||
q->len--;
|
||||
|
||||
return q->data[ptail];
|
||||
}
|
||||
|
||||
int
|
||||
pq_qlength(pq_queue_t *q)
|
||||
{
|
||||
return q->len;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
target_sources(lwip_xil PRIVATE
|
||||
sys_arch.c
|
||||
sys_arch_raw.c
|
||||
)
|
||||
|
||||
@@ -0,0 +1,622 @@
|
||||
/* sys_arch.c -
|
||||
* provide sys_arch functionality as required for lwIP
|
||||
* most of this functionality is obtained from FreeRTOS
|
||||
* this file acts as a wrapper around the FreeRTOS functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
* Simon Goldschmidt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwipopts.h"
|
||||
|
||||
#if !NO_SYS
|
||||
|
||||
#include "arch/sys_arch.h"
|
||||
|
||||
/* ------------------------ lwIP includes --------------------------------- */
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/debug.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
/* Very crude mechanism used to determine if the critical section handling
|
||||
functions are being called from an interrupt context or not. This relies on
|
||||
the interrupt handler setting this variable manually. */
|
||||
u32 xInsideISR;
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_mbox_new
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Creates a new mailbox
|
||||
* Inputs:
|
||||
* int size -- Size of elements in the mailbox
|
||||
* Outputs:
|
||||
* sys_mbox_t -- Handle to new mailbox
|
||||
*---------------------------------------------------------------------------*/
|
||||
err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize )
|
||||
{
|
||||
err_t xReturn = ERR_MEM;
|
||||
|
||||
*pxMailBox = xQueueCreate( iSize, sizeof( void * ) );
|
||||
|
||||
if( *pxMailBox != NULL )
|
||||
{
|
||||
xReturn = ERR_OK;
|
||||
SYS_STATS_INC_USED( mbox );
|
||||
}
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_mbox_free
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Deallocates a mailbox. If there are messages still present in the
|
||||
* mailbox when the mailbox is deallocated, it is an indication of a
|
||||
* programming error in lwIP and the developer should be notified.
|
||||
* Inputs:
|
||||
* sys_mbox_t mbox -- Handle of mailbox
|
||||
* Outputs:
|
||||
* sys_mbox_t -- Handle to new mailbox
|
||||
*---------------------------------------------------------------------------*/
|
||||
void sys_mbox_free( sys_mbox_t *pxMailBox )
|
||||
{
|
||||
unsigned long ulMessagesWaiting;
|
||||
|
||||
ulMessagesWaiting = uxQueueMessagesWaiting( *pxMailBox );
|
||||
configASSERT( ( ulMessagesWaiting == 0 ) );
|
||||
|
||||
#if SYS_STATS
|
||||
{
|
||||
if( ulMessagesWaiting != 0UL )
|
||||
{
|
||||
SYS_STATS_INC( mbox.err );
|
||||
}
|
||||
|
||||
SYS_STATS_DEC( mbox.used );
|
||||
}
|
||||
#endif /* SYS_STATS */
|
||||
|
||||
vQueueDelete( *pxMailBox );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_mbox_post
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Post the "msg" to the mailbox.
|
||||
* Inputs:
|
||||
* sys_mbox_t mbox -- Handle of mailbox
|
||||
* void *data -- Pointer to data to post
|
||||
*---------------------------------------------------------------------------*/
|
||||
void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
if( xInsideISR != pdFALSE ) {
|
||||
xQueueSendToBackFromISR( *pxMailBox, &pxMessageToPost, &xHigherPriorityTaskWoken );
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_mbox_trypost
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Try to post the "msg" to the mailbox. Returns immediately with
|
||||
* error if cannot.
|
||||
* Inputs:
|
||||
* sys_mbox_t mbox -- Handle of mailbox
|
||||
* void *msg -- Pointer to data to post
|
||||
* Outputs:
|
||||
* err_t -- ERR_OK if message posted, else ERR_MEM
|
||||
* if not.
|
||||
*---------------------------------------------------------------------------*/
|
||||
err_t sys_mbox_trypost( sys_mbox_t *pxMailBox, void *pxMessageToPost )
|
||||
{
|
||||
err_t xReturn;
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
if( xInsideISR != pdFALSE )
|
||||
{
|
||||
xReturn = xQueueSendFromISR( *pxMailBox, &pxMessageToPost, &xHigherPriorityTaskWoken );
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = xQueueSend( *pxMailBox, &pxMessageToPost, ( portTickType ) 0 );
|
||||
}
|
||||
|
||||
if( xReturn == pdPASS )
|
||||
{
|
||||
xReturn = ERR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
LWIP_DEBUGF(NETIF_DEBUGF, ("Queue is full\r\n"));
|
||||
/* The queue was already full. */
|
||||
xReturn = ERR_MEM;
|
||||
SYS_STATS_INC( mbox.err );
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_arch_mbox_fetch
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Blocks the thread until a message arrives in the mailbox, but does
|
||||
* not block the thread longer than "timeout" milliseconds (similar to
|
||||
* the sys_arch_sem_wait() function). The "msg" argument is a result
|
||||
* parameter that is set by the function (i.e., by doing "*msg =
|
||||
* ptr"). The "msg" parameter maybe NULL to indicate that the message
|
||||
* should be dropped.
|
||||
*
|
||||
* The return values are the same as for the sys_arch_sem_wait() function:
|
||||
* Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
|
||||
* timeout.
|
||||
*
|
||||
* Note that a function with a similar name, sys_mbox_fetch(), is
|
||||
* implemented by lwIP.
|
||||
* Inputs:
|
||||
* sys_mbox_t mbox -- Handle of mailbox
|
||||
* void **msg -- Pointer to pointer to msg received
|
||||
* u32_t timeout -- Number of milliseconds until timeout
|
||||
* Outputs:
|
||||
* u32_t -- SYS_ARCH_TIMEOUT if timeout, else number
|
||||
* of milliseconds until received.
|
||||
*---------------------------------------------------------------------------*/
|
||||
u32_t sys_arch_mbox_fetch( sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut )
|
||||
{
|
||||
void *pvDummy;
|
||||
portTickType xStartTime, xEndTime, xElapsed;
|
||||
unsigned long ulReturn;
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
xStartTime = xTaskGetTickCount();
|
||||
|
||||
if( NULL == ppvBuffer )
|
||||
{
|
||||
ppvBuffer = &pvDummy;
|
||||
}
|
||||
|
||||
if( ulTimeOut != 0UL )
|
||||
{
|
||||
if( xInsideISR != pdFALSE ) {
|
||||
if( pdTRUE == xQueueReceiveFromISR( *pxMailBox, &( *ppvBuffer ), &xHigherPriorityTaskWoken ) )
|
||||
{
|
||||
xEndTime = xTaskGetTickCount();
|
||||
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
|
||||
ulReturn = xElapsed;
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvBuffer = NULL;
|
||||
ulReturn = SYS_ARCH_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), ulTimeOut/ portTICK_RATE_MS ) )
|
||||
{
|
||||
xEndTime = xTaskGetTickCount();
|
||||
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
|
||||
|
||||
ulReturn = xElapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Timed out. */
|
||||
*ppvBuffer = NULL;
|
||||
ulReturn = SYS_ARCH_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( xInsideISR != pdFALSE ) {
|
||||
xQueueReceiveFromISR( *pxMailBox, &( *ppvBuffer ), &xHigherPriorityTaskWoken );
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
xQueueReceive( *pxMailBox, &( *ppvBuffer ), portMAX_DELAY );
|
||||
xEndTime = xTaskGetTickCount();
|
||||
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
|
||||
|
||||
if( xElapsed == 0UL )
|
||||
{
|
||||
xElapsed = 1UL;
|
||||
}
|
||||
|
||||
ulReturn = xElapsed;
|
||||
}
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_arch_mbox_tryfetch
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Similar to sys_arch_mbox_fetch, but if message is not ready
|
||||
* immediately, we'll return with SYS_MBOX_EMPTY. On success, 0 is
|
||||
* returned.
|
||||
* Inputs:
|
||||
* sys_mbox_t mbox -- Handle of mailbox
|
||||
* void **msg -- Pointer to pointer to msg received
|
||||
* Outputs:
|
||||
* u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise,
|
||||
* return ERR_OK.
|
||||
*---------------------------------------------------------------------------*/
|
||||
u32_t sys_arch_mbox_tryfetch( sys_mbox_t *pxMailBox, void **ppvBuffer )
|
||||
{
|
||||
void *pvDummy;
|
||||
unsigned long ulReturn;
|
||||
long lResult;
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
if( ppvBuffer== NULL )
|
||||
{
|
||||
ppvBuffer = &pvDummy;
|
||||
}
|
||||
|
||||
if( xInsideISR != pdFALSE )
|
||||
{
|
||||
lResult = xQueueReceiveFromISR( *pxMailBox, &( *ppvBuffer ), &xHigherPriorityTaskWoken );
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lResult = xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL );
|
||||
}
|
||||
|
||||
if( lResult == pdPASS )
|
||||
{
|
||||
ulReturn = ERR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulReturn = SYS_MBOX_EMPTY;
|
||||
}
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_sem_new
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Creates and returns a new semaphore. The "ucCount" argument specifies
|
||||
* the initial state of the semaphore.
|
||||
* NOTE: Currently this routine only creates counts of 1 or 0
|
||||
* Inputs:
|
||||
* sys_mbox_t mbox -- Handle of mailbox
|
||||
* u8_t ucCount -- Initial ucCount of semaphore (1 or 0)
|
||||
* Outputs:
|
||||
* sys_sem_t -- Created semaphore or 0 if could not create.
|
||||
*---------------------------------------------------------------------------*/
|
||||
err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount )
|
||||
{
|
||||
(void) ucCount;
|
||||
err_t xReturn = ERR_MEM;
|
||||
|
||||
*pxSemaphore = xSemaphoreCreateBinary();
|
||||
|
||||
if( *pxSemaphore != NULL )
|
||||
{
|
||||
xReturn = ERR_OK;
|
||||
SYS_STATS_INC_USED( sem );
|
||||
}
|
||||
else
|
||||
{
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("Sem creation error\r\n"));
|
||||
SYS_STATS_INC( sem.err );
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_arch_sem_wait
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Blocks the thread while waiting for the semaphore to be
|
||||
* signaled. If the "timeout" argument is non-zero, the thread should
|
||||
* only be blocked for the specified time (measured in
|
||||
* milliseconds).
|
||||
*
|
||||
* If the timeout argument is non-zero, the return value is the number of
|
||||
* milliseconds spent waiting for the semaphore to be signaled. If the
|
||||
* semaphore wasn't signaled within the specified time, the return value is
|
||||
* SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
|
||||
* (i.e., it was already signaled), the function may return zero.
|
||||
*
|
||||
* Notice that lwIP implements a function with a similar name,
|
||||
* sys_sem_wait(), that uses the sys_arch_sem_wait() function.
|
||||
* Inputs:
|
||||
* sys_sem_t sem -- Semaphore to wait on
|
||||
* u32_t timeout -- Number of milliseconds until timeout
|
||||
* Outputs:
|
||||
* u32_t -- Time elapsed or SYS_ARCH_TIMEOUT.
|
||||
*---------------------------------------------------------------------------*/
|
||||
u32_t sys_arch_sem_wait( sys_sem_t *pxSemaphore, u32_t ulTimeout )
|
||||
{
|
||||
portTickType xStartTime, xEndTime, xElapsed;
|
||||
unsigned long ulReturn;
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
xStartTime = xTaskGetTickCount();
|
||||
|
||||
if( ulTimeout != 0UL )
|
||||
{
|
||||
if( xInsideISR != pdFALSE ) {
|
||||
if( xSemaphoreTakeFromISR( *pxSemaphore, &xHigherPriorityTaskWoken ) == pdTRUE )
|
||||
{
|
||||
xEndTime = xTaskGetTickCount();
|
||||
xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS;
|
||||
ulReturn = xElapsed;
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ulReturn = SYS_ARCH_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
if( xSemaphoreTake( *pxSemaphore, ulTimeout / portTICK_RATE_MS ) == pdTRUE )
|
||||
{
|
||||
xEndTime = xTaskGetTickCount();
|
||||
xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS;
|
||||
ulReturn = xElapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulReturn = SYS_ARCH_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( xInsideISR != pdFALSE ) {
|
||||
xSemaphoreTakeFromISR( *pxSemaphore, &xHigherPriorityTaskWoken );
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
xSemaphoreTake( *pxSemaphore, portMAX_DELAY );
|
||||
xEndTime = xTaskGetTickCount();
|
||||
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
|
||||
|
||||
if( xElapsed == 0UL )
|
||||
{
|
||||
xElapsed = 1UL;
|
||||
}
|
||||
|
||||
ulReturn = xElapsed;
|
||||
}
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
|
||||
/** Create a new mutex
|
||||
* @param mutex pointer to the mutex to create
|
||||
* @return a new mutex */
|
||||
err_t sys_mutex_new( sys_mutex_t *pxMutex )
|
||||
{
|
||||
err_t xReturn = ERR_MEM;
|
||||
|
||||
*pxMutex = xSemaphoreCreateMutex();
|
||||
|
||||
if( *pxMutex != NULL )
|
||||
{
|
||||
xReturn = ERR_OK;
|
||||
SYS_STATS_INC_USED( mutex );
|
||||
}
|
||||
else
|
||||
{
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("Mutex creation error\r\n"));
|
||||
SYS_STATS_INC( mutex.err );
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
/** Lock a mutex
|
||||
* @param mutex the mutex to lock */
|
||||
void sys_mutex_lock( sys_mutex_t *pxMutex )
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
if( xInsideISR != pdFALSE ) {
|
||||
xSemaphoreTakeFromISR( *pxMutex, &xHigherPriorityTaskWoken );
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
xSemaphoreTake( *pxMutex, portMAX_DELAY );
|
||||
}
|
||||
|
||||
/** Unlock a mutex
|
||||
* @param mutex the mutex to unlock */
|
||||
void sys_mutex_unlock(sys_mutex_t *pxMutex )
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
if( xInsideISR != pdFALSE ) {
|
||||
xSemaphoreGiveFromISR( *pxMutex, &xHigherPriorityTaskWoken );
|
||||
if (xHigherPriorityTaskWoken == pdTRUE)
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
else
|
||||
xSemaphoreGive( *pxMutex );
|
||||
}
|
||||
|
||||
|
||||
/** Delete a semaphore
|
||||
* @param mutex the mutex to delete */
|
||||
void sys_mutex_free( sys_mutex_t *pxMutex )
|
||||
{
|
||||
SYS_STATS_DEC( mutex.used );
|
||||
vQueueDelete( *pxMutex );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_sem_signal
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Signals (releases) a semaphore
|
||||
* Inputs:
|
||||
* sys_sem_t sem -- Semaphore to signal
|
||||
*---------------------------------------------------------------------------*/
|
||||
void sys_sem_signal( sys_sem_t *pxSemaphore )
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
if( xInsideISR != pdFALSE )
|
||||
{
|
||||
xSemaphoreGiveFromISR( *pxSemaphore, &xHigherPriorityTaskWoken );
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xSemaphoreGive( *pxSemaphore );
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_sem_free
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Deallocates a semaphore
|
||||
* Inputs:
|
||||
* sys_sem_t sem -- Semaphore to free
|
||||
*---------------------------------------------------------------------------*/
|
||||
void sys_sem_free( sys_sem_t *pxSemaphore )
|
||||
{
|
||||
SYS_STATS_DEC(sem.used);
|
||||
vQueueDelete( *pxSemaphore );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_init
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Initialize sys arch
|
||||
*---------------------------------------------------------------------------*/
|
||||
void sys_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
u32_t sys_now(void)
|
||||
{
|
||||
return ((xTaskGetTickCount() * 1000) / configTICK_RATE_HZ);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Routine: sys_thread_new
|
||||
*---------------------------------------------------------------------------*
|
||||
* Description:
|
||||
* Starts a new thread with priority "prio" that will begin its
|
||||
* execution in the function "thread()". The "arg" argument will be
|
||||
* passed as an argument to the thread() function. The id of the new
|
||||
* thread is returned. Both the id and the priority are system
|
||||
* dependent.
|
||||
* Inputs:
|
||||
* char *name -- Name of thread
|
||||
* void (* thread)(void *arg) -- Pointer to function to run.
|
||||
* void *arg -- Argument passed into function
|
||||
* int stacksize -- Required stack amount in bytes
|
||||
* int prio -- Thread priority
|
||||
* Outputs:
|
||||
* sys_thread_t -- Pointer to per-thread timeouts.
|
||||
*---------------------------------------------------------------------------*/
|
||||
sys_thread_t sys_thread_new( const char *pcName, void( *pxThread )( void *pvParameters ), void *pvArg, int iStackSize, int iPriority )
|
||||
{
|
||||
xTaskHandle xCreatedTask;
|
||||
portBASE_TYPE xResult;
|
||||
sys_thread_t xReturn;
|
||||
|
||||
xResult = xTaskCreate( pxThread, ( const char * const) pcName, iStackSize, pvArg, iPriority, &xCreatedTask );
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
xReturn = xCreatedTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = NULL;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prints an assertion messages and aborts execution.
|
||||
*/
|
||||
void sys_assert( const char *pcMessage )
|
||||
{
|
||||
(void) pcMessage;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*
|
||||
* End of File: sys_arch.c
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* Copyright (C) 2007 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xlwipconfig.h"
|
||||
|
||||
#ifdef __MICROBLAZE__
|
||||
#include "mb_interface.h"
|
||||
#endif
|
||||
|
||||
#ifdef __riscv
|
||||
#include "riscv_interface.h"
|
||||
#endif
|
||||
|
||||
#include "arch/cc.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
/*
|
||||
* This optional function does a "fast" critical region protection and returns
|
||||
* the previous protection level. This function is only called during very short
|
||||
* critical regions. An embedded system which supports ISR-based drivers might
|
||||
* want to implement this function by disabling interrupts. Task-based systems
|
||||
* might want to implement this by using a mutex or disabling tasking. This
|
||||
* function should support recursive calls from the same task or interrupt. In
|
||||
* other words, sys_arch_protect() could be called while already protected. In
|
||||
* that case the return value indicates that it is already protected.
|
||||
* sys_arch_protect() is only required if your port is supporting an operating
|
||||
* system.
|
||||
*/
|
||||
sys_prot_t
|
||||
sys_arch_protect()
|
||||
{
|
||||
sys_prot_t cur;
|
||||
#ifdef __MICROBLAZE__
|
||||
cur = mfmsr();
|
||||
mtmsr(cur & ~0x2);
|
||||
#elif __arm__
|
||||
cur = mfcpsr();
|
||||
mtcpsr(cur | 0xC0);
|
||||
#elif __aarch64__
|
||||
cur = mfcpsr();
|
||||
mtcpsr(cur | 0xC0);
|
||||
#endif
|
||||
return cur;
|
||||
}
|
||||
|
||||
/*
|
||||
* This optional function does a "fast" set of critical region protection to the
|
||||
* value specified by pval. See the documentation for sys_arch_protect() for
|
||||
* more information. This function is only required if your port is supporting
|
||||
* an operating system.
|
||||
*/
|
||||
void
|
||||
sys_arch_unprotect(sys_prot_t lev)
|
||||
{
|
||||
#if defined (__arm__) || defined (__aarch64__)
|
||||
mtcpsr(lev);
|
||||
#else
|
||||
mtmsr(lev);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2017 - 2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "netif/xadapter.h"
|
||||
|
||||
#define PLATFORM_EMAC_BASEADDR 0xE000B000
|
||||
|
||||
#define THREAD_STACKSIZE 1024
|
||||
|
||||
#define DEFAULT_IP_ADDRESS "192.168.1.10"
|
||||
#define DEFAULT_IP_MASK "255.255.255.0"
|
||||
#define DEFAULT_GW_ADDRESS "192.168.1.1"
|
||||
|
||||
struct netif server_netif;
|
||||
|
||||
// u32_t sys_now(void) { return xTaskGetTickCount() * portTICK_PERIOD_MS; }
|
||||
|
||||
static void print_ip(char *msg, ip_addr_t *ip) {
|
||||
xil_printf(msg);
|
||||
xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip), ip4_addr3(ip),
|
||||
ip4_addr4(ip));
|
||||
}
|
||||
|
||||
static void print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw) {
|
||||
print_ip("Board IP: ", ip);
|
||||
print_ip("Netmask : ", mask);
|
||||
print_ip("Gateway : ", gw);
|
||||
}
|
||||
|
||||
// static void assign_default_ip(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)
|
||||
// {
|
||||
// int err;
|
||||
|
||||
// xil_printf("Configuring default IP %s \r\n", DEFAULT_IP_ADDRESS);
|
||||
|
||||
// err = inet_aton(DEFAULT_IP_ADDRESS, ip);
|
||||
// if (!err)
|
||||
// xil_printf("Invalid default IP address: %d\r\n", err);
|
||||
|
||||
// err = inet_aton(DEFAULT_IP_MASK, mask);
|
||||
// if (!err)
|
||||
// xil_printf("Invalid default IP MASK: %d\r\n", err);
|
||||
|
||||
// err = inet_aton(DEFAULT_GW_ADDRESS, gw);
|
||||
// if (!err)
|
||||
// xil_printf("Invalid default gateway address: %d\r\n", err);
|
||||
// }
|
||||
|
||||
void init_thread(void *_) {
|
||||
|
||||
/* the mac address of the board. this should be unique per board */
|
||||
u8_t mac_ethernet_address[] = {0x00, 0x0a, 0x35, 0x00, 0x01, 0x02};
|
||||
|
||||
/* Add network interface to the netif_list, and set it as default */
|
||||
ip_addr_t ip, mask, gw;
|
||||
int err = inet_aton(DEFAULT_IP_ADDRESS, &ip);
|
||||
if (!err)
|
||||
xil_printf("Invalid default IP address: %d\r\n", err);
|
||||
|
||||
err = inet_aton(DEFAULT_IP_MASK, &mask);
|
||||
if (!err)
|
||||
xil_printf("Invalid default IP MASK: %d\r\n", err);
|
||||
|
||||
err = inet_aton(DEFAULT_GW_ADDRESS, &gw);
|
||||
if (!err)
|
||||
xil_printf("Invalid default gateway address: %d\r\n", err);
|
||||
if (!xemac_add(&server_netif, &ip, &mask, &gw, mac_ethernet_address,
|
||||
PLATFORM_EMAC_BASEADDR)) {
|
||||
xil_printf("Error adding N/W interface\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
netif_set_default(&server_netif);
|
||||
|
||||
/* specify that the network if is up */
|
||||
netif_set_up(&server_netif);
|
||||
|
||||
/* start packet receive thread - required for lwIP operation */
|
||||
sys_thread_new("xemacif_input_thread", (void (*)(void *))xemacif_input_thread,
|
||||
&server_netif, THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
|
||||
|
||||
print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask),
|
||||
&(server_netif.gw));
|
||||
xil_printf("\r\n");
|
||||
|
||||
// Some allocations do not allow task deletion
|
||||
// vTaskDelete(NULL);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
void xethernet_init() {
|
||||
// pushed into thread so it only starts after threads are started
|
||||
sys_thread_new("initxeth_thread", init_thread, 0, THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
}
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
/* Standard includes. */
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Scheduler include files. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Xilinx includes. */
|
||||
// #include "platform.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
#include "xscutimer.h"
|
||||
#include "xuartps_hw.h"
|
||||
|
||||
/*
|
||||
* Configure the hardware as necessary to run this demo.
|
||||
*/
|
||||
static void prvSetupHardware(void);
|
||||
|
||||
/*
|
||||
* The Xilinx projects use a BSP that do not allow the start up code to be
|
||||
* altered easily. Therefore the vector table used by FreeRTOS is defined in
|
||||
* FreeRTOS_asm_vectors.S, which is part of this project. Switch to use the
|
||||
* FreeRTOS vector table.
|
||||
*/
|
||||
extern void vPortInstallFreeRTOSVectorTable(void);
|
||||
|
||||
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
|
||||
within this file. */
|
||||
void vApplicationMallocFailedHook(void);
|
||||
void vApplicationIdleHook(void);
|
||||
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName);
|
||||
void vApplicationTickHook(void);
|
||||
|
||||
/* The private watchdog is used as the timer that generates run time
|
||||
stats. This frequency means it will overflow quite quickly. */
|
||||
XScuWdt xWatchDogInstance;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The interrupt controller is initialised in this file, and made available to
|
||||
other modules. */
|
||||
XScuGic xInterruptController;
|
||||
|
||||
extern SemaphoreHandle_t malloc_mutex;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
void mission(void);
|
||||
|
||||
void initFreeRTOSHelper();
|
||||
|
||||
int main(void) {
|
||||
|
||||
// Enable UARTs, so qemu knows we use them (should already be enabled by fsbl
|
||||
// on actual hw)
|
||||
XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_CR_OFFSET,
|
||||
XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN);
|
||||
XUartPs_WriteReg(XPS_UART1_BASEADDR, XUARTPS_CR_OFFSET,
|
||||
XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN);
|
||||
|
||||
/* Configure the hardware ready to run. */
|
||||
prvSetupHardware();
|
||||
|
||||
mission();
|
||||
}
|
||||
|
||||
static void prvSetupHardware(void) {
|
||||
BaseType_t xStatus;
|
||||
XScuGic_Config *pxGICConfig;
|
||||
|
||||
/* Ensure no interrupts execute while the scheduler is in an inconsistent
|
||||
state. Interrupts are automatically enabled when the scheduler is
|
||||
started. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* Obtain the configuration of the GIC. */
|
||||
pxGICConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
|
||||
|
||||
/* Sanity check the FreeRTOSConfig.h settings are correct for the
|
||||
hardware. */
|
||||
configASSERT(pxGICConfig);
|
||||
configASSERT(pxGICConfig->CpuBaseAddress ==
|
||||
(configINTERRUPT_CONTROLLER_BASE_ADDRESS +
|
||||
configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET));
|
||||
configASSERT(pxGICConfig->DistBaseAddress ==
|
||||
configINTERRUPT_CONTROLLER_BASE_ADDRESS);
|
||||
|
||||
/* Install a default handler for each GIC interrupt. */
|
||||
xStatus = XScuGic_CfgInitialize(&xInterruptController, pxGICConfig,
|
||||
pxGICConfig->CpuBaseAddress);
|
||||
configASSERT(xStatus == XST_SUCCESS);
|
||||
(void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */
|
||||
|
||||
// TODO we can alter the startup code...
|
||||
/* The Xilinx projects use a BSP that do not allow the start up code to be
|
||||
altered easily. Therefore the vector table used by FreeRTOS is defined in
|
||||
FreeRTOS_asm_vectors.S, which is part of this project. Switch to use the
|
||||
FreeRTOS vector table. */
|
||||
vPortInstallFreeRTOSVectorTable();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vInitialiseTimerForRunTimeStats(void) {
|
||||
XScuWdt_Config *pxWatchDogInstance;
|
||||
uint32_t ulValue;
|
||||
const uint32_t ulMaxDivisor = 0xff, ulDivisorShift = 0x08;
|
||||
|
||||
pxWatchDogInstance = XScuWdt_LookupConfig(XPAR_SCUWDT_0_DEVICE_ID);
|
||||
XScuWdt_CfgInitialize(&xWatchDogInstance, pxWatchDogInstance,
|
||||
pxWatchDogInstance->BaseAddr);
|
||||
|
||||
ulValue = XScuWdt_GetControlReg(&xWatchDogInstance);
|
||||
ulValue |= ulMaxDivisor << ulDivisorShift;
|
||||
XScuWdt_SetControlReg(&xWatchDogInstance, ulValue);
|
||||
|
||||
XScuWdt_LoadWdt(&xWatchDogInstance, UINT_MAX);
|
||||
XScuWdt_SetTimerMode(&xWatchDogInstance);
|
||||
XScuWdt_Start(&xWatchDogInstance);
|
||||
}
|
||||
|
||||
#ifndef ARM_SEMIHOSTING
|
||||
void done() {
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void done_error() {
|
||||
// makes no difference
|
||||
done();
|
||||
}
|
||||
|
||||
#else // enable semihosting interface for done()
|
||||
void done() {
|
||||
|
||||
// Call semihosting interface to signal exit
|
||||
// see https://github.com/ARM-software/abi-aa -> Miscellaneous material ->
|
||||
// Semihosting for AArch32 and AArch64
|
||||
register int reg0 asm("r0");
|
||||
register int reg1 asm("r1");
|
||||
|
||||
reg0 = 0x18; // SYS_EXIT
|
||||
reg1 = 0x20026; // ADP_Stopped_ApplicationExit
|
||||
|
||||
asm("svc 0x123456"); // syscall to semihosting interface
|
||||
}
|
||||
|
||||
void done_error() {
|
||||
// same as done(), will make qemu return 1
|
||||
register int reg0 asm("r0");
|
||||
register int reg1 asm("r1");
|
||||
|
||||
reg0 = 0x18; // SYS_EXIT
|
||||
reg1 = 0x20023; // ADP_Stopped_RunTimeErrorUnknown
|
||||
|
||||
asm("svc 0x123456"); // syscall to semihosting interface
|
||||
}
|
||||
|
||||
#endif /* SEMIHOSTING */
|
||||
|
||||
void vApplicationIdleHook(void) {
|
||||
volatile size_t xFreeHeapSpace, xMinimumEverFreeHeapSpace;
|
||||
|
||||
/* This is just a trivial example of an idle hook. It is called on each
|
||||
cycle of the idle task. It must *NOT* attempt to block. In this case the
|
||||
idle task just queries the amount of FreeRTOS heap that remains. See the
|
||||
memory management section on the http://www.FreeRTOS.org web site for memory
|
||||
management options. If there is a lot of heap memory free then the
|
||||
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
|
||||
RAM. */
|
||||
// xFreeHeapSpace = xPortGetFreeHeapSize();
|
||||
// xMinimumEverFreeHeapSpace = xPortGetMinimumEverFreeHeapSize();
|
||||
|
||||
// /* Remove compiler warning about xFreeHeapSpace being set but never used.
|
||||
// */ (void)xFreeHeapSpace; (void)xMinimumEverFreeHeapSpace;
|
||||
}
|
||||
|
||||
void vApplicationTickHook(void) {
|
||||
#if (mainSELECTED_APPLICATION == 1)
|
||||
{
|
||||
/* The full demo includes a software timer demo/test that requires
|
||||
prodding periodically from the tick interrupt. */
|
||||
vTimerPeriodicISRTests();
|
||||
|
||||
/* Call the periodic queue overwrite from ISR demo. */
|
||||
vQueueOverwritePeriodicISRDemo();
|
||||
|
||||
/* Call the periodic event group from ISR demo. */
|
||||
vPeriodicEventGroupsProcessing();
|
||||
|
||||
/* Use task notifications from an interrupt. */
|
||||
xNotifyTaskFromISR();
|
||||
|
||||
/* Use mutexes from interrupts. */
|
||||
vInterruptSemaphorePeriodicTest();
|
||||
|
||||
/* Writes to stream buffer byte by byte to test the stream buffer trigger
|
||||
level functionality. */
|
||||
vPeriodicStreamBufferProcessing();
|
||||
|
||||
/* Writes a string to a string buffer four bytes at a time to demonstrate
|
||||
a stream being sent from an interrupt to a task. */
|
||||
vBasicStreamBufferSendFromISR();
|
||||
|
||||
#if (configUSE_QUEUE_SETS == 1)
|
||||
{
|
||||
vQueueSetAccessQueueSetFromISR();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Test flop alignment in interrupts - calling printf from an interrupt
|
||||
is BAD! */
|
||||
#if (configASSERT_DEFINED == 1)
|
||||
{
|
||||
char cBuf[20];
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
sprintf(cBuf, "%1.3f", 1.234);
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
|
||||
|
||||
configASSERT(strcmp(cBuf, "1.234") == 0);
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Needs to be INTERFACE'd so it is build as part of the main application and can be found by the linker
|
||||
# Otherwise, the linker seems to be unable to link it into newlib
|
||||
target_sources(bsp INTERFACE close.c exit.c read.c write.c)
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
// TODO
|
||||
int close(int _) {
|
||||
(void)_;
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
void _exit (int _status)
|
||||
{
|
||||
(void)_status;
|
||||
while (1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "xil_printf.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
#include "../hardware/interface_access.h"
|
||||
#include "../hardware/interface_fds.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <reent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int read(int fd, void *ptr, size_t len) {
|
||||
if (ptr == NULL) {
|
||||
// _REENT_ERRNO(_REENT) = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 0 is stdin, TODO: do we support it?
|
||||
if (fd < 1) {
|
||||
// _REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// stdout and stderr
|
||||
if (fd < 3) {
|
||||
// _REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd < INTERFACE_FDS_NEXT) {
|
||||
int result = hw_interface_read(fd, ptr, len);
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
// } else if (_REENT_ERRNO(_REENT) != EBADF) {
|
||||
// return result;
|
||||
}
|
||||
// continue if fd did not match to try other fd providers
|
||||
}
|
||||
|
||||
// we do not have dynamic fds, so fd is invalid
|
||||
// _REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "xil_printf.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
#include "../hardware/interface_access.h"
|
||||
#include "../hardware/interface_fds.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <reent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int write(int fd, const void *ptr, size_t len) {
|
||||
if (ptr == NULL) {
|
||||
// _REENT_ERRNO(_REENT) = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
//TODO check len
|
||||
|
||||
// 0 is stdin, do not write to it
|
||||
if (fd < 1) {
|
||||
// _REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
// we only support a single debug UART, so
|
||||
// stdout and stderr are the same and go to the xilinx stdout UART
|
||||
// We output directely to avoid loops and allow debugging (not via a write)
|
||||
if (fd < 3) {
|
||||
size_t todo;
|
||||
|
||||
const char *data = ptr;
|
||||
|
||||
for (todo = 0; todo < len; todo++) {
|
||||
outbyte(*data++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
if (fd < INTERFACE_FDS_NEXT) {
|
||||
int result = hw_interface_write(fd, ptr, len);
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
// } else if (_REENT_ERRNO(_REENT) != EBADF) {
|
||||
// return result;
|
||||
}
|
||||
// continue if fd did not match to try other fd providers
|
||||
}
|
||||
|
||||
// we do not have dynamic fds, so fd is invalid
|
||||
// _REENT_ERRNO(_REENT) = EBADF;
|
||||
return -1;
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
add_subdirectory(libsrc/emacps)
|
||||
add_subdirectory(libsrc/gpiops)
|
||||
add_subdirectory(libsrc/scugic)
|
||||
add_subdirectory(libsrc/scutimer)
|
||||
add_subdirectory(libsrc/scuwdt)
|
||||
add_subdirectory(libsrc/standalone)
|
||||
add_subdirectory(libsrc/uartps)
|
||||
add_subdirectory(libsrc/uartps)
|
||||
|
||||
target_include_directories(
|
||||
bsp PUBLIC include)
|
||||
@@ -0,0 +1,11 @@
|
||||
This is based on the bsp of the zynq_fsbl in https://github.com/Xilinx/embeddedsw/tree/xilinx_v2024.1/lib/sw_apps/zynq_fsbl
|
||||
|
||||
It is generated/collected by xilinx's build system when building the fsbl.
|
||||
|
||||
Currently, version xilinx_v2024.1 is used.
|
||||
|
||||
We use our own CMakeLists.txt located in the subfolders of `libsrc` to select which files to include in our bsp.
|
||||
|
||||
Xilinx exports CMakeLists.txt files for some of their folders as well, which we remove to avoid confusion.
|
||||
|
||||
Additionally, drivers from https://github.com/Xilinx/embeddedsw/tree/xilinx_v2024.1/XilinxProcessorIPLib/drivers are added as needed.
|
||||
@@ -9,8 +9,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define USE_WRITE 1 /* 1: Enable disk_write function */
|
||||
#define USE_IOCTL 1 /* 1: Enable disk_ioctl function */
|
||||
#define USE_WRITE 1 /**< 1: Enable disk_write function */
|
||||
#define USE_IOCTL 1 /**< 1: Enable disk_ioctl function */
|
||||
|
||||
#include "ff.h"
|
||||
#include "xil_types.h"
|
||||
@@ -20,11 +20,11 @@ typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
RES_OK = 0, /**< 0: Successful */
|
||||
RES_ERROR, /**< 1: R/W Error */
|
||||
RES_WRPRT, /**< 2: Write Protected */
|
||||
RES_NOTRDY, /**< 3: Not Ready */
|
||||
RES_PARERR /**< 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
@@ -41,40 +41,40 @@ DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01U /* Drive not initialized */
|
||||
#define STA_NODISK 0x02U /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04U /* Write protected */
|
||||
#define STA_NOINIT 0x01U /**< Drive not initialized */
|
||||
#define STA_NODISK 0x02U /**< No medium in the drive */
|
||||
#define STA_PROTECT 0x04U /**< Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0U /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1U /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2U /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3U /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4U /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
#define CTRL_SYNC 0U /**< Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1U /**< Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2U /**< Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3U /**< Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4U /**< Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5U /* Get/Set power status */
|
||||
#define CTRL_LOCK 6U /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7U /* Eject media */
|
||||
#define CTRL_FORMAT 8U /* Create physical format on the media */
|
||||
#define CTRL_POWER 5U /**< Get/Set power status */
|
||||
#define CTRL_LOCK 6U /**< Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7U /**< Eject media */
|
||||
#define CTRL_FORMAT 8U /**< Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10U /* Get card type */
|
||||
#define MMC_GET_CSD 11U /* Get CSD */
|
||||
#define MMC_GET_CID 12U /* Get CID */
|
||||
#define MMC_GET_OCR 13U /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14U /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
#define MMC_GET_TYPE 10U /**< Get card type */
|
||||
#define MMC_GET_CSD 11U /**< Get CSD */
|
||||
#define MMC_GET_CID 12U /**< Get CID */
|
||||
#define MMC_GET_OCR 13U /**< Get OCR */
|
||||
#define MMC_GET_SDSTAT 14U /**< Get SD status */
|
||||
#define ISDIO_READ 55 /**< Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /**< Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /**< Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20U /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21U /* Get model name */
|
||||
#define ATA_GET_SN 22U /* Get serial number */
|
||||
#define ATA_GET_REV 20U /**< Get F/W revision */
|
||||
#define ATA_GET_MODEL 21U /**< Get model name */
|
||||
#define ATA_GET_SN 22U /**< Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
#include "xilffs.h"
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
@@ -355,7 +355,7 @@ int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
/* Some API fucntions are implemented as macro */
|
||||
/* Some API functions are implemented as macro */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef SDT
|
||||
#include "xilffs_config.h"
|
||||
#else
|
||||
#include "xparameters.h"
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
@@ -34,7 +38,7 @@ extern "C" {
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#ifdef FILE_SYSTEM_USE_STRFUNC
|
||||
#if FILE_SYSTEM_USE_STRFUNC == 0
|
||||
#define FF_USE_STRFUNC 0 /* 0:Disable */
|
||||
#elif FILE_SYSTEM_USE_STRFUNC == 1
|
||||
@@ -42,6 +46,9 @@ extern "C" {
|
||||
#elif FILE_SYSTEM_USE_STRFUNC == 2
|
||||
#define FF_USE_STRFUNC 2 /* 2:Enable */
|
||||
#endif
|
||||
#else
|
||||
#define FF_USE_STRFUNC 0 /* 0:Disable */
|
||||
#endif
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
@@ -87,7 +94,6 @@ extern "C" {
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 0
|
||||
#define FF_PRINT_LLI 1
|
||||
#define FF_PRINT_FLOAT 1
|
||||
#define FF_STRF_ENCODE 3
|
||||
@@ -187,7 +193,7 @@ extern "C" {
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#ifdef FILE_SYSTEM_SET_FS_RPATH
|
||||
#if FILE_SYSTEM_SET_FS_RPATH == 0
|
||||
#define FF_FS_RPATH 0U
|
||||
#elif FILE_SYSTEM_SET_FS_RPATH == 1
|
||||
@@ -195,6 +201,9 @@ extern "C" {
|
||||
#elif FILE_SYSTEM_SET_FS_RPATH == 2
|
||||
#define FF_FS_RPATH 2U
|
||||
#endif
|
||||
#else
|
||||
#define FF_FS_RPATH 0U
|
||||
#endif
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2022 - 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file pm_api_version.h
|
||||
*
|
||||
* @addtogroup xpm_versal_apis XilPM APIs
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef PM_API_VERSION_H_
|
||||
#define PM_API_VERSION_H_
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @section EEMI_API_DETAIL XilPM EEMI API Version Detail
|
||||
*
|
||||
* This section provides details of EEMI API version and it's history for PM APIs of XilPM library.
|
||||
*
|
||||
* | NAME | ID | Platform | Version| Description |
|
||||
* |----------------------------|-------|---------------|:------:|---------------------------------------------------------------------------|
|
||||
* | PM_GET_API_VERSION | 0x1 | Both | 1 | The API is used to request the version number of the API |
|
||||
* | PM_SET_CONFIGURATION | 0x2 | ZynqMP | 1 | The API is used to configure the power management framework |
|
||||
* | ^ | ^ | ^ | ^ | Note: Deprecated in Versal but supported in ZynqMP |
|
||||
* | PM_GET_NODE_STATUS | 0x3 | Both | 1 | The API is used to obtain information about current status of a device |
|
||||
* | PM_GET_OP_CHARACTERISTIC | 0x4 | Both | 2 | V1 - The API is used to get operating characteristics of a device |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of bitmask functionality, user can check the supported\n "type" first before performing the actual functionality |
|
||||
* | PM_REGISTER_NOTIFIER | 0x5 | Both | 2 | V1 - The API is used to register a subsystem to be notified about the\n device event |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of event management functionality |
|
||||
* | ^ | ^ | ^ | ^ | Note: V2 is supported in Versal but ZynqMP supports only V1 |
|
||||
* | PM_REQUEST_SUSPEND | 0x6 | Both | 1 | The API is used to send suspend request to another subsystem |
|
||||
* | PM_SELF_SUSPEND | 0x7 | Both | 3 | V1 - The API is used to suspend a child subsystem |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of cpu idle functionality during force powerdown |
|
||||
* | ^ | ^ | ^ | ^ | V3 - Added support of CPU off state |
|
||||
* | ^ | ^ | ^ | ^ | Note: V3 is supported in Versal and Versal NET but ZynqMP supports only V1|
|
||||
* | PM_FORCE_POWERDOWN | 0x8 | Both | 2 | V1 - The API is used to Powerdown other processor or node |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of cpu idle functionality during force powerdown |
|
||||
* | ^ | ^ | ^ | ^ | Note: V2 is supported in Versal but ZynqMP supports only V1 |
|
||||
* | PM_ABORT_SUSPEND | 0x9 | Both | 1 | The API is used by a subsystem to abort suspend of a child subsystem |
|
||||
* | PM_REQUEST_WAKEUP | 0xA | Both | 1 | The API is used to start-up and wake-up a child subsystem |
|
||||
* | PM_SET_WAKEUP_SOURCE | 0xB | Both | 1 | The API is used to set wakeup source |
|
||||
* | PM_SYSTEM_SHUTDOWN | 0xC | Both | 1 | The API is used to shutdown or restart the system |
|
||||
* | PM_REQUEST_NODE | 0xD | Both | 2 | V1 - The API is used to request the usage of a device |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of security policy handling during request device |
|
||||
* | ^ | ^ | ^ | ^ | Note: V2 is supported in Versal but ZynqMP supports only V1 |
|
||||
* | PM_RELEASE_NODE | 0xE | Both | 2 | V1 - The API is used to release the usage of a device |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of security policy handling during request device |
|
||||
* | ^ | ^ | ^ | ^ | Note: V2 is supported in Versal but ZynqMP supports only V1 |
|
||||
* | PM_SET_REQUIREMENT | 0xF | Both | 1 | The API is used to announce a change in requirement for a specific slave\n node which is currently in use |
|
||||
* | PM_SET_MAX_LATENCY | 0x10 | Both | 1 | The API is used to set maximum allowed latency for the device |
|
||||
* | PM_RESET_ASSERT | 0x11 | Both | 1 | The API is used to reset or de-reset a device |
|
||||
* | PM_RESET_GET_STATUS | 0x12 | Both | 1 | The API is used to read the device reset state |
|
||||
* | PM_MMIO_WRITE | 0x13 | ZynqMP | 1 | The API is used to write a value into a register |
|
||||
* | ^ | ^ | ^ | ^ | Note: Deprecated in Versal but supported in ZynqMP |
|
||||
* | PM_MMIO_READ | 0x14 | ZynqMP | 1 | The API is used to read a value from a register |
|
||||
* | ^ | ^ | ^ | ^ | Note: Deprecated in Versal but supported in ZynqMP |
|
||||
* | PM_INIT_FINALIZE | 0x15 | Both | 1 | The API is used to initialize subsystem and release unused devices |
|
||||
* | PM_GET_CHIPID | 0x18 | Both | 1 | The API is used to request the version and ID code of a chip |
|
||||
* | PM_PINCTRL_REQUEST | 0x1C | Both | 1 | The API is used to request the pin |
|
||||
* | PM_PINCTRL_RELEASE | 0x1D | Both | 1 | The API is used to release the pin |
|
||||
* | PM_PINCTRL_GET_FUNCTION | 0x1E | Both | 1 | The API is used to read the pin function |
|
||||
* | PM_PINCTRL_SET_FUNCTION | 0x1F | Both | 1 | The API is used to set the pin function |
|
||||
* | PM_PINCTRL_CONFIG_PARAM_GET| 0x20 | Both | 1 | The API is used to read the pin parameter value |
|
||||
* | PM_PINCTRL_CONFIG_PARAM_SET| 0x21 | Both | 2 | V1 - The API is used to set the pin parameter value |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of MIO tri-state controlling functionality |
|
||||
* | ^ | ^ | ^ | ^ | Note: V2 is supported in ZynqMP but Versal supports only V1 |
|
||||
* | PM_IOCTL | 0x22 | Both | 3 | V1 - The API is used to perform driver-like IOCTL functions on shared\n system devices |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of bitmask functionality, user can check the supported\n ID first before performing the actual functionality |
|
||||
* | ^ | ^ | ^ | ^ | V3 - Add support of zeroization of AIE data and program memory separately |
|
||||
* | ^ | ^ | ^ | ^ | Note: V3 is supported in Versal but ZynqMP supports only V2 |
|
||||
* | PM_QUERY_DATA | 0x23 | Both | 2 | V1 - The API is used to query information about the platform resources |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of bitmask functionality, user can check the supported\n ID first before performing the actual functionality |
|
||||
* | PM_CLOCK_ENABLE | 0x24 | Both | 1 | The API is used to enable the clock |
|
||||
* | PM_CLOCK_DISABLE | 0x25 | Both | 1 | The API is used to disable the clock |
|
||||
* | PM_CLOCK_GETSTATE | 0x26 | Both | 1 | The API is used to read the clock state |
|
||||
* | PM_CLOCK_SETDIVIDER | 0x27 | Both | 1 | The API is used to set the divider value of the clock |
|
||||
* | PM_CLOCK_GETDIVIDER | 0x28 | Both | 1 | The API is used to read the clock divider |
|
||||
* | PM_CLOCK_SETPARENT | 0x2B | Both | 1 | The API is used to set the parent of the clock |
|
||||
* | PM_CLOCK_GETPARENT | 0x2C | Both | 1 | The API is used to read the clock parent |
|
||||
* | PM_PLL_SET_PARAM | 0x30 | Both | 1 | The API is used to set the parameter of PLL clock |
|
||||
* | PM_PLL_GET_PARAM | 0x31 | Both | 1 | The API is used to read the parameter of PLL clock |
|
||||
* | PM_PLL_SET_MODE | 0x32 | Both | 1 | The API is used to set the mode of PLL clock |
|
||||
* | PM_PLL_GET_MODE | 0x33 | Both | 1 | The API is used to read the mode of PLL clock |
|
||||
* | PM_REGISTER_ACCESS | 0x34 | ZynqMP | 1 | The API is used for register read/write access data |
|
||||
* | ^ | ^ | ^ | ^ | Note: Deprecated in Versal but supported in ZynqMP |
|
||||
* | PM_EFUSE_ACCESS | 0x35 | ZynqMP | 1 | The API is used to provide access to efuse memory |
|
||||
* | ^ | ^ | ^ | ^ | Note: Deprecated in Versal but supported in ZynqMP |
|
||||
* | PM_FEATURE_CHECK | 0x3F | Both | 2 | V1 - The API is used to return supported version of the given API |
|
||||
* | ^ | ^ | ^ | ^ | V2 - Added support of bitmask payload functionality |
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @section IOCTL_ID_DETAIL XilPM IOCTL IDs Detail
|
||||
*
|
||||
* This section provides the details of the IOCTL IDs which are supported across the different platforms and their brief descriptions.
|
||||
*
|
||||
* | Name | ID | Platform | Description |
|
||||
* |------------------------------------|-------|---------------|---------------------------------------|
|
||||
* | IOCTL_GET_RPU_OPER_MODE | 0 | Both | Get RPU mode |
|
||||
* | IOCTL_SET_RPU_OPER_MODE | 1 | Both | Set RPU mode |
|
||||
* | IOCTL_RPU_BOOT_ADDR_CONFIG | 2 | Both | RPU boot address config |
|
||||
* | IOCTL_TCM_COMB_CONFIG | 3 | Both | TCM config |
|
||||
* | IOCTL_SET_TAPDELAY_BYPASS | 4 | Both | TAP delay bypass |
|
||||
* | IOCTL_SD_DLL_RESET | 6 | Both | SD DLL reset |
|
||||
* | IOCTL_SET_SD_TAPDELAY | 7 | Both | SD TAP delay |
|
||||
* | IOCTL_SET_PLL_FRAC_MODE | 8 | Both | Set PLL frac mode |
|
||||
* | IOCTL_GET_PLL_FRAC_MODE | 9 | Both | Get PLL frac mode |
|
||||
* | IOCTL_SET_PLL_FRAC_DATA | 10 | Both | Set PLL frac data |
|
||||
* | IOCTL_GET_PLL_FRAC_DATA | 11 | Both | Get PLL frac data |
|
||||
* | IOCTL_WRITE_GGS | 12 | Both | Write GGS |
|
||||
* | IOCTL_READ_GGS | 13 | Both | Read GGS |
|
||||
* | IOCTL_WRITE_PGGS | 14 | Both | Write PGGS |
|
||||
* | IOCTL_READ_PGGS | 15 | Both | Read PGGS |
|
||||
* | IOCTL_ULPI_RESET | 16 | ZynqMP | ULPI reset |
|
||||
* | IOCTL_SET_BOOT_HEALTH_STATUS | 17 | Both | Set boot status |
|
||||
* | IOCTL_AFI | 18 | ZynqMP | AFI |
|
||||
* | IOCTL_OSPI_MUX_SELECT | 21 | Versal | OSPI mux select |
|
||||
* | IOCTL_USB_SET_STATE | 22 | Versal | USB set state |
|
||||
* | IOCTL_GET_LAST_RESET_REASON | 23 | Versal | Get last reset reason |
|
||||
* | IOCTL_AIE_ISR_CLEAR | 24 | Versal | AIE ISR clear |
|
||||
* | IOCTL_REGISTER_SGI | 25 | None | Register SGI to ATF |
|
||||
* | IOCTL_SET_FEATURE_CONFIG | 26 | ZynqMP | Set runtime feature config |
|
||||
* | IOCTL_GET_FEATURE_CONFIG | 27 | ZynqMP | Get runtime feature config |
|
||||
* | IOCTL_READ_REG | 28 | Versal | Read a 32-bit register |
|
||||
* | IOCTL_MASK_WRITE_REG | 29 | Versal | RMW a 32-bit register |
|
||||
* | IOCTL_SET_SD_CONFIG | 30 | ZynqMP | Set SD config register value |
|
||||
* | IOCTL_SET_GEM_CONFIG | 31 | ZynqMP | Set GEM config register value |
|
||||
* | IOCTL_SET_USB_CONFIG | 32 | ZynqMP | Set USB config register value |
|
||||
* | IOCTL_AIE_OPS | 33 | Versal | AIE1/AIEML Run Time Operations |
|
||||
* | IOCTL_GET_QOS | 34 | Versal | Get Device QoS value |
|
||||
* | IOCTL_GET_APU_OPER_MODE | 35 | Versal | Get APU operation mode |
|
||||
* | IOCTL_SET_APU_OPER_MODE | 36 | Versal | Set APU operation mode |
|
||||
* | IOCTL_PREPARE_DDR_SHUTDOWN | 37 | Versal | Prepare DDR for shut down |
|
||||
* | IOCTL_GET_SSIT_TEMP | 38 | Versal | Get secondary SLR min/max temperature |
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @section QUERY_ID_DETAIL XilPM QUERY IDs Detail
|
||||
*
|
||||
* This section provides the details of the QUERY IDs which are supported across the different platforms and their brief descriptions.
|
||||
*
|
||||
* | Name | ID | Platform | Description |
|
||||
* |--------------------------------------------|-------|---------------|---------------------------------------|
|
||||
* | XPM_QID_INVALID | 0 | Both | Invalid Query ID |
|
||||
* | XPM_QID_CLOCK_GET_NAME | 1 | Both | Get clock name |
|
||||
* | XPM_QID_CLOCK_GET_TOPOLOGY | 2 | Both | Get clock topology |
|
||||
* | XPM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS | 3 | Both | Get clock fixedfactor parameter |
|
||||
* | XPM_QID_CLOCK_GET_MUXSOURCES | 4 | Both | Get clock mux sources |
|
||||
* | XPM_QID_CLOCK_GET_ATTRIBUTES | 5 | Both | Get clock attributes |
|
||||
* | XPM_QID_PINCTRL_GET_NUM_PINS | 6 | Both | Get total pins |
|
||||
* | XPM_QID_PINCTRL_GET_NUM_FUNCTIONS | 7 | Both | Get total pin functions |
|
||||
* | XPM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS | 8 | Both | Get total pin function groups |
|
||||
* | XPM_QID_PINCTRL_GET_FUNCTION_NAME | 9 | Both | Get pin function name |
|
||||
* | XPM_QID_PINCTRL_GET_FUNCTION_GROUPS | 10 | Both | Get pin function groups |
|
||||
* | XPM_QID_PINCTRL_GET_PIN_GROUPS | 11 | Both | Get pin groups |
|
||||
* | XPM_QID_CLOCK_GET_NUM_CLOCKS | 12 | Both | Get number of clocks |
|
||||
* | XPM_QID_CLOCK_GET_MAX_DIVISOR | 13 | Both | Get max clock divisor |
|
||||
* | XPM_QID_PLD_GET_PARENT | 14 | Versal | Get PLD parent |
|
||||
* | XPM_QID_PINCTRL_GET_ATTRIBUTES | 15 | Versal | Get pin attributes |
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @section GET_OP_CHAR_DETAIL XilPM GET_OP_CHAR IDs Detail
|
||||
*
|
||||
* This section provides the details of the GET_OP_CHAR IDs which are supported across the different platforms and their brief descriptions.
|
||||
*
|
||||
* | Name | ID | Platform | Description |
|
||||
* |------------------------------------|-------|---------------|-----------------------------------------------|
|
||||
* | PM_OPCHAR_TYPE_POWER | 1 | ZynqMP | Operating characteristic ID power |
|
||||
* | PM_OPCHAR_TYPE_TEMP | 2 | Versal | Operating characteristic ID temperature |
|
||||
* | PM_OPCHAR_TYPE_LATENCY | 3 | Both | Operating characteristic ID latency |
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* PM API IDs
|
||||
*/
|
||||
typedef enum {
|
||||
PM_API_MIN, /**< 0x0 */
|
||||
PM_GET_API_VERSION, /**< 0x1 */
|
||||
PM_SET_CONFIGURATION, /**< 0x2 */
|
||||
PM_GET_NODE_STATUS, /**< 0x3 */
|
||||
PM_GET_OP_CHARACTERISTIC, /**< 0x4 */
|
||||
PM_REGISTER_NOTIFIER, /**< 0x5 */
|
||||
PM_REQUEST_SUSPEND, /**< 0x6 */
|
||||
PM_SELF_SUSPEND, /**< 0x7 */
|
||||
PM_FORCE_POWERDOWN, /**< 0x8 */
|
||||
PM_ABORT_SUSPEND, /**< 0x9 */
|
||||
PM_REQUEST_WAKEUP, /**< 0xA */
|
||||
PM_SET_WAKEUP_SOURCE, /**< 0xB */
|
||||
PM_SYSTEM_SHUTDOWN, /**< 0xC */
|
||||
PM_REQUEST_NODE, /**< 0xD */
|
||||
PM_RELEASE_NODE, /**< 0xE */
|
||||
PM_SET_REQUIREMENT, /**< 0xF */
|
||||
PM_SET_MAX_LATENCY, /**< 0x10 */
|
||||
PM_RESET_ASSERT, /**< 0x11 */
|
||||
PM_RESET_GET_STATUS, /**< 0x12 */
|
||||
PM_MMIO_WRITE, /**< 0x13 */
|
||||
PM_MMIO_READ, /**< 0x14 */
|
||||
PM_INIT_FINALIZE, /**< 0x15 */
|
||||
PM_FPGA_LOAD, /**< 0x16 */
|
||||
PM_FPGA_GET_STATUS, /**< 0x17 */
|
||||
PM_GET_CHIPID, /**< 0x18 */
|
||||
PM_SECURE_RSA_AES, /**< 0x19 */
|
||||
PM_SECURE_SHA, /**< 0x1A */
|
||||
PM_SECURE_RSA, /**< 0x1B */
|
||||
PM_PINCTRL_REQUEST, /**< 0x1C */
|
||||
PM_PINCTRL_RELEASE, /**< 0x1D */
|
||||
PM_PINCTRL_GET_FUNCTION, /**< 0x1E */
|
||||
PM_PINCTRL_SET_FUNCTION, /**< 0x1F */
|
||||
PM_PINCTRL_CONFIG_PARAM_GET, /**< 0x20 */
|
||||
PM_PINCTRL_CONFIG_PARAM_SET, /**< 0x21 */
|
||||
PM_IOCTL, /**< 0x22 */
|
||||
PM_QUERY_DATA, /**< 0x23 */
|
||||
PM_CLOCK_ENABLE, /**< 0x24 */
|
||||
PM_CLOCK_DISABLE, /**< 0x25 */
|
||||
PM_CLOCK_GETSTATE, /**< 0x26 */
|
||||
PM_CLOCK_SETDIVIDER, /**< 0x27 */
|
||||
PM_CLOCK_GETDIVIDER, /**< 0x28 */
|
||||
PM_CLOCK_SETRATE, /**< 0x29 */
|
||||
/* PM_CLOCK_GETRATE API is deprecated */
|
||||
PM_RESERVE_ID, /**< 0x2A */
|
||||
PM_CLOCK_SETPARENT, /**< 0x2B */
|
||||
PM_CLOCK_GETPARENT, /**< 0x2C */
|
||||
PM_SECURE_IMAGE, /**< 0x2D */
|
||||
PM_FPGA_READ, /**< 0x2E */
|
||||
PM_SECURE_AES, /**< 0x2F */
|
||||
PM_PLL_SET_PARAMETER, /**< 0x30 */
|
||||
PM_PLL_GET_PARAMETER, /**< 0x31 */
|
||||
PM_PLL_SET_MODE, /**< 0x32 */
|
||||
PM_PLL_GET_MODE, /**< 0x33 */
|
||||
PM_REGISTER_ACCESS, /**< 0x34 */
|
||||
PM_EFUSE_ACCESS, /**< 0x35 */
|
||||
PM_ADD_SUBSYSTEM, /**< 0x36 */
|
||||
PM_DESTROY_SUBSYSTEM, /**< 0x37 */
|
||||
PM_DESCRIBE_NODES, /**< 0x38 */
|
||||
PM_ADD_NODE, /**< 0x39 */
|
||||
PM_ADD_NODE_PARENT, /**< 0x3A */
|
||||
PM_ADD_NODE_NAME, /**< 0x3B */
|
||||
PM_ADD_REQUIREMENT, /**< 0x3C */
|
||||
PM_SET_CURRENT_SUBSYSTEM, /**< 0x3D */
|
||||
PM_INIT_NODE, /**< 0x3E */
|
||||
PM_FEATURE_CHECK, /**< 0x3F */
|
||||
PM_ISO_CONTROL, /**< 0x40 */
|
||||
PM_ACTIVATE_SUBSYSTEM, /**< 0x41 */
|
||||
PM_SET_NODE_ACCESS, /**< 0x42 */
|
||||
PM_BISR, /**< 0x43 */
|
||||
PM_APPLY_TRIM, /**< 0x44 */
|
||||
PM_NOC_CLOCK_ENABLE, /**< 0x45 */
|
||||
PM_IF_NOC_CLOCK_ENABLE, /**< 0x46 */
|
||||
PM_FORCE_HOUSECLEAN, /**< 0x47 */
|
||||
PM_FPGA_GET_VERSION, /**< 0x48 */
|
||||
PM_FPGA_GET_FEATURE_LIST, /**< 0x49 */
|
||||
PM_API_MAX /**< 0x4A */
|
||||
} XPm_ApiId;
|
||||
|
||||
#endif /* PM_API_VERSION_H_ */
|
||||
@@ -12,19 +12,22 @@
|
||||
* the new terms are clearly indicated on the first page of each file where
|
||||
* they apply.
|
||||
*
|
||||
*/
|
||||
*****************************************************************************/
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
/*
|
||||
* print -- do a raw print of a string
|
||||
*/
|
||||
#include "xil_printf.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* print -- do a raw print of a string
|
||||
*
|
||||
******************************************************************************/
|
||||
void print(const char8 *ptr)
|
||||
{
|
||||
#if defined (__aarch64__) && (HYP_GUEST == 1) && (EL1_NONSECURE == 1) && defined (XEN_USE_PV_CONSOLE)
|
||||
XPVXenConsole_Write(ptr);
|
||||
#else
|
||||
#ifdef STDOUT_BASEADDRESS
|
||||
#if defined(STDOUT_BASEADDRESS) || defined(SDT)
|
||||
while (*ptr != (char8)0) {
|
||||
outbyte (*ptr);
|
||||
ptr++;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2014 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -30,7 +31,8 @@
|
||||
* 8.0 sk 03/17/22 Modify sleep_MB parameter type from unsigned int to
|
||||
* u32 and usleep_MB parameter type from unsigned long to
|
||||
* ULONG to fix misra_c_2012_rule_4_6 violation.
|
||||
*
|
||||
* 9.0 ml 03/03/23 Add description to fix doxygen warnings.
|
||||
* 9.1 mus 10/24/23 Add support for RISC-V.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -87,6 +89,7 @@ extern "C" {
|
||||
(timeout>0) ? 0 : -1; \
|
||||
} )
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
void usleep(ULONG useconds);
|
||||
void sleep(u32 seconds);
|
||||
void usleep_R5(ULONG useconds);
|
||||
@@ -97,6 +100,10 @@ int usleep_A53(unsigned long useconds);
|
||||
unsigned sleep_A53(unsigned int seconds);
|
||||
int usleep_A9(unsigned long useconds);
|
||||
unsigned sleep_A9(unsigned int seconds);
|
||||
void sleep_riscv(u32 seconds);
|
||||
void usleep_riscv(ULONG useconds);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xadcps.h
|
||||
* @addtogroup xadcps_v2_6
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
@@ -157,6 +158,8 @@
|
||||
* 2.6 aad 11/02/20 Fix MISRAC Mandatory and Advisory errors.
|
||||
* aad 12/17/20 Added missing function declarations and removed
|
||||
* functions with no definitions.
|
||||
* 2.7 cog 07/24/23 Added support for SDT flow
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
@@ -300,7 +303,11 @@ extern "C" {
|
||||
* device.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef SDT
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
#else
|
||||
char *Name;
|
||||
#endif
|
||||
u32 BaseAddress; /**< Device base address */
|
||||
} XAdcPs_Config;
|
||||
|
||||
@@ -472,7 +479,11 @@ typedef struct {
|
||||
/**
|
||||
* Functions in xadcps_sinit.c
|
||||
*/
|
||||
#ifndef SDT
|
||||
XAdcPs_Config *XAdcPs_LookupConfig(u16 DeviceId);
|
||||
#else
|
||||
XAdcPs_Config *XAdcPs_LookupConfig(u32 BaseAddress);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Functions in xadcps.c
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xadcps_hw.h
|
||||
* @addtogroup xadcps_v2_6
|
||||
* @addtogroup Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and basic driver functions (or
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2021-2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
#ifndef XIL_XCORTEXA9_H_ /* prevent circular inclusions */
|
||||
#define XIL_XCORTEXA9_H_ /* by using protection macros */
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
|
||||
/**************************** Type Definitions ******************************/
|
||||
typedef struct {
|
||||
u32 CpuFreq;
|
||||
} XCortexa9_Config;
|
||||
|
||||
#endif /* XIL_XCORTEXA9_H_ */
|
||||
@@ -0,0 +1,18 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2021-2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
#ifndef XIL_XCORTEXA9_CONFIG_H_ /* prevent circular inclusions */
|
||||
#define XIL_XCORTEXA9_CONFIG_H_ /* by using protection macros */
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xcortexa9.h"
|
||||
|
||||
/************************** Variable Definitions ****************************/
|
||||
extern XCortexa9_Config XCortexa9_ConfigTable;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions ********************/
|
||||
#define XGet_CpuFreq() XCortexa9_ConfigTable.CpuFreq
|
||||
#endif /* XIL_XCORTEXA9_CONFIG_H_ */
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xcpu_cortexa9.h
|
||||
* @addtogroup cpu_cortexa9_v2_11
|
||||
* @addtogroup cpu_cortexa9 Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2022 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -61,13 +61,13 @@ int printf(const char *format, ...);
|
||||
|
||||
#else /* defined(DEBUG) && !defined(NDEBUG) */
|
||||
|
||||
#define xdbg_stmnt(x)
|
||||
#define xdbg_stmnt(x) /**< Debug statement */
|
||||
|
||||
/* See VxWorks comments above */
|
||||
#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS)
|
||||
#define xdbg_printf(type, args...)
|
||||
#else /* ANSI Syntax */
|
||||
#define xdbg_printf(...)
|
||||
#define xdbg_printf(...) /**< Debug printf */
|
||||
#endif
|
||||
#endif /* defined(DEBUG) && !defined(NDEBUG) */
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xdevcfg.h
|
||||
* @addtogroup devcfg_v3_7
|
||||
* @addtogroup devcfg Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
@@ -133,6 +134,7 @@
|
||||
* 3.5 ms 04/18/17 Modified tcl file to add suffix U for all macros
|
||||
* definitions of devcfg in xparameters.h
|
||||
* ms 08/07/17 Fixed compilation warnings in xdevcfg_sinit.c
|
||||
* 3.8 Nava 06/21/23 Added support for system device-tree flow.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -178,8 +180,18 @@ typedef void (*XDcfg_IntrHandler) (void *CallBackRef, u32 Status);
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef SDT
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
#else
|
||||
char *Name;
|
||||
#endif
|
||||
u32 BaseAddr; /**< Base address of the device */
|
||||
#ifdef SDT
|
||||
u32 IntrId; /** Bits[11:0] Interrupt-id Bits[15:12]
|
||||
* trigger type and level flags */
|
||||
UINTPTR IntrParent; /** Bit[0] Interrupt parent type Bit[64/32:1]
|
||||
* Parent base address */
|
||||
#endif
|
||||
} XDcfg_Config;
|
||||
|
||||
/**
|
||||
@@ -210,7 +222,7 @@ typedef struct {
|
||||
*****************************************************************************/
|
||||
#define XDcfg_Unlock(InstancePtr) \
|
||||
XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, \
|
||||
XDCFG_UNLOCK_OFFSET, XDCFG_UNLOCK_DATA)
|
||||
XDCFG_UNLOCK_OFFSET, XDCFG_UNLOCK_DATA)
|
||||
|
||||
|
||||
|
||||
@@ -230,8 +242,8 @@ typedef struct {
|
||||
#define XDcfg_GetPsVersion(InstancePtr) \
|
||||
((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, \
|
||||
XDCFG_MCTRL_OFFSET)) & \
|
||||
XDCFG_MCTRL_PCAP_PS_VERSION_MASK) >> \
|
||||
XDCFG_MCTRL_PCAP_PS_VERSION_SHIFT
|
||||
XDCFG_MCTRL_PCAP_PS_VERSION_MASK) >> \
|
||||
XDCFG_MCTRL_PCAP_PS_VERSION_SHIFT
|
||||
|
||||
|
||||
|
||||
@@ -250,7 +262,7 @@ typedef struct {
|
||||
*****************************************************************************/
|
||||
#define XDcfg_ReadMultiBootConfig(InstancePtr) \
|
||||
XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, \
|
||||
XDCFG_MULTIBOOT_ADDR_OFFSET)
|
||||
XDCFG_MULTIBOOT_ADDR_OFFSET)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -269,8 +281,8 @@ typedef struct {
|
||||
*****************************************************************************/
|
||||
#define XDcfg_SelectIcapInterface(InstancePtr) \
|
||||
XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET, \
|
||||
((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \
|
||||
& ( ~XDCFG_CTRL_PCAP_PR_MASK)))
|
||||
((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \
|
||||
& ( ~XDCFG_CTRL_PCAP_PR_MASK)))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
@@ -288,8 +300,8 @@ typedef struct {
|
||||
*****************************************************************************/
|
||||
#define XDcfg_SelectPcapInterface(InstancePtr) \
|
||||
XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET, \
|
||||
((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \
|
||||
| XDCFG_CTRL_PCAP_PR_MASK))
|
||||
((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \
|
||||
| XDCFG_CTRL_PCAP_PR_MASK))
|
||||
|
||||
|
||||
|
||||
@@ -298,7 +310,11 @@ typedef struct {
|
||||
/*
|
||||
* Lookup configuration in xdevcfg_sinit.c.
|
||||
*/
|
||||
#ifndef SDT
|
||||
XDcfg_Config *XDcfg_LookupConfig(u16 DeviceId);
|
||||
#else
|
||||
XDcfg_Config *XDcfg_LookupConfig(UINTPTR BaseAddress);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Selftest function in xdevcfg_selftest.c
|
||||
@@ -309,7 +325,7 @@ int XDcfg_SelfTest(XDcfg *InstancePtr);
|
||||
* Interface functions in xdevcfg.c
|
||||
*/
|
||||
int XDcfg_CfgInitialize(XDcfg *InstancePtr,
|
||||
XDcfg_Config *ConfigPtr, u32 EffectiveAddress);
|
||||
XDcfg_Config *ConfigPtr, u32 EffectiveAddress);
|
||||
|
||||
void XDcfg_EnablePCAP(XDcfg *InstancePtr);
|
||||
|
||||
@@ -344,12 +360,12 @@ u32 XDcfg_GetMiscControlRegister(XDcfg *InstancePtr);
|
||||
u32 XDcfg_IsDmaBusy(XDcfg *InstancePtr);
|
||||
|
||||
void XDcfg_InitiateDma(XDcfg *InstancePtr, u32 SourcePtr, u32 DestPtr,
|
||||
u32 SrcWordLength, u32 DestWordLength);
|
||||
u32 SrcWordLength, u32 DestWordLength);
|
||||
|
||||
u32 XDcfg_Transfer(XDcfg *InstancePtr,
|
||||
void *SourcePtr, u32 SrcWordLength,
|
||||
void *DestPtr, u32 DestWordLength,
|
||||
u32 TransferType);
|
||||
void *SourcePtr, u32 SrcWordLength,
|
||||
void *DestPtr, u32 DestWordLength,
|
||||
u32 TransferType);
|
||||
|
||||
/*
|
||||
* Interrupt related function prototypes implemented in xdevcfg_intr.c
|
||||
@@ -367,7 +383,7 @@ void XDcfg_IntrClear(XDcfg *InstancePtr, u32 Mask);
|
||||
void XDcfg_InterruptHandler(XDcfg *InstancePtr);
|
||||
|
||||
void XDcfg_SetHandler(XDcfg *InstancePtr, void *CallBackFunc,
|
||||
void *CallBackRef);
|
||||
void *CallBackRef);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xdevcfg_hw.h
|
||||
* @addtogroup devcfg_v3_7
|
||||
* @addtogroup devcfg Overview
|
||||
* @{
|
||||
*
|
||||
* This file contains the hardware interface to the Device Config Interface.
|
||||
@@ -26,6 +27,7 @@
|
||||
* version UG585 (v1.4) November 16, 2012.
|
||||
* 2.04a kpc 10/07/13 Added function prototype.
|
||||
* 3.00a kpc 25/02/14 Corrected the XDCFG_BASE_ADDRESS macro value.
|
||||
* 3.8 Nava 06/21/23 Added support for system device-tree flow.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -210,14 +212,14 @@ extern "C" {
|
||||
* of Init Signal
|
||||
*/
|
||||
#define XDCFG_IXR_ERROR_FLAGS_MASK (XDCFG_IXR_AXI_WTO_MASK | \
|
||||
XDCFG_IXR_AXI_WERR_MASK | \
|
||||
XDCFG_IXR_AXI_RTO_MASK | \
|
||||
XDCFG_IXR_AXI_RERR_MASK | \
|
||||
XDCFG_IXR_RX_FIFO_OV_MASK | \
|
||||
XDCFG_IXR_DMA_CMD_ERR_MASK |\
|
||||
XDCFG_IXR_DMA_Q_OV_MASK | \
|
||||
XDCFG_IXR_P2D_LEN_ERR_MASK |\
|
||||
XDCFG_IXR_PCFG_HMAC_ERR_MASK)
|
||||
XDCFG_IXR_AXI_WERR_MASK | \
|
||||
XDCFG_IXR_AXI_RTO_MASK | \
|
||||
XDCFG_IXR_AXI_RERR_MASK | \
|
||||
XDCFG_IXR_RX_FIFO_OV_MASK | \
|
||||
XDCFG_IXR_DMA_CMD_ERR_MASK |\
|
||||
XDCFG_IXR_DMA_Q_OV_MASK | \
|
||||
XDCFG_IXR_P2D_LEN_ERR_MASK |\
|
||||
XDCFG_IXR_PCFG_HMAC_ERR_MASK)
|
||||
|
||||
|
||||
#define XDCFG_IXR_ALL_MASK 0x00F7F8EF
|
||||
@@ -266,9 +268,9 @@ extern "C" {
|
||||
* Status
|
||||
*/
|
||||
#define XDCFG_STATUS_EFUSE_BBRAM_KEY_DISABLE_MASK 0x00000008
|
||||
/**< BBRAM key
|
||||
* disable
|
||||
*/
|
||||
/**< BBRAM key
|
||||
* disable
|
||||
*/
|
||||
#define XDCFG_STATUS_EFUSE_SEC_EN_MASK 0x00000004 /**< Efuse Security
|
||||
* Enable Status
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2009 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2009 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xdmaps.h
|
||||
* @addtogroup dmaps_v2_8
|
||||
* @addtogroup dmaps Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
@@ -60,6 +61,7 @@
|
||||
* 2.4 adk 13/08/18 Fixed armcc compiler warnings in the driver CR-1008310.
|
||||
* 2.8 sk 05/18/21 Modify all inline functions declarations from extern inline
|
||||
* to static inline to avoid the linkage conflict for IAR compiler.
|
||||
* 2.9 aj 11/07/23 Added support for system device tree
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
@@ -88,8 +90,19 @@ extern "C" {
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef SDT
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
#else
|
||||
char *Name;
|
||||
#endif
|
||||
u32 BaseAddress; /**< Base address of device (IPIF) */
|
||||
|
||||
#ifdef SDT
|
||||
u32 IntrId[9]; /** Bits[11:0] Interrupt-id Bits[15:12]
|
||||
* trigger type and level flags */
|
||||
UINTPTR IntrParent; /** Bit[0] Interrupt parent type Bit[64/32:1]
|
||||
* Parent base address */
|
||||
#endif
|
||||
} XDmaPs_Config;
|
||||
|
||||
|
||||
@@ -169,15 +182,15 @@ typedef struct {
|
||||
* It's the done handler a user can set for a channel
|
||||
*/
|
||||
typedef void (*XDmaPsDoneHandler) (unsigned int Channel,
|
||||
XDmaPs_Cmd *DmaCmd,
|
||||
void *CallbackRef);
|
||||
XDmaPs_Cmd *DmaCmd,
|
||||
void *CallbackRef);
|
||||
|
||||
/**
|
||||
* It's the fault handler a user can set for a channel
|
||||
*/
|
||||
typedef void (*XDmaPsFaultHandler) (unsigned int Channel,
|
||||
XDmaPs_Cmd *DmaCmd,
|
||||
void *CallbackRef);
|
||||
XDmaPs_Cmd *DmaCmd,
|
||||
void *CallbackRef);
|
||||
|
||||
#define XDMAPS_MAX_CHAN_BUFS 2
|
||||
#define XDMAPS_CHAN_BUF_LEN 128
|
||||
@@ -236,18 +249,18 @@ typedef struct {
|
||||
* Functions implemented in xdmaps.c
|
||||
*/
|
||||
int XDmaPs_CfgInitialize(XDmaPs *InstPtr,
|
||||
XDmaPs_Config *Config,
|
||||
u32 EffectiveAddr);
|
||||
XDmaPs_Config *Config,
|
||||
u32 EffectiveAddr);
|
||||
|
||||
int XDmaPs_Start(XDmaPs *InstPtr, unsigned int Channel,
|
||||
XDmaPs_Cmd *Cmd,
|
||||
int HoldDmaProg);
|
||||
XDmaPs_Cmd *Cmd,
|
||||
int HoldDmaProg);
|
||||
|
||||
int XDmaPs_IsActive(XDmaPs *InstPtr, unsigned int Channel);
|
||||
int XDmaPs_GenDmaProg(XDmaPs *InstPtr, unsigned int Channel,
|
||||
XDmaPs_Cmd *Cmd);
|
||||
XDmaPs_Cmd *Cmd);
|
||||
int XDmaPs_FreeDmaProg(XDmaPs *InstPtr, unsigned int Channel,
|
||||
XDmaPs_Cmd *Cmd);
|
||||
XDmaPs_Cmd *Cmd);
|
||||
void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd);
|
||||
|
||||
|
||||
@@ -256,13 +269,13 @@ int XDmaPs_ResetChannel(XDmaPs *InstPtr, unsigned int Channel);
|
||||
|
||||
|
||||
int XDmaPs_SetDoneHandler(XDmaPs *InstPtr,
|
||||
unsigned Channel,
|
||||
XDmaPsDoneHandler DoneHandler,
|
||||
void *CallbackRef);
|
||||
unsigned Channel,
|
||||
XDmaPsDoneHandler DoneHandler,
|
||||
void *CallbackRef);
|
||||
|
||||
int XDmaPs_SetFaultHandler(XDmaPs *InstPtr,
|
||||
XDmaPsFaultHandler FaultHandler,
|
||||
void *CallbackRef);
|
||||
XDmaPsFaultHandler FaultHandler,
|
||||
void *CallbackRef);
|
||||
|
||||
void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd);
|
||||
int XDmaPs_Instr_DMARMB(char *DmaProg);
|
||||
@@ -276,10 +289,10 @@ int XDmaPs_Instr_DMAWMB(char *DmaProg);
|
||||
static INLINE int XDmaPs_Instr_DMAEND(char *DmaProg);
|
||||
static INLINE void XDmaPs_Memcpy4(char *Dst, char *Src);
|
||||
static INLINE int XDmaPs_Instr_DMAGO(char *DmaProg, unsigned int Cn,
|
||||
u32 Imm, unsigned int Ns);
|
||||
u32 Imm, unsigned int Ns);
|
||||
static INLINE int XDmaPs_Instr_DMALD(char *DmaProg);
|
||||
static INLINE int XDmaPs_Instr_DMALP(char *DmaProg, unsigned Lc,
|
||||
unsigned LoopIterations);
|
||||
unsigned LoopIterations);
|
||||
static INLINE int XDmaPs_Instr_DMALPEND(char *DmaProg, char *BodyStart, unsigned Lc);
|
||||
static INLINE int XDmaPs_Instr_DMAMOV(char *DmaProg, unsigned Rd, u32 Imm);
|
||||
static INLINE int XDmaPs_Instr_DMANOP(char *DmaProg);
|
||||
@@ -312,7 +325,12 @@ void XDmaPs_FaultISR(XDmaPs *InstPtr);
|
||||
/*
|
||||
* Static loopup function implemented in xdmaps_sinit.c
|
||||
*/
|
||||
#ifndef SDT
|
||||
XDmaPs_Config *XDmaPs_LookupConfig(u16 DeviceId);
|
||||
#else
|
||||
XDmaPs_Config *XDmaPs_LookupConfig(UINTPTR BaseAddress);
|
||||
u32 XDmaPs_GetDrvIndex(XDmaPs *InstancePtr, UINTPTR BaseAddress);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2009 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2009 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xdmaps_hw.h
|
||||
* @addtogroup dmaps_v2_8
|
||||
* @addtogroup dmaps Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains the hardware interface of an XDmaPs device.
|
||||
@@ -233,7 +234,7 @@ extern "C" {
|
||||
#define XDMAPS_INTCLR_ALL_MASK 0xFF
|
||||
|
||||
#define XDmaPs_ReadReg(BaseAddress, RegOffset) \
|
||||
Xil_In32((BaseAddress) + (RegOffset))
|
||||
Xil_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
@@ -251,7 +252,7 @@ extern "C" {
|
||||
* u32 RegisterValue)
|
||||
******************************************************************************/
|
||||
#define XDmaPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \
|
||||
Xil_Out32((BaseAddress) + (RegOffset), (RegisterValue))
|
||||
Xil_Out32((BaseAddress) + (RegOffset), (RegisterValue))
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xemacps.h
|
||||
* @addtogroup emacps_v3_16
|
||||
* @addtogroup emacps Overview
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
@@ -417,15 +418,15 @@ extern "C" {
|
||||
#define XEMACPS_SGMII_ENABLE_OPTION 0x00008000U
|
||||
|
||||
#define XEMACPS_DEFAULT_OPTIONS \
|
||||
((u32)XEMACPS_FLOW_CONTROL_OPTION | \
|
||||
(u32)XEMACPS_FCS_INSERT_OPTION | \
|
||||
(u32)XEMACPS_FCS_STRIP_OPTION | \
|
||||
(u32)XEMACPS_BROADCAST_OPTION | \
|
||||
(u32)XEMACPS_LENTYPE_ERR_OPTION | \
|
||||
(u32)XEMACPS_TRANSMITTER_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_RECEIVER_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_RX_CHKSUM_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_TX_CHKSUM_ENABLE_OPTION)
|
||||
((u32)XEMACPS_FLOW_CONTROL_OPTION | \
|
||||
(u32)XEMACPS_FCS_INSERT_OPTION | \
|
||||
(u32)XEMACPS_FCS_STRIP_OPTION | \
|
||||
(u32)XEMACPS_BROADCAST_OPTION | \
|
||||
(u32)XEMACPS_LENTYPE_ERR_OPTION | \
|
||||
(u32)XEMACPS_TRANSMITTER_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_RECEIVER_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_RX_CHKSUM_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_TX_CHKSUM_ENABLE_OPTION)
|
||||
|
||||
/**< Default options set when device is initialized or reset */
|
||||
/*@}*/
|
||||
@@ -456,11 +457,11 @@ extern "C" {
|
||||
#define XEMACPS_HDR_VLAN_SIZE 18U /* size of Ethernet header with VLAN */
|
||||
#define XEMACPS_TRL_SIZE 4U /* size of Ethernet trailer (FCS) */
|
||||
#define XEMACPS_MAX_FRAME_SIZE (XEMACPS_MTU + XEMACPS_HDR_SIZE + \
|
||||
XEMACPS_TRL_SIZE)
|
||||
XEMACPS_TRL_SIZE)
|
||||
#define XEMACPS_MAX_VLAN_FRAME_SIZE (XEMACPS_MTU + XEMACPS_HDR_SIZE + \
|
||||
XEMACPS_HDR_VLAN_SIZE + XEMACPS_TRL_SIZE)
|
||||
XEMACPS_HDR_VLAN_SIZE + XEMACPS_TRL_SIZE)
|
||||
#define XEMACPS_MAX_VLAN_FRAME_SIZE_JUMBO (XEMACPS_MTU_JUMBO + XEMACPS_HDR_SIZE + \
|
||||
XEMACPS_HDR_VLAN_SIZE + XEMACPS_TRL_SIZE)
|
||||
XEMACPS_HDR_VLAN_SIZE + XEMACPS_TRL_SIZE)
|
||||
|
||||
/* DMACR Bust length hash defines */
|
||||
|
||||
@@ -500,7 +501,7 @@ typedef void (*XEmacPs_Handler) (void *CallBackRef);
|
||||
*
|
||||
*/
|
||||
typedef void (*XEmacPs_ErrHandler) (void *CallBackRef, u8 Direction,
|
||||
u32 ErrorWord);
|
||||
u32 ErrorWord);
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -508,12 +509,25 @@ typedef void (*XEmacPs_ErrHandler) (void *CallBackRef, u8 Direction,
|
||||
* This typedef contains configuration information for a device.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifdef SDT
|
||||
char *Name; /**< Unique name of the device */
|
||||
#else
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
#endif
|
||||
UINTPTR BaseAddress;/**< Physical base address of IPIF registers */
|
||||
u8 IsCacheCoherent; /**< Applicable only to A53 in EL1 mode;
|
||||
* describes whether Cache Coherent or not */
|
||||
#if defined (XCLOCKING)
|
||||
#ifdef SDT
|
||||
u16 IntrId;
|
||||
UINTPTR IntrParent;
|
||||
#endif
|
||||
#if defined (XCLOCKING) || defined (SDT)
|
||||
u32 RefClk; /**< Input clock */
|
||||
#endif
|
||||
#ifdef SDT
|
||||
char *PhyType; /**< PhyType indicates which type of PHY interface is
|
||||
* used (MII, GMII, RGMII, etc.
|
||||
*/
|
||||
#endif
|
||||
u16 S1GDiv0; /**< 1Gbps Clock Divider 0 */
|
||||
u8 S1GDiv1; /**< 1Gbps Clock Divider 1 */
|
||||
@@ -606,8 +620,8 @@ typedef struct XEmacPs_Instance {
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IntEnable(InstancePtr, Mask) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_IER_OFFSET, \
|
||||
((Mask) & XEMACPS_IXR_ALL_MASK));
|
||||
XEMACPS_IER_OFFSET, \
|
||||
((Mask) & XEMACPS_IXR_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
@@ -627,8 +641,8 @@ typedef struct XEmacPs_Instance {
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IntDisable(InstancePtr, Mask) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_IDR_OFFSET, \
|
||||
((Mask) & XEMACPS_IXR_ALL_MASK));
|
||||
XEMACPS_IDR_OFFSET, \
|
||||
((Mask) & XEMACPS_IXR_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
@@ -648,8 +662,8 @@ typedef struct XEmacPs_Instance {
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IntQ1Enable(InstancePtr, Mask) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_INTQ1_IER_OFFSET, \
|
||||
((Mask) & XEMACPS_INTQ1_IXR_ALL_MASK));
|
||||
XEMACPS_INTQ1_IER_OFFSET, \
|
||||
((Mask) & XEMACPS_INTQ1_IXR_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
@@ -669,8 +683,8 @@ typedef struct XEmacPs_Instance {
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IntQ1Disable(InstancePtr, Mask) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_INTQ1_IDR_OFFSET, \
|
||||
((Mask) & XEMACPS_INTQ1_IXR_ALL_MASK));
|
||||
XEMACPS_INTQ1_IDR_OFFSET, \
|
||||
((Mask) & XEMACPS_INTQ1_IXR_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
@@ -687,10 +701,10 @@ typedef struct XEmacPs_Instance {
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_Transmit(InstancePtr) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCTRL_OFFSET, \
|
||||
(XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCTRL_OFFSET) | XEMACPS_NWCTRL_STARTTX_MASK))
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCTRL_OFFSET, \
|
||||
(XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCTRL_OFFSET) | XEMACPS_NWCTRL_STARTTX_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
@@ -711,9 +725,9 @@ typedef struct XEmacPs_Instance {
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IsRxCsum(InstancePtr) \
|
||||
((XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCFG_OFFSET) & XEMACPS_NWCFG_RXCHKSUMEN_MASK) != 0U \
|
||||
? TRUE : FALSE)
|
||||
((XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCFG_OFFSET) & XEMACPS_NWCFG_RXCHKSUMEN_MASK) != 0U \
|
||||
? TRUE : FALSE)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
@@ -734,9 +748,9 @@ typedef struct XEmacPs_Instance {
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IsTxCsum(InstancePtr) \
|
||||
((XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_DMACR_OFFSET) & XEMACPS_DMACR_TCPCKSUM_MASK) != 0U \
|
||||
? TRUE : FALSE)
|
||||
((XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_DMACR_OFFSET) & XEMACPS_DMACR_TCPCKSUM_MASK) != 0U \
|
||||
? TRUE : FALSE)
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
@@ -761,10 +775,10 @@ typedef struct XEmacPs_Instance {
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_SetRXWatermark(InstancePtr, High, Low) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_RXWATERMARK_OFFSET, \
|
||||
(High & XEMACPS_RXWM_HIGH_MASK) | \
|
||||
((Low << XEMACPS_RXWM_LOW_SHFT_MSK) & XEMACPS_RXWM_LOW_MASK) |)
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_RXWATERMARK_OFFSET, \
|
||||
(High & XEMACPS_RXWM_HIGH_MASK) | \
|
||||
((Low << XEMACPS_RXWM_LOW_SHFT_MSK) & XEMACPS_RXWM_LOW_MASK) |)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
@@ -781,8 +795,8 @@ typedef struct XEmacPs_Instance {
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_GetRXWatermark(InstancePtr) \
|
||||
XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_RXWATERMARK_OFFSET)
|
||||
XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_RXWATERMARK_OFFSET)
|
||||
/*
|
||||
* Initialization functions in xemacps.c
|
||||
*/
|
||||
@@ -797,7 +811,12 @@ void XEmacPs_SetQueuePtr(XEmacPs *InstancePtr, UINTPTR QPtr, u8 QueueNum,
|
||||
/*
|
||||
* Lookup configuration in xemacps_sinit.c
|
||||
*/
|
||||
|
||||
#ifndef SDT
|
||||
XEmacPs_Config *XEmacPs_LookupConfig(u16 DeviceId);
|
||||
#else
|
||||
XEmacPs_Config *XEmacPs_LookupConfig(UINTPTR BaseAddress);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interrupt-related functions in xemacps_intr.c
|
||||
@@ -823,7 +842,7 @@ void XEmacPs_ClearHash(XEmacPs *InstancePtr);
|
||||
void XEmacPs_GetHash(XEmacPs *InstancePtr, void *AddressPtr);
|
||||
|
||||
void XEmacPs_SetMdioDivisor(XEmacPs *InstancePtr,
|
||||
XEmacPs_MdcDiv Divisor);
|
||||
XEmacPs_MdcDiv Divisor);
|
||||
void XEmacPs_SetOperatingSpeed(XEmacPs *InstancePtr, u16 Speed);
|
||||
u16 XEmacPs_GetOperatingSpeed(XEmacPs *InstancePtr);
|
||||
LONG XEmacPs_PhyRead(XEmacPs *InstancePtr, u32 PhyAddress,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 - 2024 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xemacps_bd.h
|
||||
* @addtogroup emacps_v3_16
|
||||
* @addtogroup emacps Overview
|
||||
* @{
|
||||
*
|
||||
* This header provides operations to manage buffer descriptors in support
|
||||
@@ -45,6 +46,7 @@
|
||||
* 3.2 hk 11/18/15 Change BD typedef and number of words.
|
||||
* 3.8 hk 08/18/18 Remove duplicate definition of XEmacPs_BdSetLength
|
||||
* 3.8 mus 11/05/18 Support 64 bit DMA addresses for Microblaze-X platform.
|
||||
* 3.9 aj 22/03/24 Add mask for XEmaPs_BdGetBufAddr
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
@@ -239,11 +241,11 @@ typedef u32 XEmacPs_Bd[XEMACPS_BD_NUM_WORDS];
|
||||
*****************************************************************************/
|
||||
#if defined(__aarch64__) || defined(__arch64__)
|
||||
#define XEmacPs_BdGetBufAddr(BdPtr) \
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) | \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & XEMACPS_RXBUF_ADD_MASK) | \
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_HI_OFFSET)) << 32U)
|
||||
#else
|
||||
#define XEmacPs_BdGetBufAddr(BdPtr) \
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET))
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & XEMACPS_RXBUF_ADD_MASK)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2010 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -7,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xemacps_bdring.h
|
||||
* @addtogroup emacps_v3_16
|
||||
* @addtogroup emacps Overview
|
||||
* @{
|
||||
*
|
||||
* The Xiline EmacPs Buffer Descriptor ring driver. This is part of EmacPs
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/**
|
||||
*
|
||||
* @file xemacps_hw.h
|
||||
* @addtogroup emacps_v3_16
|
||||
* @addtogroup emacps Overview
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and low-level driver functions (or
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2022 - 2024 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -124,6 +124,11 @@
|
||||
* 3.8 sne 09/17/20 Added description for Versal PS and PMC GPIO pins.
|
||||
* 3.9 sne 03/15/21 Fixed MISRA-C violations.
|
||||
* 3.11 sg 02/23/23 Update bank and pin mapping information.
|
||||
* 3.12 gm 07/11/23 Added SDT support.
|
||||
* 3.13 gm 03/15/24 Remove const of XGpioPs InstancePtr from function proto
|
||||
* type of XGpioPs_IntrEnable, XGpioPs_IntrDisable,
|
||||
* XGpioPs_IntrEnablePin and XGpioPs_IntrDisablePin
|
||||
* to add multi-core interrupt support.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
@@ -167,6 +172,7 @@ extern "C" {
|
||||
* Zynq Ultrascale+ MP GPIO device
|
||||
*/
|
||||
#define XGPIOPS_MAX_BANKS 0x04U /**< Max banks in a Zynq GPIO device */
|
||||
#define XGPIOPS_MAX_BANKS_CNT 0x06U /**< Max banks number of all platforms */
|
||||
|
||||
#define XGPIOPS_DEVICE_MAX_PIN_NUM_ZYNQMP (u32)174 /**< Max pins in the
|
||||
* Zynq Ultrascale+ MP GPIO device
|
||||
@@ -209,8 +215,18 @@ typedef void (*XGpioPs_Handler) (void *CallBackRef, u32 Bank, u32 Status);
|
||||
* This typedef contains configuration information for a device.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef SDT
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
#else
|
||||
char *Name;
|
||||
#endif
|
||||
UINTPTR BaseAddr; /**< Register base address */
|
||||
#ifdef SDT
|
||||
u16 IntrId; /** Bits[11:0] Interrupt-id Bits[15:12]
|
||||
* trigger type and level flags */
|
||||
UINTPTR IntrParent; /** Bit[0] Interrupt parent type Bit[64/32:1]
|
||||
* Parent base address */
|
||||
#endif
|
||||
} XGpioPs_Config;
|
||||
|
||||
/**
|
||||
@@ -227,6 +243,7 @@ typedef struct {
|
||||
u32 MaxPinNum; /**< Max pins in the GPIO device */
|
||||
u8 MaxBanks; /**< Max banks in a GPIO device */
|
||||
u32 PmcGpio; /**< Flag for accessing PS GPIO for versal*/
|
||||
u32 CoreIntrMask[XGPIOPS_MAX_BANKS_CNT]; /**< Interrupt mask per core */
|
||||
} XGpioPs;
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
@@ -262,12 +279,12 @@ void XGpioPs_SetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin, u32 OpEnabl
|
||||
u32 XGpioPs_GetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin);
|
||||
|
||||
/* Diagnostic functions in xgpiops_selftest.c */
|
||||
s32 XGpioPs_SelfTest(const XGpioPs *InstancePtr);
|
||||
s32 XGpioPs_SelfTest(XGpioPs *InstancePtr);
|
||||
|
||||
/* Functions in xgpiops_intr.c */
|
||||
/* Bank APIs in xgpiops_intr.c */
|
||||
void XGpioPs_IntrEnable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask);
|
||||
void XGpioPs_IntrDisable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask);
|
||||
void XGpioPs_IntrEnable(XGpioPs *InstancePtr, u8 Bank, u32 Mask);
|
||||
void XGpioPs_IntrDisable(XGpioPs *InstancePtr, u8 Bank, u32 Mask);
|
||||
u32 XGpioPs_IntrGetEnabled(const XGpioPs *InstancePtr, u8 Bank);
|
||||
u32 XGpioPs_IntrGetStatus(const XGpioPs *InstancePtr, u8 Bank);
|
||||
void XGpioPs_IntrClear(const XGpioPs *InstancePtr, u8 Bank, u32 Mask);
|
||||
@@ -283,14 +300,18 @@ void XGpioPs_IntrHandler(const XGpioPs *InstancePtr);
|
||||
void XGpioPs_SetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin, u8 IrqType);
|
||||
u8 XGpioPs_GetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin);
|
||||
|
||||
void XGpioPs_IntrEnablePin(const XGpioPs *InstancePtr, u32 Pin);
|
||||
void XGpioPs_IntrDisablePin(const XGpioPs *InstancePtr, u32 Pin);
|
||||
void XGpioPs_IntrEnablePin(XGpioPs *InstancePtr, u32 Pin);
|
||||
void XGpioPs_IntrDisablePin(XGpioPs *InstancePtr, u32 Pin);
|
||||
u32 XGpioPs_IntrGetEnabledPin(const XGpioPs *InstancePtr, u32 Pin);
|
||||
u32 XGpioPs_IntrGetStatusPin(const XGpioPs *InstancePtr, u32 Pin);
|
||||
void XGpioPs_IntrClearPin(const XGpioPs *InstancePtr, u32 Pin);
|
||||
|
||||
/* Functions in xgpiops_sinit.c */
|
||||
#ifndef SDT
|
||||
XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId);
|
||||
#else
|
||||
XGpioPs_Config *XGpioPs_LookupConfig(u32 BaseAddress);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2022 - 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2010 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -26,6 +27,7 @@
|
||||
* 3.04a sdm 01/02/12 Remove redundant dsb/dmb instructions in cache maintenance
|
||||
* APIs.
|
||||
* 6.8 aru 09/06/18 Removed compilation warnings for ARMCC toolchain.
|
||||
* 9.0 ml 03/03/23 Updated function prototypes.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @file xil_cryptoalginfo.h
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* Crypto algotithm information structure declaration.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- -------- -------- -----------------------------------------------
|
||||
* 9.0 mmd 07/04/23 First release.
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef XIL_CRYPTOALGINFO_H
|
||||
#define XIL_CRYPTOALGINFO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xil_types.h"
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
typedef enum _Xil_CryptoAlgNistStatus {
|
||||
NOT_APPLICABLE = 0x00,
|
||||
NIST_COMPLIANT = 0x11,
|
||||
NIST_NON_COMPLIANT = 0xFE,
|
||||
} Xil_CryptoAlgNistStatus;
|
||||
|
||||
typedef struct _Xil_CryptoAlgInfo {
|
||||
u32 Version;
|
||||
Xil_CryptoAlgNistStatus NistStatus;
|
||||
} Xil_CryptoAlgInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* XIL_CRYPTOALGINFO_H */
|
||||
@@ -75,8 +75,10 @@
|
||||
#include "xil_types.h"
|
||||
#include "xpseudo_asm.h"
|
||||
#include "bspconfig.h"
|
||||
#ifndef SDT
|
||||
#include "xparameters.h"
|
||||
#include "xdebug.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -228,7 +230,7 @@ extern "C" {
|
||||
/*
|
||||
* XIL_EXCEPTION_ID_INT is defined for all Xilinx processors.
|
||||
*/
|
||||
#if (defined (versal) && !defined(ARMR5) && EL3) || defined(ARMR52)
|
||||
#if (defined (versal) && !defined(ARMR5) && EL3)
|
||||
#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_FIQ_INT
|
||||
#else
|
||||
#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_IRQ_INT
|
||||
@@ -267,7 +269,7 @@ extern XExc_VectorTableEntry XExc_VectorTable[];
|
||||
* C-Style signature: void Xil_ExceptionEnableMask(Mask)
|
||||
*
|
||||
******************************************************************************/
|
||||
#if (defined (versal) && !defined(ARMR5) && EL3) || defined(ARMR52)
|
||||
#if (defined (versal) && !defined(ARMR5) && EL3)
|
||||
/*
|
||||
* Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports
|
||||
* only FIQ at EL3. Hence, tweaking this macro to always enable FIQ
|
||||
@@ -295,7 +297,7 @@ extern XExc_VectorTableEntry XExc_VectorTable[];
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#if (defined (versal) && !defined(ARMR5) && EL3) || defined(ARMR52)
|
||||
#if (defined (versal) && !defined(ARMR5) && EL3)
|
||||
#define Xil_ExceptionEnable() \
|
||||
Xil_ExceptionEnableMask(XIL_EXCEPTION_FIQ)
|
||||
#else
|
||||
@@ -315,7 +317,7 @@ extern XExc_VectorTableEntry XExc_VectorTable[];
|
||||
* C-Style signature: Xil_ExceptionDisableMask(Mask)
|
||||
*
|
||||
******************************************************************************/
|
||||
#if (defined (versal) && !defined(ARMR5) && EL3) || defined(ARMR52)
|
||||
#if (defined (versal) && !defined(ARMR5) && EL3)
|
||||
/*
|
||||
* Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports
|
||||
* only FIQ at EL3. Hence, tweaking this macro to always disable FIQ
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2014 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2014 - 2021 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
@@ -32,12 +33,12 @@
|
||||
* 7.50 dp 02/12/21 Fix compilation error in Xil_EndianSwap32() that occur
|
||||
* when -Werror=conversion compiler flag is enabled
|
||||
* 7.5 mus 05/17/21 Update the functions with comments. It fixes CR#1067739.
|
||||
*
|
||||
* 9.0 ml 03/03/23 Add description and remove comments to fix doxygen warnings.
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIL_IO_H /* prevent circular inclusions */
|
||||
#define XIL_IO_H /* by using protection macros */
|
||||
#ifndef XIL_IO_H /**< prevent circular inclusions */
|
||||
#define XIL_IO_H /**< by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -63,25 +64,25 @@ extern u32 XStl_RegUpdate(u32 RegAddr, u32 RegVal);
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
#if defined __GNUC__
|
||||
#if defined (__MICROBLAZE__)
|
||||
# define INST_SYNC mbar(0)
|
||||
# define DATA_SYNC mbar(1)
|
||||
# define INST_SYNC mbar(0) /**< Instruction Synchronization Barrier */
|
||||
# define DATA_SYNC mbar(1) /**< Data Synchronization Barrier */
|
||||
# else
|
||||
# define SYNCHRONIZE_IO dmb()
|
||||
# define INST_SYNC isb()
|
||||
# define DATA_SYNC dsb()
|
||||
# define SYNCHRONIZE_IO dmb() /**< Data Memory Barrier */
|
||||
# define INST_SYNC isb() /**< Instruction Synchronization Barrier */
|
||||
# define DATA_SYNC dsb() /**< Data Synchronization Barrier */
|
||||
# endif
|
||||
#else
|
||||
# define SYNCHRONIZE_IO
|
||||
# define INST_SYNC
|
||||
# define DATA_SYNC
|
||||
# define INST_SYNC
|
||||
# define DATA_SYNC
|
||||
# define SYNCHRONIZE_IO /**< Data Memory Barrier */
|
||||
# define INST_SYNC /**< Instruction Synchronization Barrier */
|
||||
# define DATA_SYNC /**< Data Synchronization Barrier */
|
||||
# define INST_SYNC /**< Instruction Synchronization Barrier */
|
||||
# define DATA_SYNC /**< Data Synchronization Barrier */
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__) || defined (__ICCARM__) || defined (__MICROBLAZE__)
|
||||
#define INLINE inline
|
||||
#define INLINE inline /**< static inline keyword */
|
||||
#else
|
||||
#define INLINE __inline
|
||||
#define INLINE __inline /**<static inline keyword */
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -91,7 +92,7 @@ extern u32 XStl_RegUpdate(u32 RegAddr, u32 RegVal);
|
||||
* from the specified address and returning the 8 bit Value read from
|
||||
* that address.
|
||||
*
|
||||
* @param Addr: contains the address to perform the input operation
|
||||
* @param Addr contains the address to perform the input operation
|
||||
*
|
||||
* @return The 8 bit Value read from the specified input address.
|
||||
|
||||
@@ -109,7 +110,7 @@ static INLINE u8 Xil_In8(UINTPTR Addr)
|
||||
* the specified address and returning the 16 bit Value read from that
|
||||
* address.
|
||||
*
|
||||
* @param Addr: contains the address to perform the input operation
|
||||
* @param Addr contains the address to perform the input operation
|
||||
*
|
||||
* @return The 16 bit Value read from the specified input address.
|
||||
*
|
||||
@@ -126,7 +127,7 @@ static INLINE u16 Xil_In16(UINTPTR Addr)
|
||||
* reading from the specified address and returning the 32 bit Value
|
||||
* read from that address.
|
||||
*
|
||||
* @param Addr: contains the address to perform the input operation
|
||||
* @param Addr contains the address to perform the input operation
|
||||
*
|
||||
* @return The 32 bit Value read from the specified input address.
|
||||
*
|
||||
@@ -143,7 +144,7 @@ static INLINE u32 Xil_In32(UINTPTR Addr)
|
||||
* 64 bit Value read from that address.
|
||||
*
|
||||
*
|
||||
* @param Addr: contains the address to perform the input operation
|
||||
* @param Addr contains the address to perform the input operation
|
||||
*
|
||||
* @return The 64 bit Value read from the specified input address.
|
||||
*
|
||||
@@ -159,8 +160,8 @@ static INLINE u64 Xil_In64(UINTPTR Addr)
|
||||
* @brief Performs an output operation for an memory location by
|
||||
* writing the 8 bit Value to the the specified address.
|
||||
*
|
||||
* @param Addr: contains the address to perform the output operation
|
||||
* @param Value: contains the 8 bit Value to be written at the specified
|
||||
* @param Addr contains the address to perform the output operation
|
||||
* @param Value contains the 8 bit Value to be written at the specified
|
||||
* address.
|
||||
*
|
||||
* @return None.
|
||||
@@ -275,7 +276,7 @@ static INLINE int Xil_SecureOut32(UINTPTR Addr, u32 Value)
|
||||
*
|
||||
* @brief Perform a 16-bit endian conversion.
|
||||
*
|
||||
* @param Data: 16 bit value to be converted
|
||||
* @param Data 16 bit value to be converted
|
||||
*
|
||||
* @return 16 bit Data with converted endianness
|
||||
*
|
||||
@@ -290,7 +291,7 @@ static INLINE __attribute__((always_inline)) u16 Xil_EndianSwap16(u16 Data)
|
||||
*
|
||||
* @brief Perform a 32-bit endian conversion.
|
||||
*
|
||||
* @param Data: 32 bit value to be converted
|
||||
* @param Data : 32 bit value to be converted
|
||||
*
|
||||
* @return 32 bit data with converted endianness
|
||||
*
|
||||
@@ -317,42 +318,47 @@ static INLINE __attribute__((always_inline)) u32 Xil_EndianSwap32(u32 Data)
|
||||
|
||||
#if defined (__MICROBLAZE__)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
# define Xil_In16LE Xil_In16
|
||||
# define Xil_In32LE Xil_In32
|
||||
# define Xil_Out16LE Xil_Out16
|
||||
# define Xil_Out32LE Xil_Out32
|
||||
# define Xil_Htons Xil_EndianSwap16
|
||||
# define Xil_Htonl Xil_EndianSwap32
|
||||
# define Xil_Ntohs Xil_EndianSwap16
|
||||
# define Xil_Ntohl Xil_EndianSwap32
|
||||
# define Xil_In16LE Xil_In16 /**< Register Read of 16 Bits in Little Endian */
|
||||
# define Xil_In32LE Xil_In32 /**< Register Read of 32 Bits in Little Endian */
|
||||
# define Xil_Out16LE Xil_Out16 /**< Register Write of 16 Bits in Little Endian */
|
||||
# define Xil_Out32LE Xil_Out32 /**< Register Write of 32 Bits in Little Endian */
|
||||
# define Xil_Htons Xil_EndianSwap16 /**< Endian swap of 16 bits */
|
||||
# define Xil_Htonl Xil_EndianSwap32 /**< Endian swap of 32 bits */
|
||||
# define Xil_Ntohs Xil_EndianSwap16 /**< Endian swap of 16 bits */
|
||||
# define Xil_Ntohl Xil_EndianSwap32 /**< Endian swap of 32 bits */
|
||||
# else
|
||||
# define Xil_In16BE Xil_In16
|
||||
# define Xil_In32BE Xil_In32
|
||||
# define Xil_Out16BE Xil_Out16
|
||||
# define Xil_Out32BE Xil_Out32
|
||||
# define Xil_Htons(Data) (Data)
|
||||
# define Xil_Htonl(Data) (Data)
|
||||
# define Xil_Ntohs(Data) (Data)
|
||||
# define Xil_Ntohl(Data) (Data)
|
||||
# define Xil_In16BE Xil_In16 /**< Register Read of 16 Bits in Big Endian */
|
||||
# define Xil_In32BE Xil_In32 /**< Register Read of 32 Bits in Big Endian */
|
||||
# define Xil_Out16BE Xil_Out16 /**< Register Write of 16 Bits in Big Endian */
|
||||
# define Xil_Out32BE Xil_Out32 /**< Register Write of 32 Bits in Big Endian */
|
||||
# define Xil_Htons(Data) (Data) /**< Endian swap of 16 bits */
|
||||
# define Xil_Htonl(Data) (Data) /**< Endian swap of 32 bits */
|
||||
# define Xil_Ntohs(Data) (Data) /**< Endian swap of 16 bits */
|
||||
# define Xil_Ntohl(Data) (Data) /**< Endian swap of 32 bits */
|
||||
#endif
|
||||
#else
|
||||
# define Xil_In16LE Xil_In16
|
||||
# define Xil_In32LE Xil_In32
|
||||
# define Xil_Out16LE Xil_Out16
|
||||
# define Xil_Out32LE Xil_Out32
|
||||
# define Xil_Htons Xil_EndianSwap16
|
||||
# define Xil_Htonl Xil_EndianSwap32
|
||||
# define Xil_Ntohs Xil_EndianSwap16
|
||||
# define Xil_Ntohl Xil_EndianSwap32
|
||||
# define Xil_In16LE Xil_In16 /**< Register Read of 16 Bits in Little Endian */
|
||||
# define Xil_In32LE Xil_In32 /**< Register Read of 32 Bits in Little Endian */
|
||||
# define Xil_Out16LE Xil_Out16 /**< Register Write of 16 Bits in Little Endian */
|
||||
# define Xil_Out32LE Xil_Out32 /**< Register Write of 32 Bits in Little Endian */
|
||||
# define Xil_Htons Xil_EndianSwap16 /**< Endian swap of 16 bits */
|
||||
# define Xil_Htonl Xil_EndianSwap32 /**< Endian swap of 32 bits */
|
||||
# define Xil_Ntohs Xil_EndianSwap16 /**< Endian swap of 16 bits */
|
||||
# define Xil_Ntohl Xil_EndianSwap32 /**< Endian swap of 32 bits */
|
||||
#endif
|
||||
|
||||
#if defined (__MICROBLAZE__)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
static INLINE u16 Xil_In16BE(UINTPTR Addr)
|
||||
static INLINE u16 Xil_In16BE(UINTPTR Addr) /**< Static inline function to Read
|
||||
Register of 16 Bits in Big Endian */
|
||||
#else
|
||||
static INLINE u16 Xil_In16LE(UINTPTR Addr)
|
||||
static INLINE u16 Xil_In16LE(UINTPTR Addr) /**< Static inline function to Read
|
||||
Register of 16 Bits in Little Endian */
|
||||
#endif
|
||||
#else
|
||||
/**
|
||||
* Static inline function to Read Register of 16 Bits in Big Endian.
|
||||
**********************************************************************************/
|
||||
static INLINE u16 Xil_In16BE(UINTPTR Addr)
|
||||
#endif
|
||||
{
|
||||
@@ -362,11 +368,16 @@ static INLINE u16 Xil_In16BE(UINTPTR Addr)
|
||||
|
||||
#if defined (__MICROBLAZE__)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
static INLINE u32 Xil_In32BE(UINTPTR Addr)
|
||||
static INLINE u32 Xil_In32BE(UINTPTR Addr) /**< Static inline function to Read
|
||||
Register of 32 Bits in Big Endian */
|
||||
#else
|
||||
static INLINE u32 Xil_In32LE(UINTPTR Addr)
|
||||
static INLINE u32 Xil_In32LE(UINTPTR Addr) /**< Static inline function to Read
|
||||
Register of 32 Bits in Little Endian */
|
||||
#endif
|
||||
#else
|
||||
/**
|
||||
* Static inline function to Read Register of 32 Bits in Big Endian.
|
||||
**********************************************************************************/
|
||||
static INLINE u32 Xil_In32BE(UINTPTR Addr)
|
||||
#endif
|
||||
{
|
||||
@@ -376,11 +387,16 @@ static INLINE u32 Xil_In32BE(UINTPTR Addr)
|
||||
|
||||
#if defined (__MICROBLAZE__)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value)
|
||||
static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value) /**< Static inline function to write
|
||||
Register of 16 Bits in Big Endian */
|
||||
#else
|
||||
static INLINE void Xil_Out16LE(UINTPTR Addr, u16 Value)
|
||||
static INLINE void Xil_Out16LE(UINTPTR Addr, u16 Value) /**< Static inline function to write
|
||||
Register of 16 Bits in Little Endian */
|
||||
#endif
|
||||
#else
|
||||
/**
|
||||
* Static inline function to write Register of 16 Bits in Big Endian.
|
||||
**********************************************************************************/
|
||||
static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value)
|
||||
#endif
|
||||
{
|
||||
@@ -390,11 +406,16 @@ static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value)
|
||||
|
||||
#if defined (__MICROBLAZE__)
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value)
|
||||
static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value) /**< Static inline function to write
|
||||
Register of 32 Bits in Big Endian */
|
||||
#else
|
||||
static INLINE void Xil_Out32LE(UINTPTR Addr, u32 Value)
|
||||
static INLINE void Xil_Out32LE(UINTPTR Addr, u32 Value) /**< Static inline function to write
|
||||
Register of 32 Bits in Little Endian */
|
||||
#endif
|
||||
#else
|
||||
/**
|
||||
* Static inline function to Read Register of 16 Bits in Big Endian.
|
||||
**********************************************************************************/
|
||||
static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value)
|
||||
#endif
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user