Compare commits

...

32 Commits

Author SHA1 Message Date
b8d828c438 cc: make it work with modern lark 2025-09-12 12:35:06 +02:00
467ef32107 mbv: add make precommit 2025-09-04 15:04:56 +02:00
9edebe637b mbv: move a few things around 2025-09-04 15:01:50 +02:00
dd51b5d610 mbv: async debugging in progres... 2025-07-21 10:07:21 +02:00
f0f26af791 mbv: i really though async would work this time
There's still a glitch/race somewhere.
2025-06-29 13:56:58 -07:00
724f8db1b1 mbv: fix async uart2 app. it works! 2025-06-28 18:21:11 -07:00
269a04d5f5 mbv: fix bug in xuartlite 2025-06-27 13:01:20 -07:00
2e640690ba mbv: global constructors ish 2025-06-27 13:01:06 -07:00
e7b38fb560 mbv: debugging the async app 2025-06-27 13:00:29 -07:00
e4936abb53 mbv: black 2025-06-25 08:39:33 -07:00
7f1f924331 mbv: clang-format 2025-06-25 08:38:46 -07:00
0c7206f186 mbv: add .clang-format 2025-06-24 23:04:30 -07:00
849cf7b7a1 mbv: add async app, sorta works 2025-06-24 23:04:13 -07:00
afba9e168f mbv: link with newlib nano 2025-06-24 23:03:40 -07:00
2e0507d0bb mbv: bigger prog chunks 2025-06-24 23:02:57 -07:00
d18d41fc02 mbv: small refactor interrupts 2025-06-24 23:02:38 -07:00
6553fa04aa mbv: moar cleanup in linker script 2025-06-23 22:23:58 -07:00
4ca569519e mbv: remove exidx sections in linker scripts 2025-06-23 22:20:36 -07:00
e23cf79aa0 mbv: now with out of source builds 2025-06-23 22:06:27 -07:00
af768cbb09 mbv: minor cleanup 2025-06-23 15:21:15 -07:00
73edb77577 mbv: add uart echo app 2025-06-23 08:23:59 -07:00
d91ddeea22 timer: add missing declaration
should probably put that in a bios.h file at some point
2025-06-22 07:11:33 -07:00
252467c1be mbv: fix bss init 2025-06-22 07:11:12 -07:00
d15e930649 mbv: some debug stuff 2025-06-10 23:48:29 -07:00
3db383d461 mbv: now with functioning timer interrupts!
And a few other nice things.
The bootloader now has an embedded wozmon!
If you know its offset, you can jump to it from the app.
2025-06-10 23:46:43 -07:00
fa6ae7b667 mbv: now with DDR! and a wozmon
We have access to 256 MiB of fresh DDR3.
Isn't that great?

prog.py is a bit opinionated for now:
- tty is /dev/ttyUSB1
- writing programs to DDR
2025-06-08 23:11:04 -07:00
a5c14f089b mbv: use new ninja-based build 2025-03-30 17:42:20 -07:00
922f258884 mbv: clean up build 2025-03-13 18:12:12 -07:00
0903c2b60a Add Microblaze V based board 2025-03-13 17:10:43 -07:00
a05d78afc0 arm: minor tweaks 2025-03-13 17:07:31 -07:00
ca2ba3ddda loader: add script to de-register ftdi_sio 2025-03-12 13:43:56 -07:00
e955ad7b91 loader: update to remote 9a16c25 2025-03-12 13:21:56 -07:00
112 changed files with 15038 additions and 570 deletions

1
alchitry-loader/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
alchitry_loader

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.0)
project(alchitry_loader)
set(CMAKE_CXX_STANDARD 14)
include_directories(src)
add_executable(alchitry_loader
src/Alchitry_Loader.cpp
src/config_type.cpp
src/config_type.h
src/ftd2xx.h
src/jtag.cpp
src/jtag.h
src/jtag_fsm.cpp
src/jtag_fsm.h
src/loader.cpp
src/loader.h
src/mingw.thread.h
src/spi.cpp
src/spi.h
src/WinTypes.h)
target_link_libraries(alchitry_loader
${CMAKE_SOURCE_DIR}/lib/linux/libftd2xx.a
${CMAKE_SOURCE_DIR}/lib/windows/ftd2xx.lib
pthread)

View File

@@ -1,16 +1,18 @@
FROM debian:bookworm AS deps
RUN apt-get update -qq && apt-get install -qq -y --no-install-recommends build-essential
RUN apt-get update -qq && apt-get install -qq -y --no-install-recommends build-essential cmake
FROM deps AS build
ADD . /workspace
ADD src /workspace/src
ADD lib /workspace/lib
ADD CMakeLists.txt /workspace/
WORKDIR /workspace
RUN make loader
RUN mkdir build && cd build && cmake .. && make
FROM scratch AS export
COPY --from=build /workspace/loader /
COPY --from=build /workspace/build/alchitry_loader /

View File

@@ -1,26 +1,16 @@
sources = $(wildcard src/*.cpp)
objects = $(sources:.cpp=.o)
os = $(shell uname -s)
static_libs = lib/$(os)/libftd2xx.a
libs = -lpthread
CXXFLAGS = -std=c++11
export DOCKER_BUILDKIT=1
# Assume target is Mac OS if build host is Mac OS; any other host targets Linux
ifeq ($(os), Darwin)
libs += -lobjc -framework IOKit -framework CoreFoundation
else
libs += -lrt
endif
loader: $(objects) ## build the loader executable
$(CXX) $(LDFLAGS) -o $@ $^ $(static_libs) $(libs)
build: ## build the loader in docker (linux)
.PHONY: loader
loader: ## build the loader in docker (linux)
docker build -o . .
.PHONY: ftdi-unbind
ftdi-unbind: ## unbind the ftdi-sio devices on linux (uses sudo)
sh -c "cd /sys/bus/usb/drivers/ftdi_sio && \
for dev in *:*; do \
echo \$$dev | sudo tee unbind ; \
done"
.PHONY: clean
clean:
rm -rf loader $(objects)

74
alchitry-loader/README.md Normal file
View File

@@ -0,0 +1,74 @@
# Alchitry Loader (based on D2XX)
This project was originally used as a tool by Alchitry Labs to program the Alchitry boards using the
official D2XX library from FTDI. You can find D2XX here https://ftdichip.com/drivers/d2xx-drivers/
It has been updated to include the Alchitry Au+ and can be used as a stand-alone command line tool for
loading the Alchitry boards without using Alchitry Labs.
Alchitry Labs no longer relies on this loader and instead has a fully Java loader built in.
## Building
Clone the repository
`git clone https://github.com/alchitry/alchitry-loader.git`
Enter the project files
`cd alchitry-loader`
Create the Makefile
`cmake CMakeLists.txt`
Build the project
`make`
Test it out
`./alchitry_loader`
## Linux and macOS and libftd2xx
On Linux (and macOS?) the default kernel drivers prevent libftd2xx from working properly.
On Linux, you can use this to de-register all ftdi-sio devices (until plugged again):
```
make ftdi-unbind
```
## Usage
```
Usage: "loader arguments"
Arguments:
-e : erase FPGA flash
-l : list detected boards
-h : print this help message
-f config.bin : write FPGA flash
-r config.bin : write FPGA RAM
-u config.data : write FTDI eeprom
-b n : select board "n" (defaults to 0)
-p loader.bin : Au bridge bin
-t TYPE : TYPE can be au, au+, or cu (defaults to au)
```
### Examples
Load a .bin onto an Au's RAM (lost on power cycle)
`./alchitry_loader -t au -r au_config.bin`
Load a .bin onto an Au+'s flash (persistent config)
`./alchitry_loader -t "au+" -f au_config.bin -p ./bridge/au_plus_loader.bin`
Note that to load to the Au or Au+ flash memory you need to specify a bridge bin file. These can be found
in the bridge folder of this repo. This file is loaded onto the Au and allows this loader to program the
flash memory. It acts as a bridge from the JTAG port to the SPI of the flash memory.
The source for the bridge files can be found here https://github.com/alchitry/au-bridge
This isn't needed for the Cu which has direct access to the flash over the SPI protocol.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

0
alchitry-loader/src/WinTypes.h Normal file → Executable file
View File

View File

@@ -1,6 +1,6 @@
/*++
Copyright <20> 2001-2011 Future Technology Devices International Limited
Copyright <20> 2001-2021 Future Technology Devices International Limited
THIS SOFTWARE IS PROVIDED BY FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -27,7 +27,7 @@ ftd2xx.h
Abstract:
Native USB device driver for FTDI FT232x, FT245x, FT2232x and FT4232x devices
Native USB device driver for FTDI FT232x, FT245x, FT2232x, FT4232x, FT2233H and FT4233H devices
FTD2XX library definitions
Environment:
@@ -191,7 +191,7 @@ enum {
// Events
//
typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD);
typedef void(*PFT_EVENT_HANDLER)(DWORD, DWORD);
#define FT_EVENT_RXCHAR 1
#define FT_EVENT_MODEM_STATUS 2
@@ -224,7 +224,19 @@ enum {
FT_DEVICE_4222H_0,
FT_DEVICE_4222H_1_2,
FT_DEVICE_4222H_3,
FT_DEVICE_4222_PROG,
FT_DEVICE_4222_PROG,
FT_DEVICE_900,
FT_DEVICE_930,
FT_DEVICE_UMFTPD3A,
FT_DEVICE_2233HP,
FT_DEVICE_4233HP,
FT_DEVICE_2232HP,
FT_DEVICE_4232HP,
FT_DEVICE_233HP,
FT_DEVICE_232HP,
FT_DEVICE_2232HA,
FT_DEVICE_4232HA,
FT_DEVICE_232RN,
};
//
@@ -316,15 +328,15 @@ extern "C" {
#ifdef FTD2XX_STATIC
FTD2XX_API
FT_STATUS WINAPI FT_Initialise(
void
);
FTD2XX_API
FT_STATUS WINAPI FT_Initialise(
void
);
FTD2XX_API
void WINAPI FT_Finalise(
void
);
FTD2XX_API
void WINAPI FT_Finalise(
void
);
#endif // FTD2XX_STATIC
FTD2XX_API
@@ -784,8 +796,8 @@ extern "C" {
UCHAR BIsFifoTar; // non-zero if interface is 245 FIFO CPU target
UCHAR BIsFastSer; // non-zero if interface is Fast serial
// Driver option
UCHAR ADriverType; //
UCHAR BDriverType; //
UCHAR ADriverType; // non-zero if interface is to use VCP drivers
UCHAR BDriverType; // non-zero if interface is to use VCP drivers
} FT_EEPROM_2232, *PFT_EEPROM_2232;
@@ -811,7 +823,7 @@ extern "C" {
UCHAR Cbus3; // Cbus Mux control
UCHAR Cbus4; // Cbus Mux control
// Driver option
UCHAR DriverType; //
UCHAR DriverType; // non-zero if using D2XX driver
} FT_EEPROM_232R, *PFT_EEPROM_232R;
@@ -841,8 +853,8 @@ extern "C" {
UCHAR BIsFastSer; // non-zero if interface is Fast serial
UCHAR PowerSaveEnable; // non-zero if using BCBUS7 to save power for self-powered designs
// Driver option
UCHAR ADriverType; //
UCHAR BDriverType; //
UCHAR ADriverType; // non-zero if interface is to use VCP drivers
UCHAR BDriverType; // non-zero if interface is to use VCP drivers
} FT_EEPROM_2232H, *PFT_EEPROM_2232H;
@@ -869,10 +881,10 @@ extern "C" {
UCHAR CRIIsTXDEN; // non-zero if port C uses RI as RS485 TXDEN
UCHAR DRIIsTXDEN; // non-zero if port D uses RI as RS485 TXDEN
// Driver option
UCHAR ADriverType; //
UCHAR BDriverType; //
UCHAR CDriverType; //
UCHAR DDriverType; //
UCHAR ADriverType; // non-zero if interface is to use VCP drivers
UCHAR BDriverType; // non-zero if interface is to use VCP drivers
UCHAR CDriverType; // non-zero if interface is to use VCP drivers
UCHAR DDriverType; // non-zero if interface is to use VCP drivers
} FT_EEPROM_4232H, *PFT_EEPROM_4232H;
@@ -906,10 +918,10 @@ extern "C" {
UCHAR IsFifo; // non-zero if interface is 245 FIFO
UCHAR IsFifoTar; // non-zero if interface is 245 FIFO CPU target
UCHAR IsFastSer; // non-zero if interface is Fast serial
UCHAR IsFT1248 ; // non-zero if interface is FT1248
UCHAR IsFT1248; // non-zero if interface is FT1248
UCHAR PowerSaveEnable; //
// Driver option
UCHAR DriverType; //
UCHAR DriverType; // non-zero if interface is to use VCP drivers
} FT_EEPROM_232H, *PFT_EEPROM_232H;
@@ -957,10 +969,223 @@ extern "C" {
UCHAR RS485EchoSuppress; //
UCHAR PowerSaveEnable; //
// Driver option
UCHAR DriverType; //
UCHAR DriverType; // non-zero if interface is to use VCP drivers
} FT_EEPROM_X_SERIES, *PFT_EEPROM_X_SERIES;
// FT4222H EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program
typedef struct ft_eeprom_4222h {
// Common header
FT_EEPROM_HEADER common; // common elements for all device EEPROMs
CHAR Revision; // 'A', 'B', 'C', or 'D'.
UCHAR I2C_Slave_Address;
// Suspend
UCHAR SPISuspend; // 0 for "Disable SPI, tristate pins", 2 for "Keep SPI pin status", 3 for "Enable SPI pin control"
UCHAR SuspendOutPol; // 0 for negative, 1 for positive (not implemented on Rev A)
UCHAR EnableSuspendOut; // non-zero to enable (not implemented on Rev A)
// QSPI
UCHAR Clock_SlowSlew; // non-zero if clock pin has slow slew
UCHAR Clock_Drive; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR IO0_SlowSlew; // non-zero if IO0 pin has slow slew
UCHAR IO1_SlowSlew; // non-zero if IO1 pin has slow slew
UCHAR IO2_SlowSlew; // non-zero if IO2 pin has slow slew
UCHAR IO3_SlowSlew; // non-zero if IO3 pin has slow slew
UCHAR IO_Drive; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR SlaveSelect_PullUp; // non-zero to enable pull up
UCHAR SlaveSelect_PullDown; // non-zero to enable pull down
UCHAR SlaveSelect_Drive; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR SlaveSelect_SlowSlew; // non-zero if slave select pin has slow slew
UCHAR MISO_Suspend; // 2 for push-low, 3 for push high, 0 and 1 reserved
UCHAR SIMO_Suspend; // 2 for push-low, 3 for push high, 0 and 1 reserved
UCHAR IO2_IO3_Suspend; // 2 for push-low, 3 for push high, 0 and 1 reserved
UCHAR SlaveSelect_Suspend; // 0 for no-change (not implemented on Rev A), 2 for push-low, 3 for push high, 1 reserved
// GPIO
UCHAR GPIO0_Drive; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR GPIO1_Drive; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR GPIO2_Drive; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR GPIO3_Drive; // valid values are 4mA, 8mA, 12mA, 16mA
UCHAR GPIO0_SlowSlew; // non-zero if IO0 pin has slow slew
UCHAR GPIO1_SlowSlew; // non-zero if IO0 pin has slow slew
UCHAR GPIO2_SlowSlew; // non-zero if IO0 pin has slow slew
UCHAR GPIO3_SlowSlew; // non-zero if IO0 pin has slow slew
UCHAR GPIO0_PullDown; // non-zero to enable pull down
UCHAR GPIO1_PullDown; // non-zero to enable pull down
UCHAR GPIO2_PullDown; // non-zero to enable pull down
UCHAR GPIO3_PullDown; // non-zero to enable pull down
UCHAR GPIO0_PullUp; // non-zero to enable pull up
UCHAR GPIO1_PullUp; // non-zero to enable pull up
UCHAR GPIO2_PullUp; // non-zero to enable pull up
UCHAR GPIO3_PullUp; // non-zero to enable pull up
UCHAR GPIO0_OpenDrain; // non-zero to enable open drain
UCHAR GPIO1_OpenDrain; // non-zero to enable open drain
UCHAR GPIO2_OpenDrain; // non-zero to enable open drain
UCHAR GPIO3_OpenDrain; // non-zero to enable open drain
UCHAR GPIO0_Suspend; // 0 for no-change, 1 for input (not implemented on Rev A), 2 for push-low, 3 for push high
UCHAR GPIO1_Suspend; // 0 for no-change, 1 for input (not implemented on Rev A), 2 for push-low, 3 for push high
UCHAR GPIO2_Suspend; // 0 for no-change, 1 for input (not implemented on Rev A), 2 for push-low, 3 for push high
UCHAR GPIO3_Suspend; // 0 for no-change, 1 for input (not implemented on Rev A), 2 for push-low, 3 for push high
UCHAR FallingEdge; // non-zero to change GPIO on falling edge
// BCD
UCHAR BCD_Disable; // non-zero to disable BCD
UCHAR BCD_OutputActiveLow; // non-zero to set BCD output active low
UCHAR BCD_Drive; // valid values are 4mA, 8mA, 12mA, 16mA
} FT_EEPROM_4222H, *PFT_EEPROM_4222H;
// Power Delivery structures for use with FT_EEPROM_Read and FT_EEPROM_Program
// PDO Configuration structure, mA supported values 0 to 10230mA, mV supported values 0 to 51100mV
// This is part of the FT_EEPROM_PD structure.
typedef struct ft_eeprom_PD_PDO_mv_ma {
USHORT PDO1ma; // PDO1 mA
USHORT PDO1mv; // PDO1 mV
USHORT PDO2ma; // PDO2 mA
USHORT PDO2mv; // PDO2 mV
USHORT PDO3ma; // PDO3 mA
USHORT PDO3mv; // PDO3 mV
USHORT PDO4ma; // PDO4 mA
USHORT PDO4mv; // PDO4 mV
USHORT PDO5ma; // PDO5 mA (FTx233HP only)
USHORT PDO5mv; // PDO5 mV (FTx233HP only)
USHORT PDO6ma; // PDO6 mA (FTx233HP only)
USHORT PDO6mv; // PDO6 mV (FTx233HP only)
USHORT PDO7ma; // PDO7 mA (FTx233HP only)
USHORT PDO7mv; // PDO7 mV (FTx233HP only)
} FT_EEPROM_PD_PDO_mv_ma;
// PD EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program
// This is appended to the end of the base device structure. e_g.
// struct {
// FT_EEPROM_xxx base;
// FT_EEPROM_PD pd;
// };
// Device GPIO values are:
// FTx233HP - 0 to 7, 15 for N/A
// FTx232HP - 0 to 3, 15 for N/A
typedef struct ft_eeprom_pd {
// Configuration
UCHAR srprs; // non-zero to enable Sink Request Power Role Swap
UCHAR sraprs; // non-zero to enable Sink Accept PR Swap
UCHAR srrprs; // non-zero to enable Source Request PR SWAP
UCHAR saprs; // non-zero to enable Source Accept PR SWAP
UCHAR vconns; // non-zero to enable vConn Swap
UCHAR passthru; // non-zero to enable Pass Through (FTx233HP only)
UCHAR extmcu; // non-zero to enable External MCU
UCHAR pd2en; // non-zero to enable PD2 (FTx233HP only)
UCHAR pd1autoclk; // non-zero to enable PD1 Auto Clock
UCHAR pd2autoclk; // non-zero to enable PD2 Auto Clock (FTx233HP only)
UCHAR useefuse; // non-zero to Use EFUSE
UCHAR extvconn; // non-zero to enable External vConn
// GPIO Configuration
UCHAR count; // GPIO Count, supported values are 0 to 7
UCHAR gpio1; // GPIO Number 1, supports device GPIO values
UCHAR gpio2; // GPIO Number 2, supports device GPIO values
UCHAR gpio3; // GPIO Number 3, supports device GPIO values
UCHAR gpio4; // GPIO Number 4, supports device GPIO values
UCHAR gpio5; // GPIO Number 5, supports device GPIO values (FTx233HP only)
UCHAR gpio6; // GPIO Number 6, supports device GPIO values (FTx233HP only)
UCHAR gpio7; // GPIO Number 7, supports device GPIO values (FTx233HP only)
UCHAR pd1lden; // PD1 Load Enable, supports device GPIO values
UCHAR pd2lden; // PD2 Load Enable, supports device GPIO values (FTx233HP only)
UCHAR dispin; // Discharge Pin, supports device GPIO values
UCHAR disenbm; // Discharge Enable BM, 0 for "Drive Hi", 1 for "Drive Low", 2 for "Input Mode", 3 for "Don't Care"
UCHAR disdisbm; // Discharge Disable BM, 0 for "Drive Hi", 1 for "Drive Low", 2 for "Input Mode", 3 for "Don't Care"
UCHAR ccselect; // CC Select Indicator, supports device GPIO values
// ISET Configuration
UCHAR iset1; // ISET1, supports device GPIO values
UCHAR iset2; // ISET2, supports device GPIO values
UCHAR iset3; // ISET3, supports device GPIO values
UCHAR extiset; // non-zero to enable EXTEND_ISET
UCHAR isetpd2; // non-zero to enable ISET_PD2
UCHAR iseten; // non-zero to set ISET_ENABLED
// BM Configuration, 0 for "Drive Hi", 1 for "Drive Low", 2 for "Input Mode", 3 for "Don't Care"
UCHAR PDO1_GPIO[7]; // PDO1 GPIO1 to GPIO7
UCHAR PDO2_GPIO[7]; // PDO2 GPIO1 to GPIO7
UCHAR PDO3_GPIO[7]; // PDO3 GPIO1 to GPIO7
UCHAR PDO4_GPIO[7]; // PDO4 GPIO1 to GPIO7
UCHAR PDO5_GPIO[7]; // PDO5 GPIO1 to GPIO7 (FTx233HP only)
UCHAR PDO6_GPIO[7]; // PDO6 GPIO1 to GPIO7 (FTx233HP only)
UCHAR PDO7_GPIO[7]; // PDO7 GPIO1 to GPIO7 (FTx233HP only)
UCHAR VSET0V_GPIO[7]; // PDO7 GPIO1 to GPIO7
UCHAR VSAFE5V_GPIO[7]; // PDO7 GPIO1 to GPIO7
FT_EEPROM_PD_PDO_mv_ma BM_PDO_Sink;
FT_EEPROM_PD_PDO_mv_ma BM_PDO_Source;
FT_EEPROM_PD_PDO_mv_ma BM_PDO_Sink_2; // (FTx233HP only)
// PD Timers
UCHAR srt; // Sender Response Timer
UCHAR hrt; // Hard Reset Timer
UCHAR sct; // Source Capability Timer
UCHAR dit; // Discover Identity Timer
USHORT srcrt; // Source Recover Timer
USHORT trt; // Transition Timer
USHORT sofft; // Source off timer
USHORT nrt; // No Response Timer
USHORT swct; // Sink Wait Capability Timer
USHORT snkrt; // Sink Request Timer
UCHAR dt; // Discharge Timer
UCHAR cnst; // Chunk not supported timer
USHORT it; // Idle Timer
// PD Control
UCHAR i2caddr; // I2C Address (hex)
UINT prou; // Power Reserved for OWN use
UINT trim1; // TRIM1
UINT trim2; // TRIM2
UCHAR extdc; // non-zero to enable ETERNAL_DC_POWER
} FT_EEPROM_PD, *PFT_EEPROM_PD;
// FT2233HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program
// FT2232H with power delivery
typedef struct _ft_eeprom_2233hp
{
FT_EEPROM_2232H ft2232h;
FT_EEPROM_PD pd;
} FT_EEPROM_2233HP, *PFT_EEPROM_2233HP;
// FT4233HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program
// FT4232H with power delivery
typedef struct _ft_eeprom_4233hp
{
FT_EEPROM_4232H ft4232h;
FT_EEPROM_PD pd;
} FT_EEPROM_4233HP, *PFT_EEPROM_4233HP;
// FT2232HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program
// FT2232H with power delivery
typedef struct _ft_eeprom_2232hp
{
FT_EEPROM_2232H ft2232h;
FT_EEPROM_PD pd;
} FT_EEPROM_2232HP, *PFT_EEPROM_2232HP;
// FT4232HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program
// FT4232H with power delivery
typedef struct _ft_eeprom_4232hp
{
FT_EEPROM_4232H ft4232h;
FT_EEPROM_PD pd;
} FT_EEPROM_4232HP, *PFT_EEPROM_4232HP;
// FT233HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program
// FT233H with power delivery
typedef struct _ft_eeprom_233hp
{
FT_EEPROM_232H ft232h;
FT_EEPROM_PD pd;
} FT_EEPROM_233HP, *PFT_EEPROM_233HP;
// FT232HP EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program
// FT232H with power delivery
typedef struct _ft_eeprom_232hp
{
FT_EEPROM_232H ft232h;
FT_EEPROM_PD pd;
} FT_EEPROM_232HP, *PFT_EEPROM_232HP;
FTD2XX_API
FT_STATUS WINAPI FT_EEPROM_Read(
FT_HANDLE ftHandle,
@@ -1159,20 +1384,20 @@ extern "C" {
typedef struct _FTDCB {
DWORD DCBlength; /* sizeof(FTDCB) */
DWORD BaudRate; /* Baudrate at which running */
DWORD fBinary: 1; /* Binary Mode (skip EOF check) */
DWORD fParity: 1; /* Enable parity checking */
DWORD fOutxCtsFlow:1; /* CTS handshaking on output */
DWORD fOutxDsrFlow:1; /* DSR handshaking on output */
DWORD fDtrControl:2; /* DTR Flow control */
DWORD fDsrSensitivity:1; /* DSR Sensitivity */
DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
DWORD fOutX: 1; /* Enable output X-ON/X-OFF */
DWORD fInX: 1; /* Enable input X-ON/X-OFF */
DWORD fErrorChar: 1; /* Enable Err Replacement */
DWORD fNull: 1; /* Enable Null stripping */
DWORD fRtsControl:2; /* Rts Flow control */
DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
DWORD fDummy2:17; /* Reserved */
DWORD fBinary : 1; /* Binary Mode (skip EOF check) */
DWORD fParity : 1; /* Enable parity checking */
DWORD fOutxCtsFlow : 1; /* CTS handshaking on output */
DWORD fOutxDsrFlow : 1; /* DSR handshaking on output */
DWORD fDtrControl : 2; /* DTR Flow control */
DWORD fDsrSensitivity : 1; /* DSR Sensitivity */
DWORD fTXContinueOnXoff : 1; /* Continue TX when Xoff sent */
DWORD fOutX : 1; /* Enable output X-ON/X-OFF */
DWORD fInX : 1; /* Enable input X-ON/X-OFF */
DWORD fErrorChar : 1; /* Enable Err Replacement */
DWORD fNull : 1; /* Enable Null stripping */
DWORD fRtsControl : 2; /* Rts Flow control */
DWORD fAbortOnError : 1; /* Abort all reads and writes on Error */
DWORD fDummy2 : 17; /* Reserved */
WORD wReserved; /* Not currently used */
WORD XonLim; /* Transmit X-ON threshold */
WORD XoffLim; /* Transmit X-OFF threshold */
@@ -1193,7 +1418,7 @@ extern "C" {
DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */
DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */
DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */
} FTTIMEOUTS,*LPFTTIMEOUTS;
} FTTIMEOUTS, *LPFTTIMEOUTS;
FTD2XX_API
@@ -1440,4 +1665,3 @@ extern "C" {
#endif /* FTD2XX_H */

0
alchitry-loader/src/jtag.cpp Normal file → Executable file
View File

0
alchitry-loader/src/jtag.h Normal file → Executable file
View File

0
alchitry-loader/src/jtag_fsm.cpp Normal file → Executable file
View File

0
alchitry-loader/src/jtag_fsm.h Normal file → Executable file
View File

5
alchitry-loader/src/loader.cpp Normal file → Executable file
View File

@@ -134,6 +134,11 @@ string Loader::shiftDR(int bits, string write) {
bool Loader::loadBin(string file) {
string binStr = fileToBinStr(file);
if (binStr.empty()) {
cerr << "Failed to read bin file: "+ file << endl;
return false;
}
string reversedBinStr = reverseBytes(binStr);
if (!device->setFreq(10000000)) {

0
alchitry-loader/src/loader.h Normal file → Executable file
View File

View File

@@ -9,9 +9,9 @@
#define SPI_H_
#include "ftd2xx.h"
#include <cstdint>
#include <unistd.h>
#include <string>
#include <stdint.h>
using namespace std;

View File

@@ -28,10 +28,8 @@ def write(s, offset, dat):
def jump(s, offset):
addr = struct.pack('<I', offset)
s.write(b'j')
s.write(addr)
cmd = struct.pack('<cI', b'j', offset)
s.write(cmd)
def main():

9
mbv/.clang-format Normal file
View File

@@ -0,0 +1,9 @@
---
# We'll use defaults from the LLVM style, but with 4 columns indentation.
BasedOnStyle: Google
IndentWidth: 4
---
Language: Cpp
# Force pointers to the type for C++.
DerivePointerAlignment: false
PointerAlignment: Left

29
mbv/Dockerfile Normal file
View File

@@ -0,0 +1,29 @@
ARG TARGET
FROM debian:bookworm AS deps
# possible values: x64, arm64
ARG ARCH=x64
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -y make clang libgmock-dev gdb curl ninja-build && \
apt-get clean && rm -rf /var/lib/apt/lists
RUN cd /opt && curl -L https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-3/xpack-riscv-none-elf-gcc-14.2.0-3-linux-${ARCH}.tar.gz | tar -xz
FROM deps AS dev
FROM deps AS build
ARG TARGET=${TARGET}
ADD . /workspace
WORKDIR /workspace
RUN ./configure --version=${VERSION} && ninja -C build ../out/${TARGET}
FROM scratch AS export
ARG TARGET=${TARGET}
COPY --from=build /workspace/out/${TARGET} /

45
mbv/Makefile Normal file
View File

@@ -0,0 +1,45 @@
.PHONY: bootloader
bootloader: ## Build the bootloader in docker
docker build -o . --target export --build-arg TARGET=bootloader.elf .
.PHONY: helloworld
helloworld: ## Build the helloworld app in docker
docker build -o . --target export --build-arg TARGET=helloworld.bin .
.PHONY: timer
timer: ## Build the timer app in docker
docker build -o . --target export --build-arg TARGET=timer.bin .
.PHONY: uart
uart: ## Build the uart app in docker
docker build -o . --target export --build-arg TARGET=uart.bin .
.PHONY: async
async: ## Build the async app in docker
docker build -o . --target export --build-arg TARGET=async.bin .
.PHONY: dev-image
dev-image:
docker build -t mbv-dev --target dev .
.PHONY: dev
dev: dev-image ## Run a dev container
docker run -it --rm -v $(CURDIR):/workspace -w /workspace mbv-dev
.PHONY: precommit
precommit: ## Make sure everything looks ok before pushing
$(MAKE) bootloader
$(MAKE) helloworld
$(MAKE) timer
$(MAKE) uart
$(MAKE) async
.PHONY: clean
clean: ## Remove generated files
rm -rf *.elf *.bin
.PHONY: help
help: ## Show this help
@echo Noteworthy targets:
@egrep '^[a-zA-Z_-]+:.*?## .*$$' $(firstword $(MAKEFILE_LIST)) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
.DEFAULT_GOAL := help

0
mbv/README.md Normal file
View File

49
mbv/apps/app.ld Normal file
View File

@@ -0,0 +1,49 @@
MEMORY
{
RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x10000000
}
BiosUartRead = 0x0d4;
BiosUartWrite = 0x22c;
BiosWozmon = 0x340;
BiosUartWriteNibble = 0x324;
SECTIONS
{
.text :
{
_text_begin = .;
KEEP(*(.start))
*(.text*)
_text_end = .;
*(.rodata*)
} > RAM
.init :
{
__init_array_start = .;
KEEP(*(.init_array*))
__init_array_end = .;
}
.bss (NOLOAD) :
{
_bss_begin = .;
*(.bss*)
*(.sbss*)
*(COMMON)
_bss_end = .;
} > RAM
.data :
{
*(.data*)
} > RAM
_heap_begin = .;
_initial_stack_pointer = 0x90000000;
_heap_end = 0x8f000000; /* leave 1M for the stack */
}

175
mbv/apps/async/main.cc Normal file
View File

@@ -0,0 +1,175 @@
#include "hal/gpio.h"
#include "hal/intc.h"
#include "hal/interrupts.h"
#include "hal/pol0.h"
#include "hal/timer.h"
#include "lib/async.h"
#include "lib/buffer.h"
#include "uart.h"
#include "uart_async.h"
namespace {
constexpr uint32_t kTicksPerSecond = 100'000'000;
constexpr uint32_t kTicksPerMicrosecond = 100;
constexpr uint32_t kOverflowSeconds = (1ULL << 32) / kTicksPerSecond;
constexpr uint32_t kOverflowMicroseconds =
((1ULL << 32) % kTicksPerSecond) / kTicksPerMicrosecond;
Timer* timer0;
volatile uint32_t t1overflowsecs = 0;
volatile uint32_t t1overflowusecs = 0;
Gpio* gpio0;
void ToggleLed(int which) {
uint8_t data = gpio0->data;
data ^= (0x1 << which);
gpio0->data = data;
}
void SetLed(int which) {
uint8_t data = gpio0->data;
data |= (0x1 << which);
gpio0->data = data;
}
void ClearLed(int which) {
uint8_t data = gpio0->data;
data &= ~(0x1 << which);
gpio0->data = data;
}
void Uart0Isr() { HandleUartIsr(); }
void Timer0Isr() {
if (timer0->HasT1Overflowed()) {
UartWriteCrash("t1 overflow\r\n");
t1overflowsecs += kOverflowSeconds;
t1overflowusecs += kOverflowMicroseconds;
timer0->ClearT1Overflow();
return;
}
SetLed(6);
UartWriteCrash("blarg\r\n");
__builtin_trap();
}
void SetupUart() {
InitUarts();
intc::SetIsr(UART0_IRQN, Uart0Isr);
intc::SetIrqEnabled(UART0_IRQN, true);
}
void SetupTimer() {
timer0 = Timer::Instance(TIMER0_BASE);
timer0->SetupAsWdt(100'000 * 1000);
timer0->EnableT1();
intc::SetIsr(TIMER0_IRQN, Timer0Isr);
intc::SetIrqEnabled(TIMER0_IRQN, true);
}
void SetupInterrupts() {
intc::EnableInterrupts();
SetExternalInterruptHandler(intc::InterruptHandler);
EnableExternalInterrupts();
EnableInterrupts(true);
}
async::task<> echo() {
async::task<std::byte> reader = UartReadLoop();
async::gimme<std::span<const std::byte>> feeder;
async::task<> writer = UartWriteLoop(feeder);
writer.h.resume(); // advance to first yield
while (1) {
SetLed(1);
std::byte c = co_await reader;
ClearLed(1);
co_await feeder.feed(std::span{&c, 1});
}
}
async::task<> blink() {
while (1) {
co_await async::delay(500);
ToggleLed(0);
timer0->Pet();
co_await UartWrite(".");
}
}
} // namespace
int main() {
gpio0 = Gpio::Instance(GPIO0_BASE);
gpio0->data = 0;
SetupUart();
UartWriteBlocking("uart setup done\r\n");
SetupTimer();
UartWriteBlocking("timer setup done\r\n");
SetupInterrupts();
auto e = echo();
auto b = blink();
async::schedule(e.h);
async::schedule(b.h);
UartWriteBlocking("init done. starting main loop\r\n");
async::main_loop([]() {
return false;
});
// should never get here
}
/// stdlib stuff
#include <sys/time.h>
#include <cstdint>
#include "lib/lock.h"
extern unsigned char _heap_begin, _heap_end;
extern "C" void* _sbrk(int increment) {
static unsigned char* heap = &_heap_begin;
unsigned char* prev_heap = heap;
if (heap + increment >= &_heap_end) {
UartWriteCrash("Heap overflow!\r\n");
return reinterpret_cast<void*>(-1);
}
heap += increment;
return prev_heap;
}
extern "C" int _gettimeofday(struct timeval* tv, void* tzvp) {
(void)tzvp;
uint32_t ticks = timer0->GetT1Ticks();
tv->tv_sec = ticks / kTicksPerSecond + t1overflowsecs;
tv->tv_usec =
(ticks % kTicksPerSecond) / kTicksPerMicrosecond + t1overflowusecs;
return 0;
}
extern "C" uint8_t __atomic_exchange_1(volatile void* ptr, uint8_t val,
int memorder) {
(void)memorder;
auto* dest = reinterpret_cast<volatile uint8_t*>(ptr);
bool ret;
{
InterruptLock lock;
ret = *dest;
*dest = val;
}
return ret;
}

166
mbv/apps/async/uart.cc Normal file
View File

@@ -0,0 +1,166 @@
#include "uart.h"
#include "hal/gpio.h"
#include "hal/pol0.h"
#include "lib/async.h"
#include "lib/lock.h"
#include "lib/ring_buffer.h"
#include "xuartlite.h"
#include "uart_async.h"
namespace {
using async::AwaitableType;
constexpr uintptr_t kUart0BaseAddress = UART0_BASE;
XUartLite uart0_inst;
XUartLite_Config uart0_config = {
.DeviceId = 0,
.RegBaseAddr = kUart0BaseAddress,
.BaudRate = 115200,
.UseParity = false,
.DataBits = 8,
};
constexpr size_t kUartRxBufferSize = 256;
std::array<std::byte, kUartRxBufferSize> rx_buffer = {};
RingBuffer rx_ring_buffer{.buffer = rx_buffer};
constexpr size_t kUartTxBufferSize = 256;
std::array<std::byte, kUartTxBufferSize> tx_buffer = {};
RingBuffer tx_ring_buffer{.buffer = tx_buffer};
XUartLite* uart0 = &uart0_inst;
volatile bool sending;
void StartReceiving() {
while (1) {
if (rx_ring_buffer.FreeSpace() < 1) {
// woops, full. discard some data
// TODO: keep track of overrun stats
rx_ring_buffer.Pop(1);
}
if (XUartLite_Recv(uart0, rx_ring_buffer.RawWritePointer(), 1) < 1) {
break;
}
rx_ring_buffer.Push(1);
}
}
void StartSending() {
if (sending) {
return;
}
size_t tosend = tx_ring_buffer.ContiguousAvailableData();
if (tosend < 1) {
return;
}
sending = true;
XUartLite_Send(uart0, tx_ring_buffer.RawReadPointer(), tosend);
}
} // namespace
void InitUarts() {
XUartLite_CfgInitialize(uart0, &uart0_config, uart0_config.RegBaseAddr);
XUartLite_SetSendHandler(uart0, HandleUartTxFromIsr, nullptr);
XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr);
StartReceiving();
XUartLite_EnableInterrupt(uart0);
sending = false;
}
void UartWriteCrash(std::span<const std::byte> data) {
XUartLite_DisableInterrupt(uart0);
while (data.size() > 0) {
while (XUartLite_IsSending(uart0)) {
}
auto* dat =
reinterpret_cast<uint8_t*>(const_cast<std::byte*>(data.data()));
uint8_t sent = XUartLite_Send(uart0, dat, data.size());
data = data.subspan(sent);
}
while (XUartLite_IsSending(uart0)) {
}
XUartLite_Send(uart0, nullptr,
0); // reset buffer before enabling interrupts
XUartLite_EnableInterrupt(uart0);
}
async::task<> UartWrite(std::span<const std::byte> data) {
while (!tx_ring_buffer.Store(data)) {
co_await async::await(AwaitableType::kUartTx);
}
{
InterruptLock lock;
StartSending();
}
}
async::task<> UartWriteLoop(
async::gimme<std::span<const std::byte>>& data_gen) {
while (1) {
auto data = co_await data_gen;
while (!tx_ring_buffer.Store(data)) {
co_await async::await(AwaitableType::kUartTx);
}
{
InterruptLock lock;
StartSending();
}
}
}
// TODO: use chunks to allow receiving more than 256 bytes at once
void UartReadBlocking(std::span<std::byte> data) {
while (!rx_ring_buffer.Load(data)) {
}
}
void UartWriteBlocking(std::span<const std::byte> data) {
while (!tx_ring_buffer.Store(data)) {
}
{
InterruptLock lock;
StartSending();
}
}
async::task<std::byte> UartReadLoop() {
std::byte c;
while (1) {
while (!rx_ring_buffer.Load(std::span{&c, 1})) {
co_await async::await(AwaitableType::kUartRx);
}
co_yield c;
}
}
async::task<buffer> UartRead(int size) {
auto buff = buffer::make(size);
while (!rx_ring_buffer.Load(buff.data)) {
co_await async::await(AwaitableType::kUartRx);
}
co_return buff;
}
void HandleUartTxFromIsr(void*, unsigned int transmitted) {
sending = false;
tx_ring_buffer.Pop(transmitted);
StartSending();
async::resume(AwaitableType::kUartTx);
}
void HandleUartRxFromIsr(void*, unsigned int transmitted) {
rx_ring_buffer.Push(transmitted);
StartReceiving();
async::resume(AwaitableType::kUartRx);
}
void HandleUartIsr() { XUartLite_InterruptHandler(uart0); }

35
mbv/apps/async/uart.h Normal file
View File

@@ -0,0 +1,35 @@
#pragma once
#include <cstdint>
#include <span>
#include <string_view>
void InitUarts();
// block until the provided buffer is full
void UartReadBlocking(std::span<std::byte> data);
inline uint8_t UartReadByteBlocking() {
std::byte byte;
UartReadBlocking(std::span{&byte, 1});
return static_cast<uint8_t>(byte);
}
// send and poll the uart until transmitted
void UartWriteCrash(std::span<const std::byte> data);
inline void UartWriteCrash(std::string_view s) {
return UartWriteCrash(std::as_bytes(std::span{s.data(), s.size()}));
}
// block until room is available in tx fifo, then send
void UartWriteBlocking(std::span<const std::byte> data);
inline void UartWriteBlocking(std::string_view s) {
return UartWriteBlocking(std::as_bytes(std::span{s.data(), s.size()}));
}
void HandleUartTxFromIsr(void*, unsigned int transmitted);
void HandleUartRxFromIsr(void*, unsigned int);
void HandleUartIsr();
uint8_t UartStatus();
void LogStuff();

View File

@@ -0,0 +1,15 @@
#pragma once
#include <span>
#include <string_view>
#include "lib/async.h"
#include "lib/buffer.h"
async::task<buffer> UartRead(int size);
async::task<std::byte> UartReadLoop();
async::task<> UartWrite(std::span<const std::byte> data);
inline async::task<> UartWrite(std::string_view s) {
co_await UartWrite(std::as_bytes(std::span{s.data(), s.size()}));
}
async::task<> UartWriteLoop(async::gimme<std::span<const std::byte>>& data);

View File

@@ -0,0 +1,30 @@
#include <cstdint>
#include "hal/gpio.h"
#include "hal/pol0.h"
namespace {
Gpio* gpio0;
void sleep(int ms) {
for (int m = 0; m < ms; m++) {
for (int i = 0; i < 10000; i++) {
asm volatile("");
}
}
}
} // namespace
int main() {
gpio0 = Gpio::Instance(GPIO0_BASE);
int out = 0;
while (1) {
gpio0->data = out;
out = (out + 1) % 256;
sleep(10);
}
}

48
mbv/apps/timer/timer.cc Normal file
View File

@@ -0,0 +1,48 @@
#include <cstdint>
#include "hal/bios.h"
#include "hal/gpio.h"
#include "hal/intc.h"
#include "hal/interrupts.h"
#include "hal/pol0.h"
#include "hal/timer.h"
namespace {
Gpio* leds;
Timer* timer;
void Timer0Isr() {
static int counter = 0;
leds->data = counter++;
timer->Pet();
timer->ClearInterrupt();
}
void SetupTimer() {
timer = Timer::Instance(TIMER0_BASE);
timer->SetupAsWdt(100'000'000);
timer->EnableT1();
intc::SetIsr(TIMER0_IRQN, Timer0Isr);
intc::SetIrqEnabled(TIMER0_IRQN, true);
}
} // namespace
int main() {
leds = Gpio::Instance(GPIO0_BASE);
leds->data = 0xa0;
SetupTimer();
intc::EnableInterrupts();
SetExternalInterruptHandler(intc::InterruptHandler);
EnableExternalInterrupts();
EnableInterrupts(true);
leds->data = 0xa1;
BiosWozmon();
}

80
mbv/apps/uart/uart.cc Normal file
View File

@@ -0,0 +1,80 @@
#include <cstdint>
#include "hal/gpio.h"
#include "hal/intc.h"
#include "hal/interrupts.h"
#include "hal/pol0.h"
#include "xuartlite.h"
namespace {
Gpio* leds;
XUartLite uart0_inst;
XUartLite_Config uart0_config = {
.DeviceId = 0,
.RegBaseAddr = UART0_BASE,
.BaudRate = 115200,
.UseParity = false,
.DataBits = 8,
};
XUartLite* uart0 = &uart0_inst;
volatile int incoming = 0;
void HandleUartRxFromIsr(void*, unsigned int) { incoming += 1; }
void HandleUartTxFromIsr(void*, unsigned int) {}
void Uart0Isr() { XUartLite_InterruptHandler(uart0); }
void InitUarts() {
XUartLite_CfgInitialize(uart0, &uart0_config, uart0_config.RegBaseAddr);
XUartLite_SetSendHandler(uart0, HandleUartTxFromIsr, nullptr);
XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr);
XUartLite_EnableInterrupt(uart0);
intc::SetIsr(UART0_IRQN, Uart0Isr);
intc::SetIrqEnabled(UART0_IRQN, true);
}
} // namespace
int main() {
leds = Gpio::Instance(GPIO0_BASE);
leds->data = 0xa0;
InitUarts();
intc::EnableInterrupts();
SetExternalInterruptHandler(intc::InterruptHandler);
EnableExternalInterrupts();
EnableInterrupts(true);
int counter = 0;
uint8_t c;
while (XUartLite_Recv(uart0, &c, 1) > 0) {
XUartLite_Send(uart0, &c, 1);
while (XUartLite_IsSending(uart0)) {
}
}
leds->data = 0xa1;
while (1) {
// should disable interrupts around this
if (incoming > 0) {
counter += 1;
leds->data = counter;
XUartLite_Send(uart0, &c, 1);
while (XUartLite_IsSending(uart0)) {
}
while (XUartLite_Recv(uart0, &c, 1) > 0) {
XUartLite_Send(uart0, &c, 1);
while (XUartLite_IsSending(uart0)) {
}
}
incoming -= 1;
}
}
}

View File

@@ -0,0 +1,90 @@
#include <cstdint>
#include "hal/pol0.h"
#include "xuartlite.h"
uint8_t UartRead();
void UartWrite(uint8_t);
struct Gpio {
volatile uint32_t data;
};
#define gpio0 ((Gpio*)GPIO0_BASE)
namespace {
XUartLite uart0_inst;
XUartLite_Config uart0_config = {
.DeviceId = 0,
.RegBaseAddr = UART0_BASE,
.BaudRate = 115200,
.UseParity = false,
.DataBits = 8,
};
XUartLite* uart0 = &uart0_inst;
void InitUarts() {
XUartLite_CfgInitialize(uart0, &uart0_config, uart0_config.RegBaseAddr);
}
uint32_t UartRead32() {
uint32_t val = 0;
// little endian
val |= (UartRead() << 0);
val |= (UartRead() << 8);
val |= (UartRead() << 16);
val |= (UartRead() << 24);
return val;
}
} // namespace
uint8_t UartRead() {
uint8_t c;
while (XUartLite_Recv(uart0, &c, 1) < 1) {
}
return c;
}
void UartWrite(uint8_t c) {
XUartLite_Send(uart0, &c, 1);
while (XUartLite_IsSending(uart0)) {
}
}
int main() {
gpio0->data = 1;
InitUarts();
while (1) {
uint8_t c = UartRead();
if (c == 'c') {
uint32_t addr = UartRead32();
gpio0->data = 0xb0;
uint32_t bytes = UartRead32();
gpio0->data = 0x30;
uint8_t* start = reinterpret_cast<uint8_t*>(addr);
uint8_t* end = reinterpret_cast<uint8_t*>(addr + bytes);
for (uint8_t* ptr = start; ptr < end; ptr++) {
*ptr = UartRead();
}
UartWrite('a');
UartWrite(bytes);
gpio0->data = 0xf0;
} else if (c == 'j') {
uint32_t addr = UartRead32();
gpio0->data = 0x55;
auto jump = reinterpret_cast<void (*)()>(addr);
jump();
}
}
}

View File

@@ -0,0 +1,30 @@
MEMORY
{
BLRAM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x1000
}
SECTIONS
{
.text :
{
KEEP(*(.start))
*(.text*)
*(.rodata*)
} > BLRAM
.bss (NOLOAD) :
{
_bss_begin = .;
*(.bss*)
*(COMMON)
_bss_end = .;
} > BLRAM
.data :
{
*(.data*)
} > BLRAM
_initial_stack_pointer = 0x1000;
}

131
mbv/bootloader/wozmon.cc Normal file
View File

@@ -0,0 +1,131 @@
#include <cstdint>
uint8_t UartRead();
void UartWrite(uint8_t);
namespace {
void Jump(uint32_t addr) {
auto jump = reinterpret_cast<void (*)()>(addr);
jump();
}
constexpr uint8_t kBackspace = 0x7f;
constexpr uint8_t kOtherBackspace = 0x08;
uint8_t ReadHexNibble(uint8_t c) {
// lowercase only
if (c <= '9') {
return c - '0';
}
return 10 + (c - 'a');
}
uint32_t ReadHex(const char* buf) {
uint32_t out = 0;
while (*buf == ' ') {
buf++;
}
for (int i = 0; i < 8; i++) {
uint8_t c = ReadHexNibble(*buf);
if (c > 0xf) {
break;
}
out = (out << 4) + c;
buf++;
}
return out;
}
void WriteHexNibble(uint8_t c) {
if (c > 9) {
UartWrite('a' + c - 10);
} else {
UartWrite('0' + c);
}
}
void UartWriteUint32(uint32_t a) {
for (int i = 0; i < 8; i++) {
WriteHexNibble((a >> 28) & 0xf);
a <<= 4;
}
}
void UartWriteUint8(uint8_t a) {
WriteHexNibble(a >> 4);
WriteHexNibble(a & 0xf);
}
void UartDump(uint32_t addr, int count) {
for (int i = 0; i < count; i++) {
UartWrite(' ');
UartWriteUint8(*reinterpret_cast<uint8_t*>(addr + i));
}
}
void DumpHex(uint32_t addr) {
addr &= 0xfffffffc;
UartWriteUint32(addr);
UartWrite(':');
UartDump(addr, 4);
UartWrite('\r');
UartWrite('\n');
}
int FindChar(const char* buf, uint8_t c) {
int found = 0;
while (*buf) {
if (*buf == c) {
return found;
}
found++;
buf++;
}
return -1;
}
} // namespace
__attribute__((used)) void wozmon() {
uint32_t cur_addr = 0;
uint32_t cur_data = 0;
char inbuf[64] = {};
char* inptr = inbuf;
while (1) {
uint8_t c = UartRead();
UartWrite(c); // echo
if (c == '\r') {
*inptr = 0;
if (inptr == inbuf) {
cur_addr += 4;
} else if (FindChar(inbuf, 'r') >= 0) {
Jump(cur_addr);
} else {
cur_addr = ReadHex(inbuf);
UartWrite('\n');
}
DumpHex(cur_addr);
int assigned = FindChar(inbuf, ':');
if (assigned >= 0) {
cur_data = ReadHex(inbuf + assigned + 1);
*(reinterpret_cast<uint32_t*>(cur_addr)) = cur_data;
}
inptr = inbuf;
} else if (c == kBackspace) {
inptr--;
if (inptr < inbuf) {
inptr = inbuf;
continue;
}
UartWrite(kOtherBackspace);
UartWrite(' ');
UartWrite(kOtherBackspace);
} else {
*inptr++ = c;
}
}
}

343
mbv/configure vendored Executable file
View File

@@ -0,0 +1,343 @@
#!/usr/bin/env python3
import argparse
import collections
import dataclasses
import glob
import itertools
import os
import re
class Config:
def __init__(self, builddir, outdir):
self.builddir = builddir
self.outdir = outdir
if not os.path.exists(builddir):
os.mkdir(builddir)
if not os.path.exists(outdir):
os.mkdir(outdir)
toolchain_path = f"/opt/xpack-riscv-none-elf-gcc-14.2.0-3"
toolchain_prefix = "riscv-none-elf-"
hostcflags = "-g -std=c++20 -fprofile-instr-generate -fcoverage-mapping"
hostlibs = "-lgtest -lgmock -lgtest_main"
hostldflags = "-fprofile-instr-generate -fcoverage-mapping"
include_dirs = [
".",
"hal/uart",
"hal/xilinx",
]
common_flags = [
"-g",
"-Wall",
"-Wextra",
"-flto",
"-march=rv32i_zicsr",
"-ffunction-sections",
"-Oz",
]
ldflags = [
"-Oz",
"-g",
"-Wl,--gc-sections",
"-Wl,--print-memory-usage",
"-specs=nano.specs",
"-flto",
"-march=rv32i_zicsr",
]
project_flags = [
]
@property
def include_flags(self):
return [f"-I{os.path.relpath(i, self.builddir)}" for i in self.include_dirs]
@property
def cpp_flags(self):
return ["-DNDEBUG"] + self.include_flags + self.project_flags
@property
def cc_flags(self):
return self.common_flags + self.cpp_flags
@property
def cxx_flags(self):
return self.common_flags + [
"-std=c++20",
"-fno-rtti",
"-fno-exceptions",
"-Wno-missing-field-initializers",
] + self.cpp_flags
def relbuild(self, path):
return os.path.relpath(path, self.builddir)
def gen_rules(config):
tools = {"cxx": "g++", "cc": "gcc", "as": "as", "objcopy": "objcopy"}
tc_path = config.toolchain_path
tc_prefix = config.toolchain_prefix
rules = f"""
rule cxx
command = $cxx -MMD -MT $out -MF $out.d {' '.join(config.cxx_flags)} -c $in -o $out
description = CXX $out
depfile = $out.d
deps = gcc
rule cc
command = $cc -MMD -MT $out -MF $out.d {' '.join(config.cc_flags)} -c $in -o $out
description = CC $out
depfile = $out.d
deps = gcc
rule as
command = $as $in -o $out
description = AS $out
rule link
command = $cxx {' '.join(config.ldflags)} -Wl,-T$linker_script -o $out $in $libs
description = LINK $out
rule objcopy
command = $objcopy -O binary $in $out
description = OBJCOPY $out
rule hostcxx
command = clang++ -MMD -MT $out -MF $out.d {config.hostcflags} -c $in -o $out
description = HOSTCXX $out
depfile = $out.d
deps = gcc
rule hostlink
command = clang++ {config.hostldflags} -o $out $in {config.hostlibs}
description = HOSTLINK $out
rule profdata
command = llvm-profdata merge -sparse $profraw -o $out
description = PROFDATA
rule cov
command = llvm-cov show --output-dir cov -format html --instr-profile $profdata $objects && touch $out
description = COV
rule hosttest
command = LLVM_PROFILE_FILE=$in.profraw ./$in && touch $out
"""
for var, tool in tools.items():
toolpath = os.path.join(tc_path, "bin", f"{tc_prefix}{tool}")
yield f"{var} = {toolpath}"
for line in rules.splitlines():
yield line
def get_suffix_rule(filename, cxx_rule="cxx", cc_rule="cc"):
suffix = filename.split(".")[-1]
return collections.defaultdict(
lambda: None,
{
"c": cc_rule,
"cc": cxx_rule,
"cpp": cxx_rule,
"s": "as",
},
)[suffix]
def make_cxx_rule(name, cflags=()):
cflags = " ".join(cflags)
rule = f"""
rule {name}
command = $cxx -MMD -MT $out -MF $out.d {cflags} -c $in -o $out
description = CXX $out
depfile = $out.d
deps = gcc
"""
return rule.splitlines()
def make_cc_rule(name, cflags=()):
cflags = " ".join(cflags)
rule = f"""
rule {name}
command = $cc -MMD -MT $out -MF $out.d {cflags} -c $in -o $out
description = CC $out
depfile = $out.d
deps = gcc
"""
return rule.splitlines()
@dataclasses.dataclass
class SourceSet:
name: str
sources: list[str]
cflags: list[str]
def get_objects(self, config):
for s in self.sources:
yield (config.relbuild(s), re.sub(r"\.\w+", ".o", s))
def get_targets(self, config):
return list(zip(*self.get_objects(config)))[1]
def source_set(name, sources, cflags=()):
return SourceSet(name, sources, cflags)
def build_source_set(source_set):
def __f(config):
cxx_rule = "cxx"
cc_rule = "cc"
lines = []
if source_set.cflags:
cxx_rule = f"cxx_{name}"
lines += make_cxx_rule(cxx_rule, cflags=cflags + config.cxx_flags)
cc_rule = f"cc_{name}"
lines += make_cc_rule(cc_rule, cflags=cflags + config.cc_flags)
for line in lines:
yield line
for i, o in source_set.get_objects(config):
rule = get_suffix_rule(i, cxx_rule=cxx_rule, cc_rule=cc_rule)
if rule is None:
continue
yield f"build {o}: {rule} {i}"
return __f
def build_image(source_set, elf_out, linker_script, dependencies=(), bin_out=None):
def __f(config):
# to make it builddir-relative
lscript = config.relbuild(linker_script)
elfout = config.relbuild(os.path.join(config.outdir, elf_out))
for l in build_source_set(source_set)(config):
yield l
objects = source_set.get_targets(config)
for dep in dependencies:
objects += dep.get_targets(config)
objects = " ".join(objects)
yield f"build {elfout}: link {objects} | {lscript}"
yield f" linker_script = {lscript}"
if bin_out is not None:
binout = config.relbuild(os.path.join(config.outdir, bin_out))
yield f"build {binout}: objcopy {elfout}"
return __f
def build_test(name, sources):
builds = [
(os.path.relpath(s, builddir), f"{name}_" + re.sub(r"\.\w+", ".o", s))
for s in sources
]
out = name
for i, o in builds:
rule = "hostcxx"
yield f"build {o}: {rule} {i}"
objects = " ".join(b[1] for b in builds)
yield f"build {out}: hostlink {objects}"
yield f"build {out}.run: hosttest {out}"
def make_coverage(binaries):
bins = " ".join(binaries)
profraw = " ".join(f"{x}.profraw" for x in binaries)
objects = " ".join(f"--object {x}" for x in binaries)
testruns = " ".join(f"{x}.run" for x in binaries)
yield f"build profdata: profdata | {testruns}"
yield f" profraw = {profraw}"
yield f"build cov/index.html: cov {bins} | profdata"
yield f" profdata = profdata"
yield f" objects = {objects}"
hal = source_set("hal", [
"hal/intc.cc",
"hal/interrupts.cc",
"hal/start.cc",
"hal/uart/xuartlite.c",
"hal/uart/xuartlite_intr.c",
"hal/uart/xuartlite_stats.c",
"hal/xilinx/xil_assert.c",
])
lib = source_set("lib", [
"lib/async.cc",
"lib/lock.cc",
])
bootloader = source_set("bootloader", glob.glob("./bootloader/**/*.cc", recursive=True))
bootloader_image = build_image(
bootloader,
dependencies=[hal],
elf_out="bootloader.elf",
linker_script="bootloader/bootloader.ld",
)
def app_image(app, sources=None):
if sources is None:
sources = glob.glob(f"./apps/{app}/**/*.cc", recursive=True)
return build_image(
source_set(app, sources),
linker_script="apps/app.ld",
dependencies=[hal, lib],
elf_out=f"{app}.elf",
bin_out=f"{app}.bin",
)
all = [
build_source_set(hal),
build_source_set(lib),
bootloader_image,
app_image("helloworld"),
app_image("timer"),
app_image("uart"),
app_image("async", sources=[
"apps/async/main.cc",
"apps/async/uart.cc",
]),
]
def parse_args():
parser = argparse.ArgumentParser(description='Generate ninja build files.')
parser.add_argument('--version', required=True,
help='version tag (typically from `git describe`)')
parser.add_argument('--build-dir', default='build', help='build directory')
parser.add_argument('--out-dir', default='out', help='output directory')
return parser.parse_args()
def main():
args = parse_args()
config = Config(builddir=args.build_dir, outdir=args.out_dir)
config.project_flags.append(f'-DGIT_VERSION_TAG=\\"{args.version}\\"')
header = gen_rules(config)
lines = itertools.chain(header, *(f(config) for f in all))
with open(os.path.join(config.builddir, "build.ninja"), "w") as f:
f.write("\n".join(lines))
f.write("\n")
print(
f'Configure done. Build with "ninja -C {config.builddir}". Output will be in {config.outdir}/'
)
if __name__ == "__main__":
main()

11
mbv/hal/bios.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
#include <cstdint>
extern "C" {
uint8_t BiosUartRead();
void BiosUartWrite(uint8_t);
void BiosWozmon();
void BiosUartWriteNibble(uint8_t);
}

23
mbv/hal/debug.cc Normal file
View File

@@ -0,0 +1,23 @@
#include <cstdint>
extern "C" {
uint8_t BiosUartRead();
void BiosUartWrite(uint8_t);
void BiosWozmon();
void BiosUartWriteNibble(uint8_t n);
__attribute__((used)) void UartWriteU32(uint32_t a) {
for (int i = 0; i < 8; i++) {
BiosUartWriteNibble(a >> 28);
a <<= 4;
}
}
__attribute__((used)) void UartWriteString(const char* s) {
while (*s) {
BiosUartWrite(*s);
s++;
}
}
}

11
mbv/hal/gpio.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
#include <cstdint>
struct Gpio {
volatile uint32_t data;
static Gpio* Instance(uint32_t base) {
return reinterpret_cast<Gpio*>(base);
}
};

62
mbv/hal/intc.cc Normal file
View File

@@ -0,0 +1,62 @@
#include "intc.h"
// this interrupt controller is tied to the pol0 design
#include "pol0.h"
namespace intc {
namespace {
struct IntC {
volatile uint32_t ISR;
volatile uint32_t IPR;
volatile uint32_t IER;
volatile uint32_t IAR;
volatile uint32_t SIE;
volatile uint32_t CIE;
volatile uint32_t IVR;
volatile uint32_t MER;
volatile uint32_t IMR;
volatile uint32_t ILR;
// the rest is not enabled
};
IntC* intc = reinterpret_cast<IntC*>(INTC_BASE);
Isr isrs[NIRQ] = {};
} // namespace
bool SetIrqEnabled(uint8_t irqn, bool enabled) {
uint32_t mask = 1 << irqn;
uint32_t ier = intc->IER;
bool was_enabled = (ier & (~mask)) > 0;
if (enabled) {
intc->IER = ier | mask;
} else {
intc->IER = ier & (~mask);
}
return was_enabled;
}
void SetIsr(uint8_t irqn, Isr isr) { isrs[irqn] = isr; }
void EnableInterrupts() { intc->MER = 0x3; }
void InterruptHandler() {
uint32_t ipr = intc->IPR;
for (int i = 0; i < NIRQ; i++) {
uint32_t mask = 1 << i;
if ((ipr & mask) > 0) {
// interrupt pending
if (isrs[i] != nullptr) {
isrs[i]();
}
intc->IAR = mask; // ack
}
}
}
} // namespace intc

20
mbv/hal/intc.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
namespace intc {
using Isr = void (*)(void);
/// Returns: true if the IRQ was previously enabled
bool SetIrqEnabled(uint8_t irqn, bool enabled);
void SetIsr(uint8_t irqn, Isr isr);
// Call this once to enable all HW interrupts
void EnableInterrupts();
// Feed this to the CPU's interrupt handler
void InterruptHandler();
} // namespace intc

64
mbv/hal/interrupts.cc Normal file
View File

@@ -0,0 +1,64 @@
#include "interrupts.h"
#include <cstdint>
#include "bios.h"
namespace {
constexpr uint32_t kMstatusMieMask = 1 << 3;
constexpr uint32_t kMieExternalInterruptMask = 1 << 11;
constexpr uint32_t kExternalInterruptCause = 0x0b;
constexpr uint32_t kInterruptCauseMask = 0xff;
Isr external_handler = nullptr;
__attribute__((interrupt)) void TrapHandler() {
uint32_t mcause;
uint32_t mip;
asm volatile("csrr %0, mcause" : "=r"(mcause));
asm volatile("csrr %0, mip" : "=r"(mip));
// check for external interrupt
if ((mcause & kInterruptCauseMask) == kExternalInterruptCause) {
if (external_handler != nullptr) {
external_handler();
}
mip &= ~(kMieExternalInterruptMask);
asm volatile("csrw mip, %0" ::"r"(mip));
} else {
BiosWozmon();
}
}
} // namespace
void SetExternalInterruptHandler(Isr handler) { external_handler = handler; }
void EnableExternalInterrupts() {
uint32_t mie;
Isr trap = TrapHandler;
asm volatile("csrr %0, mie" : "=r"(mie));
asm volatile("csrw mtvec, %0" ::"r"(trap));
mie |= kMieExternalInterruptMask;
asm volatile("csrw mie, %0" ::"r"(mie));
}
bool EnableInterrupts(bool on) {
uint32_t mstatus;
bool was_on;
asm volatile("csrr %0, mstatus" : "=r"(mstatus));
was_on = (mstatus & kMstatusMieMask) > 0;
if (on) {
mstatus |= kMstatusMieMask;
} else {
mstatus &= ~kMstatusMieMask;
}
asm volatile("csrw mstatus, %0" ::"r"(mstatus));
return was_on;
}

9
mbv/hal/interrupts.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
using Isr = void (*)();
void SetExternalInterruptHandler(Isr handler);
void EnableExternalInterrupts();
/** Returns true if interrupts were enabled, false otherwise */
bool EnableInterrupts(bool on);

18
mbv/hal/pol0.h Normal file
View File

@@ -0,0 +1,18 @@
// Platform definitions for pol0
// LED output
#define GPIO0_BASE (0x40000000)
// /dev/ttyUSB1
#define UART0_BASE (0x40600000)
// Interrupt controller
#define INTC_BASE (0x41200000)
// It's uh.. a timer.
#define TIMER0_BASE (0x41c00000)
// IRQs
#define UART0_IRQN (0)
#define TIMER0_IRQN (1)
#define NIRQ (2)

21
mbv/hal/start.cc Normal file
View File

@@ -0,0 +1,21 @@
#include <cstdint>
extern "C" uint32_t _bss_begin, _bss_end, _initial_stack_pointer;
extern "C" int main();
extern "C" void __libc_init_array();
__attribute__((section(".start"), used, naked)) void _start() {
// clear .bss
for (uint32_t* ptr = &_bss_begin; ptr < &_bss_end; ptr++) {
*ptr = 0;
}
asm volatile("la sp, _initial_stack_pointer");
__libc_init_array();
main();
while (true) {
}
}

71
mbv/hal/timer.h Normal file
View File

@@ -0,0 +1,71 @@
#pragma once
#include <cstdint>
struct TimerControl {
union {
struct {
uint32_t MDT0 : 1;
uint32_t UDT0 : 1;
uint32_t GENT0 : 1;
uint32_t CAPT0 : 1;
uint32_t ARHT0 : 1;
uint32_t LOAD0 : 1;
uint32_t ENIT0 : 1;
uint32_t ENT0 : 1;
uint32_t T0INT : 1;
uint32_t PWMA0 : 1;
uint32_t ENALL : 1;
uint32_t CASC : 1;
uint32_t reserved : 20;
};
uint32_t raw;
};
};
struct Timer {
volatile TimerControl TCSR0;
volatile uint32_t TLR0;
volatile uint32_t TCR0;
uint32_t _reserved;
volatile TimerControl TCSR1;
volatile uint32_t TLR1;
volatile uint32_t TCR1;
void EnableT1() {
TCSR1.ARHT0 = 1;
TCSR1.ENIT0 = 1; // enable interrupt for overflows
TCSR1.ENT0 = 1;
}
uint32_t GetT1Ticks() { return TCR1; }
bool HasT1Overflowed() { return TCSR1.T0INT; }
void ClearT1Overflow() { TCSR1.T0INT = 1; }
void SetupAsWdt(uint32_t timeout_ticks) {
TLR0 = timeout_ticks;
TCSR0.LOAD0 = 1; // reset counter
TCSR0.UDT0 = 1; // count backwards from the load value
TCSR0.ENIT0 = 1; // enable interrupt
TCSR0.LOAD0 = 0; // allow counter to run
TCSR0.ENT0 = 1; // enable timer
}
void Pet() {
TCSR0.ENT0 = 0;
TCSR0.LOAD0 = 1;
TCSR0.LOAD0 = 0;
TCSR0.ENT0 = 1;
}
void ClearInterrupt() { TCSR0.T0INT = 0; }
static Timer* Instance(uint32_t base) {
return reinterpret_cast<Timer*>(base);
}
};

654
mbv/hal/uart/xuartlite.c Normal file
View File

@@ -0,0 +1,654 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite.c
* @addtogroup uartlite_v3_7
* @{
*
* Contains required functions for the XUartLite driver. See the xuartlite.h
* header file for more details on this driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 08/31/01 First release
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
* 1.00b rmm 05/13/03 Fixed diab compiler warnings relating to asserts
* 1.01a jvb 12/13/05 Changed Initialize() into CfgInitialize(), and made
* CfgInitialize() take a pointer to a config structure
* instead of a device id. Moved Initialize() into
* xgpio_sinit.c, and had Initialize() call CfgInitialize()
* after it retrieved the config structure using the device
* id. Removed include of xparameters.h along with any
* dependencies on xparameters.h and the _g.c config table.
* 1.01a wsy 05/08/06 fix CR220811 and CR224103.
* 1.12a mta 03/31/07 Updated to new coding conventions
* 1.13a sv 01/21/08 Updated driver to support access through DCR bus
* 1.14a sdm 09/26/08 Updated code to avoid race condition in
* XUartLite_SendBuffer
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. The macros have been
* renamed to remove _m from the name. XUartLite_mClearStats
* macro is removed and XUartLite_ClearStats function should
* be used in its place.
* 2.00a hvm 08/11/11 Removed the SetOptions related information in the
* Recv and RecvBuffer function header notes section.
* CR620849.
* 2.01a adk 18/04/13 Updated the code to avoid unused variable
* warnings when compiling with the -Wextra -Wall flags
* In the file xuartlite.c. CR:704999.
* 3.1 nsk 21/07/15 Updated XUartLite_ReceiveBuffer function to update the
* receive data into user buffer in critical region.
* CR#865787.
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
* Changed the prototype of XUartLite_CfgInitialize API.
* 3.6 rna 02/19/21 Added 'XUartLite_GetSR' internal API to read Status
* register and update the error stats.
*
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xuartlite.h"
#include "xuartlite_i.h"
#include "xil_io.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
static void StubHandler(void *CallBackRef, unsigned int ByteCount);
/****************************************************************************/
/**
*
* Initialize a XUartLite instance. The receive and transmit FIFOs of the
* UART are not flushed, so the user may want to flush them. The hardware
* device does not have any way to disable the receiver such that any valid
* data may be present in the receive FIFO. This function disables the UART
* interrupt. The baudrate and format of the data are fixed in the hardware
* at hardware build time.
*
* @param InstancePtr is a pointer to the XUartLite instance.
* @param Config is a reference to a structure containing information
* about a specific UART Lite device. This function initializes an
* InstancePtr object for a specific device specified by the
* contents of Config. This function can initialize multiple
* instance objects with the use of multiple calls giving different
* Config information on each call.
* @param EffectiveAddr is the device base address in the virtual memory
* address space. The caller is responsible for keeping the address
* mapping from EffectiveAddr to the device physical base address
* unchanged once this function is invoked. Unexpected errors may
* occur if the address mapping changes after this function is
* called. If address translation is not used, use
* Config->BaseAddress for this parameters, passing the physical
* address instead.
*
* @return
* - XST_SUCCESS if everything starts up as expected.
*
* @note The Config pointer argument is not used by this function,
* but is provided to keep the function signature consistent
* with other drivers.
*
*****************************************************************************/
int XUartLite_CfgInitialize(XUartLite *InstancePtr, XUartLite_Config *Config,
UINTPTR EffectiveAddr)
{
(void) Config;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Set some default values, including setting the callback
* handlers to stubs.
*/
InstancePtr->SendBuffer.NextBytePtr = NULL;
InstancePtr->SendBuffer.RemainingBytes = 0;
InstancePtr->SendBuffer.RequestedBytes = 0;
InstancePtr->ReceiveBuffer.NextBytePtr = NULL;
InstancePtr->ReceiveBuffer.RemainingBytes = 0;
InstancePtr->ReceiveBuffer.RequestedBytes = 0;
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
#if (XPAR_XUARTLITE_USE_DCR_BRIDGE != 0)
InstancePtr->RegBaseAddress = ((EffectiveAddr >> 2)) & 0xFFF;
#else
InstancePtr->RegBaseAddress = EffectiveAddr;
#endif
InstancePtr->RecvHandler = StubHandler;
InstancePtr->SendHandler = StubHandler;
/* Write to the control register to disable the interrupts, don't
* reset the FIFOs are the user may want the data that's present
*/
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, 0);
/*
* Clear the statistics for this driver
*/
XUartLite_ClearStats(InstancePtr);
return XST_SUCCESS;
}
/****************************************************************************/
/**
*
* This functions sends the specified buffer of data using the UART in either
* polled or interrupt driven modes. This function is non-blocking such that it
* will return before the data has been sent by the UART. If the UART is busy
* sending data, it will return and indicate zero bytes were sent.
*
* In a polled mode, this function will only send as much data as the UART can
* buffer in the FIFO. The application may need to call it repeatedly to
* send a buffer.
*
* In interrupt mode, this function will start sending the specified buffer and
* then the interrupt handler of the driver will continue sending data until the
* buffer has been sent. A callback function, as specified by the application,
* will be called to indicate the completion of sending the buffer.
*
* @param InstancePtr is a pointer to the XUartLite instance.
* @param DataBufferPtr is pointer to a buffer of data to be sent.
* @param NumBytes contains the number of bytes to be sent. A value of
* zero will stop a previous send operation that is in progress
* in interrupt mode. Any data that was already put into the
* transmit FIFO will be sent.
*
* @return The number of bytes actually sent.
*
* @note The number of bytes is not asserted so that this function may
* be called with a value of zero to stop an operation that is
* already in progress.
*
******************************************************************************/
unsigned int XUartLite_Send(XUartLite *InstancePtr, u8 *DataBufferPtr,
unsigned int NumBytes)
{
unsigned int BytesSent;
u32 StatusRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(DataBufferPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(((signed)NumBytes) >= 0);
/*
* Enter a critical region by disabling the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven.
*/
StatusRegister = XUartLite_GetSR(InstancePtr);
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, 0);
/*
* Setup the specified buffer to be sent by setting the instance
* variables so it can be sent with polled or interrupt mode
*/
InstancePtr->SendBuffer.RequestedBytes = NumBytes;
InstancePtr->SendBuffer.RemainingBytes = NumBytes;
InstancePtr->SendBuffer.NextBytePtr = DataBufferPtr;
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited.
* This is done here to minimize the amount of time the interrupt is
* disabled since there is only one interrupt and the receive could
* be filling up while interrupts are blocked.
*/
StatusRegister &= XUL_CR_ENABLE_INTR;
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, StatusRegister);
/*
* Send the buffer using the UART and return the number of bytes sent
*/
BytesSent = XUartLite_SendBuffer(InstancePtr);
return BytesSent;
}
/****************************************************************************/
/**
*
* This function will attempt to receive a specified number of bytes of data
* from the UART and store it into the specified buffer. This function is
* designed for either polled or interrupt driven modes. It is non-blocking
* such that it will return if no data has already received by the UART.
*
* In a polled mode, this function will only receive as much data as the UART
* can buffer in the FIFO. The application may need to call it repeatedly to
* receive a buffer. Polled mode is the default mode of operation for the driver.
*
* In interrupt mode, this function will start receiving and then the interrupt
* handler of the driver will continue receiving data until the buffer has been
* received. A callback function, as specified by the application, will be called
* to indicate the completion of receiving the buffer or when any receive errors
* or timeouts occur.
*
* @param InstancePtr is a pointer to the XUartLite instance.
* @param DataBufferPtr is pointer to buffer for data to be received into.
* @param NumBytes is the number of bytes to be received. A value of zero
* will stop a previous receive operation that is in progress in
* interrupt mode.
*
* @return The number of bytes received.
*
* @note The number of bytes is not asserted so that this function
* may be called with a value of zero to stop an operation
* that is already in progress.
*
*****************************************************************************/
unsigned int XUartLite_Recv(XUartLite *InstancePtr, u8 *DataBufferPtr,
unsigned int NumBytes)
{
unsigned int ReceivedCount;
u32 StatusRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(DataBufferPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(((signed)NumBytes) >= 0);
/*
* Enter a critical region by disabling all the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven
*/
StatusRegister = XUartLite_GetSR(InstancePtr);
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, 0);
/*
* Setup the specified buffer to be received by setting the instance
* variables so it can be received with polled or interrupt mode
*/
InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes;
InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes;
InstancePtr->ReceiveBuffer.NextBytePtr = DataBufferPtr;
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited
*/
StatusRegister &= XUL_CR_ENABLE_INTR;
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, StatusRegister);
/*
* Receive the data from the UART and return the number of bytes
* received
* This is done here to minimize the amount of time the interrupt is
* disabled since there is only one interrupt and the transmit could
* be emptying out while interrupts are blocked.
*/
ReceivedCount = XUartLite_ReceiveBuffer(InstancePtr);
return ReceivedCount;
}
/****************************************************************************/
/**
*
* This function resets the FIFOs, both transmit and receive, of the UART such
* that they are emptied. Since the UART does not have any way to disable it
* from receiving data, it may be necessary for the application to reset the
* FIFOs to get rid of any unwanted data.
*
* @param InstancePtr is a pointer to the XUartLite instance .
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XUartLite_ResetFifos(XUartLite *InstancePtr)
{
u32 Register;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Read the status register 1st such that the next write to the control
* register won't destroy the state of the interrupt enable bit
*/
Register = XUartLite_ReadReg(InstancePtr->RegBaseAddress,
XUL_STATUS_REG_OFFSET);
/*
* Mask off the interrupt enable bit to maintain it's state.
*/
Register &= XUL_SR_INTR_ENABLED;
/*
* Write to the control register to reset both FIFOs, these bits are
* self-clearing such that there's no need to clear them
*/
XUartLite_WriteReg(InstancePtr->RegBaseAddress, XUL_CONTROL_REG_OFFSET,
Register | XUL_CR_FIFO_TX_RESET | XUL_CR_FIFO_RX_RESET);
}
/****************************************************************************/
/**
*
* This function determines if the specified UART is sending data. If the
* transmitter register is not empty, it is sending data.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return A value of TRUE if the UART is sending data, otherwise FALSE.
*
* @note None.
*
*****************************************************************************/
int XUartLite_IsSending(XUartLite *InstancePtr)
{
u32 StatusRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Read the status register to determine if the transmitter is empty
*/
StatusRegister = XUartLite_GetSR(InstancePtr);
/*
* If the transmitter is not empty then indicate that the UART is still
* sending some data
*/
return ((StatusRegister & XUL_SR_TX_FIFO_EMPTY) == 0);
}
/****************************************************************************
*
* This function provides a stub handler such that if the application does not
* define a handler but enables interrupts, this function will be called.
*
* @param CallBackRef has no purpose but is necessary to match the
* interface for a handler.
* @param ByteCount has no purpose but is necessary to match the
* interface for a handler.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
static void StubHandler(void *CallBackRef, unsigned int ByteCount)
{
(void) CallBackRef;
(void) ByteCount;
/*
* Assert occurs always since this is a stub and should never be called
*/
Xil_AssertVoidAlways();
}
/****************************************************************************/
/**
*
* This function sends a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is designed to be
* an internal function for the XUartLite component such that it may be called
* from a shell function that sets up the buffer or from an interrupt handler.
*
* This function sends the specified buffer of data to the UART in either
* polled or interrupt driven modes. This function is non-blocking such that
* it will return before the data has been sent by the UART.
*
* In a polled mode, this function will only send as much data as the UART can
* buffer, either in the transmitter or in the FIFO if present and enabled.
* The application may need to call it repeatedly to send a buffer.
*
* In interrupt mode, this function will start sending the specified buffer and
* then the interrupt handler of the driver will continue until the buffer
* has been sent. A callback function, as specified by the application, will
* be called to indicate the completion of sending the buffer.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return NumBytes is the number of bytes actually sent (put into the
* UART transmitter and/or FIFO).
*
* @note None.
*
*****************************************************************************/
unsigned int XUartLite_SendBuffer(XUartLite *InstancePtr)
{
unsigned int SentCount = 0;
u8 StatusRegister;
u8 IntrEnableStatus;
/*
* Read the status register to determine if the transmitter is full
*/
StatusRegister = XUartLite_GetSR(InstancePtr);
/*
* Enter a critical region by disabling all the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven
*/
StatusRegister = XUartLite_GetSR(InstancePtr);
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, 0);
/*
* Save the status register contents to restore the interrupt enable
* register to it's previous value when that the critical region is
* exited
*/
IntrEnableStatus = StatusRegister;
/*
* Fill the FIFO from the the buffer that was specified
*/
while (((StatusRegister & XUL_SR_TX_FIFO_FULL) == 0) &&
(SentCount < InstancePtr->SendBuffer.RemainingBytes)) {
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_TX_FIFO_OFFSET,
InstancePtr->SendBuffer.NextBytePtr[
SentCount]);
SentCount++;
StatusRegister = XUartLite_GetSR(InstancePtr);
}
/*
* Update the buffer to reflect the bytes that were sent from it
*/
InstancePtr->SendBuffer.NextBytePtr += SentCount;
InstancePtr->SendBuffer.RemainingBytes -= SentCount;
/*
* Increment associated counters
*/
InstancePtr->Stats.CharactersTransmitted += SentCount;
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited
*/
IntrEnableStatus &= XUL_CR_ENABLE_INTR;
XUartLite_WriteReg(InstancePtr->RegBaseAddress, XUL_CONTROL_REG_OFFSET,
IntrEnableStatus);
/*
* Return the number of bytes that were sent, although they really were
* only put into the FIFO, not completely sent yet
*/
return SentCount;
}
/****************************************************************************/
/**
*
* This function receives a buffer that has been previously specified by setting
* up the instance variables of the instance. This function is designed to be
* an internal function for the XUartLite component such that it may be called
* from a shell function that sets up the buffer or from an interrupt handler.
*
* This function will attempt to receive a specified number of bytes of data
* from the UART and store it into the specified buffer. This function is
* designed for either polled or interrupt driven modes. It is non-blocking
* such that it will return if there is no data has already received by the
* UART.
*
* In a polled mode, this function will only receive as much data as the UART
* can buffer, either in the receiver or in the FIFO if present and enabled.
* The application may need to call it repeatedly to receive a buffer. Polled
* mode is the default mode of operation for the driver.
*
* In interrupt mode, this function will start receiving and then the interrupt
* handler of the driver will continue until the buffer has been received. A
* callback function, as specified by the application, will be called to indicate
* the completion of receiving the buffer or when any receive errors or timeouts
* occur.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return The number of bytes received.
*
* @note None.
*
*****************************************************************************/
unsigned int XUartLite_ReceiveBuffer(XUartLite *InstancePtr)
{
u8 StatusRegister;
u8 StatusRegisterVal;
unsigned int ReceivedCount = 0;
/*
* Enter a critical region by disabling all the UART interrupts to allow
* this call to stop a previous operation that may be interrupt driven
*/
StatusRegisterVal = XUartLite_GetSR(InstancePtr);
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, 0);
/*
* Loop until there is not more data buffered by the UART or the
* specified number of bytes is received
*/
while (ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes) {
/*
* Read the Status Register to determine if there is any data in
* the receiver/FIFO
*/
StatusRegister = XUartLite_GetSR(InstancePtr);
/*
* If there is data ready to be removed, then put the next byte
* received into the specified buffer and update the stats to
* reflect any receive errors for the byte
*/
if (StatusRegister & XUL_SR_RX_FIFO_VALID_DATA) {
InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount++]=
XUartLite_ReadReg(InstancePtr->RegBaseAddress,
XUL_RX_FIFO_OFFSET);
}
/*
* There's no more data buffered, so exit such that this
* function does not block waiting for data
*/
else {
break;
}
}
/*
* Update the receive buffer to reflect the number of bytes that was
* received
*/
InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount;
InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount;
/*
* Increment associated counters in the statistics
*/
InstancePtr->Stats.CharactersReceived += ReceivedCount;
/*
* Restore the interrupt enable register to it's previous value such
* that the critical region is exited
*/
StatusRegisterVal &= XUL_CR_ENABLE_INTR;
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, StatusRegisterVal);
return ReceivedCount;
}
/****************************************************************************/
/**
*
* This function reads the status register and updates the error stats, before
* returning the status register value. The status register is a clear on read
* register, so the errors if occurred have to be recorded everytime status
* register is read. This function is designed to be an internal function for
* the XUartLite component such that it may be called from wherever the status
* register needs to be read from the other driver functions.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return The value of status register.
*
* @note None.
*
*****************************************************************************/
u8 XUartLite_GetSR(XUartLite *InstancePtr)
{
u8 StatusRegister;
StatusRegister = XUartLite_GetStatusReg(InstancePtr->RegBaseAddress);
/*
* Update Stats everytime status reg is read as it is a clear on read
* register and as a result, there is a chance of missing the errors.
*/
XUartLite_UpdateStats(InstancePtr, StatusRegister);
return StatusRegister;
}
/** @} */

274
mbv/hal/uart/xuartlite.h Normal file
View File

@@ -0,0 +1,274 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite.h
* @addtogroup uartlite_v3_7
* @{
* @details
*
* This component contains the implementation of the XUartLite component which is
* the driver for the Xilinx UART Lite device. This UART is a minimal hardware
* implementation with minimal features. Most of the features, including baud
* rate, parity, and number of data bits are only configurable when the hardware
* device is built, rather than at run time by software.
*
* The device has 16 byte transmit and receive FIFOs and supports interrupts.
* The device does not have any way to disable the receiver such that the
* receive FIFO may contain unwanted data. The FIFOs are not flushed when the
* driver is initialized, but a function is provided to allow the user to
* reset the FIFOs if desired.
*
* The driver defaults to no interrupts at initialization such that interrupts
* must be enabled if desired. An interrupt is generated when the transmit FIFO
* transitions from having data to being empty or when any data is contained in
* the receive FIFO.
*
* In order to use interrupts, it's necessary for the user to connect the driver
* interrupt handler, XUartLite_InterruptHandler, to the interrupt system of the
* application. This function does not save and restore the processor context
* such that the user must provide it. Send and receive handlers may be set for
* the driver such that the handlers are called when transmit and receive
* interrupts occur. The handlers are called from interrupt context and are
* designed to allow application specific processing to be performed.
*
* The functions, XUartLite_Send and XUartLite_Recv, are provided in the driver
* to allow data to be sent and received. They are designed to be used in
* polled or interrupt modes.
*
* The driver provides a status for each received byte indicating any parity
* frame or overrun error. The driver provides statistics which allow visibility
* into these errors.
*
* <b>Initialization & Configuration</b>
*
* The XUartLite_Config structure is used by the driver to configure itself. This
* configuration structure is typically created by the tool-chain based on HW
* build properties.
*
* To support multiple runtime loading and initialization strategies employed
* by various operating systems, the driver instance can be initialized in one
* of the following ways:
*
* - XUartLite_Initialize(InstancePtr, DeviceId) - The driver looks up its own
* configuration structure created by the tool-chain based on an ID provided
* by the tool-chain.
*
* - XUartLite_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a
* configuration structure provided by the caller. If running in a system
* with address translation, the provided virtual memory base address
* replaces the physical address present in the configuration structure.
*
* <b>RTOS Independence</b>
*
* This driver is intended to be RTOS and processor independent. It works
* with physical addresses only. Any needs for dynamic memory management,
* threads or thread mutual exclusion, virtual memory, or cache control must
* be satisfied by the layer above this driver.
*
* @note
*
* The driver is partitioned such that a minimal implementation may be used.
* More features require additional files to be linked in.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 08/31/01 First release
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
* 1.01a jvb 12/14/05 I separated dependency on the static config table and
* xparameters.h from the driver initialization by moving
* _Initialize and _LookupConfig to _sinit.c. I also added
* the new _CfgInitialize routine.
* 1.02a rpm 02/14/07 Added check for outstanding transmission before
* calling the send callback (avoids extraneous
* callback invocations) in interrupt service routine.
* 1.12a mta 03/31/07 Updated to new coding conventions
* 1.13a sv 01/21/08 Updated driver to support access through DCR bus
* 1.14a sdm 08/22/08 Removed support for static interrupt handlers from the MDD
* file
* 1.14a sdm 09/26/08 Updated code to avoid race condition in
* XUartLite_SendBuffer
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. The macros have been
* renamed to remove _m from the name. XUartLite_mClearStats
* macro is removed and XUartLite_ClearStats function should
* be used in its place.
* 2.01a adk 18/04/13 Updated the code to avoid unused variable
* warnings when compiling with the -Wextra -Wall flags
* In the file xuartlite.c. CR:704999.
* Added notes for CR 710483 that the XUL_FIFO_SIZE is not
* used in the driver. This is the size of the FIFO for
* Transmit/Receive FIFOs which cannot be changed.
* 3.0 adk 17/12/13 Fixed CR:741186,761863 Changes are made in the file
* xuartlite_selftest.c
* 3.0 adk 19/12/13 Update the driver as per new TCL API's
* 3.1 nsk 21/07/15 Updated XUartLite_ReceiveBuffer function in xuartlite.c
* to update the receive data into user buffer in critical
* region.CR#865787.
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
* Changed the prototype of XUartLite_CfgInitialize API.
* ms 01/23/17 Added xil_printf statement in main function for all
* examples to ensure that "Successfully ran" and "Failed"
* strings are available in all examples. This is a fix
* for CR-965028.
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
* generation.
* 3.3 sne 09/09/19 Updated driver tcl file for supporting pl and ps ip's.
* 3.3 sne 09/13/19 Updated driver tcl file for mdm & tmr_sem ip's.
* 3.7 adk 31/01/22 Fix interrupt controller name in SMP designs, Changes are
* made in the interrupt app tcl file.
* 3.7 adk 14/02/22 When generating peripheral tests for TMR subsystem based
* designs don't pull the driver examples when uartlite is
* configured as a TMR SEM fix for CR-1121291, changes are
* made in the uartlite_tapp.tcl file.
* </pre>
*
*****************************************************************************/
#ifndef XUARTLITE_H /* prevent circular inclusions */
#define XUARTLITE_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/**
* Callback function. The first argument is a callback reference passed in by
* the upper layer when setting the callback functions, and passed back to the
* upper layer when the callback is invoked.
* The second argument is the ByteCount which is the number of bytes that
* actually moved from/to the buffer provided in the _Send/_Receive call.
*/
typedef void (*XUartLite_Handler)(void *CallBackRef, unsigned int ByteCount);
/**
* Statistics for the XUartLite driver
*/
typedef struct {
u32 TransmitInterrupts; /**< Number of transmit interrupts */
u32 ReceiveInterrupts; /**< Number of receive interrupts */
u32 CharactersTransmitted; /**< Number of characters transmitted */
u32 CharactersReceived; /**< Number of characters received */
u32 ReceiveOverrunErrors; /**< Number of receive overruns */
u32 ReceiveParityErrors; /**< Number of receive parity errors */
u32 ReceiveFramingErrors; /**< Number of receive framing errors */
} XUartLite_Stats;
/**
* The following data type is used to manage the buffers that are handled
* when sending and receiving data in the interrupt mode. It is intended
* for internal use only.
*/
typedef struct {
u8 *NextBytePtr;
unsigned int RequestedBytes;
unsigned int RemainingBytes;
} XUartLite_Buffer;
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
UINTPTR RegBaseAddr; /**< Register base address */
u32 BaudRate; /**< Fixed baud rate */
u8 UseParity; /**< Parity generator enabled when TRUE */
u8 ParityOdd; /**< Parity generated is odd when TRUE, even
when FALSE */
u8 DataBits; /**< Fixed data bits */
} XUartLite_Config;
/**
* The XUartLite driver instance data. The user is required to allocate a
* variable of this type for every UART Lite device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XUartLite_Stats Stats; /* Component Statistics */
UINTPTR RegBaseAddress; /* Base address of registers */
u32 IsReady; /* Device is initialized and ready */
XUartLite_Buffer SendBuffer;
XUartLite_Buffer ReceiveBuffer;
XUartLite_Handler RecvHandler;
void *RecvCallBackRef; /* Callback ref for recv handler */
XUartLite_Handler SendHandler;
void *SendCallBackRef; /* Callback ref for send handler */
} XUartLite;
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Function Prototypes *****************************/
/*
* Initialization functions in xuartlite_sinit.c
*/
int XUartLite_Initialize(XUartLite *InstancePtr, u16 DeviceId);
XUartLite_Config *XUartLite_LookupConfig(u16 DeviceId);
/*
* Required functions, in file xuart.c
*/
int XUartLite_CfgInitialize(XUartLite *InstancePtr,
XUartLite_Config *Config,
UINTPTR EffectiveAddr);
void XUartLite_ResetFifos(XUartLite *InstancePtr);
unsigned int XUartLite_Send(XUartLite *InstancePtr, u8 *DataBufferPtr,
unsigned int NumBytes);
unsigned int XUartLite_Recv(XUartLite *InstancePtr, u8 *DataBufferPtr,
unsigned int NumBytes);
int XUartLite_IsSending(XUartLite *InstancePtr);
/*
* Functions for statistics, in file xuartlite_stats.c
*/
void XUartLite_GetStats(XUartLite *InstancePtr, XUartLite_Stats *StatsPtr);
void XUartLite_ClearStats(XUartLite *InstancePtr);
/*
* Functions for self-test, in file xuartlite_selftest.c
*/
int XUartLite_SelfTest(XUartLite *InstancePtr);
/*
* Functions for interrupts, in file xuartlite_intr.c
*/
void XUartLite_EnableInterrupt(XUartLite *InstancePtr);
void XUartLite_DisableInterrupt(XUartLite *InstancePtr);
void XUartLite_SetRecvHandler(XUartLite *InstancePtr, XUartLite_Handler FuncPtr,
void *CallBackRef);
void XUartLite_SetSendHandler(XUartLite *InstancePtr, XUartLite_Handler FuncPtr,
void *CallBackRef);
void XUartLite_InterruptHandler(XUartLite *InstancePtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View File

@@ -0,0 +1,63 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite_g.c
* @addtogroup uartlite_v3_7
* @{
*
* This file contains a configuration table that specifies the configuration of
* UART Lite devices in the system. Each device in the system should have an
* entry in the table.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 08/31/01 First release
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xuartlite.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Prototypes ******************************/
/**
* The configuration table for UART Lite devices
*/
XUartLite_Config XUartLite_ConfigTable[XPAR_XUARTLITE_NUM_INSTANCES] =
{
{
XPAR_UARTLITE_0_DEVICE_ID, /* Unique ID of device */
XPAR_UARTLITE_0_BASEADDR, /* Device base address */
XPAR_UARTLITE_0_BAUDRATE, /* Fixed baud rate */
XPAR_UARTLITE_0_USE_PARITY, /* Fixed parity */
XPAR_UARTLITE_0_ODD_PARITY, /* Fixed parity type */
XPAR_UARTLITE_0_DATA_BITS /* Fixed data bits */
},
};
/** @} */

100
mbv/hal/uart/xuartlite_i.h Normal file
View File

@@ -0,0 +1,100 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite_i.h
* @addtogroup uartlite_v3_7
* @{
*
* Contains data which is shared between the files of the XUartLite component.
* It is intended for internal use only.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 08/31/01 First release
* 1.00b jhl 02/21/02 Reparitioned the driver for smaller files
* 1.00b rpm 04/24/02 Moved register definitions to xuartlite_l.h and
* updated macro naming convention
* 2.00a ktn 10/20/09 The macros have been renamed to remove _m from
* the name. XUartLite_mClearStats macro is removed and
* XUartLite_ClearStats function should be used in its place.
* 3.6 rna 02/19/21 Added 'XUartLite_GetSR' internal API.
* </pre>
*
*****************************************************************************/
#ifndef XUARTLITE_I_H /* prevent circular inclusions */
#define XUARTLITE_I_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xuartlite.h"
#include "xuartlite_l.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/****************************************************************************
*
* Update the statistics of the instance.
*
* @param InstancePtr is a pointer to the XUartLite instance.
* @param StatusRegister contains the contents of the UART status
* register to update the statistics with.
*
* @return None.
*
* @note
*
* Signature: void XUartLite_UpdateStats(XUartLite *InstancePtr,
* u32 StatusRegister)
*
*****************************************************************************/
#define XUartLite_UpdateStats(InstancePtr, StatusRegister) \
{ \
if ((StatusRegister) & XUL_SR_OVERRUN_ERROR) \
{ \
(InstancePtr)->Stats.ReceiveOverrunErrors++; \
} \
if ((StatusRegister) & XUL_SR_PARITY_ERROR) \
{ \
(InstancePtr)->Stats.ReceiveParityErrors++; \
} \
if ((StatusRegister) & XUL_SR_FRAMING_ERROR) \
{ \
(InstancePtr)->Stats.ReceiveFramingErrors++; \
} \
}
/************************** Variable Definitions ****************************/
/* the configuration table */
extern XUartLite_Config XUartLite_ConfigTable[];
/************************** Function Prototypes *****************************/
unsigned int XUartLite_SendBuffer(XUartLite *InstancePtr);
unsigned int XUartLite_ReceiveBuffer(XUartLite *InstancePtr);
u8 XUartLite_GetSR(XUartLite *InstancePtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View File

@@ -0,0 +1,310 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite_intr.c
* @addtogroup uartlite_v3_7
* @{
*
* This file contains interrupt-related functions for the UART Lite component
* (XUartLite).
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 08/31/01 First release
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
* 1.02a rpm 02/14/07 Added check for outstanding transmission before
* calling the send callback (avoids extraneous
* callback invocations)
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. The macros have been
* renamed to remove _m from the name.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xuartlite.h"
#include "xuartlite_i.h"
#include "xil_io.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Function Prototypes *****************************/
static void ReceiveDataHandler(XUartLite *InstancePtr);
static void SendDataHandler(XUartLite *InstancePtr);
/************************** Variable Definitions ****************************/
typedef void (*Handler)(XUartLite *InstancePtr);
/****************************************************************************/
/**
*
* This function sets the handler that will be called when an event (interrupt)
* occurs in the driver. The purpose of the handler is to allow application
* specific processing to be performed.
*
* @param InstancePtr is a pointer to the XUartLite instance.
* @param FuncPtr is the pointer to the callback function.
* @param CallBackRef is the upper layer callback reference passed back
* when the callback function is invoked.
*
* @return None.
*
* @note There is no assert on the CallBackRef since the driver doesn't
* know what it is (nor should it)
*
*****************************************************************************/
void XUartLite_SetRecvHandler(XUartLite *InstancePtr,
XUartLite_Handler FuncPtr, void *CallBackRef)
{
/*
* Assert validates the input arguments
* CallBackRef not checked, no way to know what is valid
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FuncPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->RecvHandler = FuncPtr;
InstancePtr->RecvCallBackRef = CallBackRef;
}
/****************************************************************************/
/**
*
* This function sets the handler that will be called when an event (interrupt)
* occurs in the driver. The purpose of the handler is to allow application
* specific processing to be performed.
*
* @param InstancePtr is a pointer to the XUartLite instance .
* @param FuncPtr is the pointer to the callback function.
* @param CallBackRef is the upper layer callback reference passed back
* when the callback function is invoked.
*
* @return None.
*
* @note There is no assert on the CallBackRef since the driver doesn't
* know what it is (nor should it)
*
*****************************************************************************/
void XUartLite_SetSendHandler(XUartLite *InstancePtr,
XUartLite_Handler FuncPtr, void *CallBackRef)
{
/*
* Assert validates the input arguments
* CallBackRef not checked, no way to know what is valid
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FuncPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->SendHandler = FuncPtr;
InstancePtr->SendCallBackRef = CallBackRef;
}
/****************************************************************************/
/**
*
* This function is the interrupt handler for the UART lite driver.
* It must be connected to an interrupt system by the user such that it is
* called when an interrupt for any UART lite occurs. This function
* does not save or restore the processor context such that the user must
* ensure this occurs.
*
* @param InstancePtr contains a pointer to the instance of the UART that
* the interrupt is for.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XUartLite_InterruptHandler(XUartLite *InstancePtr)
{
u32 IsrStatus;
Xil_AssertVoid(InstancePtr != NULL);
/*
* Read the status register to determine which, coulb be both
* interrupt is active
*/
IsrStatus = XUartLite_GetSR(InstancePtr);
if ((IsrStatus & (XUL_SR_RX_FIFO_FULL |
XUL_SR_RX_FIFO_VALID_DATA)) != 0) {
ReceiveDataHandler(InstancePtr);
}
if (((IsrStatus & XUL_SR_TX_FIFO_EMPTY) != 0) &&
(InstancePtr->SendBuffer.RequestedBytes > 0)) {
SendDataHandler(InstancePtr);
}
}
/****************************************************************************/
/**
*
* This function handles the interrupt when data is received, either a single
* byte when FIFOs are not enabled, or multiple bytes with the FIFO.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
static void ReceiveDataHandler(XUartLite *InstancePtr)
{
/*
* If there are bytes still to be received in the specified buffer
* go ahead and receive them
*/
if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) {
XUartLite_ReceiveBuffer(InstancePtr);
} else {
return;
}
/*
* If the last byte of a message was received then call the application
* handler, this code should not use an else from the previous check of
* the number of bytes to receive because the call to receive the buffer
* updates the bytes to receive
*/
if (InstancePtr->ReceiveBuffer.RemainingBytes == 0) {
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef,
InstancePtr->ReceiveBuffer.RequestedBytes -
InstancePtr->ReceiveBuffer.RemainingBytes);
}
/*
* Update the receive stats to reflect the receive interrupt
*/
InstancePtr->Stats.ReceiveInterrupts++;
}
/****************************************************************************/
/**
*
* This function handles the interrupt when data has been sent, the transmit
* FIFO is empty (transmitter holding register).
*
* @param InstancePtr is a pointer to the XUartLite instance .
*
* @return None.
*
* @note None.
*
*****************************************************************************/
static void SendDataHandler(XUartLite *InstancePtr)
{
/*
* If there are not bytes to be sent from the specified buffer,
* call the callback function
*/
if (InstancePtr->SendBuffer.RemainingBytes == 0) {
int SaveReq;
/*
* Save and zero the requested bytes since transmission
* is complete
*/
SaveReq = InstancePtr->SendBuffer.RequestedBytes;
InstancePtr->SendBuffer.RequestedBytes = 0;
/*
* Call the application handler to indicate
* the data has been sent
*/
InstancePtr->SendHandler(InstancePtr->SendCallBackRef, SaveReq);
}
/*
* Otherwise there is still more data to send in the specified buffer
* so go ahead and send it
*/
else {
XUartLite_SendBuffer(InstancePtr);
}
/*
* Update the transmit stats to reflect the transmit interrupt
*/
InstancePtr->Stats.TransmitInterrupts++;
}
/*****************************************************************************/
/**
*
* This function disables the UART interrupt. After calling this function,
* data may still be received by the UART but no interrupt will be generated
* since the hardware device has no way to disable the receiver.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XUartLite_DisableInterrupt(XUartLite *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Write to the control register to disable the interrupts, the only
* other bits in this register are the FIFO reset bits such that
* writing them to zero will not affect them.
*/
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, 0);
}
/*****************************************************************************/
/**
*
* This function enables the UART interrupt such that an interrupt will occur
* when data is received or data has been transmitted. The device contains
* 16 byte receive and transmit FIFOs such that an interrupt is generated
* anytime there is data in the receive FIFO and when the transmit FIFO
* transitions from not empty to empty.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XUartLite_EnableInterrupt(XUartLite *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Write to the control register to enable the interrupts, the only
* other bits in this register are the FIFO reset bits such that
* writing them to zero will not affect them.
*/
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
XUL_CONTROL_REG_OFFSET, XUL_CR_ENABLE_INTR);
}
/** @} */

View File

@@ -0,0 +1,95 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite_l.c
* @addtogroup uartlite_v3_7
* @{
*
* This file contains low-level driver functions that can be used to access the
* device. The user should refer to the hardware device specification for more
* details of the device operation.
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00b rpm 04/25/02 First release
* 1.12a rpm 07/16/07 Fixed arg type for RecvByte
* 2.00a ktn 10/20/09 The macros have been renamed to remove _m from the name.
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
* Changed the prototypes of XUartLite_SendByte,
* XUartLite_RecvByte APIs.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xuartlite_l.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Prototypes ******************************/
/****************************************************************************/
/**
*
* This functions sends a single byte using the UART. It is blocking in that it
* waits for the transmitter to become non-full before it writes the byte to
* the transmit register.
*
* @param BaseAddress is the base address of the device
* @param Data is the byte of data to send
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XUartLite_SendByte(UINTPTR BaseAddress, u8 Data)
{
while (XUartLite_IsTransmitFull(BaseAddress));
XUartLite_WriteReg(BaseAddress, XUL_TX_FIFO_OFFSET, Data);
}
/****************************************************************************/
/**
*
* This functions receives a single byte using the UART. It is blocking in that
* it waits for the receiver to become non-empty before it reads from the
* receive register.
*
* @param BaseAddress is the base address of the device
*
* @return The byte of data received.
*
* @note None.
*
******************************************************************************/
u8 XUartLite_RecvByte(UINTPTR BaseAddress)
{
while (XUartLite_IsReceiveEmpty(BaseAddress));
return (u8)XUartLite_ReadReg(BaseAddress, XUL_RX_FIFO_OFFSET);
}
/** @} */

310
mbv/hal/uart/xuartlite_l.h Normal file
View File

@@ -0,0 +1,310 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite_l.h
* @addtogroup uartlite_v3_7
* @{
*
* This header file contains identifiers and low-level driver functions (or
* macros) that can be used to access the device. High-level driver functions
* are defined in xuartlite.h.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00b rpm 04/25/02 First release
* 1.00b rpm 07/07/03 Removed references to XUartLite_GetControlReg macro
* since the control register is write-only
* 1.12a mta 03/21/07 Updated to new coding style
* 1.13a sv 01/21/08 Updated driver to support access through DCR bus
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. The macros have been
* renamed to remove _m from the name.
* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
* Changed the prototypes of XUartLite_SendByte,
* XUartLite_RecvByte APIs.
* </pre>
*
*****************************************************************************/
#ifndef XUARTLITE_L_H /* prevent circular inclusions */
#define XUARTLITE_L_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/*
* XPAR_XUARTLITE_USE_DCR_BRIDGE has to be set to 1 if the UartLite device is
* accessed through a DCR bus connected to a bridge.
*/
#define XPAR_XUARTLITE_USE_DCR_BRIDGE 0
#if (XPAR_XUARTLITE_USE_DCR_BRIDGE != 0)
#include "xio_dcr.h"
#endif
/************************** Constant Definitions ****************************/
/* UART Lite register offsets */
#if (XPAR_XUARTLITE_USE_DCR_BRIDGE != 0)
#define XUL_RX_FIFO_OFFSET 0 /* receive FIFO, read only */
#define XUL_TX_FIFO_OFFSET 1 /* transmit FIFO, write only */
#define XUL_STATUS_REG_OFFSET 2 /* status register, read only */
#define XUL_CONTROL_REG_OFFSET 3 /* control reg, write only */
#else
#define XUL_RX_FIFO_OFFSET 0 /* receive FIFO, read only */
#define XUL_TX_FIFO_OFFSET 4 /* transmit FIFO, write only */
#define XUL_STATUS_REG_OFFSET 8 /* status register, read only */
#define XUL_CONTROL_REG_OFFSET 12 /* control reg, write only */
#endif
/* Control Register bit positions */
#define XUL_CR_ENABLE_INTR 0x10 /* enable interrupt */
#define XUL_CR_FIFO_RX_RESET 0x02 /* reset receive FIFO */
#define XUL_CR_FIFO_TX_RESET 0x01 /* reset transmit FIFO */
/* Status Register bit positions */
#define XUL_SR_PARITY_ERROR 0x80
#define XUL_SR_FRAMING_ERROR 0x40
#define XUL_SR_OVERRUN_ERROR 0x20
#define XUL_SR_INTR_ENABLED 0x10 /* interrupt enabled */
#define XUL_SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
#define XUL_SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */
#define XUL_SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
#define XUL_SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */
/* The following constant specifies the size of the Transmit/Receive FIFOs.
* The FIFO size is fixed to 16 in the Uartlite IP and the size is not
* configurable. This constant is not used in the driver.
*/
#define XUL_FIFO_SIZE 16
/* Stop bits are fixed at 1. Baud, parity, and data bits are fixed on a
* per instance basis
*/
#define XUL_STOP_BITS 1
/* Parity definitions
*/
#define XUL_PARITY_NONE 0
#define XUL_PARITY_ODD 1
#define XUL_PARITY_EVEN 2
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/*
* Define the appropriate I/O access method to memory mapped I/O or DCR.
*/
#if (XPAR_XUARTLITE_USE_DCR_BRIDGE != 0)
#define XUartLite_In32 XIo_DcrIn
#define XUartLite_Out32 XIo_DcrOut
#else
#define XUartLite_In32 Xil_In32
#define XUartLite_Out32 Xil_Out32
#endif
/****************************************************************************/
/**
*
* Write a value to a UartLite register. A 32 bit write is performed.
*
* @param BaseAddress is the base address of the UartLite device.
* @param RegOffset is the register offset from the base to write to.
* @param Data is the data written to the register.
*
* @return None.
*
* @note C-style signature:
* void XUartLite_WriteReg(u32 BaseAddress, u32 RegOffset,
* u32 Data)
*
****************************************************************************/
#define XUartLite_WriteReg(BaseAddress, RegOffset, Data) \
XUartLite_Out32((BaseAddress) + (RegOffset), (u32)(Data))
/****************************************************************************/
/**
*
* Read a value from a UartLite register. A 32 bit read is performed.
*
* @param BaseAddress is the base address of the UartLite device.
* @param RegOffset is the register offset from the base to read from.
*
* @return Data read from the register.
*
* @note C-style signature:
* u32 XUartLite_ReadReg(u32 BaseAddress, u32 RegOffset)
*
****************************************************************************/
#define XUartLite_ReadReg(BaseAddress, RegOffset) \
XUartLite_In32((BaseAddress) + (RegOffset))
/****************************************************************************/
/**
*
* Set the contents of the control register. Use the XUL_CR_* constants defined
* above to create the bit-mask to be written to the register.
*
* @param BaseAddress is the base address of the device
* @param Mask is the 32-bit value to write to the control register
*
* @return None.
*
* @note C-style Signature:
* void XUartLite_SetControlReg(u32 BaseAddress, u32 Mask);
*
*****************************************************************************/
#define XUartLite_SetControlReg(BaseAddress, Mask) \
XUartLite_WriteReg((BaseAddress), XUL_CONTROL_REG_OFFSET, (Mask))
/****************************************************************************/
/**
*
* Get the contents of the status register. Use the XUL_SR_* constants defined
* above to interpret the bit-mask returned.
*
* @param BaseAddress is the base address of the device
*
* @return A 32-bit value representing the contents of the status register.
*
* @note C-style Signature:
* u32 XUartLite_GetStatusReg(u32 BaseAddress);
*
*****************************************************************************/
#define XUartLite_GetStatusReg(BaseAddress) \
XUartLite_ReadReg((BaseAddress), XUL_STATUS_REG_OFFSET)
/****************************************************************************/
/**
*
* Check to see if the receiver has data.
*
* @param BaseAddress is the base address of the device
*
* @return TRUE if the receiver is empty, FALSE if there is data present.
*
* @note C-style Signature:
* int XUartLite_IsReceiveEmpty(u32 BaseAddress);
*
*****************************************************************************/
#define XUartLite_IsReceiveEmpty(BaseAddress) \
((XUartLite_GetStatusReg((BaseAddress)) & XUL_SR_RX_FIFO_VALID_DATA) != \
XUL_SR_RX_FIFO_VALID_DATA)
/****************************************************************************/
/**
*
* Check to see if the transmitter is full.
*
* @param BaseAddress is the base address of the device
*
* @return TRUE if the transmitter is full, FALSE otherwise.
*
* @note C-style Signature:
* int XUartLite_IsTransmitFull(u32 BaseAddress);
*
*****************************************************************************/
#define XUartLite_IsTransmitFull(BaseAddress) \
((XUartLite_GetStatusReg((BaseAddress)) & XUL_SR_TX_FIFO_FULL) == \
XUL_SR_TX_FIFO_FULL)
/****************************************************************************/
/**
*
* Check to see if the interrupt is enabled.
*
* @param BaseAddress is the base address of the device
*
* @return TRUE if the interrupt is enabled, FALSE otherwise.
*
* @note C-style Signature:
* int XUartLite_IsIntrEnabled(u32 BaseAddress);
*
*****************************************************************************/
#define XUartLite_IsIntrEnabled(BaseAddress) \
((XUartLite_GetStatusReg((BaseAddress)) & XUL_SR_INTR_ENABLED) == \
XUL_SR_INTR_ENABLED)
/****************************************************************************/
/**
*
* Enable the device interrupt. We cannot read the control register, so we
* just write the enable interrupt bit and clear all others. Since the only
* other ones are the FIFO reset bits, this works without side effects.
*
* @param BaseAddress is the base address of the device
*
* @return None.
*
* @note C-style Signature:
* void XUartLite_EnableIntr(u32 BaseAddress);
*
*****************************************************************************/
#define XUartLite_EnableIntr(BaseAddress) \
XUartLite_SetControlReg((BaseAddress), XUL_CR_ENABLE_INTR)
/****************************************************************************/
/**
*
* Disable the device interrupt. We cannot read the control register, so we
* just clear all bits. Since the only other ones are the FIFO reset bits,
* this works without side effects.
*
* @param BaseAddress is the base address of the device
*
* @return None.
*
* @note C-style Signature:
* void XUartLite_DisableIntr(u32 BaseAddress);
*
*****************************************************************************/
#define XUartLite_DisableIntr(BaseAddress) \
XUartLite_SetControlReg((BaseAddress), 0)
/************************** Function Prototypes *****************************/
void XUartLite_SendByte(UINTPTR BaseAddress, u8 Data);
u8 XUartLite_RecvByte(UINTPTR BaseAddress);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View File

@@ -0,0 +1,114 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite_selftest.c
* @addtogroup uartlite_v3_7
* @{
*
* This file contains the self-test functions for the UART Lite component
* (XUartLite).
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 08/31/01 First release
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. The macros have been
* renamed to remove _m from the name.
* 3.0 adk 17/12/13 Fixed CR:741186,761863 Reset the FIFO's before reading
* the status register We don't know the status of the Status
* Register in case of if there is more than one uartlite IP
* instance in the h/w design.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xuartlite.h"
#include "xuartlite_i.h"
#include "xil_io.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/****************************************************************************/
/**
*
* Runs a self-test on the device hardware. Since there is no way to perform a
* loopback in the hardware, this test can only check the state of the status
* register to verify it is correct. This test assumes that the hardware
* device is still in its reset state, but has been initialized with the
* Initialize function.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return
* - XST_SUCCESS if the self-test was successful.
* - XST_FAILURE if the self-test failed, the status register
* value was not correct
*
* @note None.
*
******************************************************************************/
int XUartLite_SelfTest(XUartLite *InstancePtr)
{
u32 StatusRegister;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Reset the FIFO's before reading the status register.
* It is likely that the Uartlite IP may not always have an
* empty Tx and Rx FIFO when a selftest is performed if more than one
* uartlite instance is present in the h/w design.
*/
XUartLite_ResetFifos(InstancePtr);
/*
* Read the Status register value to check if it is the correct value
* after a reset
*/
StatusRegister = XUartLite_ReadReg(InstancePtr->RegBaseAddress,
XUL_STATUS_REG_OFFSET);
/*
* If the status register is any other value other than
* XUL_SR_TX_FIFO_EMPTY then the test is a failure since this is
* the not the value after reset
*/
if (StatusRegister != XUL_SR_TX_FIFO_EMPTY) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/** @} */

View File

@@ -0,0 +1,122 @@
/******************************************************************************
* Copyright (C) 2005 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite_sinit.c
* @addtogroup uartlite_v3_7
* @{
*
* The implementation of the XUartLite component's static initialization
* functionality.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.01a jvb 10/13/05 First release
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xstatus.h"
#include "xparameters.h"
#include "xuartlite_i.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/****************************************************************************
*
* Looks up the device configuration based on the unique device ID. The table
* UartliteConfigTable contains the configuration info for each device in the
* system.
*
* @param DeviceId is the unique device ID to match on.
*
* @return A pointer to the configuration data for the device, or
* NULL if no match was found.
*
* @note None.
*
******************************************************************************/
XUartLite_Config *XUartLite_LookupConfig(u16 DeviceId)
{
XUartLite_Config *CfgPtr = NULL;
u32 Index;
for (Index=0; Index < XPAR_XUARTLITE_NUM_INSTANCES; Index++) {
if (XUartLite_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XUartLite_ConfigTable[Index];
break;
}
}
return CfgPtr;
}
/****************************************************************************/
/**
*
* Initialize a XUartLite instance. The receive and transmit FIFOs of the
* UART are not flushed, so the user may want to flush them. The hardware
* device does not have any way to disable the receiver such that any valid
* data may be present in the receive FIFO. This function disables the UART
* interrupt. The baudrate and format of the data are fixed in the hardware
* at hardware build time.
*
* @param InstancePtr is a pointer to the XUartLite instance.
* @param DeviceId is the unique id of the device controlled by this
* XUartLite instance. Passing in a device id associates the
* generic XUartLite instance to a specific device, as chosen by
* the caller or application developer.
*
* @return
* - XST_SUCCESS if everything starts up as expected.
* - XST_DEVICE_NOT_FOUND if the device is not found in the
* configuration table.
*
* @note None.
*
*****************************************************************************/
int XUartLite_Initialize(XUartLite *InstancePtr, u16 DeviceId)
{
XUartLite_Config *ConfigPtr;
/*
* Assert validates the input arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Lookup the device configuration in the configuration table. Use this
* configuration info when initializing this component.
*/
ConfigPtr = XUartLite_LookupConfig(DeviceId);
if (ConfigPtr == (XUartLite_Config *)NULL) {
return XST_DEVICE_NOT_FOUND;
}
return XUartLite_CfgInitialize(InstancePtr, ConfigPtr,
ConfigPtr->RegBaseAddr);
}
/** @} */

View File

@@ -0,0 +1,118 @@
/******************************************************************************
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
*
* @file xuartlite_stats.c
* @addtogroup uartlite_v3_7
* @{
*
* This file contains the statistics functions for the UART Lite component
* (XUartLite).
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 08/31/01 First release
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs.
* XUartLite_mClearStats macro is removed.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xuartlite.h"
#include "xuartlite_i.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/****************************************************************************/
/**
*
* Returns a snapshot of the current statistics in the structure specified.
*
* @param InstancePtr is a pointer to the XUartLite instance.
* @param StatsPtr is a pointer to a XUartLiteStats structure to where the
* statistics are to be copied.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XUartLite_GetStats(XUartLite *InstancePtr, XUartLite_Stats *StatsPtr)
{
/*
* Assert validates the input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(StatsPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/* Copy the stats from the instance to the specified stats */
StatsPtr->TransmitInterrupts = InstancePtr->Stats.TransmitInterrupts;
StatsPtr->ReceiveInterrupts = InstancePtr->Stats.ReceiveInterrupts;
StatsPtr->CharactersTransmitted =
InstancePtr->Stats.CharactersTransmitted;
StatsPtr->CharactersReceived = InstancePtr->Stats.CharactersReceived;
StatsPtr->ReceiveOverrunErrors =
InstancePtr->Stats.ReceiveOverrunErrors;
StatsPtr->ReceiveFramingErrors =
InstancePtr->Stats.ReceiveFramingErrors;
StatsPtr->ReceiveParityErrors = InstancePtr->Stats.ReceiveParityErrors;
}
/****************************************************************************/
/**
*
* This function zeros the statistics for the given instance.
*
* @param InstancePtr is a pointer to the XUartLite instance.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XUartLite_ClearStats(XUartLite *InstancePtr)
{
/*
* Assert validates the input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->Stats.TransmitInterrupts = 0;
InstancePtr->Stats.ReceiveInterrupts = 0;
InstancePtr->Stats.CharactersTransmitted = 0;
InstancePtr->Stats.CharactersReceived = 0;
InstancePtr->Stats.ReceiveOverrunErrors = 0;
InstancePtr->Stats.ReceiveFramingErrors = 0;
InstancePtr->Stats.ReceiveParityErrors = 0;
}
/** @} */

View File

@@ -0,0 +1,128 @@
/******************************************************************************
* Copyright (c) 2020 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_clocking.c
*
* The xil_clocking.c file contains clocking related functions and macros.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 7.2 sd 02/06/20 First release of clocking
* 7.2 sd 03/20/20 Added checking for isolation case
* </pre>
*
******************************************************************************/
#include "xil_clocking.h"
/************************** Variable Definitions *****************************/
#if defined (XPAR_XCRPSU_0_DEVICE_ID) && defined (XCLOCKING)
XClock ClockInstance; /* Instance of clock Controller */
XClockPs_Config *ConfigPtr;
XStatus Xil_ClockInit(void)
{
XStatus Status = XST_FAILURE;
/* Lookup clock configurations */
ConfigPtr = XClock_LookupConfig(XPAR_XCLOCKPS_DEVICE_ID);
/* Initialize the Clock controller driver */
Status = XClock_CfgInitialize(&ClockInstance, ConfigPtr);
return Status;
}
XStatus Xil_ClockEnable(XClock_OutputClks ClockId)
{
XStatus Status = XST_FAILURE;
Status = XClock_EnableClock(ClockId);
return Status;
}
XStatus Xil_ClockDisable(XClock_OutputClks ClockId)
{
XStatus Status = XST_FAILURE;
Status = XClock_DisableClock(ClockId);
return Status;
}
XStatus Xil_ClockGetRate(XClock_OutputClks ClockId, XClockRate *Rate)
{
XStatus Status = XST_FAILURE;
Xil_AssertNonvoid(Rate != NULL);
Status = XClock_GetRate(ClockId, Rate);
if (XST_SUCCESS == Status) {
xdbg_printf(XDBG_DEBUG_GENERAL, "Operating rate = %lx\n",*Rate);
} else {
xdbg_printf(XDBG_DEBUG_ERROR, "Failed: Fetching rate\r\n");
}
return Status;
}
XStatus Xil_ClockSetRate(XClock_OutputClks ClockId, XClockRate Rate,
XClockRate *SetRate)
{
XStatus Status = XST_FAILURE;
Xil_AssertNonvoid(SetRate != NULL);
if (Rate == 0) {
return XST_FAILURE;
}
Status = XClock_SetRate(ClockId, Rate, SetRate);
if (XST_SUCCESS != Status) {
xdbg_printf(XDBG_DEBUG_ERROR, "Failed Setting rate\n");
}
return Status;
}
#else
XStatus Xil_ClockGetRate(XClock_OutputClks ClockId, XClockRate *Rate)
{
(void) ClockId;
(void) Rate;
return XST_FAILURE;
}
XStatus Xil_ClockSetRate(XClock_OutputClks ClockId, XClockRate Rate,
XClockRate *SetRate) {
(void) ClockId;
(void) Rate;
(void) SetRate;
return XST_FAILURE;
}
XStatus Xil_ClockInit(void)
{
return XST_SUCCESS;
}
XStatus Xil_ClockEnable(XClock_OutputClks ClockId)
{
(void) ClockId;
return XST_SUCCESS;
}
XStatus Xil_ClockDisable(XClock_OutputClks ClockId)
{
(void) ClockId;
return XST_SUCCESS;
}
#endif /* XCLOCKING */

View File

@@ -0,0 +1,65 @@
/******************************************************************************
* Copyright (c) 2020 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_clocking.h
*
* The xil_clocking.h file contains clocking related functions and macros.
* certain conditions.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 7.2 sd 12/11/19 First release
* 7.2 sd 03/20/20 Added checking for isolation case
* 7.7 sk 01/10/22 Add function prototype for Xil_ClockGetRate to fix
* misra_c_2012_rule_8_4 violation.
* </pre>
*
******************************************************************************/
#ifndef XIL_CLOCKING_H /* prevent circular inclusions */
#define XIL_CLOCKING_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
#include "xdebug.h"
#include "xil_printf.h"
#include "xil_types.h"
#include "xil_assert.h"
#include "xparameters.h"
#include "xstatus.h"
#if defined (XPAR_XCRPSU_0_DEVICE_ID)
#include "xclockps.h"
#else
typedef u32 XClock_OutputClks;
typedef u64 XClockRate;
#endif
/***************************** Include Files *********************************/
/************************** Constant Definitions *****************************/
XStatus Xil_ClockDisable(XClock_OutputClks ClockId);
XStatus Xil_ClockEnable(XClock_OutputClks ClockId);
XStatus Xil_ClockInit(void);
XStatus Xil_ClockGet(void);
XStatus Xil_ClockSetRate(XClock_OutputClks ClockId, XClockRate Rate, XClockRate *SetRate);
XStatus Xil_ClockGetRate(XClock_OutputClks ClockId, XClockRate *Rate);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View File

@@ -0,0 +1,446 @@
/******************************************************************************
* Copyright (c) 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xinterrupt_wrap.c
*
* The xinterrupt_wrap.c file contains interrupt related functions and macros.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 7.2 mus 22/11/21 First release of xil interrupt support
* </pre>
*
******************************************************************************/
#include "xinterrupt_wrap.h"
#ifdef XIL_INTERRUPT
#if defined (XPAR_SCUGIC) /* available in xscugic.h */
XScuGic XScuGicInstance;
#endif
#if defined (XPAR_AXI_INTC) /* available in xintc.h */
XIntc XIntcInstance ;
#endif
/*****************************************************************************/
/**
*
* @brief Initializes the interrupt controller.
*
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return XST_SUCCESS if initialization was successful
* XST_FAILURE in case of failure
*
* @note None.
*
******************************************************************************/
int XConfigInterruptCntrl(UINTPTR IntcParent) {
int Status = XST_FAILURE;
UINTPTR BaseAddr = XGet_BaseAddr(IntcParent);
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
#if defined (XPAR_SCUGIC)
XScuGic_Config *CfgPtr = NULL;
if (XScuGicInstance.IsReady != XIL_COMPONENT_IS_READY) {
CfgPtr = XScuGic_LookupConfigBaseAddr(BaseAddr);
Status = XScuGic_CfgInitialize(&XScuGicInstance, CfgPtr, 0);
} else {
Status = XST_SUCCESS;
}
return Status;
#else
return XST_FAILURE;
#endif
} else {
#if defined (XPAR_AXI_INTC)
if (XIntcInstance.IsStarted != XIL_COMPONENT_IS_STARTED)
Status = XIntc_Initialize(&XIntcInstance, BaseAddr);
else
Status = XST_SUCCESS;
return Status;
#else
return XST_FAILURE;
#endif
}
}
/*****************************************************************************/
/**
*
* @brief connects to the interrupt controller.
*
* @param IntrId: Interrupt Id.
* @param IntrHandler: Interrupt handler.
* @param CallBackRef: Callback reference for handler.
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return XST_SUCCESS if initialization was successful
* XST_FAILURE in case of failure
*
* @note None.
*
******************************************************************************/
int XConnectToInterruptCntrl(u32 IntrId, void *IntrHandler, void *CallBackRef, UINTPTR IntcParent)
{
int Status;
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
#if defined (XPAR_SCUGIC)
u16 IntrNum = XGet_IntrId(IntrId);
u16 Offset = XGet_IntrOffset(IntrId);
IntrNum += Offset;
Status = XScuGic_Connect(&XScuGicInstance, IntrNum, \
(Xil_ExceptionHandler) IntrHandler, CallBackRef);
return Status;
#else
return XST_FAILURE;
#endif
} else {
#if defined (XPAR_AXI_INTC)
Status = XIntc_Connect(&XIntcInstance, IntrId, \
(XInterruptHandler)IntrHandler, CallBackRef);
return Status;
#else
return XST_FAILURE;
#endif
}
}
/*****************************************************************************/
/**
*
* @brief disconnects the interrupt controller.
*
* @param IntrId: Interrupt Id.
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return XST_SUCCESS if initialization was successful
* XST_FAILURE in case of failure
*
* @note None.
*
******************************************************************************/
int XDisconnectInterruptCntrl(u32 IntrId, UINTPTR IntcParent)
{
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) {
#if defined (XPAR_SCUGIC)
u16 IntrNum = XGet_IntrId(IntrId);
u16 Offset = XGet_IntrOffset(IntrId);
IntrNum += Offset;
XScuGic_Disconnect(&XScuGicInstance, IntrNum);
#else
return XST_FAILURE;
#endif
} else {
#if defined (XPAR_AXI_INTC)
XIntc_Disconnect(&XIntcInstance, IntrId);
#else
return XST_FAILURE;
#endif
}
return XST_FAILURE;
}
/*****************************************************************************/
/**
*
* @brief Starts the interrupt controller.
*
* @param Mode: Interrupt controller mode type.
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return XST_SUCCESS if initialization was successful
* XST_FAILURE in case of failure
*
* @note None.
*
******************************************************************************/
int XStartInterruptCntrl(u32 Mode, UINTPTR IntcParent)
{
#if defined (XPAR_AXI_INTC)
int Status = XST_FAILURE;
#else
(void) Mode;
#endif
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
/*
* For XPAR_SCUGIC, XConfigInterruptCntrl starts controller
* hence returning without doing anything
*/
return 0;
} else {
#if defined (XPAR_AXI_INTC)
if (XIntcInstance.IsStarted != XIL_COMPONENT_IS_STARTED)
Status = XIntc_Start(&XIntcInstance, Mode);
else
Status = XST_SUCCESS;
return Status;
#else
return XST_FAILURE;
#endif
}
}
/*****************************************************************************/
/**
*
* @brief Enable the interrupt id.
*
* @param IntrId: Interrupt Id.
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XEnableIntrId( u32 IntrId, UINTPTR IntcParent)
{
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
#if defined (XPAR_SCUGIC)
u16 IntrNum = XGet_IntrId(IntrId);
u16 Offset = XGet_IntrOffset(IntrId);
IntrNum += Offset;
XScuGic_Enable(&XScuGicInstance, IntrNum);
#endif
} else {
#if defined (XPAR_AXI_INTC)
XIntc_Enable(&XIntcInstance, IntrId);
#endif
}
}
/*****************************************************************************/
/**
*
* @brief disable the interrupt id.
*
* @param IntrId: Interrupt Id.
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XDisableIntrId( u32 IntrId, UINTPTR IntcParent)
{
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
#if defined (XPAR_SCUGIC)
u16 IntrNum = XGet_IntrId(IntrId);
u16 Offset = XGet_IntrOffset(IntrId);
IntrNum += Offset;
XScuGic_Disable(&XScuGicInstance, IntrNum);
#endif
} else {
#if defined (XPAR_AXI_INTC)
XIntc_Disable(&XIntcInstance, IntrId);
#endif
}
}
/*****************************************************************************/
/**
*
* @brief Configures the priority and trigger type.
*
* @param IntrId: Interrupt Id.
* @param Priority: Priority of the interrupt
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XSetPriorityTriggerType( u32 IntrId, u8 Priority, UINTPTR IntcParent)
{
#if defined (XPAR_SCUGIC)
u8 Trigger = (((XGet_TriggerType(IntrId) == 1) || (XGet_TriggerType(IntrId) == 2)) ? XINTR_IS_EDGE_TRIGGERED
: XINTR_IS_LEVEL_TRIGGERED);
#else
(void) Priority;
#endif
u16 IntrNum = XGet_IntrId(IntrId);
u16 Offset = XGet_IntrOffset(IntrId);
IntrNum += Offset;
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
#if defined (XPAR_SCUGIC)
XScuGic_SetPriorityTriggerType(&XScuGicInstance, IntrNum, Priority, Trigger);
#endif
}
}
/*****************************************************************************/
/**
*
* @brief Gets the priority of the interrupt controller.
*
* @param IntrId: Interrupt Id.
* @param Priority: Priority of the interrupt
* @param Trigger: Trigger type of the interrupt
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XGetPriorityTriggerType( u32 IntrId, u8 *Priority, u8 *Trigger, UINTPTR IntcParent)
{
#if !defined (XPAR_SCUGIC)
(void) IntrId;
(void) Priority;
(void) Trigger;
#endif
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
#if defined (XPAR_SCUGIC)
XScuGic_GetPriorityTriggerType(&XScuGicInstance, IntrId, Priority, Trigger);
#endif
}
}
/*****************************************************************************/
/**
*
* @brief stops the interrupt controller.
*
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XStopInterruptCntrl( UINTPTR IntcParent)
{
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
#if defined (XPAR_SCUGIC)
XScuGic_Stop(&XScuGicInstance);
#endif
} else {
#if defined (XPAR_AXI_INTC)
XIntc_Stop(&XIntcInstance);
#endif
}
}
/*****************************************************************************/
/**
*
* @brief Registers the interrupt handler.
*
* @param IntrHandler: Interrupt handler.
* @param IntcParent: Interrupt controller baseaddress and type.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XRegisterInterruptHandler(void *IntrHandler, UINTPTR IntcParent)
{
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
{
#if defined (XPAR_SCUGIC)
if (IntrHandler == NULL)
{
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
&XScuGicInstance);
} else {
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \
(Xil_ExceptionHandler) IntrHandler,
&XScuGicInstance);
}
#endif
} else {
#if defined (XPAR_AXI_INTC)
if (IntrHandler == NULL)
{
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \
(Xil_ExceptionHandler) XIntc_InterruptHandler,
&XIntcInstance);
} else {
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \
(Xil_ExceptionHandler) IntrHandler,
&XIntcInstance);
}
#endif
}
}
/*****************************************************************************/
/**
*
* @brief Setup the interrupt system.
*
* @param DriverInstance: Driver instance pointer.
* @param IntrHandler: Interrupt handler funtion pointer.
* @param IntrId: Interrupt Id.
* @param IntcParent: Interrupt controller baseaddress and type.
* @param Priority: Interrupt priority.
*
* @return XST_SUCCESS if initialization was successful
* XST_FAILURE in case of failure
*
* @note None.
*
******************************************************************************/
int XSetupInterruptSystem(void *DriverInstance, void *IntrHandler, u32 IntrId, UINTPTR IntcParent, u16 Priority)
{
int Status;
Status = XConfigInterruptCntrl(IntcParent);
if (Status != XST_SUCCESS)
return XST_FAILURE;
XSetPriorityTriggerType( IntrId, Priority, IntcParent);
Status = XConnectToInterruptCntrl( IntrId, (Xil_ExceptionHandler) IntrHandler, \
DriverInstance, IntcParent);
if (Status != XST_SUCCESS)
return XST_FAILURE;
#if defined (XPAR_AXI_INTC)
XStartInterruptCntrl(XIN_REAL_MODE, IntcParent);
#endif
XEnableIntrId(IntrId, IntcParent);
XRegisterInterruptHandler(NULL, IntcParent);
Xil_ExceptionInit();
Xil_ExceptionEnable();
return XST_SUCCESS;
}
#endif

View File

@@ -0,0 +1,74 @@
/******************************************************************************
* Copyright (c) 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xinterrupt_wrap.h
*
* The xinterrupt_wrap.h file contains interrupt related functions and macros.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 7.2 mus 22/11/21 First release of xil interrupt support
* </pre>
*
******************************************************************************/
#ifndef XINTERRUPT_WRAP_H /* prevent circular inclusions */
#define XINTERRUPT_WRAP_H /* by using protection macros */
#include "xil_types.h"
#include "xstatus.h"
#include "xparameters.h"
#include "xil_exception.h"
#ifdef XIL_INTERRUPT
#if defined(XPAR_AXI_INTC)
#include "xintc.h"
#endif
#if defined(XPAR_SCUGIC)
#include "xscugic.h"
#define XSPI_INTR_OFFSET 32U
#endif
#define XINTERRUPT_DEFAULT_PRIORITY 0xA0U /* AXI INTC doesnt support priority setting, it is default priority for GIC interrupts */
#define XINTC_TYPE_IS_SCUGIC 0U
#define XINTC_TYPE_IS_INTC 1U
#define XINTR_IS_EDGE_TRIGGERED 3U
#define XINTR_IS_LEVEL_TRIGGERED 1U
#define XINTC_TYPE_MASK 0x1
#define XINTC_INTR_TYPE_MASK 0x100000
#define XINTC_BASEADDR_MASK 0xFFFFFFFFFFFFFFFE
#define XINTC_INTRID_MASK 0xFFF
#define XINTC_TRIGGER_MASK 0xF000
#define XINTC_TRIGGER_SHIFT 12
#define XINTC_INTR_TYPE_SHIFT 20U
#define XGet_IntcType(IntParent) (IntParent & XINTC_TYPE_MASK)
#define XGet_IntrType(IntId) ((IntId & XINTC_INTR_TYPE_MASK) >> XINTC_INTR_TYPE_SHIFT)
#define XGet_BaseAddr(IntParent) (IntParent & XINTC_BASEADDR_MASK)
#define XGet_IntrId(IntId) (IntId & XINTC_INTRID_MASK)
#define XGet_TriggerType(IntId) ((IntId & XINTC_TRIGGER_MASK) >> XINTC_TRIGGER_SHIFT)
#define XGet_IntrOffset(IntId) (( XGet_IntrType(IntId) == 1) ? 16 : 32) /* For PPI offset is 16 and for SPI it is 32 */
extern int XConfigInterruptCntrl(UINTPTR IntcParent);
extern int XConnectToInterruptCntrl(u32 IntrId, void *IntrHandler, void *CallBackRef, UINTPTR IntcParent);
extern int XDisconnectInterruptCntrl(u32 IntrId, UINTPTR IntcParent);
extern int XStartInterruptCntrl(u32 Mode, UINTPTR IntcParent);
extern void XEnableIntrId( u32 IntrId, UINTPTR IntcParent);
extern void XDisableIntrId( u32 IntrId, UINTPTR IntcParent);
extern void XSetPriorityTriggerType( u32 IntrId, u8 Priority, UINTPTR IntcParent);
extern void XGetPriorityTriggerType( u32 IntrId, u8 *Priority, u8 *Trigger, UINTPTR IntcParent);
extern void XStopInterruptCntrl( UINTPTR IntcParent);
extern void XRegisterInterruptHandler( void *IntrHandler, UINTPTR IntcParent);
extern int XSetupInterruptSystem(void *DriverInstance, void *IntrHandler, u32 IntrId, UINTPTR IntcParent, u16 Priority);
#endif
#endif /* end of protection macro */

36
mbv/hal/xilinx/print.c Normal file
View File

@@ -0,0 +1,36 @@
/* print.c -- print a string on the output device.
*
* Copyright (c) 1995 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*
*/
/*
* print -- do a raw print of a string
*/
#include "xil_printf.h"
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
while (*ptr != (char8)0) {
outbyte (*ptr);
ptr++;
}
#else
(void)ptr;
#endif
#endif
}

99
mbv/hal/xilinx/sleep.h Normal file
View File

@@ -0,0 +1,99 @@
/******************************************************************************
* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
* @file sleep.h
*
* This header file contains ARM Cortex A53,A9,R5,Microblaze specific sleep
* related APIs.
*
* <pre>
* MODIFICATION HISTORY :
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 6.6 srm 11/02/17 Added processor specific sleep routines
* function prototypes.
* 7.7 sk 01/10/22 Typecast sleep declaration argument from unsigned int to
* u32 to fix misra_c_2012_directive_4_6 violation.
* 7.7 sk 01/10/22 Modify the return type of sleep_R5 and usleep_R5 from
* unsigned to void to fix misra_c_2012_rule_17_7 violation.
* 7.7 sk 03/02/22 Update usleep_R5 and usleep parameter types to fix misra_
* c_2012_directive_4_6 violation.
*
* </pre>
*
******************************************************************************/
#ifndef SLEEP_H
#define SLEEP_H
#include "xil_types.h"
#include "xil_io.h"
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************/
/**
*
* This macro polls an address periodically until a condition is met or till the
* timeout occurs.
* The minimum timeout for calling this macro is 100us. If the timeout is less
* than 100us, it still waits for 100us. Also the unit for the timeout is 100us.
* If the timeout is not a multiple of 100us, it waits for a timeout of
* the next usec value which is a multiple of 100us.
*
* @param IO_func - accessor function to read the register contents.
* Depends on the register width.
* @param ADDR - Address to be polled
* @param VALUE - variable to read the value
* @param COND - Condition to checked (usually involves VALUE)
* @param TIMEOUT_US - timeout in micro seconds
*
* @return 0 - when the condition is met
* -1 - when the condition is not met till the timeout period
*
* @note none
*
*****************************************************************************/
#define Xil_poll_timeout(IO_func, ADDR, VALUE, COND, TIMEOUT_US) \
( { \
u64 timeout = TIMEOUT_US/100; \
if(TIMEOUT_US%100!=0) \
timeout++; \
for(;;) { \
VALUE = IO_func(ADDR); \
if(COND) \
break; \
else { \
usleep(100); \
timeout--; \
if(timeout==0) \
break; \
} \
} \
(timeout>0) ? 0 : -1; \
} )
void usleep(ULONG useconds);
void sleep(u32 seconds);
void usleep_R5(ULONG useconds);
void sleep_R5(u32 seconds);
int usleep_MB(unsigned long useconds);
unsigned sleep_MB(unsigned int seconds);
int usleep_A53(unsigned long useconds);
unsigned sleep_A53(unsigned int seconds);
int usleep_A9(unsigned long useconds);
unsigned sleep_A9(unsigned int seconds);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,479 @@
/******************************************************************************
* Copyright (c) 2021 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_error_node.h
*
* This is the file which contains node IDs information for error events.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------------
* 7.7 bsv 12/22/2021 Initial release
* ma 01/17/2022 Add PLM exceptions to SW errors list
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XIL_ERROR_NODE_H
#define XIL_ERROR_NODE_H
#ifdef __cplusplus
extern "C" {
#endif
/************************** Constant Definitions *****************************/
/**@name Versal Event Node IDs
* @defgroup xileventnodes Event Node IDs
* @ingroup xilnodeids
* @{
*/
/**
* Error Event Node Ids
*/
#define XIL_NODETYPE_EVENT_ERROR_PMC_ERR1 (0x28100000U)
#define XIL_NODETYPE_EVENT_ERROR_PMC_ERR2 (0x28104000U)
#define XIL_NODETYPE_EVENT_ERROR_PSM_ERR1 (0x28108000U)
#define XIL_NODETYPE_EVENT_ERROR_PSM_ERR2 (0x2810C000U)
#define XIL_NODETYPE_EVENT_ERROR_SW_ERR (0x28110000U)
/**
* @}
*/
/**@name Versal Error event Mask
* @defgroup xilerroreventmask Error Event Mask
* @ingroup xilnodeids
* @{
* @defgroup pmcerr1 Error Event Mask for PMC ERR1
* @ingroup xilerroreventmask
* @{
* @brief Error Events belong to PMC ERR1 Node
*/
/** Error event mask for PMC Boot Correctable Error.
* Set by ROM code during ROM execution during Boot. */
#define XIL_EVENT_ERROR_MASK_BOOT_CR (0x00000001U)
/** Error event mask for PMC Boot Non-Correctable Error.
* Set by ROM code during ROM execution during Boot. */
#define XIL_EVENT_ERROR_MASK_BOOT_NCR (0x00000002U)
/** Error event mask for PMC Firmware Boot Correctable Error.
* Set by PLM during firmware execution during Boot. */
#define XIL_EVENT_ERROR_MASK_FW_CR (0x00000004U)
/** Error event mask for PMC Firmware Boot Non-Correctable Error.
* Set by PLM during firmware execution during Boot. */
#define XIL_EVENT_ERROR_MASK_FW_NCR (0x00000008U)
/** Error event mask for General Software Correctable Error.
* Set by any processors after Boot. */
#define XIL_EVENT_ERROR_MASK_GSW_CR (0x00000010U)
/** Error event mask for General Software Non-Correctable Error.
* Set by any processors after Boot. */
#define XIL_EVENT_ERROR_MASK_GSW_NCR (0x00000020U)
/** Error event mask for CFU Error. */
#define XIL_EVENT_ERROR_MASK_CFU (0x00000040U)
/** Error event mask for CFRAME Error. */
#define XIL_EVENT_ERROR_MASK_CFRAME (0x00000080U)
/** Error event mask for PSM Correctable Error,
* Summary from PSM Error Management. */
#define XIL_EVENT_ERROR_MASK_PMC_PSM_CR (0x00000100U)
/** Error event mask for PSM Non-Correctable Error,
* Summary from PSM Error Management. */
#define XIL_EVENT_ERROR_MASK_PMC_PSM_NCR (0x00000200U)
/** Error event mask for DDRMC MB Correctable ECC Error. */
#define XIL_EVENT_ERROR_MASK_DDRMB_CR (0x00000400U)
/** Error event mask for DDRMC MB Non-Correctable ECC Error. */
#define XIL_EVENT_ERROR_MASK_DDRMB_NCR (0x00000800U)
/** Error event mask for NoC Type1 Correctable Error. */
#define XIL_EVENT_ERROR_MASK_NOCTYPE1_CR (0x00001000U)
/** Error event mask for NoC Type1 Non-Correctable Error. */
#define XIL_EVENT_ERROR_MASK_NOCTYPE1_NCR (0x00002000U)
/** Error event mask for NoC User Error. */
#define XIL_EVENT_ERROR_MASK_NOCUSER (0x00004000U)
/** Error event mask for MMCM Lock Error. */
#define XIL_EVENT_ERROR_MASK_MMCM (0x00008000U)
/** Error event mask for ME Correctable Error. */
#define XIL_EVENT_ERROR_MASK_AIE_CR (0x00010000U)
/** Error event mask for ME Non-Correctable Error. */
#define XIL_EVENT_ERROR_MASK_AIE_NCR (0x00020000U)
/** Error event mask for DDRMC MC Correctable ECC Error. */
#define XIL_EVENT_ERROR_MASK_DDRMC_CR (0x00040000U)
/** Error event mask for DDRMC MC Non-Correctable ECC Error. */
#define XIL_EVENT_ERROR_MASK_DDRMC_NCR (0x00080000U)
/** Error event mask for GT Correctable Error. */
#define XIL_EVENT_ERROR_MASK_GT_CR (0x00100000U)
/** Error event mask for GT Non-Correctable Error. */
#define XIL_EVENT_ERROR_MASK_GT_NCR (0x00200000U)
/** Error event mask for PL Sysmon Correctable Error. */
#define XIL_EVENT_ERROR_MASK_PLSMON_CR (0x00400000U)
/** Error event mask for PL Sysmon Non-Correctable Error. */
#define XIL_EVENT_ERROR_MASK_PLSMON_NCR (0x00800000U)
/** Error event mask for User defined PL generic error. */
#define XIL_EVENT_ERROR_MASK_PL0 (0x01000000U)
/** Error event mask for User defined PL generic error. */
#define XIL_EVENT_ERROR_MASK_PL1 (0x02000000U)
/** Error event mask for User defined PL generic error. */
#define XIL_EVENT_ERROR_MASK_PL2 (0x04000000U)
/** Error event mask for User defined PL generic error. */
#define XIL_EVENT_ERROR_MASK_PL3 (0x08000000U)
/** Error event mask for NPI Root Error. */
#define XIL_EVENT_ERROR_MASK_NPIROOT (0x10000000U)
/** Error event mask for SSIT Error from Slave SLR1,
* Only used in Master SLR. */
#define XIL_EVENT_ERROR_MASK_SSIT3 (0x20000000U)
/** Error event mask for SSIT Error from Slave SLR2,
* Only used in Master SLR. */
#define XIL_EVENT_ERROR_MASK_SSIT4 (0x40000000U)
/** Error event mask for SSIT Error from Slave SLR3,
* Only used in Master SLR. */
#define XIL_EVENT_ERROR_MASK_SSIT5 (0x80000000U)
/**
* @}
*/
/**
* @defgroup pmcerr2 Error Event Mask for PMC ERR2
* @ingroup xilerroreventmask
* @{
* @brief Error Events belong to PMC ERR2 Node
*/
/** Error event mask for General purpose PMC error,
* can be triggered by any of the following peripherals:,
* - PMC Global Regsiters,- PMC Clock & Reset (CRP),- PMC IOU Secure SLCR,
* - PMC IOU SLCR,- BBRAM Controller,- PMC Analog Control Registers,
* - RTC Control Registers. */
#define XIL_EVENT_ERROR_MASK_PMCAPB (0x00000001U)
/** Error event mask for PMC ROM Validation Error. */
#define XIL_EVENT_ERROR_MASK_PMCROM (0x00000002U)
/** Error event mask for PMC PPU0 MB TMR Fatal Error. */
#define XIL_EVENT_ERROR_MASK_MB_FATAL0 (0x00000004U)
/** Error event mask for PMC PPU1 MB TMR Fatal Error. */
#define XIL_EVENT_ERROR_MASK_MB_FATAL1 (0x00000008U)
/** Error event mask for PMC Switch and PMC IOU Parity Errors. */
#define XIL_EVENT_ERROR_MASK_PMCPAR (0x00000010U)
/** Error event mask for PMC Correctable Errors:,
* PPU0 RAM correctable error.,PPU1 instruction RAM correctable error.,
* PPU1 data RAM correctable error. */
#define XIL_EVENT_ERROR_MASK_PMC_CR (0x00000020U)
/** Error event mask for PMC Non-Correctable Errors:
* PPU0 RAM non-correctable error, PPU1 instruction RAM non-correctable error,
* PPU1 data RAM non-correctable error, PRAM non-correctable error. */
#define XIL_EVENT_ERROR_MASK_PMC_NCR (0x00000040U)
/** Error event mask for PMC Temperature Shutdown Alert and Power Supply
* Failure Detection Errors from PMC Sysmon alarm[0].
* Indicates an alarm condition on any of SUPPLY0 to SUPPLY31. */
#define XIL_EVENT_ERROR_MASK_PMCSMON0 (0x00000080U)
/** Error event mask for PMC Temperature Shutdown Alert and Power Supply
* Failure Detection Errors from PMC Sysmon alarm[1].
* Indicates an alarm condition on any of SUPPLY32 to SUPPLY63. */
#define XIL_EVENT_ERROR_MASK_PMCSMON1 (0x00000100U)
/** Error event mask for PMC Temperature Shutdown Alert and Power Supply
* Failure Detection Errors from PMC Sysmon alarm[2].
* Indicates an alarm condition on any of SUPPLY64 to SUPPLY95. */
#define XIL_EVENT_ERROR_MASK_PMCSMON2 (0x00000200U)
/** Error event mask for PMC Temperature Shutdown Alert and Power Supply
* Failure Detection Errors from PMC Sysmon alarm[3].
* Indicates an alarm condition on any of SUPPLY96 to SUPPLY127. */
#define XIL_EVENT_ERROR_MASK_PMCSMON3 (0x00000400U)
/** Error event mask for PMC Temperature Shutdown Alert and Power Supply
* Failure Detection Errors from PMC Sysmon alarm[4].
* Indicates an alarm condition on any of SUPPLY128 to SUPPLY159. */
#define XIL_EVENT_ERROR_MASK_PMCSMON4 (0x00000800U)
/** Error event mask for PMC Temperature Shutdown Alert and Power Supply
* Failure Detection Errors from PMC Sysmon alarm[8].
* Indicates an over-temperature alarm. */
#define XIL_EVENT_ERROR_MASK_PMCSMON8 (0x00008000U)
/** Error event mask for PMC Temperature Shutdown Alert and Power Supply
* Failure Detection Errors from PMC Sysmon alarm[9].
* Indicates a device temperature alarm. */
#define XIL_EVENT_ERROR_MASK_PMCSMON9 (0x00010000U)
/** Error event mask for CFI Non-Correctable Error. */
#define XIL_EVENT_ERROR_MASK_CFI (0x00020000U)
/** Error event mask for CFRAME SEU CRC Error. */
#define XIL_EVENT_ERROR_MASK_SEUCRC (0x00040000U)
/** Error event mask for CFRAME SEU ECC Error. */
#define XIL_EVENT_ERROR_MASK_SEUECC (0x00080000U)
/** Error event mask for RTC Alarm Error. */
#define XIL_EVENT_ERROR_MASK_RTCALARM (0x00400000U)
/** Error event mask for PMC NPLL Lock Error,
* this error can be unmasked after the NPLL is locked to alert when the
* NPLL loses lock. */
#define XIL_EVENT_ERROR_MASK_NPLL (0x00800000U)
/** Error event mask for PMC PPLL Lock Error,
* this error can be unmasked after the PPLL is locked to alert when the
* PPLL loses lock. */
#define XIL_EVENT_ERROR_MASK_PPLL (0x01000000U)
/** Error event mask for Clock Monitor Errors, collected from CRP's
* CLKMON_STATUS register. */
#define XIL_EVENT_ERROR_MASK_CLKMON (0x02000000U)
/** Error event mask for PMC Interconnect Timeout Errors.
* Collected from: Interconnect mission interrupt status register,
* Interconnect latent status register, Timeout interrupt status register
* for SERBs. */
#define XIL_EVENT_ERROR_MASK_PMCTO (0x04000000U)
/** Error event mask for PMC XMPU Errors: Register access error on APB,
* Read permission violation, Write permission violation, Security violation. */
#define XIL_EVENT_ERROR_MASK_PMCXMPU (0x08000000U)
/** Error event mask for PMC XPPU Errors: Register access error on APB,
* Master ID not found, Read permission violation, Master ID parity error,
* Master ID access violation, TrustZone violation, Aperture parity error. */
#define XIL_EVENT_ERROR_MASK_PMCXPPU (0x10000000U)
/** Error event mask for For Master SLR: SSIT Error from Slave SLR1,
* For Slave SLRs: SSIT Error0 from Master SLR. */
#define XIL_EVENT_ERROR_MASK_SSIT0 (0x20000000U)
/** Error event mask for For Master SLR: SSIT Error from Slave SLR2,
* For Slave SLRs: SSIT Error1 from Master SLR. */
#define XIL_EVENT_ERROR_MASK_SSIT1 (0x40000000U)
/** Error event mask for For Master SLR: SSIT Error from Slave SLR3,
* For Slave SLRs: SSIT Error2 from Master SLR. */
#define XIL_EVENT_ERROR_MASK_SSIT2 (0x80000000U)
/**
* @}
*/
/**
* @defgroup psmerr1 Error Event Mask for PSM ERR1
* @ingroup xilerroreventmask
* @{
* @brief Error Events belong to PSM ERR1 Node
*/
/** Error event mask for PS Software can write to trigger register to
* generate this Correctable Error. */
#define XIL_EVENT_ERROR_MASK_PS_SW_CR (0x00000001U)
/** Error event mask for PS Software can write to trigger register to
* generate this Non-Correctable Error. */
#define XIL_EVENT_ERROR_MASK_PS_SW_NCR (0x00000002U)
/** Error event mask for PSM Firmware can write to trigger register to
* generate this Correctable Error. */
#define XIL_EVENT_ERROR_MASK_PSM_B_CR (0x00000004U)
/** Error event mask for PSM Firmware can write to trigger register to
* generate this Non-Correctable Error. */
#define XIL_EVENT_ERROR_MASK_PSM_B_NCR (0x00000008U)
/** Error event mask for Or of MB Fatal1, Fatal2, Fatal3 Error. */
#define XIL_EVENT_ERROR_MASK_MB_FATAL (0x00000010U)
/** Error event mask for PSM Correctable. */
#define XIL_EVENT_ERROR_MASK_PSM_CR (0x00000020U)
/** Error event mask for PSM Non-Correctable. */
#define XIL_EVENT_ERROR_MASK_PSM_NCR (0x00000040U)
/** Error event mask for Non-Correctable ECC Error during an OCM access. */
#define XIL_EVENT_ERROR_MASK_OCM_ECC (0x00000080U)
/** Error event mask for Non-Correctable ECC Error during APU L2 Cache access. */
#define XIL_EVENT_ERROR_MASK_L2_ECC (0x00000100U)
/** Error event mask for ECC Errors during a RPU memory access.
* Floating-point operation exceptions. RPU REG APB error. */
#define XIL_EVENT_ERROR_MASK_RPU_ECC (0x00000200U)
/** Error event mask for RPU Lockstep Errors from R5_0.
* The Lockstep error is not initialized until RPU clock is enabled.
* Therefore the error outcomes are masked by default and are expected to be
* unmasked after processor clock is enabled and before its reset is released. */
#define XIL_EVENT_ERROR_MASK_RPU_LS (0x00000400U)
/** Error event mask for RPU Common Cause Failures ORed together.
* The CCF Error register with the masking capability has to reside in the RPU. */
#define XIL_EVENT_ERROR_MASK_RPU_CCF (0x00000800U)
/** Error event mask for APU GIC AXI Error by the AXI4 master port,
* such as SLVERR or DECERR. */
#define XIL_EVENT_ERROR_MASK_GIC_AXI (0x00001000U)
/** Error event mask for APU GIC ECC Error,
* a Non-Correctable ECC error occurred in any ECC-protected RAM. */
#define XIL_EVENT_ERROR_MASK_GIC_ECC (0x00002000U)
/** Error event mask for APLL Lock Errors.
* The error can be unmasked after the PLL is locked to alert when the
* PLL loses lock. */
#define XIL_EVENT_ERROR_MASK_APLL_LOCK (0x00004000U)
/** Error event mask for RPLL Lock Errors.
* The error can be unmasked after the PLL is locked to alert when the
* PLL loses lock. */
#define XIL_EVENT_ERROR_MASK_RPLL_LOCK (0x00008000U)
/** Error event mask for CPM Correctable Error. */
#define XIL_EVENT_ERROR_MASK_CPM_CR (0x00010000U)
/** Error event mask for CPM Non-Correctable Error. */
#define XIL_EVENT_ERROR_MASK_CPM_NCR (0x00020000U)
/** Error event mask for LPD APB Errors from: IPI REG, USB2 REG, CRL REG,
* LPD AFIFM4 REG, LPD IOU REG, LPD IOU SECURE SLCR REG, LPD SLCR REG,
* LPD SLCR SECURE REG. */
#define XIL_EVENT_ERROR_MASK_LPD_APB (0x00040000U)
/** Error event mask for FPD APB Errors from: FPD AFIFM0 REG, FPD AFIFM2 REG,
* FPD SLCR REG,FPD SLCR SECURE REG, CRF REG. */
#define XIL_EVENT_ERROR_MASK_FPD_APB (0x00080000U)
/** Error event mask for Data parity errors from the interfaces connected
* to the LPD interconnect. */
#define XIL_EVENT_ERROR_MASK_LPD_PAR (0x00100000U)
/** Error event mask for Data parity errors from the interfaces connected
* to the FPD interconnect. */
#define XIL_EVENT_ERROR_MASK_FPD_PAR (0x00200000U)
/** Error event mask for LPD IO Peripheral Unit Parity Error. */
#define XIL_EVENT_ERROR_MASK_IOU_PAR (0x00400000U)
/** Error event mask for Data parity errors from the interfaces connected
* to the PSM interconnect. */
#define XIL_EVENT_ERROR_MASK_PSM_PAR (0x00800000U)
/** Error event mask for LPD Interconnect Timeout errors.
* Collected from: Timeout errors at the slaves connected to the LPD
* interconnect, Address decode error, Interconnect mission errors for
* the slaves connected to the LPD interconnect. */
#define XIL_EVENT_ERROR_MASK_LPD_TO (0x01000000U)
/** Error event mask for FPD Interconnect Timeout errors.
* Collected from: Coresight debug trace alarms, Timeout errors at the
* slaves connected to the FPD interconnect, Address decode error,
* Data parity errors on the interfaces connected to the FPD interconnect. */
#define XIL_EVENT_ERROR_MASK_FPD_TO (0x02000000U)
/** Error event mask for PSM Interconnect Timeout Errors.
* Collected from: Interconnect mission errors for PSM_LOCAL slave or
* PSM_GLOBAL slave or MDM slave or LPD interconnect or PSM master,
* Interconnect latent errors for PSM_LOCAL slave or PSM_GLOBAL slave or
* MDM slave or LPD interconnect or PSM master, Timeout errors at the slaves
* connected to the PSM interconnect. */
#define XIL_EVENT_ERROR_MASK_PSM_TO (0x04000000U)
/** Error event mask for XRAM Correctable error.
* Only applicable in devices that have XRAM. */
#define XIL_EVENT_ERROR_MASK_XRAM_CR (0x08000000U)
/** Error event mask for XRAM Non-Correctable error.
* Only applicable in devices that have XRAM. */
#define XIL_EVENT_ERROR_MASK_XRAM_NCR (0x10000000U)
/**
* @}
*/
/**
* @defgroup psmerr2 Error Event Mask for PSM ERR2
* @ingroup xilerroreventmask
* @brief Error Events belong to PSM ERR2 Node
* @{
*/
/** Error event mask for Error from Watchdog Timer in the LPD Subsystem. */
#define XIL_EVENT_ERROR_MASK_LPD_SWDT (0x00000001U)
/** Error event mask for Error from Watchdog Timer in the FPD Subsystem. */
#define XIL_EVENT_ERROR_MASK_FPD_SWDT (0x00000002U)
/** Error event mask for LPD XMPU Errors: Register access error on APB,
* Read permission violation, Write permission violation, Security violation. */
#define XIL_EVENT_ERROR_MASK_LPD_XMPU (0x00040000U)
/** Error event mask for LPD XPPU Errors: Register access error on APB,
* Master ID not found, Read permission violation, Master ID parity error,
* Master ID access violation, TrustZone violation, Aperture parity error. */
#define XIL_EVENT_ERROR_MASK_LPD_XPPU (0x00080000U)
/** Error event mask for FPD XMPU Errors: Register access error on APB,
* Read permission violation, Write permission violation, Security violation. */
#define XIL_EVENT_ERROR_MASK_FPD_XMPU (0x00100000U)
/**
* @}
*/
/**
* @defgroup swerr Error Event Mask for Software error events
* @ingroup xilerroreventmask
* @{
* @brief Error Events belong to SW ERR Node
*/
/** Error event mask for Software error events */
/** Health Boot Monitoring errors */
#define XIL_EVENT_ERROR_MASK_HB_MON_0 (0x00000001U)
#define XIL_EVENT_ERROR_MASK_HB_MON_1 (0x00000002U)
#define XIL_EVENT_ERROR_MASK_HB_MON_2 (0x00000004U)
#define XIL_EVENT_ERROR_MASK_HB_MON_3 (0x00000008U)
#define XIL_EVENT_ERROR_MASK_PLM_EXCEPTION (0x00000010U)
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* XIL_ERROR_NODE_H */

View File

@@ -0,0 +1,89 @@
/******************************************************************************
* Copyright (c) 2021 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_hw.h
*
* This is the header file which contains definitions for the hardware
* registers.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 7.7 bsv 02/21/2017 Initial release
* 7.8 skd 03/09/2022 Compilation warning fix
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XIL_HW_H
#define XIL_HW_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
/**@cond xil_internal
* @{
*/
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/*
* PMC_GLOBAL Base Address
*/
#define PMC_GLOBAL_BASEADDR (0XF1110000U)
/*
* Register: PMC_GLOBAL_DOMAIN_ISO_CNTRL
*/
#define PMC_GLOBAL_DOMAIN_ISO_CNTRL_PMC_PL_CFRAME_MASK (0X00000400U)
#define PMC_GLOBAL_DOMAIN_ISO_CNTRL_PMC_PL_TEST_MASK (0X00000800U)
/*
* Definitions required from pmc_tap.h
*/
#define PMC_TAP_BASEADDR (0XF11A0000U)
#define PMC_TAP_IDCODE (PMC_TAP_BASEADDR + 0X00000000U)
#define PMC_TAP_VERSION (PMC_TAP_BASEADDR + 0X00000004U)
#define PMC_TAP_VERSION_PMC_VERSION_MASK (0X000000FFU)
/*
* Definitions required from crp.h
*/
#define CRP_BASEADDR (0XF1260000U)
#define CRP_RESET_REASON (CRP_BASEADDR + 0X00000220U)
#define CRP_RST_NONPS (CRP_BASEADDR + 0X00000320U)
#define CRP_RST_NONPS_NPI_RESET_MASK (0X10U)
/*
* Register: CRP_RST_PS
*/
#define CRP_RST_PS (CRP_BASEADDR + 0x0000031CU)
/*
* Register: PMC_IOU_SLCR
*/
#define PMC_IOU_SLCR_BASEADDR (0XF1060000U)
/**
* @}
* @endcond
*/
#ifdef __cplusplus
}
#endif
#endif /* XIL_HW_H */

View File

@@ -0,0 +1,113 @@
/******************************************************************************
* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xbasic_types.h
*
*
* @note Dummy File for backwards compatibility
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a adk 1/31/14 Added in bsp common folder for backward compatibility
* 7.0 aru 01/21/19 Modified the typedef of u32,u16,u8
* 7.0 aru 02/06/19 Included stdint.h and stddef.h
* </pre>
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XBASIC_TYPES_H /* prevent circular inclusions */
#define XBASIC_TYPES_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
/** @name Legacy types
* Deprecated legacy types.
* @{
*/
typedef uint8_t Xuint8; /**< unsigned 8-bit */
typedef char Xint8; /**< signed 8-bit */
typedef uint16_t Xuint16; /**< unsigned 16-bit */
typedef short Xint16; /**< signed 16-bit */
typedef uint32_t Xuint32; /**< unsigned 32-bit */
typedef long Xint32; /**< signed 32-bit */
typedef float Xfloat32; /**< 32-bit floating point */
typedef double Xfloat64; /**< 64-bit double precision FP */
typedef unsigned long Xboolean; /**< boolean (XTRUE or XFALSE) */
#if !defined __XUINT64__
typedef struct
{
Xuint32 Upper;
Xuint32 Lower;
} Xuint64;
#endif
/** @name New types
* New simple types.
* @{
*/
#ifndef __KERNEL__
#ifndef XIL_TYPES_H
typedef Xuint32 u32;
typedef Xuint16 u16;
typedef Xuint8 u8;
#endif
#else
#include <linux/types.h>
#endif
#ifndef TRUE
# define TRUE 1U
#endif
#ifndef FALSE
# define FALSE 0U
#endif
#ifndef NULL
#define NULL 0U
#endif
/*
* Xilinx NULL, TRUE and FALSE legacy support. Deprecated.
* Please use NULL, TRUE and FALSE
*/
#define XNULL NULL
#define XTRUE TRUE
#define XFALSE FALSE
/*
* This file is deprecated and users
* should use xil_types.h and xil_assert.h\n\r
*/
#warning The xbasics_type.h file is deprecated and users should use xil_types.h and xil_assert.
#warning Please refer the Standalone BSP UG647 for further details
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
*@endcond
*/

73
mbv/hal/xilinx/xdebug.h Normal file
View File

@@ -0,0 +1,73 @@
/******************************************************************************
* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
#ifndef XDEBUG
#define XDEBUG
#ifdef __cplusplus
extern "C" {
#endif
#if defined(DEBUG) && !defined(NDEBUG)
#ifndef XDEBUG_WARNING
#define XDEBUG_WARNING
#warning DEBUG is enabled
#endif
int printf(const char *format, ...);
#define XDBG_DEBUG_ERROR 0x00000001U /* error condition messages */
#define XDBG_DEBUG_GENERAL 0x00000002U /* general debug messages */
#define XDBG_DEBUG_ALL 0xFFFFFFFFU /* all debugging data */
#define XDBG_DEBUG_FIFO_REG 0x00000100U /* display register reads/writes */
#define XDBG_DEBUG_FIFO_RX 0x00000101U /* receive debug messages */
#define XDBG_DEBUG_FIFO_TX 0x00000102U /* transmit debug messages */
#define XDBG_DEBUG_FIFO_ALL 0x0000010FU /* all fifo debug messages */
#define XDBG_DEBUG_TEMAC_REG 0x00000400U /* display register reads/writes */
#define XDBG_DEBUG_TEMAC_RX 0x00000401U /* receive debug messages */
#define XDBG_DEBUG_TEMAC_TX 0x00000402U /* transmit debug messages */
#define XDBG_DEBUG_TEMAC_ALL 0x0000040FU /* all temac debug messages */
#define XDBG_DEBUG_TEMAC_ADPT_RX 0x00000800U /* receive debug messages */
#define XDBG_DEBUG_TEMAC_ADPT_TX 0x00000801U /* transmit debug messages */
#define XDBG_DEBUG_TEMAC_ADPT_IOCTL 0x00000802U /* ioctl debug messages */
#define XDBG_DEBUG_TEMAC_ADPT_MISC 0x00000803U /* debug msg for other routines */
#define XDBG_DEBUG_TEMAC_ADPT_ALL 0x0000080FU /* all temac adapter debug messages */
#define xdbg_current_types (XDBG_DEBUG_GENERAL | XDBG_DEBUG_ERROR | XDBG_DEBUG_TEMAC_REG | XDBG_DEBUG_FIFO_RX | XDBG_DEBUG_FIFO_TX | XDBG_DEBUG_FIFO_REG)
#define xdbg_stmnt(x) x
/* In VxWorks, if _WRS_GNU_VAR_MACROS is defined, special syntax is needed for
* macros that accept variable number of arguments
*/
#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS)
#define xdbg_printf(type, args...) (((type) & xdbg_current_types) ? printf (## args) : 0)
#else /* ANSI Syntax */
#define xdbg_printf(type, ...) (((type) & xdbg_current_types) ? printf (__VA_ARGS__) : 0)
#endif
#else /* defined(DEBUG) && !defined(NDEBUG) */
#define xdbg_stmnt(x)
/* See VxWorks comments above */
#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS)
#define xdbg_printf(type, args...)
#else /* ANSI Syntax */
#define xdbg_printf(...)
#endif
#endif /* defined(DEBUG) && !defined(NDEBUG) */
#ifdef __cplusplus
}
#endif
#endif /* XDEBUG */

169
mbv/hal/xilinx/xenv.h Normal file
View File

@@ -0,0 +1,169 @@
/******************************************************************************
* Copyright (c) 2002 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xenv.h
*
* Defines common services that are typically found in a host operating.
* environment. This include file simply includes an OS specific file based
* on the compile-time constant BUILD_ENV_*, where * is the name of the target
* environment.
*
* All services are defined as macros.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00b ch 10/24/02 Added XENV_LINUX
* 1.00a rmm 04/17/02 First release
* </pre>
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XENV_H /* prevent circular inclusions */
#define XENV_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/*
* Select which target environment we are operating under
*/
/* VxWorks target environment */
#if defined XENV_VXWORKS
#include "xenv_vxworks.h"
/* Linux target environment */
#elif defined XENV_LINUX
#include "xenv_linux.h"
/* Unit test environment */
#elif defined XENV_UNITTEST
#include "ut_xenv.h"
/* Integration test environment */
#elif defined XENV_INTTEST
#include "int_xenv.h"
/* Standalone environment selected */
#else
#include "xenv_standalone.h"
#endif
/*
* The following comments specify the types and macro wrappers that are
* expected to be defined by the target specific header files
*/
/**************************** Type Definitions *******************************/
/*****************************************************************************/
/**
*
* XENV_TIME_STAMP
*
* A structure that contains a time stamp used by other time stamp macros
* defined below. This structure is processor dependent.
*/
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
*
* XENV_MEM_COPY(void *DestPtr, void *SrcPtr, unsigned Bytes)
*
* Copies a non-overlapping block of memory.
*
* @param DestPtr is the destination address to copy data to.
* @param SrcPtr is the source address to copy data from.
* @param Bytes is the number of bytes to copy.
*
* @return None
*/
/*****************************************************************************/
/**
*
* XENV_MEM_FILL(void *DestPtr, char Data, unsigned Bytes)
*
* Fills an area of memory with constant data.
*
* @param DestPtr is the destination address to set.
* @param Data contains the value to set.
* @param Bytes is the number of bytes to set.
*
* @return None
*/
/*****************************************************************************/
/**
*
* XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr)
*
* Samples the processor's or external timer's time base counter.
*
* @param StampPtr is the storage for the retrieved time stamp.
*
* @return None
*/
/*****************************************************************************/
/**
*
* XENV_TIME_STAMP_DELTA_US(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr)
*
* Computes the delta between the two time stamps.
*
* @param Stamp1Ptr - First sampled time stamp.
* @param Stamp1Ptr - Sedond sampled time stamp.
*
* @return An unsigned int value with units of microseconds.
*/
/*****************************************************************************/
/**
*
* XENV_TIME_STAMP_DELTA_MS(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr)
*
* Computes the delta between the two time stamps.
*
* @param Stamp1Ptr - First sampled time stamp.
* @param Stamp1Ptr - Sedond sampled time stamp.
*
* @return An unsigned int value with units of milliseconds.
*/
/*****************************************************************************//**
*
* XENV_USLEEP(unsigned delay)
*
* Delay the specified number of microseconds.
*
* @param delay is the number of microseconds to delay.
*
* @return None
*/
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
*@endcond
*/

View File

@@ -0,0 +1,350 @@
/******************************************************************************
* Copyright (c) 2002 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xenv_standalone.h
*
* Defines common services specified by xenv.h.
*
* @note
* This file is not intended to be included directly by driver code.
* Instead, the generic xenv.h file is intended to be included by driver
* code.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a wgr 02/28/07 Added cache handling macros.
* 1.00a wgr 02/27/07 Simplified code. Deprecated old-style macro names.
* 1.00a rmm 01/24/06 Implemented XENV_USLEEP. Assume implementation is being
* used under Xilinx standalone BSP.
* 1.00a xd 11/03/04 Improved support for doxygen.
* 1.00a rmm 03/21/02 First release
* 1.00a wgr 03/22/07 Converted to new coding style.
* 1.00a rpm 06/29/07 Added udelay macro for standalone
* 1.00a xd 07/19/07 Included xparameters.h as XPAR_ constants are referred
* to in MICROBLAZE section
* 1.00a ecm 09/19/08 updated for v7.20 of Microblaze, new functionality
*
* </pre>
*
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XENV_STANDALONE_H
#define XENV_STANDALONE_H
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
/******************************************************************************
*
* Get the processor dependent includes
*
******************************************************************************/
#include <string.h>
#if defined __MICROBLAZE__
# include "mb_interface.h"
# include "xparameters.h" /* XPAR constants used below in MB section */
#elif defined __PPC__
# include "sleep.h"
# include "xcache_l.h" /* also include xcache_l.h for caching macros */
#endif
/******************************************************************************
*
* MEMCPY / MEMSET related macros.
*
* The following are straight forward implementations of memset and memcpy.
*
* NOTE: memcpy may not work if source and target memory area are overlapping.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* Copies a non-overlapping block of memory.
*
* @param DestPtr
* Destination address to copy data to.
*
* @param SrcPtr
* Source address to copy data from.
*
* @param Bytes
* Number of bytes to copy.
*
* @return None.
*
* @note
* The use of XENV_MEM_COPY is deprecated. Use memcpy() instead.
*
* @note
* This implementation MAY BREAK work if source and target memory
* area are overlapping.
*
*****************************************************************************/
#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \
memcpy((void *) DestPtr, (const void *) SrcPtr, (size_t) Bytes)
/*****************************************************************************/
/**
*
* Fills an area of memory with constant data.
*
* @param DestPtr
* Destination address to copy data to.
*
* @param Data
* Value to set.
*
* @param Bytes
* Number of bytes to copy.
*
* @return None.
*
* @note
* The use of XENV_MEM_FILL is deprecated. Use memset() instead.
*
*****************************************************************************/
#define XENV_MEM_FILL(DestPtr, Data, Bytes) \
memset((void *) DestPtr, (s32) Data, (size_t) Bytes)
/******************************************************************************
*
* TIME related macros
*
******************************************************************************/
/**
* A structure that contains a time stamp used by other time stamp macros
* defined below. This structure is processor dependent.
*/
typedef s32 XENV_TIME_STAMP;
/*****************************************************************************/
/**
*
* Time is derived from the 64 bit PPC timebase register
*
* @param StampPtr is the storage for the retrieved time stamp.
*
* @return None.
*
* @note
*
* Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr)
* <br><br>
* This macro must be implemented by the user.
*
*****************************************************************************/
#define XENV_TIME_STAMP_GET(StampPtr)
/*****************************************************************************/
/**
*
* This macro is not yet implemented and always returns 0.
*
* @param Stamp1Ptr is the first sampled time stamp.
* @param Stamp2Ptr is the second sampled time stamp.
*
* @return 0
*
* @note
*
* This macro must be implemented by the user.
*
*****************************************************************************/
#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0)
/*****************************************************************************/
/**
*
* This macro is not yet implemented and always returns 0.
*
* @param Stamp1Ptr is the first sampled time stamp.
* @param Stamp2Ptr is the second sampled time stamp.
*
* @return 0
*
* @note
*
* This macro must be implemented by the user.
*
*****************************************************************************/
#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0)
/*****************************************************************************/
/**
* XENV_USLEEP(unsigned delay)
*
* Delay the specified number of microseconds. Not implemented without OS
* support.
*
* @param delay
* Number of microseconds to delay.
*
* @return None.
*
*****************************************************************************/
#ifdef __PPC__
#define XENV_USLEEP(delay) usleep(delay)
#define udelay(delay) usleep(delay)
#else
#define XENV_USLEEP(delay)
#define udelay(delay)
#endif
/******************************************************************************
*
* CACHE handling macros / mappings
*
******************************************************************************/
/******************************************************************************
*
* Processor independent macros
*
******************************************************************************/
#define XCACHE_ENABLE_CACHE() \
{ XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); }
#define XCACHE_DISABLE_CACHE() \
{ XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); }
/******************************************************************************
*
* MicroBlaze case
*
* NOTE: Currently the following macros will only work on systems that contain
* only ONE MicroBlaze processor. Also, the macros will only be enabled if the
* system is built using a xparameters.h file.
*
******************************************************************************/
#if defined __MICROBLAZE__
/* Check if MicroBlaze data cache was built into the core.
*/
#if (XPAR_MICROBLAZE_USE_DCACHE == 1)
# define XCACHE_ENABLE_DCACHE() microblaze_enable_dcache()
# define XCACHE_DISABLE_DCACHE() microblaze_disable_dcache()
# define XCACHE_INVALIDATE_DCACHE() microblaze_invalidate_dcache()
# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \
microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len))
#if (XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK == 1)
# define XCACHE_FLUSH_DCACHE() microblaze_flush_dcache()
# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \
microblaze_flush_dcache_range((s32)(Addr), (s32)(Len))
#else
# define XCACHE_FLUSH_DCACHE() microblaze_invalidate_dcache()
# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \
microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len))
#endif /*XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK*/
#else
# define XCACHE_ENABLE_DCACHE()
# define XCACHE_DISABLE_DCACHE()
# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len)
# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len)
#endif /*XPAR_MICROBLAZE_USE_DCACHE*/
/* Check if MicroBlaze instruction cache was built into the core.
*/
#if (XPAR_MICROBLAZE_USE_ICACHE == 1)
# define XCACHE_ENABLE_ICACHE() microblaze_enable_icache()
# define XCACHE_DISABLE_ICACHE() microblaze_disable_icache()
# define XCACHE_INVALIDATE_ICACHE() microblaze_invalidate_icache()
# define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) \
microblaze_invalidate_icache_range((s32)(Addr), (s32)(Len))
#else
# define XCACHE_ENABLE_ICACHE()
# define XCACHE_DISABLE_ICACHE()
#endif /*XPAR_MICROBLAZE_USE_ICACHE*/
/******************************************************************************
*
* PowerPC case
*
* Note that the XCACHE_ENABLE_xxx functions are hardcoded to enable a
* specific memory region (0x80000001). Each bit (0-30) in the regions
* bitmask stands for 128MB of memory. Bit 31 stands for the upper 2GB
* range.
*
* regions --> cached address range
* ------------|--------------------------------------------------
* 0x80000000 | [0, 0x7FFFFFF]
* 0x00000001 | [0xF8000000, 0xFFFFFFFF]
* 0x80000001 | [0, 0x7FFFFFF],[0xF8000000, 0xFFFFFFFF]
*
******************************************************************************/
#elif defined __PPC__
#define XCACHE_ENABLE_DCACHE() XCache_EnableDCache(0x80000001)
#define XCACHE_DISABLE_DCACHE() XCache_DisableDCache()
#define XCACHE_ENABLE_ICACHE() XCache_EnableICache(0x80000001)
#define XCACHE_DISABLE_ICACHE() XCache_DisableICache()
#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \
XCache_InvalidateDCacheRange((u32)(Addr), (u32)(Len))
#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \
XCache_FlushDCacheRange((u32)(Addr), (u32)(Len))
#define XCACHE_INVALIDATE_ICACHE() XCache_InvalidateICache()
/******************************************************************************
*
* Unknown processor / architecture
*
******************************************************************************/
#else
/* #error "Unknown processor / architecture. Must be MicroBlaze or PowerPC." */
#endif
#ifdef __cplusplus
}
#endif
#endif /* #ifndef XENV_STANDALONE_H */
/**
*@endcond
*/

126
mbv/hal/xilinx/xil_assert.c Normal file
View File

@@ -0,0 +1,126 @@
/******************************************************************************
* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_assert.c
* @addtogroup common_assert_apis Assert APIs and Macros
* @{
*
* This file contains basic assert related functions for Xilinx software IP.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 07/14/09 Initial release
* 6.0 kvn 05/31/16 Make Xil_AsserWait a global variable
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
/**
* @brief This variable allows testing to be done easier with asserts. An assert
* sets this variable such that a driver can evaluate this variable
* to determine if an assert occurred.
*/
u32 Xil_AssertStatus;
/**
* @brief This variable allows the assert functionality to be changed for testing
* such that it does not wait infinitely. Use the debugger to disable the
* waiting during testing of asserts.
*/
s32 Xil_AssertWait = 1;
/* The callback function to be invoked when an assert is taken */
static Xil_AssertCallback Xil_AssertCallbackRoutine = NULL;
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/**
*
* @brief Implement assert. Currently, it calls a user-defined callback
* function if one has been set. Then, it potentially enters an
* infinite loop depending on the value of the Xil_AssertWait
* variable.
*
* @param File: filename of the source
* @param Line: linenumber within File
*
* @return None.
*
* @note None.
*
******************************************************************************/
void Xil_Assert(const char8 *File, s32 Line)
{
/* if the callback has been set then invoke it */
if (Xil_AssertCallbackRoutine != 0) {
(*Xil_AssertCallbackRoutine)(File, Line);
}
/* if specified, wait indefinitely such that the assert will show up
* in testing
*/
while (Xil_AssertWait != 0) {
}
}
/*****************************************************************************/
/**
*
* @brief Set up a callback function to be invoked when an assert occurs.
* If a callback is already installed, then it will be replaced.
*
* @param Routine: callback to be invoked when an assert is taken
*
* @return None.
*
* @note This function has no effect if NDEBUG is set
*
******************************************************************************/
void Xil_AssertSetCallback(Xil_AssertCallback Routine)
{
Xil_AssertCallbackRoutine = Routine;
}
/*****************************************************************************/
/**
*
* @brief Null handler function. This follows the XInterruptHandler
* signature for interrupt handlers. It can be used to assign a null
* handler (a stub) to an interrupt controller vector table.
*
* @param NullParameter: arbitrary void pointer and not used.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XNullHandler(void *NullParameter)
{
(void) NullParameter;
}
/**
* @} End of "addtogroup common_assert_apis".
*/

176
mbv/hal/xilinx/xil_assert.h Normal file
View File

@@ -0,0 +1,176 @@
/******************************************************************************
* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_assert.h
*
* @addtogroup common_assert_apis Assert APIs and Macros
*
* The xil_assert.h file contains assert related functions and macros.
* Assert APIs/Macros specifies that a application program satisfies certain
* conditions at particular points in its execution. These function can be
* used by application programs to ensure that, application code is satisfying
* certain conditions.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 07/14/09 First release
* 6.0 kvn 05/31/16 Make Xil_AsserWait a global variable
* </pre>
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XIL_ASSERT_H /* prevent circular inclusions */
#define XIL_ASSERT_H /* by using protection macros */
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
/************************** Constant Definitions *****************************/
#define XIL_ASSERT_NONE 0U
#define XIL_ASSERT_OCCURRED 1U
#define XNULL NULL
extern u32 Xil_AssertStatus;
extern s32 Xil_AssertWait;
extern void Xil_Assert(const char8 *File, s32 Line);
/**
*@endcond
*/
void XNullHandler(void *NullParameter);
/**
* This data type defines a callback to be invoked when an
* assert occurs. The callback is invoked only when asserts are enabled
*/
typedef void (*Xil_AssertCallback) (const char8 *File, s32 Line);
/***************** Macros (Inline Functions) Definitions *********************/
#ifndef NDEBUG
/*****************************************************************************/
/**
* @brief This assert macro is to be used for void functions. This in
* conjunction with the Xil_AssertWait boolean can be used to
* accommodate tests so that asserts which fail allow execution to
* continue.
*
* @param Expression: expression to be evaluated. If it evaluates to
* false, the assert occurs.
*
* @return Returns void unless the Xil_AssertWait variable is true, in which
* case no return is made and an infinite loop is entered.
*
******************************************************************************/
#define Xil_AssertVoid(Expression) \
{ \
if (Expression) { \
Xil_AssertStatus = XIL_ASSERT_NONE; \
} else { \
Xil_Assert(__FILE__, __LINE__); \
Xil_AssertStatus = XIL_ASSERT_OCCURRED; \
return; \
} \
}
/*****************************************************************************/
/**
* @brief This assert macro is to be used for functions that do return a
* value. This in conjunction with the Xil_AssertWait boolean can be
* used to accommodate tests so that asserts which fail allow execution
* to continue.
*
* @param Expression: expression to be evaluated. If it evaluates to false,
* the assert occurs.
*
* @return Returns 0 unless the Xil_AssertWait variable is true, in which
* case no return is made and an infinite loop is entered.
*
******************************************************************************/
#define Xil_AssertNonvoid(Expression) \
{ \
if (Expression) { \
Xil_AssertStatus = XIL_ASSERT_NONE; \
} else { \
Xil_Assert(__FILE__, __LINE__); \
Xil_AssertStatus = XIL_ASSERT_OCCURRED; \
return 0; \
} \
}
/*****************************************************************************/
/**
* @brief Always assert. This assert macro is to be used for void functions.
* Use for instances where an assert should always occur.
*
* @return Returns void unless the Xil_AssertWait variable is true, in which
* case no return is made and an infinite loop is entered.
*
******************************************************************************/
#define Xil_AssertVoidAlways() \
{ \
Xil_Assert(__FILE__, __LINE__); \
Xil_AssertStatus = XIL_ASSERT_OCCURRED; \
return; \
}
/*****************************************************************************/
/**
* @brief Always assert. This assert macro is to be used for functions that
* do return a value. Use for instances where an assert should always
* occur.
*
* @return Returns void unless the Xil_AssertWait variable is true, in which
* case no return is made and an infinite loop is entered.
*
******************************************************************************/
#define Xil_AssertNonvoidAlways() \
{ \
Xil_Assert(__FILE__, __LINE__); \
Xil_AssertStatus = XIL_ASSERT_OCCURRED; \
return 0; \
}
#else
#define Xil_AssertVoid(Expression)
#define Xil_AssertVoidAlways()
#define Xil_AssertNonvoid(Expression)
#define Xil_AssertNonvoidAlways()
#endif
/************************** Function Prototypes ******************************/
void Xil_AssertSetCallback(Xil_AssertCallback Routine);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_assert_apis".
*/

View File

@@ -0,0 +1,74 @@
/******************************************************************************
* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_cache_vxworks.h
*
* Contains the cache related functions for VxWorks that is wrapped by
* xil_cache.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 12/11/09 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XIL_CACHE_VXWORKS_H
#define XIL_CACHE_VXWORKS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "vxWorks.h"
#include "vxLib.h"
#include "sysLibExtra.h"
#include "cacheLib.h"
#if (CPU_FAMILY==PPC)
#define Xil_DCacheEnable() cacheEnable(DATA_CACHE)
#define Xil_DCacheDisable() cacheDisable(DATA_CACHE)
#define Xil_DCacheInvalidateRange(Addr, Len) \
cacheInvalidate(DATA_CACHE, (void *)(Addr), (Len))
#define Xil_DCacheFlushRange(Addr, Len) \
cacheFlush(DATA_CACHE, (void *)(Addr), (Len))
#define Xil_ICacheEnable() cacheEnable(INSTRUCTION_CACHE)
#define Xil_ICacheDisable() cacheDisable(INSTRUCTION_CACHE)
#define Xil_ICacheInvalidateRange(Addr, Len) \
cacheInvalidate(INSTRUCTION_CACHE, (void *)(Addr), (Len))
#else
#error "Unknown processor / architecture. Must be PPC for VxWorks."
#endif
#ifdef __cplusplus
}
#endif
#endif
/**
*@endcond
*/

43
mbv/hal/xilinx/xil_hal.h Normal file
View File

@@ -0,0 +1,43 @@
/******************************************************************************
* Copyright (c) 2009 - 2020 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_hal.h
*
* Contains all the HAL header files.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 07/28/09 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XIL_HAL_H
#define XIL_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "xil_cache.h"
#include "xil_io.h"
#include "xil_assert.h"
#include "xil_exception.h"
#include "xil_types.h"
#ifdef __cplusplus
}
#endif
#endif

412
mbv/hal/xilinx/xil_io.h Normal file
View File

@@ -0,0 +1,412 @@
/******************************************************************************
* Copyright (c) 2014 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_io.h
*
* @addtogroup common_io_interfacing_apis Register IO interfacing APIs
*
* The xil_io.h file contains the interface for the general I/O component, which
* encapsulates the Input/Output functions for the processors that do not
* require any special I/O handling.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------
* 5.00 pkp 05/29/14 First release
* 6.00 mus 08/19/16 Remove checking of __LITTLE_ENDIAN__ flag for
* ARM processors
* 7.20 har 01/03/20 Added Xil_SecureOut32 for avoiding blindwrite for
* CR-1049218
* 7.30 kpt 09/21/20 Moved Xil_EndianSwap16 and Xil_EndianSwap32 to
* xil_io.h and made them as static inline
* am 10/13/20 Changed the return type of Xil_SecureOut32 function
* from u32 to int
* 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.
*
* </pre>
******************************************************************************/
#ifndef XIL_IO_H /* prevent circular inclusions */
#define XIL_IO_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
//#include "xil_printf.h"
#include "xstatus.h"
#if defined (__MICROBLAZE__)
#include "mb_interface.h"
#else
//#include "xpseudo_asm.h"
#endif
/************************** Function Prototypes ******************************/
#ifdef ENABLE_SAFETY
extern u32 XStl_RegUpdate(u32 RegAddr, u32 RegVal);
#endif
/***************** Macros (Inline Functions) Definitions *********************/
#if defined __GNUC__
#if defined (__MICROBLAZE__)
# define INST_SYNC mbar(0)
# define DATA_SYNC mbar(1)
# else
# define SYNCHRONIZE_IO dmb()
# define INST_SYNC isb()
# define DATA_SYNC dsb()
# endif
#else
# define SYNCHRONIZE_IO
# define INST_SYNC
# define DATA_SYNC
# define INST_SYNC
# define DATA_SYNC
#endif
#if defined (__GNUC__) || defined (__ICCARM__) || defined (__MICROBLAZE__)
#define INLINE inline
#else
#define INLINE __inline
#endif
/*****************************************************************************/
/**
*
* @brief Performs an input operation for a memory location by reading
* from the specified address and returning the 8 bit Value read from
* that address.
*
* @param Addr: contains the address to perform the input operation
*
* @return The 8 bit Value read from the specified input address.
*
******************************************************************************/
static INLINE u8 Xil_In8(UINTPTR Addr)
{
return *(volatile u8 *) Addr;
}
/*****************************************************************************/
/**
*
* @brief Performs an input operation for a memory location by reading from
* the specified address and returning the 16 bit Value read from that
* address.
*
* @param Addr: contains the address to perform the input operation
*
* @return The 16 bit Value read from the specified input address.
*
******************************************************************************/
static INLINE u16 Xil_In16(UINTPTR Addr)
{
return *(volatile u16 *) Addr;
}
/*****************************************************************************/
/**
*
* @brief Performs an input operation for a memory location by
* 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
*
* @return The 32 bit Value read from the specified input address.
*
******************************************************************************/
static INLINE u32 Xil_In32(UINTPTR Addr)
{
return *(volatile u32 *) Addr;
}
/*****************************************************************************/
/**
*
* @brief Performs an input operation for a memory location by reading the
* 64 bit Value read from that address.
*
*
* @param Addr: contains the address to perform the input operation
*
* @return The 64 bit Value read from the specified input address.
*
******************************************************************************/
static INLINE u64 Xil_In64(UINTPTR Addr)
{
return *(volatile u64 *) 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
* address.
*
* @return None.
*
******************************************************************************/
static INLINE void Xil_Out8(UINTPTR Addr, u8 Value)
{
/* write 8 bit value to specified address */
volatile u8 *LocalAddr = (volatile u8 *)Addr;
*LocalAddr = Value;
}
/*****************************************************************************/
/**
*
* @brief Performs an output operation for a memory location by writing the
* 16 bit Value to the the specified address.
*
* @param Addr contains the address to perform the output operation
* @param Value contains the Value to be written at the specified address.
*
* @return None.
*
******************************************************************************/
static INLINE void Xil_Out16(UINTPTR Addr, u16 Value)
{
/* write 16 bit value to specified address */
volatile u16 *LocalAddr = (volatile u16 *)Addr;
*LocalAddr = Value;
}
/*****************************************************************************/
/**
*
* @brief Performs an output operation for a memory location by writing the
* 32 bit Value to the the specified address.
*
* @param Addr contains the address to perform the output operation
* @param Value contains the 32 bit Value to be written at the specified
* address.
*
* @return None.
*
******************************************************************************/
static INLINE void Xil_Out32(UINTPTR Addr, u32 Value)
{
/* write 32 bit value to specified address */
#ifndef ENABLE_SAFETY
volatile u32 *LocalAddr = (volatile u32 *)Addr;
*LocalAddr = Value;
#else
XStl_RegUpdate(Addr, Value);
#endif
}
/*****************************************************************************/
/**
*
* @brief Performs an output operation for a memory location by writing the
* 64 bit Value to the the specified address.
*
* @param Addr contains the address to perform the output operation
* @param Value contains 64 bit Value to be written at the specified address.
*
* @return None.
*
******************************************************************************/
static INLINE void Xil_Out64(UINTPTR Addr, u64 Value)
{
/* write 64 bit value to specified address */
volatile u64 *LocalAddr = (volatile u64 *)Addr;
*LocalAddr = Value;
}
/*****************************************************************************/
/**
*
* @brief Performs an output operation for a memory location by writing the
* 32 bit Value to the the specified address and then reading it
* back to verify the value written in the register.
*
* @param Addr contains the address to perform the output operation
* @param Value contains 32 bit Value to be written at the specified address
*
* @return Returns Status
* - XST_SUCCESS on success
* - XST_FAILURE on failure
*
*****************************************************************************/
static INLINE int Xil_SecureOut32(UINTPTR Addr, u32 Value)
{
int Status = XST_FAILURE;
u32 ReadReg;
u32 ReadRegTemp;
/* writing 32 bit value to specified address */
Xil_Out32(Addr, Value);
/* verify value written to specified address with multiple reads */
ReadReg = Xil_In32(Addr);
ReadRegTemp = Xil_In32(Addr);
if( (ReadReg == Value) && (ReadRegTemp == Value) ) {
Status = XST_SUCCESS;
}
return Status;
}
/*****************************************************************************/
/**
*
* @brief Perform a 16-bit endian conversion.
*
* @param Data: 16 bit value to be converted
*
* @return 16 bit Data with converted endianness
*
******************************************************************************/
static INLINE __attribute__((always_inline)) u16 Xil_EndianSwap16(u16 Data)
{
return (u16) (((Data & 0xFF00U) >> 8U) | ((Data & 0x00FFU) << 8U));
}
/*****************************************************************************/
/**
*
* @brief Perform a 32-bit endian conversion.
*
* @param Data: 32 bit value to be converted
*
* @return 32 bit data with converted endianness
*
******************************************************************************/
static INLINE __attribute__((always_inline)) u32 Xil_EndianSwap32(u32 Data)
{
u16 LoWord;
u16 HiWord;
/* get each of the half words from the 32 bit word */
LoWord = (u16) (Data & 0x0000FFFFU);
HiWord = (u16) ((Data & 0xFFFF0000U) >> 16U);
/* byte swap each of the 16 bit half words */
LoWord = (u16)(((LoWord & 0xFF00U) >> 8U) | ((LoWord & 0x00FFU) << 8U));
HiWord = (u16)(((HiWord & 0xFF00U) >> 8U) | ((HiWord & 0x00FFU) << 8U));
/* swap the half words before returning the value */
return ((((u32)LoWord) << (u32)16U) | (u32)HiWord);
}
#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
# 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)
#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
#endif
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
static INLINE u16 Xil_In16BE(UINTPTR Addr)
#else
static INLINE u16 Xil_In16LE(UINTPTR Addr)
#endif
#else
static INLINE u16 Xil_In16BE(UINTPTR Addr)
#endif
{
u16 value = Xil_In16(Addr);
return Xil_EndianSwap16(value);
}
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
static INLINE u32 Xil_In32BE(UINTPTR Addr)
#else
static INLINE u32 Xil_In32LE(UINTPTR Addr)
#endif
#else
static INLINE u32 Xil_In32BE(UINTPTR Addr)
#endif
{
u32 value = Xil_In32(Addr);
return Xil_EndianSwap32(value);
}
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value)
#else
static INLINE void Xil_Out16LE(UINTPTR Addr, u16 Value)
#endif
#else
static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value)
#endif
{
Value = Xil_EndianSwap16(Value);
Xil_Out16(Addr, Value);
}
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value)
#else
static INLINE void Xil_Out32LE(UINTPTR Addr, u32 Value)
#endif
#else
static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value)
#endif
{
Value = Xil_EndianSwap32(Value);
Xil_Out32(Addr, Value);
}
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_io_interfacing_apis".
*/

File diff suppressed because it is too large Load Diff

70
mbv/hal/xilinx/xil_mem.c Normal file
View File

@@ -0,0 +1,70 @@
/******************************************************************************/
/**
* Copyright (c) 2015 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
* @file xil_mem.c
*
* This file contains xil mem copy function to use in case of word aligned
* data copies.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------
* 6.1 nsk 11/07/16 First release.
* 7.7 sk 01/10/22 Update Xil_MemCpy functions variables typecast
* from int to s32 to fix misra_c_2012_directive_4_6
* violations.
* 7.7 sk 01/10/22 Include xil_mem.h header file to fix Xil_MemCpy
* prototype misra_c_2012_rule_8_4 violation.
*
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_mem.h"
/***************** Inline Functions Definitions ********************/
/*****************************************************************************/
/**
* @brief This function copies memory from once location to other.
*
* @param dst: pointer pointing to destination memory
*
* @param src: pointer pointing to source memory
*
* @param cnt: 32 bit length of bytes to be copied
*
*****************************************************************************/
void Xil_MemCpy(void* dst, const void* src, u32 cnt)
{
char *d = (char*)(void *)dst;
const char *s = src;
while (cnt >= sizeof (s32)) {
*(s32*)d = *(s32*)s;
d += sizeof (s32);
s += sizeof (s32);
cnt -= sizeof (s32);
}
while (cnt >= sizeof (u16)) {
*(u16*)d = *(u16*)s;
d += sizeof (u16);
s += sizeof (u16);
cnt -= sizeof (u16);
}
while ((cnt) > 0U){
*d = *s;
d += 1U;
s += 1U;
cnt -= 1U;
}
}

47
mbv/hal/xilinx/xil_mem.h Normal file
View File

@@ -0,0 +1,47 @@
/******************************************************************************/
/**
* Copyright (c) 2015 - 2020 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
* @file xil_mem.h
*
* @addtogroup common_mem_operation_api Customized APIs for Memory Operations
*
* The xil_mem.h file contains prototype for functions related
* to memory operations. These APIs are applicable for all processors supported
* by Xilinx.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------
* 6.1 nsk 11/07/16 First release.
* 7.0 mus 01/07/19 Add cpp extern macro
*
* </pre>
*
*****************************************************************************/
#ifndef XIL_MEM_H /* prevent circular inclusions */
#define XIL_MEM_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/************************** Function Prototypes *****************************/
void Xil_MemCpy(void* dst, const void* src, u32 cnt);
#ifdef __cplusplus
}
#endif
#endif /* XIL_MEM_H */
/**
* @} End of "addtogroup common_mem_operation_api".
*/

447
mbv/hal/xilinx/xil_printf.c Normal file
View File

@@ -0,0 +1,447 @@
/******************************************************************************
* Copyright (c) 1995 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
*******************************************************************************/
/*---------------------------------------------------*/
/* Modified from : */
/* Public Domain version of printf */
/* Rud Merriam, Compsult, Inc. Houston, Tx. */
/* For Embedded Systems Programming, 1991 */
/* */
/*---------------------------------------------------*/
#include "xil_printf.h"
#include "xil_types.h"
#include "xil_assert.h"
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
static void padding( const s32 l_flag,const struct params_s *par);
static void outs(const charptr lp, struct params_s *par);
static s32 getnum( charptr* linep);
typedef struct params_s {
s32 len;
s32 num1;
s32 num2;
char8 pad_character;
s32 do_padding;
s32 left_flag;
s32 unsigned_flag;
} params_t;
/*---------------------------------------------------*/
/* The purpose of this routine is to output data the */
/* same as the standard printf function without the */
/* overhead most run-time libraries involve. Usually */
/* the printf brings in many kilobytes of code and */
/* that is unacceptable in most embedded systems. */
/*---------------------------------------------------*/
/*---------------------------------------------------*/
/* */
/* This routine puts pad characters into the output */
/* buffer. */
/* */
static void padding( const s32 l_flag, const struct params_s *par)
{
s32 i;
if ((par->do_padding != 0) && (l_flag != 0) && (par->len < par->num1)) {
i=(par->len);
for (; i<(par->num1); i++) {
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( par->pad_character);
#endif
}
}
}
/*---------------------------------------------------*/
/* */
/* This routine moves a string to the output buffer */
/* as directed by the padding and positioning flags. */
/* */
static void outs(const charptr lp, struct params_s *par)
{
charptr LocalPtr;
LocalPtr = lp;
/* pad on left if needed */
if(LocalPtr != NULL) {
par->len = (s32)strlen( LocalPtr);
padding( !(par->left_flag), par);
/* Move string to the buffer */
while (((*LocalPtr) != (char8)0) && ((par->num2) != 0)) {
(par->num2)--;
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte(*LocalPtr);
#endif
LocalPtr += 1;
}
}
/* Pad on right if needed */
/* CR 439175 - elided next stmt. Seemed bogus. */
padding( par->left_flag, par);
}
/*---------------------------------------------------*/
/* */
/* This routine moves a number to the output buffer */
/* as directed by the padding and positioning flags. */
/* */
static void outnum( const s32 n, const s32 base, struct params_s *par)
{
s32 negative;
s32 i;
char8 outbuf[32];
const char8 digits[] = "0123456789ABCDEF";
u32 num;
for(i = 0; i<32; i++) {
outbuf[i] = '0';
}
/* Check if number is negative */
if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) {
negative = 1;
num =(-(n));
}
else{
num = n;
negative = 0;
}
/* Build number (backwards) in outbuf */
i = 0;
do {
outbuf[i] = digits[(num % (u32)base)];
i++;
num /= base;
} while (num > 0U);
if (negative != 0) {
outbuf[i] = '-';
i++;
}
outbuf[i] = '\0';
i--;
/* Move the converted number to the buffer and */
/* add in the padding where needed. */
par->len = (s32)strlen(outbuf);
padding( !(par->left_flag), par);
while (&outbuf[i] >= outbuf) {
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( outbuf[i] );
#endif
i--;
}
padding( par->left_flag, par);
}
/*---------------------------------------------------*/
/* */
/* This routine moves a 64-bit number to the output */
/* buffer as directed by the padding and positioning */
/* flags. */
/* */
#if defined (__aarch64__) || defined (__arch64__)
static void outnum1( const s64 n, const s32 base, params_t *par)
{
s32 negative;
s32 i;
char8 outbuf[64];
const char8 digits[] = "0123456789ABCDEF";
u64 num;
for(i = 0; i<64; i++) {
outbuf[i] = '0';
}
/* Check if number is negative */
if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) {
negative = 1;
num =(-(n));
}
else{
num = (n);
negative = 0;
}
/* Build number (backwards) in outbuf */
i = 0;
do {
outbuf[i] = digits[(num % base)];
i++;
num /= base;
} while (num > 0);
if (negative != 0) {
outbuf[i] = '-';
i++;
}
outbuf[i] = '\0';
i--;
/* Move the converted number to the buffer and */
/* add in the padding where needed. */
par->len = (s32)strlen(outbuf);
padding( !(par->left_flag), par);
while (&outbuf[i] >= outbuf) {
outbyte( outbuf[i] );
i--;
}
padding( par->left_flag, par);
}
#endif
/*---------------------------------------------------*/
/* */
/* This routine gets a number from the format */
/* string. */
/* */
static s32 getnum(charptr* linep)
{
s32 n = 0;
s32 ResultIsDigit = 0;
charptr cptr = *linep;
while (cptr != NULL) {
ResultIsDigit = isdigit(((u8)*cptr));
if (ResultIsDigit == 0) {
break;
}
n = ((n*10) + (((s32)*cptr) - (s32)'0'));
cptr += 1;
}
*linep = ((charptr)(cptr));
return(n);
}
/*---------------------------------------------------*/
/* */
/* This routine operates just like a printf/sprintf */
/* routine. It outputs a set of data under the */
/* control of a formatting string. Not all of the */
/* standard C format control are supported. The ones */
/* provided are primarily those needed for embedded */
/* systems work. Primarily the floating point */
/* routines are omitted. Other formats could be */
/* added easily by following the examples shown for */
/* the supported formats. */
/* */
/* void esp_printf( const func_ptr f_ptr,
const charptr ctrl1, ...) */
#if defined (__aarch64__) && HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE
void xil_printf( const char8 *ctrl1, ...){
XPVXenConsole_Printf(ctrl1);
}
#else
void xil_printf( const char8 *ctrl1, ...)
{
va_list argp;
va_start(argp, ctrl1);
xil_vprintf(ctrl1, argp);
va_end(argp);
}
#endif
/* This routine is equivalent to vprintf routine */
void xil_vprintf(const char8 *ctrl1, va_list argp)
{
s32 Check;
#if defined (__aarch64__) || defined (__arch64__)
s32 long_flag;
#endif
s32 dot_flag;
params_t par;
u8 ch;
char8 *ctrl = (char8 *)ctrl1;
while ((ctrl != NULL) && (*ctrl != (char8)0)) {
/* move format string chars to buffer until a */
/* format control is found. */
if (*ctrl != '%') {
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte(*ctrl);
#endif
ctrl += 1;
continue;
}
/* initialize all the flags for this format. */
dot_flag = 0;
#if defined (__aarch64__) || defined (__arch64__)
long_flag = 0;
#endif
par.unsigned_flag = 0;
par.left_flag = 0;
par.do_padding = 0;
par.pad_character = ' ';
par.num2=32767;
par.num1=0;
par.len=0;
try_next:
if(ctrl != NULL) {
ctrl += 1;
}
if(ctrl != NULL) {
ch = (u8)*ctrl;
} else {
break;
}
if (isdigit(ch) != 0) {
if (dot_flag != 0) {
par.num2 = getnum(&ctrl);
}
else {
if (ch == (u8)'0') {
par.pad_character = '0';
}
if(ctrl != NULL) {
par.num1 = getnum(&ctrl);
}
par.do_padding = 1;
}
if(ctrl != NULL) {
ctrl -= 1;
}
goto try_next;
}
switch (tolower(ch)) {
case '%':
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( '%');
#endif
Check = 1;
break;
case '-':
par.left_flag = 1;
Check = 0;
break;
case '.':
dot_flag = 1;
Check = 0;
break;
case 'l':
#if defined (__aarch64__) || defined (__arch64__)
long_flag = 1;
#endif
Check = 0;
break;
case 'u':
par.unsigned_flag = 1;
/* fall through */
case 'i':
case 'd':
#if defined (__aarch64__) || defined (__arch64__)
if (long_flag != 0){
outnum1((s64)va_arg(argp, s64), 10L, &par);
}
else {
outnum( va_arg(argp, s32), 10L, &par);
}
#else
outnum( va_arg(argp, s32), 10L, &par);
#endif
Check = 1;
break;
case 'p':
#if defined (__aarch64__) || defined (__arch64__)
par.unsigned_flag = 1;
outnum1((s64)va_arg(argp, s64), 16L, &par);
Check = 1;
break;
#endif
case 'X':
case 'x':
par.unsigned_flag = 1;
#if defined (__aarch64__) || defined (__arch64__)
if (long_flag != 0) {
outnum1((s64)va_arg(argp, s64), 16L, &par);
}
else {
outnum((s32)va_arg(argp, s32), 16L, &par);
}
#else
outnum((s32)va_arg(argp, s32), 16L, &par);
#endif
Check = 1;
break;
case 's':
outs( va_arg( argp, char *), &par);
Check = 1;
break;
case 'c':
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( (char8)va_arg( argp, s32));
#endif
Check = 1;
break;
case '\\':
switch (*ctrl) {
case 'a':
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( ((char8)0x07));
#endif
break;
case 'h':
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( ((char8)0x08));
#endif
break;
case 'r':
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( ((char8)0x0D));
#endif
break;
case 'n':
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( ((char8)0x0D));
outbyte( ((char8)0x0A));
#endif
break;
default:
#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM)
outbyte( *ctrl);
#endif
break;
}
ctrl += 1;
Check = 0;
break;
default:
Check = 1;
break;
}
if(Check == 1) {
if(ctrl != NULL) {
ctrl += 1;
}
continue;
}
goto try_next;
}
}
/*---------------------------------------------------*/

View File

@@ -0,0 +1,53 @@
/******************************************************************************
* Copyright (c) 1995 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
*******************************************************************************/
#ifndef XIL_PRINTF_H
#define XIL_PRINTF_H
#ifdef __cplusplus
extern "C" {
#endif
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
#include "xil_types.h"
#include "xparameters.h"
#include "bspconfig.h"
#if defined (__aarch64__) && HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE
#include "xen_console.h"
#endif
/*----------------------------------------------------*/
/* Use the following parameter passing structure to */
/* make xil_printf re-entrant. */
/*----------------------------------------------------*/
struct params_s;
/*---------------------------------------------------*/
/* The purpose of this routine is to output data the */
/* same as the standard printf function without the */
/* overhead most run-time libraries involve. Usually */
/* the printf brings in many kilobytes of code and */
/* that is unacceptable in most embedded systems. */
/*---------------------------------------------------*/
typedef char8* charptr;
typedef s32 (*func_ptr)(int c);
/* */
void xil_printf( const char8 *ctrl1, ...);
void xil_vprintf(const char8 *ctrl1, va_list argp);
void print( const char8 *ptr);
extern void outbyte (char c);
extern char inbyte(void);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View File

@@ -0,0 +1,85 @@
/******************************************************************************
* Copyright (c) 2017 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
*@file xil_sleepcommon.c
*
* This file contains the sleep API's
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------
* 6.6 srm 11/02/17 First release
* 7.7 sk 01/10/22 Typecast sleep function argument from unsigned
* int to u32 to fix misra_c_2012_directive_4_6
* violation.
* 7.7 sk 03/02/22 Update usleep argument type to fix misra_c_2012_
* directive_4_6 violation.
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_io.h"
#include "sleep.h"
/**************************** Constant Definitions *************************/
/*****************************************************************************/
/**
*
* This API gives delay in sec
*
* @param seconds - delay time in seconds
*
* @return none
*
* @note none
*
*****************************************************************************/
void sleep(u32 seconds)
{
#if defined (ARMR5)
sleep_R5(seconds);
#elif defined (__aarch64__) || defined (ARMA53_32)
sleep_A53(seconds);
#elif defined (__MICROBLAZE__)
sleep_MB(seconds);
#else
sleep_A9(seconds);
#endif
}
/****************************************************************************/
/**
*
* This API gives delay in usec
*
* @param useconds - delay time in useconds
*
* @return none
*
* @note none
*
*****************************************************************************/
void usleep(ULONG useconds)
{
#if defined (ARMR5)
usleep_R5(useconds);
#elif defined (__aarch64__) || defined (ARMA53_32)
usleep_A53(useconds);
#elif defined (__MICROBLAZE__)
usleep_MB(useconds);
#else
usleep_A9(useconds);
#endif
}

View File

@@ -0,0 +1,341 @@
/******************************************************************************
* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_testcache.c
* @addtogroup common_test_utils
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 07/28/09 Initial release
* 4.1 asa 05/09/14 Ensured that the address uses for cache test is aligned
* cache line.
* </pre>
*
******************************************************************************/
#ifdef __ARM__
#include "xil_cache.h"
#include "xil_testcache.h"
#include "xil_types.h"
#include "xpseudo_asm.h"
#ifdef __aarch64__
#include "xreg_cortexa53.h"
#else
#include "xreg_cortexr5.h"
#endif
#include "xil_types.h"
extern void xil_printf(const char8 *ctrl1, ...);
#define DATA_LENGTH 128
#ifdef __aarch64__
static INTPTR Data[DATA_LENGTH] __attribute__ ((aligned(64)));
#else
static INTPTR Data[DATA_LENGTH] __attribute__ ((aligned(32)));
#endif
/*****************************************************************************/
/**
*
* @brief Perform DCache range related API test such as Xil_DCacheFlushRange
* and Xil_DCacheInvalidateRange. This test function writes a constant
* value to the Data array, flushes the range, writes a new value, then
* invalidates the corresponding range.
*
* @return
* - -1 is returned for a failure
* - 0 is returned for a pass
*
*****************************************************************************/
s32 Xil_TestDCacheRange(void)
{
s32 Index;
s32 Status = 0;
u32 CtrlReg;
INTPTR Value;
xil_printf("-- Cache Range Test --\n\r");
for (Index = 0; Index < DATA_LENGTH; Index++)
Data[Index] = 0xA0A00505;
xil_printf(" initialize Data done:\r\n");
Xil_DCacheFlushRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR));
xil_printf(" flush range done\r\n");
dsb();
#ifdef __aarch64__
CtrlReg = mfcp(SCTLR_EL3);
CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT);
mtcp(SCTLR_EL3,CtrlReg);
#else
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT);
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
#endif
dsb();
Status = 0;
for (Index = 0; Index < DATA_LENGTH; Index++) {
Value = Data[Index];
if (Value != 0xA0A00505) {
Status = -1;
xil_printf("Data[%d] = %x\r\n", Index, Value);
break;
}
}
if (!Status) {
xil_printf(" Flush worked\r\n");
}
else {
xil_printf("Error: flush dcache range not working\r\n");
}
dsb();
#ifdef __aarch64__
CtrlReg = mfcp(SCTLR_EL3);
CtrlReg |= (XREG_CONTROL_DCACHE_BIT);
mtcp(SCTLR_EL3,CtrlReg);
#else
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
CtrlReg |= (XREG_CP15_CONTROL_C_BIT);
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
#endif
dsb();
for (Index = 0; Index < DATA_LENGTH; Index++)
Data[Index] = 0xA0A0C505;
Xil_DCacheFlushRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR));
for (Index = 0; Index < DATA_LENGTH; Index++)
Data[Index] = Index + 3;
Xil_DCacheInvalidateRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR));
xil_printf(" invalidate dcache range done\r\n");
dsb();
#ifdef __aarch64__
CtrlReg = mfcp(SCTLR_EL3);
CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT);
mtcp(SCTLR_EL3,CtrlReg);
#else
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT);
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
#endif
dsb();
for (Index = 0; Index < DATA_LENGTH; Index++)
Data[Index] = 0xA0A0A05;
dsb();
#ifdef __aarch64__
CtrlReg = mfcp(SCTLR_EL3);
CtrlReg |= (XREG_CONTROL_DCACHE_BIT);
mtcp(SCTLR_EL3,CtrlReg);
#else
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
CtrlReg |= (XREG_CP15_CONTROL_C_BIT);
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
#endif
dsb();
Status = 0;
for (Index = 0; Index < DATA_LENGTH; Index++) {
Value = Data[Index];
if (Value != 0xA0A0A05) {
Status = -1;
xil_printf("Data[%d] = %x\r\n", Index, Value);
break;
}
}
if (!Status) {
xil_printf(" Invalidate worked\r\n");
}
else {
xil_printf("Error: Invalidate dcache range not working\r\n");
}
xil_printf("-- Cache Range Test Complete --\r\n");
return Status;
}
/*****************************************************************************/
/**
* @brief Perform DCache all related API test such as Xil_DCacheFlush and
* Xil_DCacheInvalidate. This test function writes a constant value
* to the Data array, flushes the DCache, writes a new value,
* then invalidates the DCache.
*
* @return
* - 0 is returned for a pass
* - -1 is returned for a failure
*****************************************************************************/
s32 Xil_TestDCacheAll(void)
{
s32 Index;
s32 Status;
INTPTR Value;
u32 CtrlReg;
xil_printf("-- Cache All Test --\n\r");
for (Index = 0; Index < DATA_LENGTH; Index++)
Data[Index] = 0x50500A0A;
xil_printf(" initialize Data done:\r\n");
Xil_DCacheFlush();
xil_printf(" flush all done\r\n");
dsb();
#ifdef __aarch64__
CtrlReg = mfcp(SCTLR_EL3);
CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT);
mtcp(SCTLR_EL3,CtrlReg);
#else
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT);
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
#endif
dsb();
Status = 0;
for (Index = 0; Index < DATA_LENGTH; Index++) {
Value = Data[Index];
if (Value != 0x50500A0A) {
Status = -1;
xil_printf("Data[%d] = %x\r\n", Index, Value);
break;
}
}
if (!Status) {
xil_printf(" Flush all worked\r\n");
}
else {
xil_printf("Error: Flush dcache all not working\r\n");
}
dsb();
#ifdef __aarch64__
CtrlReg = mfcp(SCTLR_EL3);
CtrlReg |= (XREG_CONTROL_DCACHE_BIT);
mtcp(SCTLR_EL3,CtrlReg);
#else
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
CtrlReg |= (XREG_CP15_CONTROL_C_BIT);
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
#endif
dsb();
for (Index = 0; Index < DATA_LENGTH; Index++)
Data[Index] = 0x505FFA0A;
Xil_DCacheFlush();
for (Index = 0; Index < DATA_LENGTH; Index++)
Data[Index] = Index + 3;
Xil_DCacheInvalidate();
xil_printf(" invalidate all done\r\n");
dsb();
#ifdef __aarch64__
CtrlReg = mfcp(SCTLR_EL3);
CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT);
mtcp(SCTLR_EL3,CtrlReg);
#else
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT);
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
#endif
dsb();
for (Index = 0; Index < DATA_LENGTH; Index++)
Data[Index] = 0x50CFA0A;
dsb();
#ifdef __aarch64__
CtrlReg = mfcp(SCTLR_EL3);
CtrlReg |= (XREG_CONTROL_DCACHE_BIT);
mtcp(SCTLR_EL3,CtrlReg);
#else
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
CtrlReg |= (XREG_CP15_CONTROL_C_BIT);
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
#endif
dsb();
Status = 0;
for (Index = 0; Index < DATA_LENGTH; Index++) {
Value = Data[Index];
if (Value != 0x50CFA0A) {
Status = -1;
xil_printf("Data[%d] = %x\r\n", Index, Value);
break;
}
}
if (!Status) {
xil_printf(" Invalidate all worked\r\n");
}
else {
xil_printf("Error: Invalidate dcache all not working\r\n");
}
xil_printf("-- DCache all Test Complete --\n\r");
return Status;
}
/*****************************************************************************/
/**
* @brief Perform Xil_ICacheInvalidateRange() on a few function pointers.
*
* @return
* - 0 is returned for a pass
*
* @note The function will hang if it fails.
*****************************************************************************/
s32 Xil_TestICacheRange(void)
{
Xil_ICacheInvalidateRange((INTPTR)Xil_TestICacheRange, 1024);
Xil_ICacheInvalidateRange((INTPTR)Xil_TestDCacheRange, 1024);
Xil_ICacheInvalidateRange((INTPTR)Xil_TestDCacheAll, 1024);
xil_printf("-- Invalidate icache range done --\r\n");
return 0;
}
/*****************************************************************************/
/**
* @brief Perform Xil_ICacheInvalidate() on a few function pointers.
*
* @return
* - 0 is returned for a pass
*
* @note The function will hang if it fails.
*****************************************************************************/
s32 Xil_TestICacheAll(void)
{
Xil_ICacheInvalidate();
xil_printf("-- Invalidate icache all done --\r\n");
return 0;
}
#endif

View File

@@ -0,0 +1,54 @@
/******************************************************************************
* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_testcache.h
*
* @addtogroup common_test_utils
* <h2>Cache test </h2>
* The xil_testcache.h file contains utility functions to test cache.
*
* @{
* <pre>
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a hbm 07/29/09 First release
* </pre>
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XIL_TESTCACHE_H /* prevent circular inclusions */
#define XIL_TESTCACHE_H /* by using protection macros */
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
extern s32 Xil_TestDCacheRange(void);
extern s32 Xil_TestDCacheAll(void);
extern s32 Xil_TestICacheRange(void);
extern s32 Xil_TestICacheAll(void);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
*@endcond
*/
/**
* @} End of "addtogroup common_test_utils".
*/

273
mbv/hal/xilinx/xil_testio.c Normal file
View File

@@ -0,0 +1,273 @@
/******************************************************************************
* Copyright (c) 2009 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_testio.c
* @addtogroup common_test_utils
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a hbm 08/25/09 First release
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xil_testio.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions ****************************/
/************************** Function Prototypes *****************************/
/**
*
* Endian swap a 16-bit word.
* @param Data is the 16-bit word to be swapped.
* @return The endian swapped value.
*
*/
static u16 Swap16(u16 Data)
{
return ((Data >> 8U) & 0x00FFU) | ((Data << 8U) & 0xFF00U);
}
/**
*
* Endian swap a 32-bit word.
* @param Data is the 32-bit word to be swapped.
* @return The endian swapped value.
*
*/
static u32 Swap32(u32 Data)
{
u16 Lo16;
u16 Hi16;
u16 Swap16Lo;
u16 Swap16Hi;
Hi16 = (u16)((Data >> 16U) & 0x0000FFFFU);
Lo16 = (u16)(Data & 0x0000FFFFU);
Swap16Lo = Swap16(Lo16);
Swap16Hi = Swap16(Hi16);
return (((u32)(Swap16Lo)) << 16U) | ((u32)Swap16Hi);
}
/*****************************************************************************/
/**
*
* @brief Perform a destructive 8-bit wide register IO test where the
* register is accessed using Xil_Out8 and Xil_In8, and comparing
* the written values by reading them back.
*
* @param Addr: a pointer to the region of memory to be tested.
* @param Length: Length of the block.
* @param Value: constant used for writing the memory.
*
* @return
* - -1 is returned for a failure
* - 0 is returned for a pass
*
*****************************************************************************/
s32 Xil_TestIO8(u8 *Addr, s32 Length, u8 Value)
{
u8 ValueIn;
s32 Index;
s32 Status = 0;
for (Index = 0; Index < Length; Index++) {
Xil_Out8((INTPTR)Addr, Value);
ValueIn = Xil_In8((INTPTR)Addr);
if ((Value != ValueIn) && (Status == 0)) {
Status = -1;
break;
}
}
return Status;
}
/*****************************************************************************/
/**
*
* @brief Perform a destructive 16-bit wide register IO test. Each location
* is tested by sequentially writing a 16-bit wide register, reading
* the register, and comparing value. This function tests three kinds
* of register IO functions, normal register IO, little-endian register
* IO, and big-endian register IO. When testing little/big-endian IO,
* the function performs the following sequence, Xil_Out16LE/Xil_Out16BE,
* Xil_In16, Compare In-Out values, Xil_Out16, Xil_In16LE/Xil_In16BE,
* Compare In-Out values. Whether to swap the read-in value before
* comparing is controlled by the 5th argument.
*
* @param Addr: a pointer to the region of memory to be tested.
* @param Length: Length of the block.
* @param Value: constant used for writing the memory.
* @param Kind: Type of test. Acceptable values are:
* XIL_TESTIO_DEFAULT, XIL_TESTIO_LE, XIL_TESTIO_BE.
* @param Swap: indicates whether to byte swap the read-in value.
*
* @return
* - -1 is returned for a failure
* - 0 is returned for a pass
*
*****************************************************************************/
s32 Xil_TestIO16(u16 *Addr, s32 Length, u16 Value, s32 Kind, s32 Swap)
{
u16 *TempAddr16;
u16 ValueIn = 0U;
s32 Index;
TempAddr16 = Addr;
Xil_AssertNonvoid(TempAddr16 != NULL);
for (Index = 0; Index < Length; Index++) {
switch (Kind) {
case XIL_TESTIO_LE:
Xil_Out16LE((INTPTR)TempAddr16, Value);
break;
case XIL_TESTIO_BE:
Xil_Out16BE((INTPTR)TempAddr16, Value);
break;
default:
Xil_Out16((INTPTR)TempAddr16, Value);
break;
}
ValueIn = Xil_In16((INTPTR)TempAddr16);
if ((Kind != 0) && (Swap != 0)) {
ValueIn = Swap16(ValueIn);
}
if (Value != ValueIn) {
return -1;
}
/* second round */
Xil_Out16((INTPTR)TempAddr16, Value);
switch (Kind) {
case XIL_TESTIO_LE:
ValueIn = Xil_In16LE((INTPTR)TempAddr16);
break;
case XIL_TESTIO_BE:
ValueIn = Xil_In16BE((INTPTR)TempAddr16);
break;
default:
ValueIn = Xil_In16((INTPTR)TempAddr16);
break;
}
if ((Kind != 0) && (Swap != 0)) {
ValueIn = Swap16(ValueIn);
}
if (Value != ValueIn) {
return -1;
}
TempAddr16 += sizeof(u16);
}
return 0;
}
/*****************************************************************************/
/**
*
* @brief Perform a destructive 32-bit wide register IO test. Each location
* is tested by sequentially writing a 32-bit wide register, reading
* the register, and comparing value. This function tests three kinds
* of register IO functions, normal register IO, little-endian register IO,
* and big-endian register IO. When testing little/big-endian IO,
* the function perform the following sequence, Xil_Out32LE/
* Xil_Out32BE, Xil_In32, Compare, Xil_Out32, Xil_In32LE/Xil_In32BE, Compare.
* Whether to swap the read-in value *before comparing is controlled
* by the 5th argument.
* @param Addr: a pointer to the region of memory to be tested.
* @param Length: Length of the block.
* @param Value: constant used for writing the memory.
* @param Kind: type of test. Acceptable values are:
* XIL_TESTIO_DEFAULT, XIL_TESTIO_LE, XIL_TESTIO_BE.
* @param Swap: indicates whether to byte swap the read-in value.
*
* @return
* - -1 is returned for a failure
* - 0 is returned for a pass
*
*****************************************************************************/
s32 Xil_TestIO32(u32 *Addr, s32 Length, u32 Value, s32 Kind, s32 Swap)
{
u32 *TempAddr;
u32 ValueIn = 0U;
s32 Index;
TempAddr = Addr;
Xil_AssertNonvoid(TempAddr != NULL);
for (Index = 0; Index < Length; Index++) {
switch (Kind) {
case XIL_TESTIO_LE:
Xil_Out32LE((INTPTR)TempAddr, Value);
break;
case XIL_TESTIO_BE:
Xil_Out32BE((INTPTR)TempAddr, Value);
break;
default:
Xil_Out32((INTPTR)TempAddr, Value);
break;
}
ValueIn = Xil_In32((INTPTR)TempAddr);
if ((Kind != 0) && (Swap != 0)) {
ValueIn = Swap32(ValueIn);
}
if (Value != ValueIn) {
return -1;
}
/* second round */
Xil_Out32((INTPTR)TempAddr, Value);
switch (Kind) {
case XIL_TESTIO_LE:
ValueIn = Xil_In32LE((INTPTR)TempAddr);
break;
case XIL_TESTIO_BE:
ValueIn = Xil_In32BE((INTPTR)TempAddr);
break;
default:
ValueIn = Xil_In32((INTPTR)TempAddr);
break;
}
if ((Kind != 0) && (Swap != 0)) {
ValueIn = Swap32(ValueIn);
}
if (Value != ValueIn) {
return -1;
}
TempAddr += sizeof(u32);
}
return 0;
}

View File

@@ -0,0 +1,76 @@
/******************************************************************************
* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_testio.h
*
* @addtogroup common_test_utils Test Utilities for Memory and Caches
* <h2>I/O test </h2>
* The xil_testio.h file contains utility functions to test endian related memory
* IO functions.
*
* A subset of the memory tests can be selected or all of the tests can be run
* in order. If there is an error detected by a subtest, the test stops and the
* failure code is returned. Further tests are not run even if all of the tests
* are selected.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00 hbm 08/05/09 First release
* </pre>
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XIL_TESTIO_H /* prevent circular inclusions */
#define XIL_TESTIO_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
/************************** Constant Definitions *****************************/
#define XIL_TESTIO_DEFAULT 0
#define XIL_TESTIO_LE 1
#define XIL_TESTIO_BE 2
/**
*@endcond
*/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
extern s32 Xil_TestIO8(u8 *Addr, s32 Length, u8 Value);
extern s32 Xil_TestIO16(u16 *Addr, s32 Length, u16 Value, s32 Kind, s32 Swap);
extern s32 Xil_TestIO32(u32 *Addr, s32 Length, u32 Value, s32 Kind, s32 Swap);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_test_utils".
*/

1575
mbv/hal/xilinx/xil_testmem.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,165 @@
/******************************************************************************
* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_testmem.h
* @addtogroup common_test_utils Test Utilities for Memory and Caches
*
* - Cache test: xil_testcache.h contains utility functions to test cache.
*
* - I/O test: The Xil_testio.h file contains endian related memory IO functions. A
* subset of the memory tests can be selected or all of the tests can be run in order.
* If there is an error detected by a subtest, the test stops and the failure code is
* returned. Further tests are not run even if all of the tests are selected.
*
* - Memory test: The xil_testmem.h file contains utility functions to test memory.
* A subset of the memory tests can be selected or all of the tests can be run
* in order. If there is an error detected by a subtest, the test stops and the
* failure code is returned. Further tests are not run even if all of the tests are selected.
*
*
* Following list describes the supported memory tests:
*
* - XIL_TESTMEM_ALLMEMTESTS: This test runs all of the subtests.
*
* - XIL_TESTMEM_INCREMENT: This test
* starts at 'XIL_TESTMEM_INIT_VALUE' and uses the incrementing value as the
* test value for memory.
*
* - XIL_TESTMEM_WALKONES: Also known as the Walking ones test. This test
* uses a walking '1' as the test value for memory.
* @code
* location 1 = 0x00000001
* location 2 = 0x00000002
* ...
* @endcode
*
* - XIL_TESTMEM_WALKZEROS: Also known as the Walking zero's test.
* This test uses the inverse value of the walking ones test
* as the test value for memory.
* @code
* location 1 = 0xFFFFFFFE
* location 2 = 0xFFFFFFFD
* ...
*@endcode
*
* - XIL_TESTMEM_INVERSEADDR: Also known as the inverse address test.
* This test uses the inverse of the address of the location under test
* as the test value for memory.
*
* - XIL_TESTMEM_FIXEDPATTERN: Also known as the fixed pattern test.
* This test uses the provided patters as the test value for memory.
* If zero is provided as the pattern the test uses '0xDEADBEEF".
*
* @warning
* The tests are <b>DESTRUCTIVE</b>. Run before any initialized memory spaces
* have been set up.
* The address provided to the memory tests is not checked for
* validity except for the NULL case. It is possible to provide a code-space
* pointer for this test to start with and ultimately destroy executable code
* causing random failures.
*
* @note
* Used for spaces where the address range of the region is smaller than
* the data width. If the memory range is greater than 2 ** width,
* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will
* repeat on a boundary of a power of two making it more difficult to detect
* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR
* tests suffer the same problem. Ideally, if large blocks of memory are to be
* tested, break them up into smaller regions of memory to allow the test
* patterns used not to repeat over the region tested.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a hbm 08/25/09 First release
* 7.5 mus 03/10/21 Added new set of Xil_TestMem32, Xil_TestMem16 and
* Xil_TestMem8 APIs to support memory test for memory
* regions mapped at extended addresses
* (addresses > 4 GB). These new set of APIs would be
* compiled only for 32 bit Microblaze processor, if
* XPAR_MICROBLAZE_ADDR_SIZE is greater than 32.
* It fixes CR#1089129.
* </pre>
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XIL_TESTMEM_H /* prevent circular inclusions */
#define XIL_TESTMEM_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/* xutil_memtest defines */
#define XIL_TESTMEM_INIT_VALUE 1U
/** @name Memory subtests
* @{
*/
/**
* See the detailed description of the subtests in the file description.
*/
#define XIL_TESTMEM_ALLMEMTESTS 0x00U
#define XIL_TESTMEM_INCREMENT 0x01U
#define XIL_TESTMEM_WALKONES 0x02U
#define XIL_TESTMEM_WALKZEROS 0x03U
#define XIL_TESTMEM_INVERSEADDR 0x04U
#define XIL_TESTMEM_FIXEDPATTERN 0x05U
#define XIL_TESTMEM_MAXTEST XIL_TESTMEM_FIXEDPATTERN
/* @} */
#if !defined(__aarch64__) && !defined(__arch64__)
#define NUM_OF_BITS_IN_BYTE 8U
#define NUM_OF_BYTES_IN_HW 2U
#define NUM_OF_BITS_IN_HW 16U
#define NUM_OF_BYTES_IN_WORD 4U
#define NUM_OF_BITS_IN_WORD 32U
#endif
/***************** Macros (Inline Functions) Definitions *********************/
/**
*@endcond
*/
/************************** Function Prototypes ******************************/
/* xutil_testmem prototypes */
#if defined(__MICROBLAZE__) && !defined(__arch64__) && (XPAR_MICROBLAZE_ADDR_SIZE > 32)
extern s32 Xil_TestMem32(u32 AddrLow, u32 AddrHigh, u32 Words, u32 Pattern, u8 Subtest);
extern s32 Xil_TestMem16(u32 AddrLow, u32 AddrHigh, u32 Words, u16 Pattern, u8 Subtest);
extern s32 Xil_TestMem8(u32 AddrLow, u32 AddrHigh, u32 Words, u8 Pattern, u8 Subtest);
#else
extern s32 Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest);
extern s32 Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest);
extern s32 Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest);
#endif
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_test_utils".
*/

203
mbv/hal/xilinx/xil_types.h Normal file
View File

@@ -0,0 +1,203 @@
/******************************************************************************
* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_types.h
*
* @addtogroup common_types Basic Data types for Xilinx&reg; Software IP
*
* The xil_types.h file contains basic types for Xilinx software IP. These data types
* are applicable for all processors supported by Xilinx.
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 07/14/09 First release
* 3.03a sdm 05/30/11 Added Xuint64 typedef and XUINT64_MSW/XUINT64_LSW macros
* 5.00 pkp 05/29/14 Made changes for 64 bit architecture
* srt 07/14/14 Use standard definitions from stdint.h and stddef.h
* Define LONG and ULONG datatypes and mask values
* 7.00 mus 01/07/19 Add cpp extern macro
* 7.1 aru 08/19/19 Shift the value in UPPER_32_BITS only if it
* is 64-bit processor
* </pre>
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XIL_TYPES_H /* prevent circular inclusions */
#define XIL_TYPES_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
/************************** Constant Definitions *****************************/
#ifndef TRUE
# define TRUE 1U
#endif
#ifndef FALSE
# define FALSE 0U
#endif
#ifndef NULL
#define NULL 0U
#endif
#define XIL_COMPONENT_IS_READY 0x11111111U /**< In device drivers, This macro will be
assigend to "IsReady" member of driver
instance to indicate that driver
instance is initialized and ready to use. */
#define XIL_COMPONENT_IS_STARTED 0x22222222U /**< In device drivers, This macro will be assigend to
"IsStarted" member of driver instance
to indicate that driver instance is
started and it can be enabled. */
/* @name New types
* New simple types.
* @{
*/
#ifndef __KERNEL__
#ifndef XBASIC_TYPES_H
/*
* guarded against xbasic_types.h.
*/
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
/** @}*/
#define __XUINT64__
typedef struct
{
u32 Upper;
u32 Lower;
} Xuint64;
/*****************************************************************************/
/**
* @brief Return the most significant half of the 64 bit data type.
*
* @param x is the 64 bit word.
*
* @return The upper 32 bits of the 64 bit word.
*
******************************************************************************/
#define XUINT64_MSW(x) ((x).Upper)
/*****************************************************************************/
/**
* @brief Return the least significant half of the 64 bit data type.
*
* @param x is the 64 bit word.
*
* @return The lower 32 bits of the 64 bit word.
*
******************************************************************************/
#define XUINT64_LSW(x) ((x).Lower)
#endif /* XBASIC_TYPES_H */
/*
* xbasic_types.h does not typedef s* or u64
*/
/** @{ */
typedef char char8;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef uint64_t u64;
typedef int sint32;
typedef intptr_t INTPTR;
typedef uintptr_t UINTPTR;
typedef ptrdiff_t PTRDIFF;
/** @}*/
#if !defined(LONG) || !defined(ULONG)
typedef long LONG;
typedef unsigned long ULONG;
#endif
#define ULONG64_HI_MASK 0xFFFFFFFF00000000U
#define ULONG64_LO_MASK ~ULONG64_HI_MASK
#else
#include <linux/types.h>
#endif
/** @{ */
/**
* This data type defines an interrupt handler for a device.
* The argument points to the instance of the component
*/
typedef void (*XInterruptHandler) (void *InstancePtr);
/**
* This data type defines an exception handler for a processor.
* The argument points to the instance of the component
*/
typedef void (*XExceptionHandler) (void *InstancePtr);
/**
* @brief Returns 32-63 bits of a number.
* @param n : Number being accessed.
* @return Bits 32-63 of number.
*
* @note A basic shift-right of a 64- or 32-bit quantity.
* Use this to suppress the "right shift count >= width of type"
* warning when that quantity is 32-bits.
*/
#if defined (__aarch64__) || defined (__arch64__)
#define UPPER_32_BITS(n) ((u32)(((n) >> 16) >> 16))
#else
#define UPPER_32_BITS(n) 0U
#endif
/**
* @brief Returns 0-31 bits of a number
* @param n : Number being accessed.
* @return Bits 0-31 of number
*/
#define LOWER_32_BITS(n) ((u32)(n))
/************************** Constant Definitions *****************************/
#ifndef TRUE
#define TRUE 1U
#endif
#ifndef FALSE
#define FALSE 0U
#endif
#ifndef NULL
#define NULL 0U
#endif
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
*@endcond
*/
/**
* @} End of "addtogroup common_types".
*/

1238
mbv/hal/xilinx/xil_util.c Normal file

File diff suppressed because it is too large Load Diff

232
mbv/hal/xilinx/xil_util.h Normal file
View File

@@ -0,0 +1,232 @@
/******************************************************************************/
/**
* Copyright (c) 2019 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/****************************************************************************/
/**
* @file xil_util.h
* @addtogroup common_utilities Common Utility APIs
* @{
* @details
*
* xil_util.h file contains xil utility functions declarations
* Except few functions, most of these functions are wrappers to standard functions.
* The standard string functions do not validate the input and that results into
* buffer overflows. To avoid it, the wrapper function validates the input and
* then passed to standard function. There are few constant time functions
* ( xxx_CT() ) which are used to compare the data in constant time.
* The constant time functions should be used while comparing secure data
* like password, keys which prevent disclosing of the data using
* timing analysis.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------
* 6.4 mmd 04/21/19 First release.
* 6.5 kal 02/29/20 Added Xil_ConvertStringToHexBE API
* 7.3 kal 06/30/20 Converted Xil_Ceil macro to API
* rpo 08/19/20 Added function for read, modify and write
* bsv 08/21/20 Added XSECURE_TEMPORAL_CHECK macro to add
* redundancy in security critical functions, to avoid
* glitches from altering the return values of security
* critical functions. The macro requires a label to be
* passed to "go to" in case of error.
* kpt 09/03/20 Added XSECURE_TEMPORAL_IMPL macro for redundancy
* kal 09/22/20 Changed the param type from const char to const char*
* to avoid copying key onto stack
* td 10/16/20 Added Xil_Strcpy, Xil_Strcat, Xil_SecureMemCpy and
* Xil_MemCmp functions
* am 10/13/20 Resolved Coverity warning
* td 11/19/20 Updated XSECURE_TEMPORAL_CHECK and
* XSECURE_TEMPORAL_IMPL to fix MISRA C Rule 15.3
* 7.4 am 11/26/20 Added Xil_StrCpyRange function
* 7.6 kpt 07/15/21 Added Xil_SecureZeroize function
* 7.7 kpt 11/09/21 Added Xil_SMemCmp, Xil_SMemCmp_CT, Xil_SMemCpy,
* Xil_SMemSet, Xil_SStrCat, Xil_SStrCmp, Xil_SStrCmp_CT
* Xil_SStrCpy functions
* 7.7 sk 01/10/22 Update functions return type to fix misra_c_2012_
* directive_4_6 violations.
* mmd 02/28/22 Added Xil_SMemMove function prototype
*
* </pre>
*
*****************************************************************************/
#ifndef XIL_UTIL_H_
#define XIL_UTIL_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "xil_types.h"
#include "xil_io.h"
#include "xstatus.h"
/*************************** Constant Definitions *****************************/
#define XIL_SIZE_OF_NIBBLE_IN_BITS 4U
#define XIL_SIZE_OF_BYTE_IN_BITS 8U
/* Maximum string length handled by Xil_ValidateHexStr function */
#define XIL_MAX_HEX_STR_LEN 512U
/****************** Macros (Inline Functions) Definitions *********************/
#ifdef __GNUC__
/******************************************************************************/
/**
*
* Updates the return value of the called function into Var and VarTmp variables
* for redundancy. This is to avoid glitches from altering the return values of
* security critical functions.
*
* @param Var is the variable which holds the return value of function
* executed
* @param VarTmp is the variable which holds the value stored in Var
* @param Function is the function to be executed
* @param Other params are arguments to the called function
*
* @return None
*
******************************************************************************/
#define XSECURE_TEMPORAL_IMPL(Var, VarTmp, Function, ...) \
{ \
Var = XST_FAILURE; \
VarTmp = XST_FAILURE; \
Var = Function(__VA_ARGS__); \
VarTmp = Var; \
}
/******************************************************************************/
/**
*
* Adds redundancy while checking the status of the called function.
* This is to avoid glitches from altering the return values of security
* critical functions. The macro requires a label to be passed to "go to"
* in case of error.
*
* @param Label is the label defined in function and the control
* will jump to the label in case of XST_FAILURE
* @param Status is the variable which holds the return value of
* function executed
* @param Function is the function to be executed
* @param Other params are arguments to the called function
*
* @return None
*
******************************************************************************/
#define XSECURE_TEMPORAL_CHECK(Label, Status, Function, ...) \
{ \
volatile int StatusTmp = XST_FAILURE; \
XSECURE_TEMPORAL_IMPL(Status, StatusTmp, Function, __VA_ARGS__); \
if ((Status != XST_SUCCESS) || \
(StatusTmp != XST_SUCCESS)) { \
Status |= StatusTmp;\
goto Label; \
} \
}
#endif
/*************************** Function Prototypes ******************************/
/* Ceils the provided float value */
s32 Xil_Ceil(float Value);
/* Converts input character to nibble */
u32 Xil_ConvertCharToNibble(u8 InChar, u8 *Num);
/* Convert input hex string to array of 32-bits integers */
u32 Xil_ConvertStringToHex(const char *Str, u32 *buf, u8 Len);
/* Waits for specified event */
u32 Xil_WaitForEvent(u32 RegAddr, u32 EventMask, u32 Event, u32 Timeout);
/* Waits for specified events */
u32 Xil_WaitForEvents(u32 EventsRegAddr, u32 EventsMask, u32 WaitEvents,
u32 Timeout, u32* Events);
/* Validate input hex character */
u32 Xil_IsValidHexChar(const char *Ch);
/* Validate the input string contains only hexadecimal characters */
u32 Xil_ValidateHexStr(const char *HexStr);
/* Convert string to hex numbers in little enidian format */
u32 Xil_ConvertStringToHexLE(const char *Str, u8 *Buf, u32 Len);
/* Returns length of the input string */
u32 Xil_Strnlen(const char *Str, u32 MaxLen);
/* Convert string to hex numbers in big endian format */
u32 Xil_ConvertStringToHexBE(const char * Str, u8 * Buf, u32 Len);
/*Read, Modify and Write to an address*/
void Xil_UtilRMW32(u32 Addr, u32 Mask, u32 Value);
/* Copies source string to destination string */
int Xil_Strcpy(char *DestPtr, const char *SrcPtr, const u32 Size);
/* Copies specified range from source string to destination string */
int Xil_StrCpyRange(const u8 *Src, u8 *Dest, u32 From, u32 To, u32 MaxSrcLen,
u32 MaxDstLen);
/* Appends string2 to string1 */
int Xil_Strcat(char* Str1Ptr, const char* Str2Ptr, const u32 Size);
/* Copies Len bytes from source memory to destination memory */
int Xil_SecureMemCpy(void * DestPtr, u32 DestPtrLen, const void * SrcPtr, u32 Len);
/* Compares Len bytes from memory1 and memory2 */
int Xil_MemCmp(const void * Buf1Ptr, const void * Buf2Ptr, u32 Len);
/* Zeroizes the memory of given length */
int Xil_SecureZeroize(u8 *DataPtr, const u32 Length);
/* Copies Len bytes from source memory to destination memory */
int Xil_SMemCpy (void *Dest, const u32 DestSize,
const void *Src, const u32 SrcSize, const u32 CopyLen);
/* Copies Len bytes from source memory to destination memory, allows
overlapped memory between source and destination */
int Xil_SMemMove(void *Dest, const u32 DestSize,
const void *Src, const u32 SrcSize, const u32 CopyLen);
/* Compares Len bytes between source and destination memory */
int Xil_SMemCmp (const void *Src1, const u32 Src1Size,
const void *Src2, const u32 Src2Size, const u32 CmpLen);
/* Compares Len bytes between source and destination memory with constant time */
int Xil_SMemCmp_CT (const void *Src1, const u32 Src1Size,
const void *Src2, const u32 Src2Size, const u32 CmpLen);
/* Sets the destination memory of given length with given data */
int Xil_SMemSet (void *Dest, const u32 DestSize,
const u8 Data, const u32 Len);
/* Copies source string to destination string */
int Xil_SStrCpy (u8 *DestStr, const u32 DestSize,
const u8 *SrcStr, const u32 SrcSize);
/* Compares source string with destination string */
int Xil_SStrCmp (const u8 *Str1, const u32 Str1Size,
const u8 *Str2, const u32 Str2Size);
/* Compares source string with destination string with constant time */
int Xil_SStrCmp_CT (const u8 *Str1, const u32 Str1Size,
const u8 *Str2, const u32 Str2Size);
/* Concatenates source string to destination string */
int Xil_SStrCat (u8 *DestStr, const u32 DestSize,
const u8 *SrcStr, const u32 SrcSize);
#ifdef __cplusplus
}
#endif
#endif /* XIL_UTIL_H_ */
/**
* @} End of "addtogroup common_utilities".
*/

View File

@@ -0,0 +1,147 @@
/******************************************************************************
* Copyright (c) 2014 - 2021 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xplatform_info.c
* @addtogroup common_platform_info Hardware Platform Information
* @{
* This file contains information about hardware for which the code is built
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 5.00 pkp 12/15/14 Initial release
* 5.04 pkp 01/12/16 Added platform information support for Cortex-A53 32bit
* mode
* 6.00 mus 17/08/16 Removed unused variable from XGetPlatform_Info
* 6.4 ms 05/23/17 Added PSU_PMU macro to support XGetPSVersion_Info
* function for PMUFW.
* ms 06/13/17 Added PSU_PMU macro to provide support of
* XGetPlatform_Info function for PMUFW.
* mus 08/17/17 Add EL1 NS mode support for
* XGet_Zynq_UltraMp_Platform_info and XGetPSVersion_Info
* APIs.
* 7.0 aru 03/15/19 Check for versal before aarch64 and armr5
* in XGetPlatform_Info()
* 7.2 adk 08/01/20 Added versal support for the XGetPSVersion_Info function.
* 7.6 mus 08/23/21 Updated prototypes for functions which are not taking any
* arguments with void keyword. This has been done to fix
* compilation warnings with "-Wstrict-prototypes" flag.
* It fixes CR#1108601.
* 7.6 mus 08/30/21 Updated flag checking to fix compilation warnings
* reported with "-Wundef" flag. It fixes CR#1108601.
* 7.7 mus 11/02/21 Updated XGet_Zynq_UltraMp_Platform_info and
* XGetPSVersion_Info to fix compilation warning
* reported with "-Wundef" flag CR#1111453
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_io.h"
#include "xplatform_info.h"
#if defined (__aarch64__)
#include "bspconfig.h"
#include "xil_smc.h"
#endif
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/**
*
* @brief This API is used to provide information about platform
*
* @return The information about platform defined in xplatform_info.h
*
******************************************************************************/
u32 XGetPlatform_Info(void)
{
#if defined (versal)
return XPLAT_VERSAL;
#elif defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32) || defined (PSU_PMU)
return XPLAT_ZYNQ_ULTRA_MP;
#elif defined (__microblaze__)
return XPLAT_MICROBLAZE;
#else
return XPLAT_ZYNQ;
#endif
}
/*****************************************************************************/
/**
*
* @brief This API is used to provide information about zynq ultrascale MP platform
*
* @return The information about zynq ultrascale MP platform defined in
* xplatform_info.h
*
******************************************************************************/
#if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
u32 XGet_Zynq_UltraMp_Platform_info(void)
{
#if defined (__aarch64__) && (EL1_NONSECURE == 1)
XSmc_OutVar reg;
/*
* This SMC call will return,
* idcode - upper 32 bits of reg.Arg0
* version - lower 32 bits of reg.Arg1
*/
reg = Xil_Smc(GET_CHIPID_SMC_FID,0,0, 0, 0, 0, 0, 0);
return (u32)((reg.Arg1 >> XPLAT_INFO_SHIFT) & XPLAT_INFO_MASK);
#else
u32 reg;
reg = ((Xil_In32(XPLAT_PS_VERSION_ADDRESS) >> XPLAT_INFO_SHIFT )
& XPLAT_INFO_MASK);
return reg;
#endif
}
#endif
/*****************************************************************************/
/**
*
* @brief This API is used to provide information about PS Silicon version
*
* @return The information about PS Silicon version.
*
******************************************************************************/
#if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32) || defined (PSU_PMU) || defined (versal)
u32 XGetPSVersion_Info(void)
{
#if defined (__aarch64__) && (EL1_NONSECURE == 1)
/*
* This SMC call will return,
* idcode - upper 32 bits of reg.Arg0
* version - lower 32 bits of reg.Arg1
*/
XSmc_OutVar reg;
reg = Xil_Smc(GET_CHIPID_SMC_FID,0,0, 0, 0, 0, 0, 0);
return (u32)((reg.Arg1 & XPS_VERSION_INFO_MASK) >>
XPS_VERSION_INFO_SHIFT);
#else
u32 reg;
reg = (Xil_In32(XPLAT_PS_VERSION_ADDRESS)
& XPS_VERSION_INFO_MASK);
return (reg >> XPS_VERSION_INFO_SHIFT);
#endif
}
#endif
/** @} */

View File

@@ -0,0 +1,115 @@
/******************************************************************************
* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xplatform_info.h
*
*
* @addtogroup common_platform_info APIs to Get Platform Information
*
*
* The xplatform_info.h file contains definitions for various available Xilinx&reg;
* platforms. Also, it contains prototype of APIs, which can be used to get the
* platform information.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- --------- -------------------------------------------------------
* 6.4 ms 05/23/17 Added PSU_PMU macro to support XGetPSVersion_Info
* function for PMUFW.
* 7.2 adk 08/01/20 Added versal support for the XGetPSVersion_Info function.
* 7.6 mus 08/23/21 Updated prototypes for functions which are not taking any
* arguments with void keyword. This has been done to fix
* compilation warnings with "-Wstrict-prototypes" flag.
* It fixes CR#1108601.
* 7.6 mus 08/30/21 Updated flag checking to fix compilation warnings
* reported with "-Wundef" flag.
* 7.7 sk 01/10/22 Update XPLAT_INFO_MASK from signed to unsigned to fix
* misra_c_2012_rule_10_4 violation.
* </pre>
*
******************************************************************************/
/**
*@cond nocomments
*/
#ifndef XPLATFORM_INFO_H /* prevent circular inclusions */
#define XPLATFORM_INFO_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
/************************** Constant Definitions *****************************/
#if defined (versal)
#define XPAR_PMC_TAP_BASEADDR 0xF11A0000U
#define XPAR_PMC_TAP_VERSION_OFFSET 0x00000004U
#define XPLAT_PS_VERSION_ADDRESS (XPAR_PMC_TAP_BASEADDR + \
XPAR_PMC_TAP_VERSION_OFFSET)
#else
#define XPAR_CSU_BASEADDR 0xFFCA0000U
#define XPAR_CSU_VER_OFFSET 0x00000044U
#define XPLAT_PS_VERSION_ADDRESS (XPAR_CSU_BASEADDR + \
XPAR_CSU_VER_OFFSET)
#endif
#define XPLAT_ZYNQ_ULTRA_MP_SILICON 0x0
#define XPLAT_ZYNQ_ULTRA_MP 0x1
#define XPLAT_ZYNQ_ULTRA_MPVEL 0x2
#define XPLAT_ZYNQ_ULTRA_MPQEMU 0x3
#define XPLAT_ZYNQ 0x4
#define XPLAT_MICROBLAZE 0x5
#define XPLAT_VERSAL 0x6U
#define XPS_VERSION_1 0x0
#define XPS_VERSION_2 0x1
#define XPLAT_INFO_MASK (0xFU)
#if defined (versal)
#define XPS_VERSION_INFO_MASK 0xFF00U
#define XPS_VERSION_INFO_SHIFT 0x8U
#define XPLAT_INFO_SHIFT 0x18U
#else
#define XPS_VERSION_INFO_MASK (0xF)
#define XPS_VERSION_INFO_SHIFT 0x0U
#define XPLAT_INFO_SHIFT 0xCU
#endif
/**************************** Type Definitions *******************************/
/**
*@endcond
*/
/***************** Macros (Inline Functions) Definitions *********************/
u32 XGetPlatform_Info(void);
#if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32) || defined (PSU_PMU) || defined (versal)
u32 XGetPSVersion_Info(void);
#endif
#if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32)
u32 XGet_Zynq_UltraMp_Platform_info(void);
#endif
/************************** Function Prototypes ******************************/
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_platform_info".
*/

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