riscv/niosv: Adding a new NIOS V BSP to RISC-V

This commit is contained in:
Kevin Kirspel
2024-08-07 15:28:23 -04:00
committed by Kinsey Moore
parent d0e9ec85b0
commit e9957cd8e3
45 changed files with 5596 additions and 0 deletions

401
bsps/riscv/niosv/README.md Normal file
View File

@@ -0,0 +1,401 @@
# Intel NIOSV BSP
The Intel NIOSV BSP implementation provides the base components needed for any
NIOSV specific BSP: clock, console, irq, and timer. An example BSP for the Intel
Cyclone 10 LP Evaluation Board is included as a reference design and test
hardware. The base BSP assumes that the FPGA and NIOSV has the following
devices/IP attached to the processor.
* Generic QUAD SPI Controlller II (EPCQ) - the serial flash memory device
connected to the FPGA and contains the FPGA configuration, software image, and
user data area.
* On Chip ROM - an On-Chip Memory IP configured as ROM. Contains boot loader to
load software image from the EPCQ device.
* On Chip RAM - an On-Chip Memory IP configured as RAM. Used by the boot loader
for data and bss. Can be used by software image as well.
* External RAM Interface - an external memory device IP. In the case of the
Cyclone 10 LP Evaluation Board, a hyperbus controller which is attached to a
HyperRAM device.
* Benchmark Timer - a modified Interval Timer IP which will be used as the BSPs
benchmark timer.
* Watchdog Timer - an Interval Timer IP configured as a watchdog which will be
used to reset the NIOSV.
* JTAG UART - an JTAG UART IP which will be used as the console port.
The following BSP parameters need to be set in the config.ini file when building
RTEMS in order to set up the memory map for the NIOSV:
* NIOSV_EPCQ_ROM_REGION_BEGIN - the starting address of the EPCQ device
attached to the NIOSV
* NIOSV_EPCQ_ROM_REGION_SIZE - the size in bytes of the EPCQ device.
* NIOSV_ONCHIP_ROM_REGION_BEGIN - the starting address of the onchip rom IP
attached to the NIOSV
* NIOSV_ONCHIP_ROM_REGION_SIZE - the size in bytes of the onchip rom IP device.
* NIOSV_ONCHIP_RAM_REGION_BEGIN - the starting address of the onchip ram IP
attached to the NIOSV
* NIOSV_ONCHIP_RAM_REGION_SIZE - the size in bytes of the onchip ram IP device.
* NIOSV_EXT_RAM_REGION_BEGIN - the starting address of the external ram
interface IP attached to the NIOSV
* NIOSV_EXT_RAM_REGION_SIZE - the size in bytes of the external ram interface
IP device.
* NIOSV_IS_NIOSVG - Whether or not the **NIOS V/g** processor is used.
* NIOSV_HAS_FP - Whether or not the **NIOS V/g** processor has a FPU.
## Intel Cyclone 10 LP Evaluation Board Example
The **rtems_vm.jic** file included with this BSP is a Cyclone 10 LP Evaluation
Board programming file that can be downloaded to the board and has the following
IP:
* NIOS V/m Microcontroller
* timer_sw_agent - Data Master: 0x10000100 - 0x1000013f
* dm_agent - Instruction Master: 0x10030000 - 0x1003ffff,
Data Master: 0x10030000 - 0x1003ffff
* Generic QUAD SPI Controlller II
* avl_csr - Data Master: 0x10000140 - 0x1000017f
* avl_mem - Data Master: 0x11000000 - 0x11ffffff
* On-Chip Memory (RAM or ROM) configured as ROM
* s1 - Instruction Master: 0x10010000 - 0x10010fff,
Data Master: 0x10010000 - 0x10010fff
* On-Chip Memory (RAM or ROM) configured as RAM
* s1 - Instruction Master: 0x10020000 - 0x10021fff,
Data Master: 0x10020000 - 0x10021fff
* HyperBus Controller (x8) - Infineon HyperBus Controller IP which can control
up to 2 HyperRAM devices. The Cyclone 10 LP Evaluation board has the HyperRAM
connected to the 2nd device (chip select 2). The boot loader in the On-Chip ROM
sets the HyperRAM base address to 0x01000000 in the slave register.
* axi4_slave_memory - Instruction Master: 0x00000000 - 0x0fffffff,
Data Master: 0x00000000 - 0x0fffffff
* axi4_slave_register - Data Master: 0x10000000 - 0x100000ff
* Interval Timer configured for free running benchmark timer. Modified from
original Interval Timer to include a prescalar to adjust the clock rate.
* s1 - Data Master: 0x10000180 - 0x1000019f
* Interval Timer configured as watchdog timer
* s1 - Data Master: 0x100001c0 - 0x100001df
* System ID Peripheral
* control_slave - Data Master: 0x10000200 - 0x10000207
* JTAG UART
* jtag_slave - Data Master: 0x10000208 - 0x1000020f
* PIO (Parallel I/O) configured as outputs for turning on LEDs
* s1 - Data Master: 0x100001a0 - 0x100001bf
* PIO (Parallel I/O) configured as inputs for reading dip switch settings
* s1 - Data Master: 0x100001f0 - 0x100001ff
* PIO (Parallel I/O) configured as inputs for reading push buttons
* s1 - Data Master: 0x100001e0 - 0x100001ef
Here are the associated config.ini entries:
[riscv/niosvc10lp]
NIOSV_EPCQ_ROM_REGION_BEGIN = 0x11000000
NIOSV_EPCQ_ROM_REGION_SIZE = 0x01000000
NIOSV_ONCHIP_ROM_REGION_BEGIN = 0x10010000
NIOSV_ONCHIP_ROM_REGION_SIZE = 4096
NIOSV_ONCHIP_RAM_REGION_BEGIN = 0x10020000
NIOSV_ONCHIP_RAM_REGION_SIZE = 8192
NIOSV_EXT_RAM_REGION_BEGIN = 0x01000000
NIOSV_EXT_RAM_REGION_SIZE = 0x00800000
NIOSV_IS_NIOSVG = False
NIOSV_HAS_FP = False
The **rtems_vg.jic** file included has the same peripheral IP but with a
**NIOS V/g** processor.
Here are the associated config.ini entries:
[riscv/niosvc10lp]
NIOSV_EPCQ_ROM_REGION_BEGIN = 0x11000000
NIOSV_EPCQ_ROM_REGION_SIZE = 0x01000000
NIOSV_ONCHIP_ROM_REGION_BEGIN = 0x10010000
NIOSV_ONCHIP_ROM_REGION_SIZE = 4096
NIOSV_ONCHIP_RAM_REGION_BEGIN = 0x10020000
NIOSV_ONCHIP_RAM_REGION_SIZE = 8192
NIOSV_EXT_RAM_REGION_BEGIN = 0x01000000
NIOSV_EXT_RAM_REGION_SIZE = 0x00800000
NIOSV_IS_NIOSVG = True
NIOSV_HAS_FP = False
The **rtems_vgfp.jic** file included has the same peripheral IP but with a
**NIOS V/g** processor with the FPU enabled.
Here are the associated config.ini entries:
[riscv/niosvc10lp]
NIOSV_EPCQ_ROM_REGION_BEGIN = 0x11000000
NIOSV_EPCQ_ROM_REGION_SIZE = 0x01000000
NIOSV_ONCHIP_ROM_REGION_BEGIN = 0x10010000
NIOSV_ONCHIP_ROM_REGION_SIZE = 4096
NIOSV_ONCHIP_RAM_REGION_BEGIN = 0x10020000
NIOSV_ONCHIP_RAM_REGION_SIZE = 8192
NIOSV_EXT_RAM_REGION_BEGIN = 0x01000000
NIOSV_EXT_RAM_REGION_SIZE = 0x00800000
NIOSV_IS_NIOSVG = True
NIOSV_HAS_FP = True
### Intel Cyclone 10 LP Evaluation Board Implementation Details
In order to make it easier to create a RTEMS BSP for a NIOSV project built in
Quartus Prime, this BSP used the **system.h** file that is generated by the
Quartus Prime's BSP editor. The file was renamed to **bsp_system.h**. The header
guard was modifed from **__SYSTEM_H_** to **__BSP_SYSTEM_H_** to reflect the new
name of the file. The **#include "linker.h"** line was also removed as that is
not needed.
This BSP also makes use of the device driver code generated from the Quartus
Prime's BSP editor with some minor changes to make the code easier to read. A
developer could use the same strategy or create something from scratch.
The hyperbus controller IP that comes with the Cyclone 10 LP Evaluation Board is
proprietary and requires a license. Instead, the BSP uses a hyperbus controller
IP that can be requested from Infineon (no link provided because it most likely
will change). Just use your favorite search engine and you should be able find
the request form. You may need to answer some marketing questions but I had no
trouble getting it. The IP is written for Xilinx/AMD parts so you will have to
write some Verilog code to connect it to a Cyclone 10 LP. I was a novice so it
took me a while to get it to work. The biggest revelation that took me forever
to figure out was that you have to use a Input Delay From Pin assignment to meet
RWDS timing on a read. I was trying to use logic for this which was not the
right approach.
The On-Chip Memory IP configured as ROM needs to have a boot loader pre-loaded.
Follow the instructions outlined in the Quartus Prime software user guide to
initialize the ROM with the **bootloader_niosvc10lp_xx.hex** file include with
this BSP. This boot loader will initialize the hyperbus controller and load any
application image found at offset 0x100000 within the EPCQ device to the
HyperRAM (i.e. NIOSV_EXT_RAM_REGION_BEGIN). The boot loader will validate the
application image before loading it into the HyperRAM using a CRC32 algorithm.
If the image was loaded successfully in the HyperRAM, the first two LEDs will be
on; otherwise, the first, second, and fourth LEDs will be on indicating a load
failure.
The application image must have the following header information located at
offset 0x100000 within the EPCQ device in order for the boot loader to load the
application into the HyperRAM:
```
typedef struct
{
uint32_t offset; //The offset of binary code image relative to the start of
//the header information
uint32_t size; //The size of the binary code image in bytes
uint32_t crc; //The calculated CRC value for the binary code image
//(in accordance with crc.c/h)
char version[11]; //A "C" string version of the binary code image
//(i.e. "1.00.0000")
}file_header_t;
```
This is the typical memory map within the EPCQ device.
0x000000: <FPGA configuration image>
0x100000: <file_header_t><binary code image>
### Intel Cyclone 10 LP Evaluation Board Build Environment
The following are the steps I performed to create the **rtems_vm.jic** file used
to program the Cyclone 10 LP Evaluation Board. The process is broken down to
three phases. The first phase is to generate BSP files from an initial
compilation (SOF file) of the system to get the **system.h** and any C device
driver code that could to be used in the RTEMS NIOSV BSP and boot loader. The
second phase is to compile a final SOF file that contains a FPGA configuration
with the On-Chip ROM loaded with the boot loader hex file. The third phase is to
combine the FPGA configuration SOF file and an application HEX file into a JIC
file that can be programmed on the FPGA EPCQ device.
#### Phase 1
Here is an outline of the first phase to generate BSP source files from a SOF
file (see the Cyclone 10 LP Evaluation Board project that comes with the board
for more details). The main outputs from this process that are useful for a
RTEMS BSP, is the **system.h** file and any C device driver source files that
can be used as a basis for RTEMS device drivers.
* Create a new project in the Quartus Prime software (I used the 23.1std.0
version)
* Set the project device to the Cyclone 10 LP 10CL025YU256I7G (check you board
to confirm)
* Set the device and pins options (use the project that comes with the eval
board for the correct settings).
* Use Platform Designer within Quartus Prime to create a system that implemets
the IP listed in the sections above.
* I have placed pictures of my Platform Designer system in the BSP
(see **Platform Designer X.png** files)
* You will still need to setup each IP correctly (use the eval board
reference design as guidance).
* For the first compilation, the ROM memory will not be initialized as you
will need to create a boot loader in the next phase.
* After completing the design, generate the HDL.
* Add a top level Verilog file to connect your generated system to the I/O pins
(see **cl10lp_rtems.v** file in BSP for an example).
* Add a SDC file to constrain the system (see **cl10lp_rtems.sdc** file in BSP
for an example)
* Compile the design.
* In the Pin Planner, assign the location for each I/O pin (use the eval board
reference design for the correct location and pin settings).
* In the Assignment editor, add an "Input Delay From Pin" assignment
(see **Assignment Editor.png** file in BSP).
* Re-compile the design.
* Use the **niosv-bsp-editor.exe** tool that comes with Quartus Prime to
generate a software BSP using the compiled SOF file.
* From the BSP generation process, the **system.h** and any C driver files can
be used to make a RTEMS BSP and boot loader.
This is the RTEMS build environment structure I used to create the RTEMS NIOSV
BSP, boot loader, and application.
```
└── home directory // the home directory of the user
└── sandbox2 // a sandbox directory for development
├── rtems // the rtems base directory for all things
│ // RTEMS (source code and install directory)
├── 6 // the rtems install directory
└── src // the rtems directory for gitlab repos
├── rsb // the rtems source builder repo directory
├── rtems // the rtems OS repo directory
└── rtems-tools // the rtems tools repo directory
├── bin // the directory where the boot and app exe
│ // outputs will be placed
├── gdb // the directory where the boot and app
│ // debug ELF outputs will be placed
├── head_file // an application that will place the
│ // <file_header_t> information in the binary
│ // output
├── boot // the NIOSV bootloader directory for On-Chip
│ // Memory (ROM)
└── app // the user application directory (RTEMS
// console app)
```
In your home directory, add a .gdbinit file to add the "sandbox/gdb" directory
as a safe path for loading files with GDB.
* add-auto-load-safe-path ~/sandbox/gdb
Please see the **boot.zip** file to see an example of a boot loader that can be
used in the On-Chip ROM. This boot loader uses the RTEMS BSP header files that
get installed after building RTEMS.
Please see the **app.zip** file that contains an application that is built using
the RTEMS WAF system. This application is just a console app that can control
some device driver features.
Please see the **head_file.zip** file that contains an application to add the
<file_header_t> information to the binary image.
This is the RTEMS BSP build environment structure I used.
```
└── rtems src directory // the rtems top level directory
├── bsps // the rtems bsps directory
├── riscv // the rtems riscv bsp top level directory
└── niosv // the rtems niosv bsp top level directory
├── cache // the niosv cache implementation
├── clock // the niosv clock device implementation
├── console // the niosv console implementation using
│ // the JTAG UART
├── flash // the niosv EPCQ device implementation
├── include // the niosv base bsp include files
├── irq // the niosv IRQ implementation
├── niosvc10lp // the Intel Cyclone 10 LP evaluation board
│ // bsp example
├── start // the niosv bsp start up implementation
├── README.md // this file
└── supporting.zip // a zip file containing all the supporting
// code and files referenced in
// this README.md
└── spec // the rtems spec directory
└── build // the rtems spec build directory
└── bsps // the rtems spec bsps directory
└── riscv // the rtems spec riscv directory
└── niosv // the rtems spec niosv directory containing
// the configuration for all niosv bsps. Add
// new BSP configurations here.
```
#### Phase 2
Here is an outline of the second phase to generate a boot loader HEX file that
can be loaded into the On-Chip ROM memory.
* Create the rtems src directory under ${HOME}/sandbox2
(i.e. ${HOME}/sandbox2/rtems/src).
* Follow the steps in the RTEMS documentation to download the RTEMS Resource
Builder (RSB).
* Use RSB to compile the riscv-rtems6 binaries.
* Follow the steps in the RTEMS documentation to download the RTEMS RTOS.
* Develop a BSP for the NIOSV by adding source files to the
**bsps/riscv/niosv** and **spec/build/bsps/riscv/niosv** directories.
* Add a **config.ini** to configure the NIOSV BSP.
* Build the RTEMS NIOSV BSP.
* Create the boot loader directory under ${HOME}/sandbox2
(i.e. ${HOME}/sandbox2/boot).
* Develop a boot loader that will fit in the On-Chip ROM memory that will load
an application from the EPCQ device.
* Build the boot loader HEX file output
* Create the head_file directory under ${HOME}/sandbox2
(i.e. ${HOME}/sandbox2/head_file).
* Develop a Linux application that will put the **file_header_t** information
in front of the binary code image.
* Build the head_file Linux application.
* Create the application directory under ${HOME}/sandbox2
(i.e. ${HOME}/sandbox2/app).
* Develop an application using the RTEMS WAF system that will fit in the EPCQ
device (EPCQ size - maximum FPGA configuration size)
and include the **file_header_t** information.
* Build the application HEX file output.
Once the boot loader and application compiles succesfully, follow these steps to
complete phase 2.
* Use the **elf2hex.exe** tool that comes with Quartus Prime to convert the
boot loader output to a HEX file that can be loaded into the
On-Chip ROM
```
elf2hex.exe --width=32 --base=0x10010000 --end=0x10010fff
--input=<full path to boot loader hex file>
--output=<full path to Quartus Prime project hex file>
```
* In Platform designer, intialize the On-Chip ROM memory with the generated HEX
file from **elf2hex.exe**
* Save the Platform Designer project and re-generated the HDL.
* In Quartus Prime, re-compile the project.
* You now have an SOF file which contains the boot loader.
#### Phase 3
Follow these steps to generate a JIC file that can be programmed on the FPGA.
* In Quartus Prime, select **File>Convert Programming Files** tool.
* Change the Programming file type to .jic
* Press the ellipse button next to the Configuration device and select the
Cyclone 10 LP device family and the EPCQ128A device (verify on your own
hardware).
* Press OK.
* Change the file name of the JIC file to **rtems_vm.jic**.
* Select the **Flash Loader** input file and press the **Add Device** button.
* Select **Cyclone 10 LP** and then **10CL025Y** (verify on your own hardware).
* Press OK.
* Select the **SOF Data** input file and press the **Add File** button.
* Navigate to the generated SOF file from phase 2 and select it.
* Press Open
* Now, press the **Add Hex Data** button.
* In the dialog, select **Relative addressing** and enter 0x100000 as the start
address.
* Press the ellipse button next to the Hex file box.
* Navigate to the HEX file that was generated by the application build and
select it.
* Press OK.
* Press the **Generate** button to produce the **rtems_vm.jic** file.
### Programming the JIC file on the Cyclone 10 LP Evaluation Board
Make sure the Cyclone 10 LP Evaluation Board is powered up through the USB cable
and connected to the computer running Quartus Prime. Also, make sure SW.4 is
**On**. If the virtual JTAG chain is enabled, the programmer will be unable to
program the EPCQ device.
* In Quartus Prime, select **Tools>Programmer**.
* Select the currently loaded SOF file and press **Delete**.
* Press **Add File**.
* Navigate to the **rtems_vm.jic**, select it, and press **Open**.
* select the Program/Configure checkbox on the JIC file.
* Press **Start** to program the file onto the device.
Enjoy!

141
bsps/riscv/niosv/cache/alt_cache.c vendored Normal file
View File

@@ -0,0 +1,141 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#include <stddef.h>
#include <bsp_system.h>
#include <alt_cache.h>
#define CPU_DATA_CACHE_ALIGNMENT ALT_CPU_DCACHE_LINE_SIZE
#define CPU_INSTRUCTION_CACHE_ALIGNMENT ALT_CPU_ICACHE_LINE_SIZE
#define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
#define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
static inline void _CPU_cache_flush_1_data_line(const void *d_addr)
{
alt_dcache_flush(d_addr, ALT_CPU_DCACHE_LINE_SIZE);
}
static inline void
_CPU_cache_flush_data_range(
const void *d_addr,
size_t n_bytes
)
{
alt_dcache_flush(d_addr, n_bytes);
}
static inline void _CPU_cache_invalidate_1_data_line(const void *d_addr)
{
alt_dcache_flush_no_writeback(d_addr, ALT_CPU_DCACHE_LINE_SIZE);
}
static inline void
_CPU_cache_invalidate_data_range(
const void *d_addr,
size_t n_bytes
)
{
alt_dcache_flush_no_writeback(d_addr, n_bytes);
}
static inline void _CPU_cache_freeze_data(void)
{
/* TODO */
}
static inline void _CPU_cache_unfreeze_data(void)
{
/* TODO */
}
static inline void _CPU_cache_invalidate_1_instruction_line(const void *i_addr)
{
alt_icache_flush(i_addr, ALT_CPU_ICACHE_LINE_SIZE);
}
static inline void
_CPU_cache_invalidate_instruction_range( const void *i_addr, size_t n_bytes)
{
alt_icache_flush(i_addr, n_bytes);
}
static inline void _CPU_cache_freeze_instruction(void)
{
/* TODO */
}
static inline void _CPU_cache_unfreeze_instruction(void)
{
/* TODO */
}
static inline void _CPU_cache_flush_entire_data(void)
{
alt_dcache_flush_all();
}
static inline void _CPU_cache_invalidate_entire_data(void)
{
alt_dcache_flush_all();
}
static inline void _CPU_cache_enable_data(void)
{
}
static inline void _CPU_cache_disable_data(void)
{
}
static inline void _CPU_cache_invalidate_entire_instruction(void)
{
alt_icache_flush_all();
}
static inline void _CPU_cache_enable_instruction(void)
{
}
static inline void _CPU_cache_disable_instruction(void)
{
}
static inline size_t _CPU_cache_get_data_cache_size(uint32_t level)
{
return ALT_CPU_DCACHE_SIZE;
}
static inline size_t _CPU_cache_get_instruction_cache_size(uint32_t level)
{
return ALT_CPU_ICACHE_SIZE;
}
#include "../../shared/cache/cacheimpl.h"

View File

@@ -0,0 +1,205 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <bsp/fatal.h>
#include <bsp/irq.h>
#include <bsp/niosv.h>
#include <rtems/sysinit.h>
#include <rtems/counter.h>
#include <rtems/timecounter.h>
#include <rtems/btimer.h>
#include <rtems/score/riscv-utility.h>
#define BENCHMARK_TIMER_INTERVAL_FREQ 1000000
/* This is defined in dev/clock/clockimpl.h */
void Clock_isr(void *arg);
static volatile uint64_t interval_period;
static volatile uint64_t last_mtimecmp;
static volatile uint64_t benchmark_timer_base;
static struct timecounter niosv_clock_tc;
static uint64_t niosv_mtime_get(void)
{
uint32_t lowbits;
uint32_t highbits;
/* Guard against rollover while acquiring each word */
do {
highbits = CLOCK_REGS->mtime_hi;
lowbits = CLOCK_REGS->mtime_lo;
} while (CLOCK_REGS->mtime_hi != highbits);
return (((uint64_t)highbits) << 32) | lowbits;
}
static void niosv_mtimecmp_set(uint64_t next_time)
{
/*
* Make sure to set the high word to a max value first to prevent triggering
* inadvertently
*/
CLOCK_REGS->mtimecmp_hi = 0xFFFFFFFF;
CLOCK_REGS->mtimecmp_lo = (uint32_t)next_time;
CLOCK_REGS->mtimecmp_hi = (uint32_t)(next_time >> 32);
last_mtimecmp = next_time;
}
static void niosv_clock_exit(void)
{
clear_csr(mie, MIP_MTIP);
}
static uint32_t niosv_timer_read( void )
{
/* Write to request snapshot of timer value */
TIMER_REGS->snap = 0;
return (0xFFFFFFFF - TIMER_REGS->snap);
}
static uint32_t niosv_tc_get_timecount(struct timecounter *tc)
{
return niosv_timer_read();
}
static void niosv_clock_initialize(void)
{
uint64_t current_time;
/* Register the driver exit procedure so we can shutdown */
atexit(niosv_clock_exit);
interval_period = (((uint64_t)CLOCK_FREQ) / 1000000) *
(uint64_t)rtems_configuration_get_microseconds_per_tick();
niosv_mtimecmp_set(MTIMECMP_MAX_VALUE);
set_csr(mie, MIP_MTIP);
current_time = niosv_mtime_get();
niosv_mtimecmp_set(current_time + interval_period);
/* Install timecounter */
niosv_clock_tc.tc_get_timecount = niosv_tc_get_timecount;
niosv_clock_tc.tc_counter_mask = 0xffffffff;
niosv_clock_tc.tc_frequency = BENCHMARK_TIMER_INTERVAL_FREQ;
niosv_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
rtems_timecounter_install(&niosv_clock_tc);
}
static void niosv_clock_at_tick(void)
{
niosv_mtimecmp_set(last_mtimecmp + interval_period);
}
static void niosv_clock_handler_install(void)
{
rtems_status_code sc;
sc = rtems_interrupt_handler_install(
NIOSV_INTERRUPT_VECTOR_TIMER,
"Clock",
RTEMS_INTERRUPT_UNIQUE,
(rtems_interrupt_handler) Clock_isr,
NULL
);
if (sc != RTEMS_SUCCESSFUL) {
bsp_fatal(RISCV_FATAL_CLOCK_IRQ_INSTALL);
}
}
static void niosv_counter_initialize( void )
{
/* Disable timer interrupt, stop timer */
TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK;
/* set period to max value, running timer */
TIMER_REGS->period = 0xFFFFFFFF;
/* set prescalar for 1us timer */
TIMER_REGS->prescalar = (
BENCHMARK_TIMER_FREQ / BENCHMARK_TIMER_INTERVAL_FREQ
) - 1;
/* For timers that can be stopped, writing to periodl/h
also stopped the timer and we have to manually start it. */
TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_CONT_MSK |
ALTERA_AVALON_TIMER_CONTROL_START_MSK;
}
void benchmark_timer_initialize(void)
{
benchmark_timer_base = niosv_timer_read();
}
benchmark_timer_t benchmark_timer_read(void)
{
uint32_t timer_snap = niosv_timer_read();
/* Check for wrap around */
if(benchmark_timer_base < timer_snap) {
return (timer_snap - benchmark_timer_base);
}
return ((0xFFFFFFFF - benchmark_timer_base) + timer_snap + 1);
}
void benchmark_timer_disable_subtracting_average_overhead(
bool find_average_overhead
)
{
( void ) find_average_overhead;
}
uint32_t _CPU_Counter_frequency( void )
{
return BENCHMARK_TIMER_INTERVAL_FREQ;
}
CPU_Counter_ticks _CPU_Counter_read( void )
{
return (CPU_Counter_ticks)niosv_timer_read();
}
RTEMS_SYSINIT_ITEM(
niosv_counter_initialize,
RTEMS_SYSINIT_CPU_COUNTER,
RTEMS_SYSINIT_ORDER_FIRST
);
#define Clock_driver_support_at_tick(arg) niosv_clock_at_tick()
#define Clock_driver_support_initialize_hardware() niosv_clock_initialize()
#define Clock_driver_support_install_isr(isr) niosv_clock_handler_install()
#include "../../../shared/dev/clock/clockimpl.h"

View File

@@ -0,0 +1,349 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/bspIo.h>
#include <rtems/console.h>
#include <rtems/sysinit.h>
#include <rtems/termiostypes.h>
#include <bsp/fatal.h>
#include <bsp/irq.h>
#include <bsp/niosv.h>
#include <bsp.h>
#include <bsp/console-termios.h>
#include <rtems/libio.h>
typedef struct {
rtems_termios_device_context base;
rtems_termios_tty *tty;
rtems_vector_number irq;
size_t out_total;
size_t out_remaining;
size_t out_current;
const char *out_buf;
} jtag_uart_context;
static void jtag_uart_initialize_interrupts(
struct rtems_termios_tty *tty,
jtag_uart_context *ctx, void (*isr)(void *)
);
static bool jtag_uart_console_first_open(
struct rtems_termios_tty *tty,
rtems_termios_device_context *base, struct termios *term,
rtems_libio_open_close_args_t *args
);
static void jtag_uart_close(
struct rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
);
static void jtag_uart_console_write_int(
rtems_termios_device_context *base,
const char *buf, size_t len
);
static size_t jtag_uart_write_to_fifo(const char *buf, size_t len);
static void jtag_uart_clear_and_set_control(
jtag_uart_context *ctx,
uint32_t clear, uint32_t set
);
static void jtag_uart_console_putchar(char c);
static jtag_uart_context jtag_uart_console_instance;
static const rtems_termios_device_handler jtag_uart_console_handler = {
.first_open = jtag_uart_console_first_open,
.last_close = jtag_uart_close,
.poll_read = NULL,
.write = jtag_uart_console_write_int,
.set_attributes = NULL,
.mode = TERMIOS_IRQ_DRIVEN
};
static void jtag_uart_clear_and_set_control(
jtag_uart_context *ctx,
uint32_t clear,
uint32_t set
)
{
volatile altera_avalon_jtag_uart_regs *ajur = JTAG_UART_REGS;
rtems_interrupt_lock_context lock_context;
uint8_t val;
rtems_termios_device_lock_acquire(&ctx->base, &lock_context);
val = ajur->control;
val &= ~clear;
val |= set;
ajur->control = val;
rtems_termios_device_lock_release(&ctx->base, &lock_context);
}
static size_t jtag_uart_write_to_fifo(const char *buf, size_t len)
{
volatile altera_avalon_jtag_uart_regs *ajur = JTAG_UART_REGS;
uint32_t space = (
ajur->control & ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK
) >> ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_OFST;
size_t out = len > space ? space : len;
size_t i;
for (i = 0; i < out; ++i) {
ajur->data = buf[i];
}
return out;
}
static void jtag_uart_isr(void *arg)
{
rtems_termios_tty *tty = arg;
jtag_uart_context *ctx = rtems_termios_get_device_context(tty);
volatile altera_avalon_jtag_uart_regs *ajur = JTAG_UART_REGS;
int i = 0;
char buf [JTAG_UART_READ_DEPTH];
/* Iterate until no more interrupts are pending */
do {
if (ajur->control & ALTERA_AVALON_JTAG_UART_CONTROL_RI_MSK) {
/* Fetch received characters */
for (i = 0; i < JTAG_UART_READ_DEPTH; ++i) {
uint32_t data = ajur->data;
if ((data & ALTERA_AVALON_JTAG_UART_DATA_RVALID_MSK) == 0) {
break;
} else {
buf[i] = (char) data;
}
}
/* Enqueue fetched characters */
rtems_termios_enqueue_raw_characters(tty, buf, i);
}
/* Do transmit */
if (ctx->out_total > 0 &&
ajur->control & ALTERA_AVALON_JTAG_UART_CONTROL_WI_MSK
) {
size_t current = ctx->out_current;
ctx->out_buf += current;
ctx->out_remaining -= current;
if(ctx->out_remaining > 0) {
ctx->out_current =
jtag_uart_write_to_fifo(ctx->out_buf, ctx->out_remaining);
} else {
rtems_termios_dequeue_characters(tty, ctx->out_total);
}
}
} while((ajur->control & (ALTERA_AVALON_JTAG_UART_CONTROL_RI_MSK |
ALTERA_AVALON_JTAG_UART_CONTROL_WI_MSK)) != 0);
}
static void jtag_uart_console_putchar(char c)
{
volatile altera_avalon_jtag_uart_regs *ajur = JTAG_UART_REGS;
/*
* Wait for the transmitter to be ready.
* Check for flow control requests and process.
* Then output the character.
*/
while ((ajur->control & ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK) == 0);
ajur->data = c;
}
static void jtag_uart_console_probe(void)
{
rtems_termios_device_context_initialize(
&jtag_uart_console_instance.base,
"JURT"
);
jtag_uart_console_instance.irq =
NIOSV_INTERRUPT_VECTOR_EXTERNAL(JTAG_UART_IRQ);
}
rtems_status_code console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_termios_device_context *base;
char jtag_uart_path[] = "/dev/ttyJtagUart";
rtems_termios_initialize();
base = &jtag_uart_console_instance.base;
rtems_termios_device_install(
jtag_uart_path,
&jtag_uart_console_handler,
NULL,
base
);
link(jtag_uart_path, CONSOLE_DEVICE_NAME);
return RTEMS_SUCCESSFUL;
}
static void jtag_uart_initialize_interrupts(
struct rtems_termios_tty *tty,
jtag_uart_context *ctx,
void (*isr)(void *)
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
sc = rtems_interrupt_handler_install(
ctx->irq,
"JTAG_UART",
RTEMS_INTERRUPT_UNIQUE,
isr,
tty
);
if (sc != RTEMS_SUCCESSFUL) {
printk( "%s: Error: Install interrupt handler\n", __func__);
rtems_fatal_error_occurred(0xdeadbeef);
}
/* Enable JUART interrupts */
alt_irq_enable(JTAG_UART_IRQ);
}
static void jtag_uart_cleanup_interrupts(
struct rtems_termios_tty *tty,
jtag_uart_context *ctx,
void (*isr)(void *)
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
/* Disable JUART interrupts */
alt_irq_disable(JTAG_UART_IRQ);
sc = rtems_interrupt_handler_remove(
ctx->irq,
isr,
tty
);
if (sc != RTEMS_SUCCESSFUL) {
/* FIXME */
printk("%s: Error: Remove interrupt handler\n", __func__);
rtems_fatal_error_occurred(0xdeadbeef);
}
}
static bool jtag_uart_console_first_open(
struct rtems_termios_tty *tty,
rtems_termios_device_context *base,
struct termios *term,
rtems_libio_open_close_args_t *args
)
{
jtag_uart_context *ctx = (jtag_uart_context *)base;
ctx->tty = tty;
if (tty->handler.mode == TERMIOS_IRQ_DRIVEN) {
jtag_uart_initialize_interrupts(tty, ctx, jtag_uart_isr);
jtag_uart_clear_and_set_control(
ctx,
ALTERA_AVALON_JTAG_UART_CONTROL_WE_MSK,
ALTERA_AVALON_JTAG_UART_CONTROL_RE_MSK
);
}
return true;
}
static void jtag_uart_close(
struct rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
)
{
jtag_uart_context *ctx = (jtag_uart_context *) base;
/* disable interrupts */
jtag_uart_clear_and_set_control(
ctx,
ALTERA_AVALON_JTAG_UART_CONTROL_WE_MSK |
ALTERA_AVALON_JTAG_UART_CONTROL_RE_MSK,
0
);
if (tty->handler.mode == TERMIOS_IRQ_DRIVEN) {
jtag_uart_cleanup_interrupts(tty, ctx, jtag_uart_isr);
}
}
static void jtag_uart_console_write_int(
rtems_termios_device_context *base,
const char *buf,
size_t len
)
{
jtag_uart_context *ctx = (jtag_uart_context *) base;
ctx->out_total = len;
if (len > 0) {
ctx->out_remaining = len;
ctx->out_buf = buf;
ctx->out_current = jtag_uart_write_to_fifo(buf, len);
jtag_uart_clear_and_set_control(
ctx,
0,
ALTERA_AVALON_JTAG_UART_CONTROL_WE_MSK
);
} else {
jtag_uart_clear_and_set_control(
ctx,
ALTERA_AVALON_JTAG_UART_CONTROL_WE_MSK,
0
);
}
}
static void jtag_uart_output_char_init(char c)
{
BSP_output_char = jtag_uart_console_putchar;
jtag_uart_console_putchar(c);
}
BSP_output_char_function_type BSP_output_char = jtag_uart_output_char_init;
BSP_polling_getchar_function_type BSP_poll_char = NULL;
RTEMS_SYSINIT_ITEM(
jtag_uart_console_probe,
RTEMS_SYSINIT_BSP_START,
RTEMS_SYSINIT_ORDER_LAST_BUT_5
);

View File

@@ -0,0 +1,902 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
******************************************************************************/
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <altera_avalon_epcq_regs.h>
#include <altera_avalon_timer_regs.h>
#include <rtems/counter.h>
#ifndef ALT_MAX_NUMBER_OF_FLASH_REGIONS
#define ALT_MAX_NUMBER_OF_FLASH_REGIONS 8
#endif /* ALT_MAX_NUMBER_OF_FLASH_REGIONS */
/* MACROS */
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
/*
* Description of a single Erase region
*/
typedef struct flash_region
{
int offset;
int region_size;
int number_of_blocks;
int block_size;
}flash_region;
/**
* Description of the flash device
*/
typedef struct alt_flash_dev alt_flash_dev;
/**
* Description of the flash device api
*/
typedef int (*alt_flash_read)(
alt_flash_dev* flash,
int offset,
void* dest_addr,
int length
);
/**
* Description of the flash device implementation
*/
struct alt_flash_dev
{
const char* name;
alt_flash_read read;
void* base_addr;
int length;
int number_of_regions;
flash_region region_info[ALT_MAX_NUMBER_OF_FLASH_REGIONS];
};
/**
* Description of the EPCQ controller
*/
typedef struct alt_epcq_controller2_dev
{
alt_flash_dev dev;
uint32_t data_base; /* base address of data slave */
uint32_t data_end; /* end address of data slave (not inclusive) */
uint32_t csr_base; /* base address of CSR slave */
uint32_t size_in_bytes; /* size of memory in bytes */
uint32_t is_epcs; /* 1 if device is an EPCS device */
uint32_t number_of_sectors; /* number of flash sectors */
uint32_t sector_size; /* size of each flash sector */
uint32_t page_size; /* page size */
uint32_t silicon_id; /* ID of silicon used with EPCQ IP */
} alt_epcq_controller2_dev;
static int altera_epcq_controller2_init(alt_epcq_controller2_dev *dev);
static int alt_epcq_controller2_erase_block(
alt_flash_dev *flash_info,
int block_offset
);
static int alt_epcq_controller2_write_block(
alt_flash_dev *flash_info,
int block_offset,
int data_offset,
const void *data, int length
);
static int alt_epcq_controller2_write(
alt_flash_dev *flash_info,
int offset,
const void *src_addr,
int length,
bool erase
);
static int alt_epcq_controller2_read(
alt_flash_dev *flash_info,
int offset,
void *dest_addr,
int length
);
static inline int alt_epcq_validate_read_write_arguments(
alt_epcq_controller2_dev *flash_info,
uint32_t offset,
uint32_t length
);
static int alt_epcq_poll_for_write_in_progress(
alt_epcq_controller2_dev* flash_info
);
/**
* Macros used by alt_sys_init.c to create data storage for driver instance
*/
#define ALTERA_EPCQ_CSR_INSTANCE(epcq_name, avl_mem, avl_csr, epcq_dev) \
static alt_epcq_controller2_dev epcq_dev = { \
.dev = { \
.read = alt_epcq_controller2_read, \
.base_addr = ((void*)(avl_mem##_BASE)), \
.length = ((int)(avl_mem##_SPAN)), \
}, \
.data_base = ((uint32_t)(avl_mem##_BASE)), \
.data_end = ((uint32_t)(avl_mem##_BASE) + (uint32_t)(avl_mem##_SPAN)), \
.csr_base = ((uint32_t)(avl_csr##_BASE)), \
.size_in_bytes = ((uint32_t)(avl_mem##_SPAN)), \
.is_epcs = ((uint32_t)(avl_mem##_IS_EPCS)), \
.number_of_sectors = ((uint32_t)(avl_mem##_NUMBER_OF_SECTORS)), \
.sector_size = ((uint32_t)(avl_mem##_SECTOR_SIZE)), \
.page_size = ((uint32_t)(avl_mem##_PAGE_SIZE)) , \
}
#define ALTERA_EPCQ_CONTROLLER2_INIT(name, dev) \
altera_epcq_controller2_init(&dev);
/**
* The EPCQ device instance
*/
ALTERA_EPCQ_CSR_INSTANCE(
EPCQ_CONTROLLER,
EPCQ_CONTROLLER_AVL_MEM,
EPCQ_CONTROLLER_AVL_CSR,
epcq_controller
);
/**
* epcq_initialize
*
* Initializes the epcq device interface.
*
**/
void epcq_initialize( void )
{
ALTERA_EPCQ_CONTROLLER2_INIT( EPCQ_CONTROLLER, epcq_controller);
}
/**
* epcq_read_buffer
*
* Reads data from the epcq device.
*
* Arguments:
* - offset: offset within the memory area to read.
* - dest_addr: the location to store the returned data.
* - length: The number of bytes to read.
*
* Returns:
* 0 -> The number of bytes actually read
* -EINVAL -> Invalid arguments.
**/
int epcq_read_buffer( int offset, uint8_t *dest_addr, int length )
{
return alt_epcq_controller2_read(
&epcq_controller.dev,
offset,
dest_addr,
length
);
}
/**
* epcs_write_buffer
*
* Writes data to the epcq device.
*
* Arguments:
* - offset: offset within the memory area to read.
* - src_addr: the data top store.
* - length: The number of bytes to write.
*
* Returns:
* 0 -> The number of bytes actually read
* -EINVAL -> Invalid arguments.
**/
int epcq_write_buffer (
int offset,
const uint8_t* src_addr,
int length,
bool erase
)
{
return alt_epcq_controller2_write (
&epcq_controller.dev,
offset,
src_addr,
length,
erase
);
}
/**
* altera_epcq_controller2_init
*
* Information in system.h is checked against expected values that are
* determined by the silicon_id. If the information doesn't match then this
* system is configured incorrectly. Most likely the wrong type of EPCS or EPCQ
* device was selected when instantiating the soft IP.
*
* Arguments:
* - *flash: Pointer to EPCQ flash device structure.
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments.
* -ENODEV -> System is configured incorrectly.
**/
static int altera_epcq_controller2_init(alt_epcq_controller2_dev *flash)
{
uint32_t silicon_id = 0;
uint32_t size_in_bytes = 0;
uint32_t number_of_sectors = 0;
/* return -EINVAL if flash is NULL */
if ( NULL == flash ) {
return -EINVAL;
}
/* return -ENODEV if CSR slave is not attached */
if ( NULL == ( void * )flash->csr_base ) {
return -ENODEV;
}
/*
* If flash is an EPCQ device, we read the EPCQ_RD_RDID register for the ID
* If flash is an EPCS device, we read the EPCQ_RD_SID register for the ID
*
* Whether or not the flash is a EPCQ or EPCS is indicated in the system.h.
* The system.h gets this value from the hw.tcl of the IP. If this value is
* set incorrectly, then things will go badly.
*
* In both cases, we can determine the number of sectors, which we can use
* to calculate a size. We compare that size to the system.h value to make
* sure the EPCQ soft IP was configured correctly.
*/
if ( 0 == flash->is_epcs ) {
/* If we're an EPCQ, we read EPCQ_RD_RDID for the silicon ID */
silicon_id = EPCQ_REGS->rd_rdid;
silicon_id &= ALTERA_EPCQ_CONTROLLER2_RDID_MASK;
/* Determine which EPCQ device so we can figure out the number of sectors */
/* EPCQ share the same ID for the same capacity*/
switch( silicon_id ) {
case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ16:
number_of_sectors = 32;
break;
case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ32:
number_of_sectors = 64;
break;
case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ64:
number_of_sectors = 128;
break;
case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ128:
number_of_sectors = 256;
break;
case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ256:
number_of_sectors = 512;
break;
case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ512:
number_of_sectors = 1024;
break;
case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ1024:
number_of_sectors = 2048;
break;
default:
return -ENODEV;
}
} else {
/* If we're an EPCS, we read EPCQ_RD_SID for the silicon ID */
silicon_id = EPCQ_REGS->rd_sid;
silicon_id &= ALTERA_EPCQ_CONTROLLER2_SID_MASK;
/* Determine which EPCS device so we can figure out various properties */
switch(silicon_id) {
case ALTERA_EPCQ_CONTROLLER2_SID_EPCS16:
number_of_sectors = 32;
break;
case ALTERA_EPCQ_CONTROLLER2_SID_EPCS64:
number_of_sectors = 128;
break;
case ALTERA_EPCQ_CONTROLLER2_SID_EPCS128:
number_of_sectors = 256;
break;
default:
return -ENODEV;
}
}
/* Calculate size of flash based on number of sectors */
size_in_bytes = number_of_sectors * flash->sector_size;
/*
* Make sure calculated size is the same size given in system.h
* Also check number of sectors is the same number given in system.h
* Otherwise the EPCQ IP was not configured correctly
*/
if (
size_in_bytes != flash->size_in_bytes ||
number_of_sectors != flash->number_of_sectors
) {
flash->dev.number_of_regions = 0;
return -ENODEV;
} else {
flash->silicon_id = silicon_id;
flash->number_of_sectors = number_of_sectors;
/*
* populate fields of region_info required to conform to HAL API
* create 1 region that composed of "number_of_sectors" blocks
*/
flash->dev.number_of_regions = 1;
flash->dev.region_info[0].offset = 0;
flash->dev.region_info[0].region_size = size_in_bytes;
flash->dev.region_info[0].number_of_blocks = number_of_sectors;
flash->dev.region_info[0].block_size = flash->sector_size;
}
return 0;
}
/**
* alt_epcq_controller2_erase_block
*
* This function erases a single flash sector.
*
* Arguments:
* - *flash_info: Pointer to QSPI flash device structure.
* - block_offset: byte-addressed offset, from start of flash, of the sector to
* be erased
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -EIO -> write failed, sector might be protected
**/
static int alt_epcq_controller2_erase_block(
alt_flash_dev *flash_info,
int block_offset
)
{
int32_t ret_code = 0;
uint32_t mem_op_value = 0; /* value to write to EPCQ_MEM_OP register */
alt_epcq_controller2_dev* epcq_flash_info = NULL;
uint32_t sector_number = 0;
/* return -EINVAL if flash_info is NULL */
if ( NULL == flash_info ) {
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller2_dev*)flash_info;
/*
* Sanity checks that block_offset is within the flash memory span and that
* the block offset is sector aligned.
*
*/
if (
( block_offset < 0 ) ||
( block_offset >= epcq_flash_info->size_in_bytes ) ||
( block_offset & ( epcq_flash_info->sector_size - 1 )) != 0
) {
return -EINVAL;
}
alt_epcq_poll_for_write_in_progress(epcq_flash_info);
/* calculate current sector/block number */
sector_number = (block_offset/(epcq_flash_info->sector_size));
/* sector value should occupy bits 23:8 */
mem_op_value = (sector_number << 8) &
ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_VALUE_MASK;
/* write enable command */
mem_op_value |= ALTERA_EPCQ_CONTROLLER2_MEM_OP_WRITE_ENABLE_CMD;
/*
* write sector erase command to EPCQ_MEM_OP register to erase sector
* "sector_number"
*/
EPCQ_REGS->mem_op = mem_op_value;
/* sector value should occupy bits 23:8 */
mem_op_value = (sector_number << 8) &
ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_VALUE_MASK;
/* sector erase commands 0b10 occupies lower 2 bits */
mem_op_value |= ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_ERASE_CMD;
/*
* write sector erase command to QSPI_MEM_OP register to erase sector
* "sector_number"
*/
EPCQ_REGS->mem_op = mem_op_value;
alt_epcq_poll_for_write_in_progress(epcq_flash_info);
/* check whether erase triggered a illegal erase interrupt */
if (
( EPCQ_REGS->isr & ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_ERASE_MASK ) ==
ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_ERASE_ACTIVE
) {
/* clear register */
/* QSPI_ISR access is write one to clear (W1C) */
EPCQ_REGS->isr = ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_ERASE_MASK;
return -EIO; /* erase failed, sector might be protected */
}
return ret_code;
}
/**
* alt_epcq_controller2_write_block
*
* This function writes one block/sector of data to flash. The length of the
* write can NOT spill into the adjacent sector.
*
* It assumes that someone has already erased the appropriate sector(s).
*
* Arguments:
* - *flash_info: Pointer to QSPI flash device structure.
* - block_offset: byte-addressed offset, from the start of flash, of the sector
* to written to
* - data-offset: Byte offset (unaligned access) of write into flash memory.
* For best performance, word(32 bits - aligned access) offset of write is
* recommended.
* - *src_addr: source buffer
* - length: size of writing
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -EIO -> write failed, sector might be protected
**/
static int alt_epcq_controller2_write_block (
alt_flash_dev *flash_info, /** flash device info */
int block_offset, /** sector/block offset in byte addressing */
int data_offset, /** offset of write from base address */
const void *data, /** data to be written */
int length /** bytes of data to be written, >0 */
)
{
uint32_t buffer_offset = 0; /** offset into data buffer to get write data */
uint32_t remaining_length = length; /** length left to write */
uint32_t write_offset = data_offset; /** offset into flash to write too */
uint32_t write_offset_32;
alt_epcq_controller2_dev *epcq_flash_info =
(alt_epcq_controller2_dev*)flash_info;
/*
* Sanity checks that data offset is not larger then a sector, that block
* offset is sector aligned and within the valid flash memory range and a
* write doesn't spill into the adjacent flash sector.
*/
if (
block_offset < 0 ||
data_offset < 0 ||
NULL == flash_info ||
NULL == data ||
data_offset >= epcq_flash_info->size_in_bytes ||
block_offset >= epcq_flash_info->size_in_bytes ||
length > (epcq_flash_info->sector_size - (data_offset - block_offset)) ||
length < 0 ||
(block_offset & (epcq_flash_info->sector_size - 1)) != 0
) {
return -EINVAL;
}
/*
* Do writes one 32-bit word at a time.
* We need to make sure that we pad the first few bytes so they're word
* aligned if they are not already.
*/
while ( remaining_length > 0 ) {
volatile uint32_t dummy_read;
/** initialize word to write to blank word */
uint32_t word_to_write = 0xFFFFFFFF;
/** bytes to pad the next word that is written */
uint32_t padding = 0;
/** number of bytes from source to copy */
uint32_t bytes_to_copy = sizeof(uint32_t);
/*
* we need to make sure the write is word aligned
* this should only be true at most 1 time
*/
if ( 0 != ( write_offset & ( sizeof( uint32_t ) - 1 ))) {
/*
* data is not word aligned
* calculate padding bytes need to add before start of a data offset
*/
padding = write_offset & (sizeof(uint32_t) - 1);
/* update variables to account for padding being added */
bytes_to_copy -= padding;
if(bytes_to_copy > remaining_length) {
bytes_to_copy = remaining_length;
}
write_offset = write_offset - padding;
if ( 0 != ( write_offset & ( sizeof( uint32_t ) - 1 ))) {
return -EINVAL;
}
} else {
if ( bytes_to_copy > remaining_length ) {
bytes_to_copy = remaining_length;
}
}
/* prepare the word to be written */
memcpy (
((( void * )&word_to_write)) + padding,
(( void * )data) + buffer_offset,
bytes_to_copy
);
/* update offset and length variables */
buffer_offset += bytes_to_copy;
remaining_length -= bytes_to_copy;
/* write to flash 32 bits at a time */
write_offset_32 = write_offset >> 2;
EPCQ_MEM_32[write_offset_32] = word_to_write;
alt_epcq_poll_for_write_in_progress(epcq_flash_info);
if ( EPCQ_MEM_32[write_offset_32] != word_to_write ) {
EPCQ_MEM_32[write_offset_32] = word_to_write;
alt_epcq_poll_for_write_in_progress(epcq_flash_info);
dummy_read = EPCQ_MEM_32[write_offset_32];
}
/* check whether write triggered a illegal write interrupt */
if (
( EPCQ_REGS->isr & ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_WRITE_MASK ) ==
ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_WRITE_ACTIVE
) {
/* clear register */
EPCQ_REGS->isr = ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_WRITE_MASK;
return -EIO; /** write failed, sector might be protected */
}
/* update current offset */
write_offset = write_offset + sizeof(uint32_t);
}
return 0;
}
/**
* alt_epcq_controller2_write
*
* Program the data into the flash at the selected address.
*
* The different between this function and alt_epcq_controller2_write_block
* function is that this function (alt_epcq_controller2_write) will
* automatically erase a block as needed
*
* Arguments:
* - *flash_info: Pointer to QSPI flash device structure.
* - offset: Byte offset (unaligned access) of write to flash memory. For best
* performance, word(32 bits - aligned access) offset of write is recommended.
* - *src_addr: source buffer
* - length: size of writing
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -EIO -> write failed, sector might be protected
*
**/
static int alt_epcq_controller2_write (
alt_flash_dev *flash_info, /** device info */
int offset, /** offset of write from base address */
const void *src_addr, /** source buffer */
int length, /** size of writing */
bool erase /** whether or not to erase before writing */
)
{
int32_t ret_code = 0;
alt_epcq_controller2_dev *epcq_flash_info = NULL;
/** address of next byte to write */
uint32_t write_offset = offset;
/** length of write data left to be written */
uint32_t remaining_length = length;
/** offset into source buffer to get write data */
uint32_t buffer_offset = 0;
uint32_t i = 0;
/* return -EINVAL if flash_info and src_addr are NULL */
if( NULL == flash_info || NULL == src_addr ) {
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller2_dev*)flash_info;
/* make sure the write parameters are within the bounds of the flash */
ret_code = alt_epcq_validate_read_write_arguments (
epcq_flash_info,
offset,
length
);
if ( 0 != ret_code ) {
return ret_code;
}
/*
* This loop erases and writes data one sector at a time. We check for write
* completion before starting the next sector.
*/
for (
i = offset / epcq_flash_info->sector_size;
i < epcq_flash_info->number_of_sectors;
i++
) {
/** block offset in byte addressing */
uint32_t block_offset = 0;
/** offset into current sector to write */
uint32_t offset_within_current_sector = 0;
/** length to write to current sector */
uint32_t length_to_write = 0;
if( 0 >= remaining_length ) {
break; /* out of data to write */
}
/* calculate current sector/block offset in byte addressing */
block_offset = write_offset & ~(epcq_flash_info->sector_size - 1);
/* calculate offset into sector/block if there is one */
if ( block_offset != write_offset ) {
offset_within_current_sector = write_offset - block_offset;
}
/* erase sector */
if( erase ) {
ret_code = alt_epcq_controller2_erase_block(flash_info, block_offset);
if( 0 != ret_code ) {
return ret_code;
}
}
/* calculate the byte size of data to be written in a sector */
length_to_write = MIN (
epcq_flash_info->sector_size - offset_within_current_sector,
remaining_length
);
/* write data to erased block */
ret_code = alt_epcq_controller2_write_block (
flash_info,
block_offset,
write_offset,
src_addr + buffer_offset,
length_to_write
);
if( 0 != ret_code ) {
return ret_code;
}
/* update remaining length and buffer_offset pointer */
remaining_length -= length_to_write;
buffer_offset += length_to_write;
write_offset += length_to_write;
}
return ret_code;
}
/**
* alt_epcq_controller2_read
*
* There's no real need to use this function as opposed to using memcpy
* directly. It does do some sanity checks on the bounds of the read.
*
* Arguments:
* - *flash_info: Pointer to general flash device structure.
* - offset: offset read from flash memory.
* - *dest_addr: destination buffer
* - length: size of reading
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
**/
static int alt_epcq_controller2_read (
alt_flash_dev *flash_info, /** device info */
int offset, /** offset of read from base address */
void *dest_addr, /** destination buffer */
int length /** size of read */
)
{
int32_t ret_code = 0;
alt_epcq_controller2_dev *epcq_flash_info = NULL;
/* return -EINVAL if flash_info and dest_addr are NULL */
if ( NULL == flash_info || NULL == dest_addr ) {
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller2_dev*)flash_info;
/* validate arguments */
ret_code = alt_epcq_validate_read_write_arguments (
epcq_flash_info,
offset,
length
);
/* copy data from flash to destination address */
if( 0 == ret_code ) {
memcpy(dest_addr, (uint8_t*)epcq_flash_info->data_base + offset, length);
}
return ret_code;
}
/*
* Helper functions used by Public API functions.
*
* Arguments:
* - *flash_info: Pointer to EPCQ flash device structure.
* - offset: Offset of read/write from base address.
* - length: Length of read/write in bytes.
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
*/
/**
* Used to check that arguments to a read or write are valid
*/
static inline int alt_epcq_validate_read_write_arguments (
alt_epcq_controller2_dev *flash_info,
uint32_t offset,
uint32_t length
)
{
alt_epcq_controller2_dev *epcq_flash_info = NULL;
uint32_t start_address = 0;
int32_t end_address = 0;
/* return -EINVAL if flash_info is NULL */
if( NULL == flash_info ) {
return -EINVAL;
}
epcq_flash_info = (alt_epcq_controller2_dev*)flash_info;
/* first address of read or write */
start_address = epcq_flash_info->data_base + offset;
/* last address of read or write (not inclusive) */
end_address = start_address + length;
/* make sure start and end address is less then the end address of the flash */
if (
start_address >= epcq_flash_info->data_end ||
end_address > epcq_flash_info->data_end ||
offset < 0 ||
length < 0
) {
return -EINVAL;
}
return 0;
}
/*
* Private function that polls write in progress bit QSPI_RD_STATUS.
*
* Write in progress will be set if any of the following operations are in
* progress:
* -WRITE STATUS REGISTER
* -WRITE NONVOLATILE CONFIGURATION REGISTER
* -PROGRAM
* -ERASE
*
* Assumes QSPI was configured correctly.
*
* If ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE is set, the function will time
* out after a period of time determined by that value.
*
* Arguments:
* - *epcq_flash_info: Pointer to QSPI flash device structure.
*
* Returns:
* 0 -> success
* -EINVAL -> Invalid arguments
* -ETIME -> Time out and skipping the looping after 0.7 sec.
*/
int static alt_epcq_poll_for_write_in_progress (
alt_epcq_controller2_dev* epcq_flash_info
)
{
/* we'll want to implement timeout if a timeout value is specified */
#if ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE > 0
uint32_t timeout = ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE;
uint16_t counter = 0;
#endif
/* return -EINVAL if epcq_flash_info is NULL */
if ( NULL == epcq_flash_info ) {
return -EINVAL;
}
/* while Write in Progress bit is set, we wait */
while (
(EPCQ_REGS->rd_status & ALTERA_EPCQ_CONTROLLER2_STATUS_WIP_MASK) ==
ALTERA_EPCQ_CONTROLLER2_STATUS_WIP_BUSY
) {
if ( counter > (ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE >> 1 )) {
rtems_counter_delay_ticks(2); /* delay 2us */
}
#if ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE > 0
if ( timeout <= counter ) {
return -ETIME;
}
counter++;
#endif
}
return 0;
}

View File

@@ -0,0 +1,196 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2003, 2007 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
******************************************************************************/
#ifndef __ALT_CACHE_H__
#define __ALT_CACHE_H__
/*
* Cache maintenance macros
* CLEAN - Writeback to memory;
* FLUSH - Writeback to memory and invalidate.
*/
#if ALT_CPU_DCACHE_SIZE > 0
#define DCACHE_CLEAN_BY_INDEX_VAL(i) \
__asm__ volatile(".insn i 0x0F, 0x2, zero, %[i_reg], 0x081" :: [i_reg] "r"(i));
#define DCACHE_FLUSH_BY_INDEX_VAL(i) \
__asm__ volatile(".insn i 0x0F, 0x2, zero, %[i_reg], 0x082" :: [i_reg] "r"(i));
#define DCACHE_INVALIDATE_BY_INDEX_VAL(i) \
__asm__ volatile(".insn i 0x0F, 0x2, zero, %[i_reg], 0x080" :: [i_reg] "r"(i));
#define ALT_FLUSH_DATA(i) \
__asm__ volatile(".option arch, +zicbom\n" "cbo.flush 0(%[addr])" :: [addr] "r"(i))
#define ALT_INVALIDATE_DATA(i) \
__asm__ volatile(".option arch, +zicbom\n" "cbo.inval 0(%[addr])" :: [addr] "r"(i))
#endif
/*
* alt_cache.h defines the processor specific functions for manipulating the
* cache.
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
* alt_icache_flush() is called to flush the instruction cache for a memory
* region of length "len" bytes, starting at address "start".
*/
static inline void alt_icache_flush (const void* start, uint32_t len)
{
#if ALT_CPU_ICACHE_SIZE > 0
__asm__ volatile(".option arch, +zifencei\n" "fence.i" ::: "memory");
#endif
}
/*
* alt_dcache_flush() is called to flush the data cache for a memory
* region of length "len" bytes, starting at address "start".
* Any dirty lines in the data cache are written back to memory.
*/
static inline void alt_dcache_flush (const void* start, uint32_t len)
{
#if ALT_CPU_DCACHE_SIZE > 0
const char* i;
const char* end = ((char*)start) + len;
for (i = start; i < end; i+= ALT_CPU_DCACHE_LINE_SIZE) {
ALT_FLUSH_DATA(i);
}
/*
* For an unaligned flush request, we've got one more line left.
* Note that this is dependent on ALT_CPU_DCACHE_LINE_SIZE to be a
* multiple of 2 (which it always is).
*/
if (((uint32_t)start) & (ALT_CPU_DCACHE_LINE_SIZE - 1)) {
ALT_FLUSH_DATA(i);
}
#endif
}
/*
* alt_dcache_flush() is called to flush the data cache for a memory
* region of length "len" bytes, starting at address "start".
* Any dirty lines in the data cache are NOT written back to memory.
*/
static inline void alt_dcache_flush_no_writeback (
const void* start,
uint32_t len
)
{
#if ALT_CPU_DCACHE_SIZE > 0
const char* i;
const char* end = ((char*)start) + len;
for (i = start; i < end; i+= ALT_CPU_DCACHE_LINE_SIZE) {
ALT_INVALIDATE_DATA(i);
}
/*
* For an unaligned invalidate request, we've got one more line left.
* Note that this is dependent on ALT_CPU_DCACHE_LINE_SIZE to be a
* multiple of 2 (which it always is).
*/
if (((uint32_t)start) & (ALT_CPU_DCACHE_LINE_SIZE - 1)) {
ALT_INVALIDATE_DATA(i);
}
#endif
}
/*
* Flush the entire instruction cache.
*/
static inline void alt_icache_flush_all (void)
{
#if ALT_CPU_ICACHE_SIZE > 0
__asm__ volatile(".option arch, +zifencei\n" "fence.i" ::: "memory");
#endif
}
/*
* Flush the entire data cache.
*/
static inline void alt_dcache_flush_all (void)
{
#if ALT_CPU_DCACHE_SIZE > 0
char* i;
for (
i = (char*)0;
i < (char*) ALT_CPU_DCACHE_SIZE;
i+= ALT_CPU_DCACHE_LINE_SIZE
) {
DCACHE_CLEAN_BY_INDEX_VAL(i);
}
#endif
}
#ifdef __cplusplus
}
#endif
#endif /* __ALT_CACHE_H__ */

View File

@@ -0,0 +1,153 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _ALTERA_AVALON_EPCQ_REGS_H
#define _ALTERA_AVALON_EPCQ_REGS_H
#include <stdbool.h>
#include <bsp_system.h>
/*
* EPCQ_RD_STATUS register description macros
*/
/** Write in progress bit */
#define ALTERA_EPCQ_CONTROLLER2_STATUS_WIP_MASK (0x00000001)
#define ALTERA_EPCQ_CONTROLLER2_STATUS_WIP_AVAILABLE (0x00000000)
#define ALTERA_EPCQ_CONTROLLER2_STATUS_WIP_BUSY (0x00000001)
/** When to time out a poll of the write in progress bit */
/* 0.7 sec time out */
#define ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE 700000
/*
* EPCQ_RD_SID register description macros
*
* Specific device values obtained from Table 14 of:
* "Serial Configuration (EPCS) Devices Datasheet"
*/
#define ALTERA_EPCQ_CONTROLLER2_SID_MASK (0x000000FF)
#define ALTERA_EPCQ_CONTROLLER2_SID_EPCS16 (0x00000014)
#define ALTERA_EPCQ_CONTROLLER2_SID_EPCS64 (0x00000016)
#define ALTERA_EPCQ_CONTROLLER2_SID_EPCS128 (0x00000018)
/*
* EPCQ_RD_RDID register description macros
*
* Specific device values obtained from Table 28 of:
* "Quad-Serial Configuration
* (EPCQ (www.altera.com/literature/hb/cfg/cfg_cf52012.pdf))
* Devices Datasheet"
*/
#define ALTERA_EPCQ_CONTROLLER2_RDID_MASK (0x000000FF)
#define ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ16 (0x00000015)
#define ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ32 (0x00000016)
#define ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ64 (0x00000017)
#define ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ128 (0x00000018)
#define ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ256 (0x00000019)
#define ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ512 (0x00000020)
#define ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ1024 (0x00000021)
/*
* EPCQ_MEM_OP register description macros
*/
#define ALTERA_EPCQ_CONTROLLER2_MEM_OP_CMD_MASK (0x00000003)
#define ALTERA_EPCQ_CONTROLLER2_MEM_OP_BULK_ERASE_CMD (0x00000001)
#define ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_ERASE_CMD (0x00000002)
#define ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_PROTECT_CMD (0x00000003)
#define ALTERA_EPCQ_CONTROLLER2_MEM_OP_WRITE_ENABLE_CMD (0x00000004)
/** see datasheet for sector values */
#define ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_VALUE_MASK (0x00FFFF00)
/*
* EPCQ_ISR register description macros
*/
#define ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_ERASE_MASK (0x00000001)
#define ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_ERASE_ACTIVE (0x00000001)
#define ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_WRITE_MASK (0x00000002)
#define ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_WRITE_ACTIVE (0x00000002)
/*
* EPCQ_IMR register description macros
*/
#define ALTERA_EPCQ_CONTROLLER2_IMR_ILLEGAL_ERASE_MASK (0x00000001)
#define ALTERA_EPCQ_CONTROLLER2_IMR_ILLEGAL_ERASE_ENABLED (0x00000001)
#define ALTERA_EPCQ_CONTROLLER2_IMR_ILLEGAL_WRITE_MASK (0x00000002)
#define ALTERA_EPCQ_CONTROLLER2_IMR_ILLEGAL_WRITE_ENABLED (0x00000002)
/*
* EPCQ_CHIP_SELECT register description macros
*/
#define ALTERA_EPCQ_CHIP1_SELECT (0x00000001)
#define ALTERA_EPCQ_CHIP2_SELECT (0x00000002)
#define ALTERA_EPCQ_CHIP3_SELECT (0x00000003)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
volatile uint32_t rd_status;
volatile uint32_t rd_sid;
volatile uint32_t rd_rdid;
volatile uint32_t mem_op;
volatile uint32_t isr;
volatile uint32_t imr;
volatile uint32_t chip_select;
volatile uint32_t flag_status;
volatile uint32_t dev_id_0;
volatile uint32_t dev_id_1;
volatile uint32_t dev_id_2;
volatile uint32_t dev_id_3;
volatile uint32_t dev_id_4;
}altera_avalon_epcq_regs;
#define EPCQ_REGS \
(( volatile altera_avalon_epcq_regs* )EPCQ_CONTROLLER_AVL_CSR_BASE )
#define EPCQ_MEM \
(( volatile uint8_t* )EPCQ_CONTROLLER_AVL_MEM_BASE )
#define EPCQ_MEM_32 \
(( volatile uint32_t* )EPCQ_CONTROLLER_AVL_MEM_BASE )
void epcq_initialize( void );
int epcq_read_buffer( int offset, uint8_t *dest_addr, int length );
int epcq_write_buffer (
int offset,
const uint8_t* src_addr,
int length,
bool erase
);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,101 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
******************************************************************************/
#ifndef _ALTERA_AVALON_JTAG_UART_REGS_H
#define _ALTERA_AVALON_JTAG_UART_REGS_H
#include <bsp_system.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ALTERA_AVALON_JTAG_UART_DATA_DATA_MSK (0x000000FFu)
#define ALTERA_AVALON_JTAG_UART_DATA_DATA_OFST (0)
#define ALTERA_AVALON_JTAG_UART_DATA_RVALID_MSK (0x00008000u)
#define ALTERA_AVALON_JTAG_UART_DATA_RVALID_OFST (15)
#define ALTERA_AVALON_JTAG_UART_DATA_RAVAIL_MSK (0xFFFF0000u)
#define ALTERA_AVALON_JTAG_UART_DATA_RAVAIL_OFST (16)
#define ALTERA_AVALON_JTAG_UART_CONTROL_RE_MSK (0x00000001u)
#define ALTERA_AVALON_JTAG_UART_CONTROL_RE_OFST (0)
#define ALTERA_AVALON_JTAG_UART_CONTROL_WE_MSK (0x00000002u)
#define ALTERA_AVALON_JTAG_UART_CONTROL_WE_OFST (1)
#define ALTERA_AVALON_JTAG_UART_CONTROL_RI_MSK (0x00000100u)
#define ALTERA_AVALON_JTAG_UART_CONTROL_RI_OFST (8)
#define ALTERA_AVALON_JTAG_UART_CONTROL_WI_MSK (0x00000200u)
#define ALTERA_AVALON_JTAG_UART_CONTROL_WI_OFST (9)
#define ALTERA_AVALON_JTAG_UART_CONTROL_AC_MSK (0x00000400u)
#define ALTERA_AVALON_JTAG_UART_CONTROL_AC_OFST (10)
#define ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK (0xFFFF0000u)
#define ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_OFST (16)
typedef struct
{
volatile uint32_t data;
volatile uint32_t control;
}altera_avalon_jtag_uart_regs;
#define JTAG_UART_REGS \
((volatile altera_avalon_jtag_uart_regs*)JTAG_UART_BASE)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,180 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
******************************************************************************/
#ifndef __ALTERA_AVALON_TIMER_REGS_H__
#define __ALTERA_AVALON_TIMER_REGS_H__
#include <bsp_system.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ALTERA_AVALON_TIMER_STATUS_TO_MSK (0x1)
#define ALTERA_AVALON_TIMER_STATUS_TO_OFST (0)
#define ALTERA_AVALON_TIMER_STATUS_RUN_MSK (0x2)
#define ALTERA_AVALON_TIMER_STATUS_RUN_OFST (1)
#define ALTERA_AVALON_TIMER_CONTROL_ITO_MSK (0x1)
#define ALTERA_AVALON_TIMER_CONTROL_ITO_OFST (0)
#define ALTERA_AVALON_TIMER_CONTROL_CONT_MSK (0x2)
#define ALTERA_AVALON_TIMER_CONTROL_CONT_OFST (1)
#define ALTERA_AVALON_TIMER_CONTROL_START_MSK (0x4)
#define ALTERA_AVALON_TIMER_CONTROL_START_OFST (2)
#define ALTERA_AVALON_TIMER_CONTROL_STOP_MSK (0x8)
#define ALTERA_AVALON_TIMER_CONTROL_STOP_OFST (3)
#define ALTERA_AVALON_TIMER_PERIODL_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_PERIODL_OFST (0)
#define ALTERA_AVALON_TIMER_PERIODH_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_PERIODH_OFST (0)
#define ALTERA_AVALON_TIMER_SNAPL_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_SNAPL_OFST (0)
#define ALTERA_AVALON_TIMER_SNAPH_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_SNAPH_OFST (0)
#define ALTERA_AVALON_TIMER_PERIOD_0_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_PERIOD_0_OFST (0)
#define ALTERA_AVALON_TIMER_PERIOD_1_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_PERIOD_1_OFST (0)
#define ALTERA_AVALON_TIMER_PERIOD_2_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_PERIOD_2_OFST (0)
#define ALTERA_AVALON_TIMER_PERIOD_3_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_PERIOD_3_OFST (0)
#define ALTERA_AVALON_TIMER_SNAP_0_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_SNAP_0_OFST (0)
#define ALTERA_AVALON_TIMER_SNAP_1_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_SNAP_1_OFST (0)
#define ALTERA_AVALON_TIMER_SNAP_2_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_SNAP_2_OFST (0)
#define ALTERA_AVALON_TIMER_SNAP_3_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_SNAP_3_OFST (0)
#define MTIMECMP_MAX_VALUE 0xFFFFFFFFFFFFFFFF
typedef struct
{
volatile uint32_t status;
volatile uint32_t control;
volatile uint32_t period_lo;
volatile uint32_t period_hi;
volatile uint32_t snap_lo;
volatile uint32_t snap_hi;
}altera_avalon_timer_regs_32;
typedef struct
{
volatile uint32_t status;
volatile uint32_t control;
volatile uint32_t period_0;
volatile uint32_t period_1;
volatile uint32_t period_2;
volatile uint32_t period_3;
volatile uint32_t snap_0;
volatile uint32_t snap_1;
volatile uint32_t snap_2;
volatile uint32_t snap_3;
}altera_avalon_timer_regs_64;
typedef struct
{
volatile uint32_t status;
volatile uint32_t control;
volatile uint32_t period;
volatile uint32_t snap;
volatile uint32_t prescalar;
}altera_avalon_timer_precale_regs;
typedef struct
{
volatile uint32_t mtimecmp_lo;
volatile uint32_t mtimecmp_hi;
volatile uint32_t mtime_lo;
volatile uint32_t mtime_hi;
}altera_niosv_timer_regs;
#define CLOCK_REGS \
((volatile altera_niosv_timer_regs* )ALT_CPU_MTIME_OFFSET)
#define CLOCK_FREQ ALT_CPU_FREQ
#define CLOCK_VECTOR NIOSV_INTERRUPT_VECTOR_TIMER
#define TIMER_REGS \
((volatile altera_avalon_timer_precale_regs* )BENCHMARK_TIMER_BASE)
#define TIMER_FREQ BENCHMARK_TIMER_FREQ
#define TIMER_VECTOR BENCHMARK_TIMER_IRQ
#define WATCHDOG_REGS \
((volatile altera_avalon_timer_regs_32* )WATCHDOG_TIMER_BASE)
#define WATCHDOG_FREQ WATCHDOG_TIMER_FREQ
#define WATCHDOG_VECTOR WATCHDOG_TIMER_IRQ
#ifdef __cplusplus
}
#endif
#endif /* __ALTERA_AVALON_TIMER_REGS_H__ */

View File

@@ -0,0 +1,174 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2024 Kevin Kirspel
*
* Copyright (c) 2015 University of York.
* Hesham Almatary <hesham@alumni.york.ac.uk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef LIBBSP_NIOSV_IRQ_H
#define LIBBSP_NIOSV_IRQ_H
#ifndef ASM
#include <bsp.h>
#include <rtems/irq.h>
#include <rtems/irq-extension.h>
#include <rtems/score/processormask.h>
#include <rtems/score/riscv-utility.h>
#define NIOSV_INTERRUPT_VECTOR_SOFTWARE 0
#define NIOSV_INTERRUPT_VECTOR_TIMER 1
#define NIOSV_INTERRUPT_VECTOR_EXTERNAL(x) ((x) + 2)
#define NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(x) ((x) >= 2)
#define NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(x) ((x) - 2)
#define BSP_INTERRUPT_VECTOR_COUNT \
NIOSV_INTERRUPT_VECTOR_EXTERNAL(NIOSV_MAXIMUM_EXTERNAL_INTERRUPTS)
#define BSP_INTERRUPT_CUSTOM_VALID_VECTOR
/*
* The following enumeration describes the value in the mcause CSR.
*/
enum alt_exception_cause_e {
NIOSV_UNDEFINED_CAUSE = -1,
NIOSV_INSTRUCTION_ADDRESS_MISALIGNED = 0,
NIOSV_INSTRUCTION_ACCESS_FAULT = 1,
NIOSV_ILLEGAL_INSTRUCTION = 2,
NIOSV_BREAKPOINT = 3,
NIOSV_LOAD_ADDRESS_MISALIGNED = 4,
NIOSV_LOAD_ACCESS_FAULT = 5,
NIOSV_STORE_AMO_ADDRESS_MISALIGNED = 6,
NIOSV_STORE_AMO_ACCESS_FAULT = 7,
NIOSV_ENVIRONMENT_CALL_FROM_U_MODE = 8,
NIOSV_ENVIRONMENT_CALL_FROM_S_MODE = 9,
NIOSV_RESERVED_BIT_10 = 10,
NIOSV_ENVIRONMENT_CALL_FROM_M_MODE = 11,
NIOSV_INSTRUCTION_PAGE_FAULT = 12,
NIOSV_LOAD_PAGE_FAULT = 13,
NIOSV_RESERVED_BIT_14 = 14,
NIOSV_STORE_AMO_PAGE_FAULT = 15
};
typedef enum alt_exception_cause_e alt_exception_cause;
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
static inline uint32_t alt_irq_pending(void)
{
uint32_t active, enabled;
active = read_csr(mip);
enabled = read_csr(mie);
/*
* we want to only process the upper 16-bits, the interrupt lines connected
* via Platform Designer.
*/
return (active & enabled) >> 16;
}
static inline uint32_t alt_irq_index(uint32_t active)
{
uint32_t mask, i;
i = 0;
mask = 1;
/*
* Test each bit in turn looking for an active interrupt. Once one is
* found, the interrupt handler asigned by a call to alt_irq_register() is
* called to clear the interrupt condition.
*/
do {
if (active & mask) {
return i;
}
mask <<= 1;
i++;
} while (1);
/* should not happen */
return 0;
}
static inline bool alt_irq_is_pending(uint32_t index)
{
uint32_t mask, active;
active = alt_irq_pending();
if(active != 0) {
mask = 1 << index;
if (active & mask) {
return true;
}
}
return false;
}
static inline bool alt_irq_is_enabled(uint32_t index)
{
uint32_t mask, enabled;
enabled = read_csr(mie) >> 16;
if(enabled != 0) {
mask = 1 << index;
if (enabled & mask) {
return true;
}
}
return false;
}
static inline void alt_irq_enable(uint32_t index)
{
uint32_t mask;
mask = 1 << (index + 16);
set_csr(mie, mask);
}
static inline void alt_irq_disable(uint32_t index)
{
uint32_t mask;
mask = 1 << (index + 16);
clear_csr(mie, mask);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ASM */
#endif /* LIBBSP_NIOSV_IRQ_H */

View File

@@ -0,0 +1,51 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef BSP_NIOSV_H
#define BSP_NIOSV_H
#include <bsp.h>
#include <rtems/score/cpuimpl.h>
#define NIOSV_MSTATUS_MIE_MASK 0x8
#define NIOSV_MIE_MASK 0xFFFFFFFF
#define NIOSV_MCAUSE_INTERRUPT_MASK 0x80000000
#ifdef __cplusplus
extern "C" {
#endif
uint32_t niosv_get_core_frequency(void);
#ifdef __cplusplus
}
#endif
#endif /* BSP_NIOSV_H */

View File

@@ -0,0 +1 @@
#include <rtems/tm27-default.h>

228
bsps/riscv/niosv/irq/irq.c Normal file
View File

@@ -0,0 +1,228 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bsp/fatal.h>
#include <bsp/irq.h>
#include <bsp/irq-generic.h>
#include <bsp/niosv.h>
#include <rtems/score/percpu.h>
#include <rtems/score/riscv-utility.h>
#include <string.h>
void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self)
{
uint32_t exception_code = (mcause & ~NIOSV_MCAUSE_INTERRUPT_MASK);
if (exception_code == RISCV_INTERRUPT_TIMER_MACHINE) {
bsp_interrupt_handler_dispatch_unchecked(NIOSV_INTERRUPT_VECTOR_TIMER);
} else if (exception_code >= 16) {
uint32_t interrupt_index, active;
active = alt_irq_pending();
while (active != 0) {
interrupt_index = alt_irq_index(active);
bsp_interrupt_handler_dispatch(
NIOSV_INTERRUPT_VECTOR_EXTERNAL(interrupt_index)
);
active = alt_irq_pending();
}
} else if (exception_code == RISCV_INTERRUPT_SOFTWARE_MACHINE) {
bsp_interrupt_handler_dispatch_unchecked(NIOSV_INTERRUPT_VECTOR_SOFTWARE);
} else {
bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION);
}
}
void bsp_interrupt_facility_initialize(void)
{
}
bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
{
return vector < (rtems_vector_number) BSP_INTERRUPT_VECTOR_COUNT;
}
rtems_status_code bsp_interrupt_get_attributes(
rtems_vector_number vector,
rtems_interrupt_attributes *attributes
)
{
attributes->is_maskable = true;
attributes->can_enable = true;
attributes->maybe_enable = true;
attributes->can_disable = true;
attributes->maybe_disable = true;
attributes->can_raise = (vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
attributes->can_raise_on = attributes->can_raise;
attributes->cleared_by_acknowledge = true;
attributes->can_get_affinity = false;
attributes->can_set_affinity = false;
if (vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE) {
attributes->trigger_signal = RTEMS_INTERRUPT_NO_SIGNAL;
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_is_pending(
rtems_vector_number vector,
bool *pending
)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
bsp_interrupt_assert(pending != NULL);
if (NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
uint32_t interrupt_index;
interrupt_index = NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
*pending = alt_irq_is_pending(interrupt_index);
return RTEMS_SUCCESSFUL;
}
if (vector == NIOSV_INTERRUPT_VECTOR_TIMER) {
*pending = (read_csr(mip) & MIP_MTIP) != 0;
return RTEMS_SUCCESSFUL;
}
_Assert(vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
*pending = (read_csr(mip) & MIP_MSIP) != 0;
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
if (vector != NIOSV_INTERRUPT_VECTOR_SOFTWARE) {
return RTEMS_UNSATISFIED;
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
return RTEMS_UNSATISFIED;
}
rtems_status_code bsp_interrupt_vector_is_enabled(
rtems_vector_number vector,
bool *enabled
)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
bsp_interrupt_assert(enabled != NULL);
if (NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
uint32_t interrupt_index;
interrupt_index = NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
*enabled = alt_irq_is_enabled(interrupt_index);
return RTEMS_SUCCESSFUL;
}
if (vector == NIOSV_INTERRUPT_VECTOR_TIMER) {
*enabled = (read_csr(mie) & MIP_MTIP) != 0;
return RTEMS_SUCCESSFUL;
}
_Assert(vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
*enabled = (read_csr(mie) & MIP_MSIP) != 0;
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
if (NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
uint32_t interrupt_index;
interrupt_index = NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
alt_irq_enable(interrupt_index);
return RTEMS_SUCCESSFUL;
}
if (vector == NIOSV_INTERRUPT_VECTOR_TIMER) {
set_csr(mie, MIP_MTIP);
return RTEMS_SUCCESSFUL;
}
_Assert(vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
set_csr(mie, MIP_MSIP);
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
if (NIOSV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
uint32_t interrupt_index;
interrupt_index = NIOSV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
alt_irq_disable(interrupt_index);
return RTEMS_SUCCESSFUL;
}
if (vector == NIOSV_INTERRUPT_VECTOR_TIMER) {
clear_csr(mie, MIP_MTIP);
return RTEMS_SUCCESSFUL;
}
_Assert(vector == NIOSV_INTERRUPT_VECTOR_SOFTWARE);
clear_csr(mie, MIP_MSIP);
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_set_priority(
rtems_vector_number vector,
uint32_t priority
)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
return RTEMS_UNSATISFIED;
}
rtems_status_code bsp_interrupt_get_priority(
rtems_vector_number vector,
uint32_t *priority
)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
bsp_interrupt_assert(priority != NULL);
return RTEMS_UNSATISFIED;
}

View File

@@ -0,0 +1,76 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bsp.h>
#include <bsp/bootcard.h>
#include <bsp/fatal.h>
#include <bsp/irq-generic.h>
#include <bsp/niosv.h>
#include <rtems/sysinit.h>
static uint32_t niosv_core_freq;
static uint32_t get_core_frequency(void)
{
return ALT_CPU_FREQ;
}
uint32_t niosv_get_core_frequency(void)
{
return niosv_core_freq;
}
void bsp_start(void)
{
/* let user know we have started RTEMS */
LED_PIO_REGS->outclear = 0x4;
bsp_interrupt_initialize();
niosv_core_freq = get_core_frequency();
}
static void bsp_predriver_hook( void )
{
epcq_initialize();
}
static void bsp_postdriver_hook(void)
{
/* TODO: add any post driver configuration functions */
}
RTEMS_SYSINIT_ITEM(
bsp_predriver_hook,
RTEMS_SYSINIT_DEVICE_DRIVERS,
RTEMS_SYSINIT_ORDER_FIRST
);
RTEMS_SYSINIT_ITEM(
bsp_postdriver_hook,
RTEMS_SYSINIT_DEVICE_DRIVERS,
RTEMS_SYSINIT_ORDER_LAST
);

View File

@@ -0,0 +1,183 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _ALTERA_AVALON_HBUS_REGS_H
#define _ALTERA_AVALON_HBUS_REGS_H
#include <bsp_system.h>
/* CSR */
#define ALTERA_HBUS_CSR_RACT_MSK (0x1)
#define ALTERA_HBUS_CSR_RACT_OFST (0)
#define ALTERA_HBUS_CSR_RDECERR_MSK (0x100)
#define ALTERA_HBUS_CSR_RDECERR_OFST (8)
#define ALTERA_HBUS_CSR_RTRSERR_MSK (0x200)
#define ALTERA_HBUS_CSR_RTRSERR_OFST (9)
#define ALTERA_HBUS_CSR_RRSTOERR_MSK (0x400)
#define ALTERA_HBUS_CSR_RRSTOERR_OFST (10)
#define ALTERA_HBUS_CSR_RDSSTALL_MSK (0x800)
#define ALTERA_HBUS_CSR_RDSSTALL_OFST (11)
#define ALTERA_HBUS_CSR_WACT_MSK (0x10000)
#define ALTERA_HBUS_CSR_WACT_OFST (16)
#define ALTERA_HBUS_CSR_WDECERR_MSK (0x1000000)
#define ALTERA_HBUS_CSR_WDECERR_OFST (24)
#define ALTERA_HBUS_CSR_WTRSERR_MSK (0x2000000)
#define ALTERA_HBUS_CSR_WTRSERR_OFST (25)
#define ALTERA_HBUS_CSR_WRSTOERR_MSK (0x4000000)
#define ALTERA_HBUS_CSR_WRSTOERR_OFST (26)
/* IEN */
#define ALTERA_HBUS_IEN_RPCINTE_MSK (0x1)
#define ALTERA_HBUS_IEN_RPCINTE_OFST (0)
#define ALTERA_HBUS_IEN_INTP_MSK (0x80000000)
#define ALTERA_HBUS_IEN_INTP_OFST (31)
/* ISR */
#define ALTERA_HBUS_ISR_RPCINTS_MSK (0x1)
#define ALTERA_HBUS_ISR_RPCINTS_OFST (0)
/* MBR */
#define ALTERA_HBUS_MBR_ADDRESS_MSK (0xFF000000)
#define ALTERA_HBUS_MBR_ADDRESS(x) (x & ALTERA_HBUS_MBR_ADDRESS_MSK)
/* MCR */
#define ALTERA_HBUS_MCR_WRAPSIZE_MSK (0x3)
#define ALTERA_HBUS_MCR_WRAPSIZE_OFST (0)
#define ALTERA_HBUS_MCR_DEVTYPE_MSK (0x10)
#define ALTERA_HBUS_MCR_DEVTYPE_OFST (4)
#define ALTERA_HBUS_MCR_CRT_MSK (0x20)
#define ALTERA_HBUS_MCR_CRT_OFST (5)
#define ALTERA_HBUS_MCR_ACS_MSK (0x10000)
#define ALTERA_HBUS_MCR_ACS_OFST (16)
#define ALTERA_HBUS_MCR_TCMO_MSK (0x20000)
#define ALTERA_HBUS_MCR_TCMO_OFST (17)
#define ALTERA_HBUS_MCR_MAXLEN_MSK (0x3FC0000)
#define ALTERA_HBUS_MCR_MAXLEN_OFST (18)
#define ALTERA_HBUS_MCR_MAXEN_MSK (0x80000000)
#define ALTERA_HBUS_MCR_MAXEN_OFST (31)
#define ALTERA_HBUS_MCR_WRAPSIZE_SELECT(x) \
((x) == 32 ? 0x3 : (x) == 64 ? 0x1 : (x) == 16 ? 0x2 : 0x3)
#define ALTERA_HBUS_MCR_WRAPSIZE(x) \
((ALTERA_HBUS_MCR_WRAPSIZE_SELECT(x) << ALTERA_HBUS_MCR_WRAPSIZE_OFST) & \
ALTERA_HBUS_MCR_WRAPSIZE_MSK)
#define ALTERA_HBUS_MCR_DEVTYPE(x) \
(((x) << ALTERA_HBUS_MCR_DEVTYPE_OFST) & ALTERA_HBUS_MCR_DEVTYPE_MSK)
#define ALTERA_HBUS_MCR_CRT(x) \
(((x) << ALTERA_HBUS_MCR_CRT_OFST) & ALTERA_HBUS_MCR_CRT_MSK)
#define ALTERA_HBUS_MCR_CRT_UPDATE(r, x) \
((r) = ((r) & ALTERA_HBUS_MCR_CRT_MSK) | ALTERA_HBUS_MCR_CRT(x))
#define ALTERA_HBUS_MCR_ACS(x) \
(((x) << ALTERA_HBUS_MCR_ACS_OFST) & ALTERA_HBUS_MCR_ACS_MSK)
#define ALTERA_HBUS_MCR_TCMO(x) \
(((x) << ALTERA_HBUS_MCR_TCMO_OFST) & ALTERA_HBUS_MCR_TCMO_MSK)
#define ALTERA_HBUS_MCR_MAXLEN(x) \
(((((x) / 2) - 1) << ALTERA_HBUS_MCR_MAXLEN_OFST) & \
ALTERA_HBUS_MCR_MAXLEN_MSK)
#define ALTERA_HBUS_MCR_MAXEN(x) \
(((x) << ALTERA_HBUS_MCR_MAXEN_OFST) & ALTERA_HBUS_MCR_MAXEN_MSK)
/* MTR */
#define ALTERA_HBUS_MTR_LTCY_MSK (0xF)
#define ALTERA_HBUS_MTR_LTCY_OFST (0)
#define ALTERA_HBUS_MTR_RFU_MSK (0xF0)
#define ALTERA_HBUS_MTR_RFU_OFST (4)
#define ALTERA_HBUS_MTR_WCSH_MSK (0xF00)
#define ALTERA_HBUS_MTR_WCSH_OFST (8)
#define ALTERA_HBUS_MTR_RCSH_MSK (0xF000)
#define ALTERA_HBUS_MTR_RCSH_OFST (12)
#define ALTERA_HBUS_MTR_WCSS_MSK (0xF0000)
#define ALTERA_HBUS_MTR_WCSS_OFST (16)
#define ALTERA_HBUS_MTR_RCSS_MSK (0xF00000)
#define ALTERA_HBUS_MTR_RCSS_OFST (20)
#define ALTERA_HBUS_MTR_WCSHI_MSK (0xF000000)
#define ALTERA_HBUS_MTR_WCSHI_OFST (24)
#define ALTERA_HBUS_MTR_RCSHI_MSK (0xF0000000)
#define ALTERA_HBUS_MTR_RCSHI_OFST (28)
#define ALTERA_HBUS_MTR_LTCY_SELECT(x) \
((x) == 6 ? 0x1 : (x) == 4 ? 0xf : (x) == 5 ? 0x0 : (x) == 3 ? 0xe : 0x1)
#define ALTERA_HBUS_MTR_LTCY(x) \
((ALTERA_HBUS_MTR_LTCY_SELECT(x) << ALTERA_HBUS_MTR_LTCY_OFST) & \
ALTERA_HBUS_MTR_LTCY_MSK)
/* GPOR */
#define ALTERA_HBUS_GPOR_GPO_MSK (0x3)
#define ALTERA_HBUS_GPOR_GPO_OFST (0)
/* WPR */
#define ALTERA_HBUS_WPR_WP_MSK (0x1)
#define ALTERA_HBUS_WPR_WP_OFST (0)
/* LBR */
#define ALTERA_HBUS_LBR_LOOPBACK_MSK (0x1)
#define ALTERA_HBUS_LBR_LOOPBACK_OFST (0)
/* TAR */
#define ALTERA_HBUS_TAR_WTA_MSK (0x3)
#define ALTERA_HBUS_TAR_WTA_OFST (0)
#define ALTERA_HBUS_TAR_RTA_MSK (0x30)
#define ALTERA_HBUS_TAR_RTA_OFST (4)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
volatile uint32_t csr;
volatile uint32_t ien;
volatile uint32_t isr;
volatile uint32_t icr;
volatile uint32_t mbr0;
volatile uint32_t mbr1;
volatile uint32_t mbr2;
volatile uint32_t mbr3;
volatile uint32_t mcr0;
volatile uint32_t mcr1;
volatile uint32_t mcr2;
volatile uint32_t mcr3;
volatile uint32_t mtr0;
volatile uint32_t mtr1;
volatile uint32_t mtr2;
volatile uint32_t mtr3;
volatile uint32_t gpor;
volatile uint32_t wpr;
volatile uint32_t lbr;
volatile uint32_t tar;
}altera_avalon_hbus_ctrl_regs;
#define HBUS_CTRL_REGS \
(( volatile altera_avalon_hbus_ctrl_regs* ) \
HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_BASE )
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,59 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _ALTERA_AVALON_PIO_REGS_H
#define _ALTERA_AVALON_PIO_REGS_H
#include <bsp_system.h>
#define ALTERA_AVALON_PIO_DIRECTION_INPUT 0
#define ALTERA_AVALON_PIO_DIRECTION_OUTPUT 1
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
volatile uint32_t data;
volatile uint32_t direction;
volatile uint32_t interruptmask;
volatile uint32_t edgecapture;
volatile uint32_t outset;
volatile uint32_t outclear;
}altera_avalon_pio_regs;
#define LED_PIO_REGS (( volatile altera_avalon_pio_regs* )LED_PIO_BASE )
#define USER_DIPSW_REGS (( volatile altera_avalon_pio_regs* )USER_DIPSW_BASE )
#define USER_PB_REGS (( volatile altera_avalon_pio_regs* )USER_PB_BASE )
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,50 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __ALTERA_AVALON_SYSID_QSYS_REGS_H__
#define __ALTERA_AVALON_SYSID_QSYS_REGS_H__
#include <bsp_system.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
volatile uint32_t sys_id;
volatile uint32_t sys_timestamp;
}altera_avalon_sysid_regs;
#define SYSID_REGS (( volatile altera_avalon_sysid_regs* )SYS_ID_BASE )
#ifdef __cplusplus
}
#endif
#endif /* __ALTERA_AVALON_SYSID_QSYS_REGS_H__ */

View File

@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef LIBBSP_NIOSV_GENERIC_H
#define LIBBSP_NIOSV_GENERIC_H
#include <rtems.h>
#include <rtems/clockdrv.h>
#include <rtems/console.h>
#include <bspopts.h>
#include <bsp/default-initial-extension.h>
#include <altera_avalon_hbus_regs.h>
#include <altera_avalon_jtag_uart_regs.h>
#include <altera_avalon_pio_regs.h>
#include <altera_avalon_sysid_qsys_regs.h>
#include <altera_avalon_timer_regs.h>
#include <altera_avalon_epcq_regs.h>
#include <status_led_device_driver.h>
#include <system_device_driver.h>
#include <rtems/devnull.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BSP_FEATURE_IRQ_EXTENSION
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* LIBBSP_NIOSV_GENERIC_H */

View File

@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __BSP_SYSTEM_H_
#define __BSP_SYSTEM_H_
#if NIOSV_IS_NIOSVG != 0
#include <bsp_system_vg.h>
#else
#include <bsp_system_vm.h>
#endif
#endif /* __BSP_SYSTEM_H_ */

View File

@@ -0,0 +1,461 @@
/*
* system.h - SOPC Builder system and BSP software package information
*
* Machine generated for CPU 'niosv_g_cpu' in SOPC Builder design 'c10lp_rtems'
* SOPC Builder design path: C:/Temp/Altera/cl10/cyclone10LP_10cl025yu256_eval_v17.0.0stdb595/examples/rtems_vg/c10lp_rtems.sopcinfo
*
* Generated: Fri Aug 02 17:56:06 EDT 2024
*/
/*
* DO NOT MODIFY THIS FILE
*
* Changing this file will have subtle consequences
* which will almost certainly lead to a nonfunctioning
* system. If you do modify this file, be aware that your
* changes will be overwritten and lost when this file
* is generated again.
*
* DO NOT MODIFY THIS FILE
*/
/*
* License Agreement
*
* Copyright (c) 2008
* Altera Corporation, San Jose, California, USA.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* This agreement shall be governed in all respects by the laws of the State
* of California and by the laws of the United States of America.
*/
#ifndef __BSP_SYSTEM_VG_H_
#define __BSP_SYSTEM_VG_H_
/*
* CPU configuration
*
*/
#define ALT_CPU_ARCHITECTURE "intel_niosv_g"
#define ALT_CPU_CPU_FREQ 100000000u
#define ALT_CPU_DATA_ADDR_WIDTH 0x20
#define ALT_CPU_DCACHE_LINE_SIZE 32
#define ALT_CPU_DCACHE_LINE_SIZE_LOG2 5
#define ALT_CPU_DCACHE_SIZE 4096
#define ALT_CPU_FREQ 100000000
#define ALT_CPU_HAS_CSR_SUPPORT 1
#define ALT_CPU_HAS_DEBUG_STUB
#define ALT_CPU_ICACHE_LINE_SIZE 32
#define ALT_CPU_ICACHE_LINE_SIZE_LOG2 5
#define ALT_CPU_ICACHE_SIZE 4096
#define ALT_CPU_INST_ADDR_WIDTH 0x20
#define ALT_CPU_MTIME_OFFSET 0x10000100
#define ALT_CPU_NAME "niosv_g_cpu"
#define ALT_CPU_NIOSV_CORE_VARIANT 3
#define ALT_CPU_NUM_GPR 32
#define ALT_CPU_RESET_ADDR 0x10010000
#define ALT_CPU_TICKS_PER_SEC NIOSV_INTERNAL_TIMER_TICKS_PER_SECOND
#define ALT_CPU_TIMER_DEVICE_TYPE 2
/*
* CPU configuration (with legacy prefix - don't use these anymore)
*
*/
#define BANTAMLAKE_CPU_FREQ 100000000u
#define BANTAMLAKE_DATA_ADDR_WIDTH 0x20
#define BANTAMLAKE_DCACHE_LINE_SIZE 32
#define BANTAMLAKE_DCACHE_LINE_SIZE_LOG2 5
#define BANTAMLAKE_DCACHE_SIZE 4096
#define BANTAMLAKE_HAS_CSR_SUPPORT 1
#define BANTAMLAKE_HAS_DEBUG_STUB
#define BANTAMLAKE_ICACHE_LINE_SIZE 32
#define BANTAMLAKE_ICACHE_LINE_SIZE_LOG2 5
#define BANTAMLAKE_ICACHE_SIZE 4096
#define BANTAMLAKE_INST_ADDR_WIDTH 0x20
#define BANTAMLAKE_MTIME_OFFSET 0x10000100
#define BANTAMLAKE_NIOSV_CORE_VARIANT 3
#define BANTAMLAKE_NUM_GPR 32
#define BANTAMLAKE_RESET_ADDR 0x10010000
#define BANTAMLAKE_TICKS_PER_SEC NIOSV_INTERNAL_TIMER_TICKS_PER_SECOND
#define BANTAMLAKE_TIMER_DEVICE_TYPE 2
/*
* Define for each module class mastered by the CPU
*
*/
#define __ALTERA_AVALON_JTAG_UART
#define __ALTERA_AVALON_ONCHIP_MEMORY2
#define __ALTERA_AVALON_PIO
#define __ALTERA_AVALON_SYSID_QSYS
#define __ALTERA_AVALON_TIMER
#define __ALTERA_GENERIC_QUAD_SPI_CONTROLLER2
#define __HYPERBUS_CTRL
#define __INTEL_NIOSV_G
#define __INTERVAL_TIMER
/*
* System configuration
*
*/
#define ALT_DEVICE_FAMILY "Cyclone 10 LP"
#define ALT_ENHANCED_INTERRUPT_API_PRESENT
#define ALT_IRQ_BASE NULL
#define ALT_LOG_PORT "/dev/null"
#define ALT_LOG_PORT_BASE 0x0
#define ALT_LOG_PORT_DEV null
#define ALT_LOG_PORT_TYPE ""
#define ALT_NUM_EXTERNAL_INTERRUPT_CONTROLLERS 0
#define ALT_NUM_INTERNAL_INTERRUPT_CONTROLLERS 1
#define ALT_NUM_INTERRUPT_CONTROLLERS 1
#define ALT_STDERR "/dev/jtag_uart"
#define ALT_STDERR_BASE 0x10000208
#define ALT_STDERR_DEV jtag_uart
#define ALT_STDERR_IS_JTAG_UART
#define ALT_STDERR_PRESENT
#define ALT_STDERR_TYPE "altera_avalon_jtag_uart"
#define ALT_STDIN "/dev/jtag_uart"
#define ALT_STDIN_BASE 0x10000208
#define ALT_STDIN_DEV jtag_uart
#define ALT_STDIN_IS_JTAG_UART
#define ALT_STDIN_PRESENT
#define ALT_STDIN_TYPE "altera_avalon_jtag_uart"
#define ALT_STDOUT "/dev/jtag_uart"
#define ALT_STDOUT_BASE 0x10000208
#define ALT_STDOUT_DEV jtag_uart
#define ALT_STDOUT_IS_JTAG_UART
#define ALT_STDOUT_PRESENT
#define ALT_STDOUT_TYPE "altera_avalon_jtag_uart"
#define ALT_SYSTEM_NAME "c10lp_rtems"
#define ALT_SYS_CLK_TICKS_PER_SEC ALT_CPU_TICKS_PER_SEC
#define ALT_TIMESTAMP_CLK_TIMER_DEVICE_TYPE ALT_CPU_TIMER_DEVICE_TYPE
/*
* benchmark_timer configuration
*
*/
#define ALT_MODULE_CLASS_benchmark_timer interval_timer
#define BENCHMARK_TIMER_BASE 0x10000180
#define BENCHMARK_TIMER_FREQ 100000000
#define BENCHMARK_TIMER_IRQ 6
#define BENCHMARK_TIMER_IRQ_INTERRUPT_CONTROLLER_ID 0
#define BENCHMARK_TIMER_NAME "/dev/benchmark_timer"
#define BENCHMARK_TIMER_SPAN 32
#define BENCHMARK_TIMER_TYPE "interval_timer"
/*
* epcq_controller_avl_csr configuration
*
*/
#define ALT_MODULE_CLASS_epcq_controller_avl_csr altera_generic_quad_spi_controller2
#define EPCQ_CONTROLLER_AVL_CSR_BASE 0x10000140
#define EPCQ_CONTROLLER_AVL_CSR_FLASH_TYPE "EPCQ128"
#define EPCQ_CONTROLLER_AVL_CSR_IRQ 1
#define EPCQ_CONTROLLER_AVL_CSR_IRQ_INTERRUPT_CONTROLLER_ID 0
#define EPCQ_CONTROLLER_AVL_CSR_IS_EPCS 0
#define EPCQ_CONTROLLER_AVL_CSR_NAME "/dev/epcq_controller_avl_csr"
#define EPCQ_CONTROLLER_AVL_CSR_NUMBER_OF_SECTORS 256
#define EPCQ_CONTROLLER_AVL_CSR_PAGE_SIZE 256
#define EPCQ_CONTROLLER_AVL_CSR_SECTOR_SIZE 65536
#define EPCQ_CONTROLLER_AVL_CSR_SPAN 64
#define EPCQ_CONTROLLER_AVL_CSR_SUBSECTOR_SIZE 4096
#define EPCQ_CONTROLLER_AVL_CSR_TYPE "altera_generic_quad_spi_controller2"
/*
* epcq_controller_avl_mem configuration
*
*/
#define ALT_MODULE_CLASS_epcq_controller_avl_mem altera_generic_quad_spi_controller2
#define EPCQ_CONTROLLER_AVL_MEM_BASE 0x11000000
#define EPCQ_CONTROLLER_AVL_MEM_FLASH_TYPE "EPCQ128"
#define EPCQ_CONTROLLER_AVL_MEM_IRQ -1
#define EPCQ_CONTROLLER_AVL_MEM_IRQ_INTERRUPT_CONTROLLER_ID -1
#define EPCQ_CONTROLLER_AVL_MEM_IS_EPCS 0
#define EPCQ_CONTROLLER_AVL_MEM_NAME "/dev/epcq_controller_avl_mem"
#define EPCQ_CONTROLLER_AVL_MEM_NUMBER_OF_SECTORS 256
#define EPCQ_CONTROLLER_AVL_MEM_PAGE_SIZE 256
#define EPCQ_CONTROLLER_AVL_MEM_SECTOR_SIZE 65536
#define EPCQ_CONTROLLER_AVL_MEM_SPAN 16777216
#define EPCQ_CONTROLLER_AVL_MEM_SUBSECTOR_SIZE 4096
#define EPCQ_CONTROLLER_AVL_MEM_TYPE "altera_generic_quad_spi_controller2"
/*
* hal2 configuration
*
*/
#define ALT_MAX_FD 32
#define ALT_SYS_CLK NIOSV_G_CPU
#define ALT_TIMESTAMP_CLK NIOSV_G_CPU
#define INTEL_FPGA_DFL_START_ADDRESS 0xffffffffffffffff
#define INTEL_FPGA_USE_DFL_WALKER 0
/*
* hyperbus_ctrl_altera_axi4_slave_memory configuration
*
*/
#define ALT_MODULE_CLASS_hyperbus_ctrl_altera_axi4_slave_memory hyperbus_ctrl
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_BASE 0x0
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_IRQ -1
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_IRQ_INTERRUPT_CONTROLLER_ID -1
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_NAME "/dev/hyperbus_ctrl_altera_axi4_slave_memory"
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_SPAN 268435456
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_TYPE "hyperbus_ctrl"
/*
* hyperbus_ctrl_altera_axi4_slave_register configuration
*
*/
#define ALT_MODULE_CLASS_hyperbus_ctrl_altera_axi4_slave_register hyperbus_ctrl
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_BASE 0x10000000
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_IRQ -1
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_IRQ_INTERRUPT_CONTROLLER_ID -1
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_NAME "/dev/hyperbus_ctrl_altera_axi4_slave_register"
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_SPAN 256
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_TYPE "hyperbus_ctrl"
/*
* intel_niosv_g_hal_driver configuration
*
*/
#define NIOSV_INTERNAL_TIMER_TICKS_PER_SECOND 1000
/*
* jtag_uart configuration
*
*/
#define ALT_MODULE_CLASS_jtag_uart altera_avalon_jtag_uart
#define JTAG_UART_BASE 0x10000208
#define JTAG_UART_IRQ 4
#define JTAG_UART_IRQ_INTERRUPT_CONTROLLER_ID 0
#define JTAG_UART_NAME "/dev/jtag_uart"
#define JTAG_UART_READ_DEPTH 64
#define JTAG_UART_READ_THRESHOLD 8
#define JTAG_UART_SPAN 8
#define JTAG_UART_TYPE "altera_avalon_jtag_uart"
#define JTAG_UART_WRITE_DEPTH 64
#define JTAG_UART_WRITE_THRESHOLD 8
/*
* led_pio configuration
*
*/
#define ALT_MODULE_CLASS_led_pio altera_avalon_pio
#define LED_PIO_BASE 0x100001a0
#define LED_PIO_BIT_CLEARING_EDGE_REGISTER 0
#define LED_PIO_BIT_MODIFYING_OUTPUT_REGISTER 1
#define LED_PIO_CAPTURE 0
#define LED_PIO_DATA_WIDTH 5
#define LED_PIO_DO_TEST_BENCH_WIRING 0
#define LED_PIO_DRIVEN_SIM_VALUE 0
#define LED_PIO_EDGE_TYPE "NONE"
#define LED_PIO_FREQ 100000000
#define LED_PIO_HAS_IN 0
#define LED_PIO_HAS_OUT 1
#define LED_PIO_HAS_TRI 0
#define LED_PIO_IRQ -1
#define LED_PIO_IRQ_INTERRUPT_CONTROLLER_ID -1
#define LED_PIO_IRQ_TYPE "NONE"
#define LED_PIO_NAME "/dev/led_pio"
#define LED_PIO_RESET_VALUE 15
#define LED_PIO_SPAN 32
#define LED_PIO_TYPE "altera_avalon_pio"
/*
* onchip_boot_rom configuration
*
*/
#define ALT_MODULE_CLASS_onchip_boot_rom altera_avalon_onchip_memory2
#define ONCHIP_BOOT_ROM_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
#define ONCHIP_BOOT_ROM_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
#define ONCHIP_BOOT_ROM_BASE 0x10010000
#define ONCHIP_BOOT_ROM_CONTENTS_INFO ""
#define ONCHIP_BOOT_ROM_DUAL_PORT 0
#define ONCHIP_BOOT_ROM_GUI_RAM_BLOCK_TYPE "AUTO"
#define ONCHIP_BOOT_ROM_INIT_CONTENTS_FILE "bootloader_niosvc10lp"
#define ONCHIP_BOOT_ROM_INIT_MEM_CONTENT 1
#define ONCHIP_BOOT_ROM_INSTANCE_ID "NONE"
#define ONCHIP_BOOT_ROM_IRQ -1
#define ONCHIP_BOOT_ROM_IRQ_INTERRUPT_CONTROLLER_ID -1
#define ONCHIP_BOOT_ROM_NAME "/dev/onchip_boot_rom"
#define ONCHIP_BOOT_ROM_NON_DEFAULT_INIT_FILE_ENABLED 1
#define ONCHIP_BOOT_ROM_RAM_BLOCK_TYPE "AUTO"
#define ONCHIP_BOOT_ROM_READ_DURING_WRITE_MODE "DONT_CARE"
#define ONCHIP_BOOT_ROM_SINGLE_CLOCK_OP 0
#define ONCHIP_BOOT_ROM_SIZE_MULTIPLE 1
#define ONCHIP_BOOT_ROM_SIZE_VALUE 4096
#define ONCHIP_BOOT_ROM_SPAN 4096
#define ONCHIP_BOOT_ROM_TYPE "altera_avalon_onchip_memory2"
#define ONCHIP_BOOT_ROM_WRITABLE 0
/*
* onchip_ram configuration
*
*/
#define ALT_MODULE_CLASS_onchip_ram altera_avalon_onchip_memory2
#define ONCHIP_RAM_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
#define ONCHIP_RAM_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
#define ONCHIP_RAM_BASE 0x10020000
#define ONCHIP_RAM_CONTENTS_INFO ""
#define ONCHIP_RAM_DUAL_PORT 0
#define ONCHIP_RAM_GUI_RAM_BLOCK_TYPE "AUTO"
#define ONCHIP_RAM_INIT_CONTENTS_FILE "c10lp_rtems_onchip_ram"
#define ONCHIP_RAM_INIT_MEM_CONTENT 0
#define ONCHIP_RAM_INSTANCE_ID "NONE"
#define ONCHIP_RAM_IRQ -1
#define ONCHIP_RAM_IRQ_INTERRUPT_CONTROLLER_ID -1
#define ONCHIP_RAM_NAME "/dev/onchip_ram"
#define ONCHIP_RAM_NON_DEFAULT_INIT_FILE_ENABLED 0
#define ONCHIP_RAM_RAM_BLOCK_TYPE "AUTO"
#define ONCHIP_RAM_READ_DURING_WRITE_MODE "DONT_CARE"
#define ONCHIP_RAM_SINGLE_CLOCK_OP 0
#define ONCHIP_RAM_SIZE_MULTIPLE 1
#define ONCHIP_RAM_SIZE_VALUE 8192
#define ONCHIP_RAM_SPAN 8192
#define ONCHIP_RAM_TYPE "altera_avalon_onchip_memory2"
#define ONCHIP_RAM_WRITABLE 1
/*
* sys_id configuration
*
*/
#define ALT_MODULE_CLASS_sys_id altera_avalon_sysid_qsys
#define SYS_ID_BASE 0x10000200
#define SYS_ID_ID 405222982
#define SYS_ID_IRQ -1
#define SYS_ID_IRQ_INTERRUPT_CONTROLLER_ID -1
#define SYS_ID_NAME "/dev/sys_id"
#define SYS_ID_SPAN 8
#define SYS_ID_TIMESTAMP 1722633287
#define SYS_ID_TYPE "altera_avalon_sysid_qsys"
/*
* user_dipsw configuration
*
*/
#define ALT_MODULE_CLASS_user_dipsw altera_avalon_pio
#define USER_DIPSW_BASE 0x100001f0
#define USER_DIPSW_BIT_CLEARING_EDGE_REGISTER 0
#define USER_DIPSW_BIT_MODIFYING_OUTPUT_REGISTER 0
#define USER_DIPSW_CAPTURE 0
#define USER_DIPSW_DATA_WIDTH 4
#define USER_DIPSW_DO_TEST_BENCH_WIRING 0
#define USER_DIPSW_DRIVEN_SIM_VALUE 0
#define USER_DIPSW_EDGE_TYPE "NONE"
#define USER_DIPSW_FREQ 100000000
#define USER_DIPSW_HAS_IN 1
#define USER_DIPSW_HAS_OUT 0
#define USER_DIPSW_HAS_TRI 0
#define USER_DIPSW_IRQ -1
#define USER_DIPSW_IRQ_INTERRUPT_CONTROLLER_ID -1
#define USER_DIPSW_IRQ_TYPE "NONE"
#define USER_DIPSW_NAME "/dev/user_dipsw"
#define USER_DIPSW_RESET_VALUE 0
#define USER_DIPSW_SPAN 16
#define USER_DIPSW_TYPE "altera_avalon_pio"
/*
* user_pb configuration
*
*/
#define ALT_MODULE_CLASS_user_pb altera_avalon_pio
#define USER_PB_BASE 0x100001e0
#define USER_PB_BIT_CLEARING_EDGE_REGISTER 0
#define USER_PB_BIT_MODIFYING_OUTPUT_REGISTER 0
#define USER_PB_CAPTURE 0
#define USER_PB_DATA_WIDTH 4
#define USER_PB_DO_TEST_BENCH_WIRING 0
#define USER_PB_DRIVEN_SIM_VALUE 0
#define USER_PB_EDGE_TYPE "NONE"
#define USER_PB_FREQ 100000000
#define USER_PB_HAS_IN 1
#define USER_PB_HAS_OUT 0
#define USER_PB_HAS_TRI 0
#define USER_PB_IRQ -1
#define USER_PB_IRQ_INTERRUPT_CONTROLLER_ID -1
#define USER_PB_IRQ_TYPE "NONE"
#define USER_PB_NAME "/dev/user_pb"
#define USER_PB_RESET_VALUE 0
#define USER_PB_SPAN 16
#define USER_PB_TYPE "altera_avalon_pio"
/*
* watchdog_timer configuration
*
*/
#define ALT_MODULE_CLASS_watchdog_timer altera_avalon_timer
#define WATCHDOG_TIMER_ALWAYS_RUN 1
#define WATCHDOG_TIMER_BASE 0x100001c0
#define WATCHDOG_TIMER_COUNTER_SIZE 32
#define WATCHDOG_TIMER_FIXED_PERIOD 1
#define WATCHDOG_TIMER_FREQ 100000000
#define WATCHDOG_TIMER_IRQ 5
#define WATCHDOG_TIMER_IRQ_INTERRUPT_CONTROLLER_ID 0
#define WATCHDOG_TIMER_LOAD_VALUE 99
#define WATCHDOG_TIMER_MULT 1.0E-6
#define WATCHDOG_TIMER_NAME "/dev/watchdog_timer"
#define WATCHDOG_TIMER_PERIOD 1
#define WATCHDOG_TIMER_PERIOD_UNITS "us"
#define WATCHDOG_TIMER_RESET_OUTPUT 1
#define WATCHDOG_TIMER_SNAPSHOT 0
#define WATCHDOG_TIMER_SPAN 32
#define WATCHDOG_TIMER_TICKS_PER_SEC 1000000
#define WATCHDOG_TIMER_TIMEOUT_PULSE_OUTPUT 0
#define WATCHDOG_TIMER_TIMER_DEVICE_TYPE 1
#define WATCHDOG_TIMER_TYPE "altera_avalon_timer"
#endif /* __BSP_SYSTEM_VG_H_ */

View File

@@ -0,0 +1,461 @@
/*
* system.h - SOPC Builder system and BSP software package information
*
* Machine generated for CPU 'niosv_m_cpu' in SOPC Builder design 'c10lp_rtems'
* SOPC Builder design path: C:/Temp/Altera/cl10/cyclone10LP_10cl025yu256_eval_v17.0.0stdb595/examples/rtems_vm/c10lp_rtems.sopcinfo
*
* Generated: Fri Aug 02 17:55:13 EDT 2024
*/
/*
* DO NOT MODIFY THIS FILE
*
* Changing this file will have subtle consequences
* which will almost certainly lead to a nonfunctioning
* system. If you do modify this file, be aware that your
* changes will be overwritten and lost when this file
* is generated again.
*
* DO NOT MODIFY THIS FILE
*/
/*
* License Agreement
*
* Copyright (c) 2008
* Altera Corporation, San Jose, California, USA.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* This agreement shall be governed in all respects by the laws of the State
* of California and by the laws of the United States of America.
*/
#ifndef __BSP_SYSTEM_VM_H_
#define __BSP_SYSTEM_VM_H_
/*
* CPU configuration
*
*/
#define ALT_CPU_ARCHITECTURE "intel_niosv_m"
#define ALT_CPU_CPU_FREQ 100000000u
#define ALT_CPU_DATA_ADDR_WIDTH 0x20
#define ALT_CPU_DCACHE_LINE_SIZE 0
#define ALT_CPU_DCACHE_LINE_SIZE_LOG2 0
#define ALT_CPU_DCACHE_SIZE 0
#define ALT_CPU_FREQ 100000000
#define ALT_CPU_HAS_CSR_SUPPORT 1
#define ALT_CPU_HAS_DEBUG_STUB
#define ALT_CPU_ICACHE_LINE_SIZE 0
#define ALT_CPU_ICACHE_LINE_SIZE_LOG2 0
#define ALT_CPU_ICACHE_SIZE 0
#define ALT_CPU_INST_ADDR_WIDTH 0x20
#define ALT_CPU_MTIME_OFFSET 0x10000100
#define ALT_CPU_NAME "niosv_m_cpu"
#define ALT_CPU_NIOSV_CORE_VARIANT 1
#define ALT_CPU_NUM_GPR 32
#define ALT_CPU_RESET_ADDR 0x10010000
#define ALT_CPU_TICKS_PER_SEC NIOSV_INTERNAL_TIMER_TICKS_PER_SECOND
#define ALT_CPU_TIMER_DEVICE_TYPE 2
/*
* CPU configuration (with legacy prefix - don't use these anymore)
*
*/
#define ABBOTTSLAKE_CPU_FREQ 100000000u
#define ABBOTTSLAKE_DATA_ADDR_WIDTH 0x20
#define ABBOTTSLAKE_DCACHE_LINE_SIZE 0
#define ABBOTTSLAKE_DCACHE_LINE_SIZE_LOG2 0
#define ABBOTTSLAKE_DCACHE_SIZE 0
#define ABBOTTSLAKE_HAS_CSR_SUPPORT 1
#define ABBOTTSLAKE_HAS_DEBUG_STUB
#define ABBOTTSLAKE_ICACHE_LINE_SIZE 0
#define ABBOTTSLAKE_ICACHE_LINE_SIZE_LOG2 0
#define ABBOTTSLAKE_ICACHE_SIZE 0
#define ABBOTTSLAKE_INST_ADDR_WIDTH 0x20
#define ABBOTTSLAKE_MTIME_OFFSET 0x10000100
#define ABBOTTSLAKE_NIOSV_CORE_VARIANT 1
#define ABBOTTSLAKE_NUM_GPR 32
#define ABBOTTSLAKE_RESET_ADDR 0x10010000
#define ABBOTTSLAKE_TICKS_PER_SEC NIOSV_INTERNAL_TIMER_TICKS_PER_SECOND
#define ABBOTTSLAKE_TIMER_DEVICE_TYPE 2
/*
* Define for each module class mastered by the CPU
*
*/
#define __ALTERA_AVALON_JTAG_UART
#define __ALTERA_AVALON_ONCHIP_MEMORY2
#define __ALTERA_AVALON_PIO
#define __ALTERA_AVALON_SYSID_QSYS
#define __ALTERA_AVALON_TIMER
#define __ALTERA_GENERIC_QUAD_SPI_CONTROLLER2
#define __HYPERBUS_CTRL
#define __INTEL_NIOSV_M
#define __INTERVAL_TIMER
/*
* System configuration
*
*/
#define ALT_DEVICE_FAMILY "Cyclone 10 LP"
#define ALT_ENHANCED_INTERRUPT_API_PRESENT
#define ALT_IRQ_BASE NULL
#define ALT_LOG_PORT "/dev/null"
#define ALT_LOG_PORT_BASE 0x0
#define ALT_LOG_PORT_DEV null
#define ALT_LOG_PORT_TYPE ""
#define ALT_NUM_EXTERNAL_INTERRUPT_CONTROLLERS 0
#define ALT_NUM_INTERNAL_INTERRUPT_CONTROLLERS 1
#define ALT_NUM_INTERRUPT_CONTROLLERS 1
#define ALT_STDERR "/dev/jtag_uart"
#define ALT_STDERR_BASE 0x10000208
#define ALT_STDERR_DEV jtag_uart
#define ALT_STDERR_IS_JTAG_UART
#define ALT_STDERR_PRESENT
#define ALT_STDERR_TYPE "altera_avalon_jtag_uart"
#define ALT_STDIN "/dev/jtag_uart"
#define ALT_STDIN_BASE 0x10000208
#define ALT_STDIN_DEV jtag_uart
#define ALT_STDIN_IS_JTAG_UART
#define ALT_STDIN_PRESENT
#define ALT_STDIN_TYPE "altera_avalon_jtag_uart"
#define ALT_STDOUT "/dev/jtag_uart"
#define ALT_STDOUT_BASE 0x10000208
#define ALT_STDOUT_DEV jtag_uart
#define ALT_STDOUT_IS_JTAG_UART
#define ALT_STDOUT_PRESENT
#define ALT_STDOUT_TYPE "altera_avalon_jtag_uart"
#define ALT_SYSTEM_NAME "c10lp_rtems"
#define ALT_SYS_CLK_TICKS_PER_SEC ALT_CPU_TICKS_PER_SEC
#define ALT_TIMESTAMP_CLK_TIMER_DEVICE_TYPE ALT_CPU_TIMER_DEVICE_TYPE
/*
* benchmark_timer configuration
*
*/
#define ALT_MODULE_CLASS_benchmark_timer interval_timer
#define BENCHMARK_TIMER_BASE 0x10000180
#define BENCHMARK_TIMER_FREQ 100000000
#define BENCHMARK_TIMER_IRQ 6
#define BENCHMARK_TIMER_IRQ_INTERRUPT_CONTROLLER_ID 0
#define BENCHMARK_TIMER_NAME "/dev/benchmark_timer"
#define BENCHMARK_TIMER_SPAN 32
#define BENCHMARK_TIMER_TYPE "interval_timer"
/*
* epcq_controller_avl_csr configuration
*
*/
#define ALT_MODULE_CLASS_epcq_controller_avl_csr altera_generic_quad_spi_controller2
#define EPCQ_CONTROLLER_AVL_CSR_BASE 0x10000140
#define EPCQ_CONTROLLER_AVL_CSR_FLASH_TYPE "EPCQ128"
#define EPCQ_CONTROLLER_AVL_CSR_IRQ 1
#define EPCQ_CONTROLLER_AVL_CSR_IRQ_INTERRUPT_CONTROLLER_ID 0
#define EPCQ_CONTROLLER_AVL_CSR_IS_EPCS 0
#define EPCQ_CONTROLLER_AVL_CSR_NAME "/dev/epcq_controller_avl_csr"
#define EPCQ_CONTROLLER_AVL_CSR_NUMBER_OF_SECTORS 256
#define EPCQ_CONTROLLER_AVL_CSR_PAGE_SIZE 256
#define EPCQ_CONTROLLER_AVL_CSR_SECTOR_SIZE 65536
#define EPCQ_CONTROLLER_AVL_CSR_SPAN 64
#define EPCQ_CONTROLLER_AVL_CSR_SUBSECTOR_SIZE 4096
#define EPCQ_CONTROLLER_AVL_CSR_TYPE "altera_generic_quad_spi_controller2"
/*
* epcq_controller_avl_mem configuration
*
*/
#define ALT_MODULE_CLASS_epcq_controller_avl_mem altera_generic_quad_spi_controller2
#define EPCQ_CONTROLLER_AVL_MEM_BASE 0x11000000
#define EPCQ_CONTROLLER_AVL_MEM_FLASH_TYPE "EPCQ128"
#define EPCQ_CONTROLLER_AVL_MEM_IRQ -1
#define EPCQ_CONTROLLER_AVL_MEM_IRQ_INTERRUPT_CONTROLLER_ID -1
#define EPCQ_CONTROLLER_AVL_MEM_IS_EPCS 0
#define EPCQ_CONTROLLER_AVL_MEM_NAME "/dev/epcq_controller_avl_mem"
#define EPCQ_CONTROLLER_AVL_MEM_NUMBER_OF_SECTORS 256
#define EPCQ_CONTROLLER_AVL_MEM_PAGE_SIZE 256
#define EPCQ_CONTROLLER_AVL_MEM_SECTOR_SIZE 65536
#define EPCQ_CONTROLLER_AVL_MEM_SPAN 16777216
#define EPCQ_CONTROLLER_AVL_MEM_SUBSECTOR_SIZE 4096
#define EPCQ_CONTROLLER_AVL_MEM_TYPE "altera_generic_quad_spi_controller2"
/*
* hal2 configuration
*
*/
#define ALT_MAX_FD 32
#define ALT_SYS_CLK NIOSV_M_CPU
#define ALT_TIMESTAMP_CLK NIOSV_M_CPU
#define INTEL_FPGA_DFL_START_ADDRESS 0xffffffffffffffff
#define INTEL_FPGA_USE_DFL_WALKER 0
/*
* hyperbus_ctrl_altera_axi4_slave_memory configuration
*
*/
#define ALT_MODULE_CLASS_hyperbus_ctrl_altera_axi4_slave_memory hyperbus_ctrl
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_BASE 0x0
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_IRQ -1
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_IRQ_INTERRUPT_CONTROLLER_ID -1
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_NAME "/dev/hyperbus_ctrl_altera_axi4_slave_memory"
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_SPAN 268435456
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_MEMORY_TYPE "hyperbus_ctrl"
/*
* hyperbus_ctrl_altera_axi4_slave_register configuration
*
*/
#define ALT_MODULE_CLASS_hyperbus_ctrl_altera_axi4_slave_register hyperbus_ctrl
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_BASE 0x10000000
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_IRQ -1
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_IRQ_INTERRUPT_CONTROLLER_ID -1
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_NAME "/dev/hyperbus_ctrl_altera_axi4_slave_register"
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_SPAN 256
#define HYPERBUS_CTRL_ALTERA_AXI4_SLAVE_REGISTER_TYPE "hyperbus_ctrl"
/*
* intel_niosv_m_hal_driver configuration
*
*/
#define NIOSV_INTERNAL_TIMER_TICKS_PER_SECOND 1000
/*
* jtag_uart configuration
*
*/
#define ALT_MODULE_CLASS_jtag_uart altera_avalon_jtag_uart
#define JTAG_UART_BASE 0x10000208
#define JTAG_UART_IRQ 4
#define JTAG_UART_IRQ_INTERRUPT_CONTROLLER_ID 0
#define JTAG_UART_NAME "/dev/jtag_uart"
#define JTAG_UART_READ_DEPTH 64
#define JTAG_UART_READ_THRESHOLD 8
#define JTAG_UART_SPAN 8
#define JTAG_UART_TYPE "altera_avalon_jtag_uart"
#define JTAG_UART_WRITE_DEPTH 64
#define JTAG_UART_WRITE_THRESHOLD 8
/*
* led_pio configuration
*
*/
#define ALT_MODULE_CLASS_led_pio altera_avalon_pio
#define LED_PIO_BASE 0x100001a0
#define LED_PIO_BIT_CLEARING_EDGE_REGISTER 0
#define LED_PIO_BIT_MODIFYING_OUTPUT_REGISTER 1
#define LED_PIO_CAPTURE 0
#define LED_PIO_DATA_WIDTH 5
#define LED_PIO_DO_TEST_BENCH_WIRING 0
#define LED_PIO_DRIVEN_SIM_VALUE 0
#define LED_PIO_EDGE_TYPE "NONE"
#define LED_PIO_FREQ 100000000
#define LED_PIO_HAS_IN 0
#define LED_PIO_HAS_OUT 1
#define LED_PIO_HAS_TRI 0
#define LED_PIO_IRQ -1
#define LED_PIO_IRQ_INTERRUPT_CONTROLLER_ID -1
#define LED_PIO_IRQ_TYPE "NONE"
#define LED_PIO_NAME "/dev/led_pio"
#define LED_PIO_RESET_VALUE 15
#define LED_PIO_SPAN 32
#define LED_PIO_TYPE "altera_avalon_pio"
/*
* onchip_boot_rom configuration
*
*/
#define ALT_MODULE_CLASS_onchip_boot_rom altera_avalon_onchip_memory2
#define ONCHIP_BOOT_ROM_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
#define ONCHIP_BOOT_ROM_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
#define ONCHIP_BOOT_ROM_BASE 0x10010000
#define ONCHIP_BOOT_ROM_CONTENTS_INFO ""
#define ONCHIP_BOOT_ROM_DUAL_PORT 0
#define ONCHIP_BOOT_ROM_GUI_RAM_BLOCK_TYPE "AUTO"
#define ONCHIP_BOOT_ROM_INIT_CONTENTS_FILE "bootloader_niosvc10lp"
#define ONCHIP_BOOT_ROM_INIT_MEM_CONTENT 1
#define ONCHIP_BOOT_ROM_INSTANCE_ID "NONE"
#define ONCHIP_BOOT_ROM_IRQ -1
#define ONCHIP_BOOT_ROM_IRQ_INTERRUPT_CONTROLLER_ID -1
#define ONCHIP_BOOT_ROM_NAME "/dev/onchip_boot_rom"
#define ONCHIP_BOOT_ROM_NON_DEFAULT_INIT_FILE_ENABLED 1
#define ONCHIP_BOOT_ROM_RAM_BLOCK_TYPE "AUTO"
#define ONCHIP_BOOT_ROM_READ_DURING_WRITE_MODE "DONT_CARE"
#define ONCHIP_BOOT_ROM_SINGLE_CLOCK_OP 0
#define ONCHIP_BOOT_ROM_SIZE_MULTIPLE 1
#define ONCHIP_BOOT_ROM_SIZE_VALUE 4096
#define ONCHIP_BOOT_ROM_SPAN 4096
#define ONCHIP_BOOT_ROM_TYPE "altera_avalon_onchip_memory2"
#define ONCHIP_BOOT_ROM_WRITABLE 0
/*
* onchip_ram configuration
*
*/
#define ALT_MODULE_CLASS_onchip_ram altera_avalon_onchip_memory2
#define ONCHIP_RAM_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0
#define ONCHIP_RAM_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0
#define ONCHIP_RAM_BASE 0x10020000
#define ONCHIP_RAM_CONTENTS_INFO ""
#define ONCHIP_RAM_DUAL_PORT 0
#define ONCHIP_RAM_GUI_RAM_BLOCK_TYPE "AUTO"
#define ONCHIP_RAM_INIT_CONTENTS_FILE "c10lp_rtems_onchip_ram"
#define ONCHIP_RAM_INIT_MEM_CONTENT 0
#define ONCHIP_RAM_INSTANCE_ID "NONE"
#define ONCHIP_RAM_IRQ -1
#define ONCHIP_RAM_IRQ_INTERRUPT_CONTROLLER_ID -1
#define ONCHIP_RAM_NAME "/dev/onchip_ram"
#define ONCHIP_RAM_NON_DEFAULT_INIT_FILE_ENABLED 0
#define ONCHIP_RAM_RAM_BLOCK_TYPE "AUTO"
#define ONCHIP_RAM_READ_DURING_WRITE_MODE "DONT_CARE"
#define ONCHIP_RAM_SINGLE_CLOCK_OP 0
#define ONCHIP_RAM_SIZE_MULTIPLE 1
#define ONCHIP_RAM_SIZE_VALUE 8192
#define ONCHIP_RAM_SPAN 8192
#define ONCHIP_RAM_TYPE "altera_avalon_onchip_memory2"
#define ONCHIP_RAM_WRITABLE 1
/*
* sys_id configuration
*
*/
#define ALT_MODULE_CLASS_sys_id altera_avalon_sysid_qsys
#define SYS_ID_BASE 0x10000200
#define SYS_ID_ID 405222982
#define SYS_ID_IRQ -1
#define SYS_ID_IRQ_INTERRUPT_CONTROLLER_ID -1
#define SYS_ID_NAME "/dev/sys_id"
#define SYS_ID_SPAN 8
#define SYS_ID_TIMESTAMP 1722632857
#define SYS_ID_TYPE "altera_avalon_sysid_qsys"
/*
* user_dipsw configuration
*
*/
#define ALT_MODULE_CLASS_user_dipsw altera_avalon_pio
#define USER_DIPSW_BASE 0x100001f0
#define USER_DIPSW_BIT_CLEARING_EDGE_REGISTER 0
#define USER_DIPSW_BIT_MODIFYING_OUTPUT_REGISTER 0
#define USER_DIPSW_CAPTURE 0
#define USER_DIPSW_DATA_WIDTH 4
#define USER_DIPSW_DO_TEST_BENCH_WIRING 0
#define USER_DIPSW_DRIVEN_SIM_VALUE 0
#define USER_DIPSW_EDGE_TYPE "NONE"
#define USER_DIPSW_FREQ 100000000
#define USER_DIPSW_HAS_IN 1
#define USER_DIPSW_HAS_OUT 0
#define USER_DIPSW_HAS_TRI 0
#define USER_DIPSW_IRQ -1
#define USER_DIPSW_IRQ_INTERRUPT_CONTROLLER_ID -1
#define USER_DIPSW_IRQ_TYPE "NONE"
#define USER_DIPSW_NAME "/dev/user_dipsw"
#define USER_DIPSW_RESET_VALUE 0
#define USER_DIPSW_SPAN 16
#define USER_DIPSW_TYPE "altera_avalon_pio"
/*
* user_pb configuration
*
*/
#define ALT_MODULE_CLASS_user_pb altera_avalon_pio
#define USER_PB_BASE 0x100001e0
#define USER_PB_BIT_CLEARING_EDGE_REGISTER 0
#define USER_PB_BIT_MODIFYING_OUTPUT_REGISTER 0
#define USER_PB_CAPTURE 0
#define USER_PB_DATA_WIDTH 4
#define USER_PB_DO_TEST_BENCH_WIRING 0
#define USER_PB_DRIVEN_SIM_VALUE 0
#define USER_PB_EDGE_TYPE "NONE"
#define USER_PB_FREQ 100000000
#define USER_PB_HAS_IN 1
#define USER_PB_HAS_OUT 0
#define USER_PB_HAS_TRI 0
#define USER_PB_IRQ -1
#define USER_PB_IRQ_INTERRUPT_CONTROLLER_ID -1
#define USER_PB_IRQ_TYPE "NONE"
#define USER_PB_NAME "/dev/user_pb"
#define USER_PB_RESET_VALUE 0
#define USER_PB_SPAN 16
#define USER_PB_TYPE "altera_avalon_pio"
/*
* watchdog_timer configuration
*
*/
#define ALT_MODULE_CLASS_watchdog_timer altera_avalon_timer
#define WATCHDOG_TIMER_ALWAYS_RUN 1
#define WATCHDOG_TIMER_BASE 0x100001c0
#define WATCHDOG_TIMER_COUNTER_SIZE 32
#define WATCHDOG_TIMER_FIXED_PERIOD 1
#define WATCHDOG_TIMER_FREQ 100000000
#define WATCHDOG_TIMER_IRQ 5
#define WATCHDOG_TIMER_IRQ_INTERRUPT_CONTROLLER_ID 0
#define WATCHDOG_TIMER_LOAD_VALUE 99
#define WATCHDOG_TIMER_MULT 1.0E-6
#define WATCHDOG_TIMER_NAME "/dev/watchdog_timer"
#define WATCHDOG_TIMER_PERIOD 1
#define WATCHDOG_TIMER_PERIOD_UNITS "us"
#define WATCHDOG_TIMER_RESET_OUTPUT 1
#define WATCHDOG_TIMER_SNAPSHOT 0
#define WATCHDOG_TIMER_SPAN 32
#define WATCHDOG_TIMER_TICKS_PER_SEC 1000000
#define WATCHDOG_TIMER_TIMEOUT_PULSE_OUTPUT 0
#define WATCHDOG_TIMER_TIMER_DEVICE_TYPE 1
#define WATCHDOG_TIMER_TYPE "altera_avalon_timer"
#endif /* __BSP_SYSTEM_VM_H_ */

View File

@@ -0,0 +1,98 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _STATUS_LED_DRIVER_H
#define _STATUS_LED_DRIVER_H
/* Definitions */
/* IOCTL Definitions */
#define IOCTL_STATUS_LED_TURN_ON 0x00
#define IOCTL_STATUS_LED_TURN_OFF 0x01
#define STATUS_LED_1 0x01
#define STATUS_LED_2 0x02
#define STATUS_LED_3 0x04
#define STATUS_LED_4 0x08
/* Global Structure definitions */
typedef struct StatusLedControlStruct
{
uint32_t led_mask;
}status_led_control_t;
#ifdef __cplusplus
extern "C" {
#endif
#define STATUS_LED_DRIVER_TABLE_ENTRY \
{ status_led_initialize, status_led_open, status_led_close, \
status_led_read, status_led_write, status_led_control }
rtems_device_driver status_led_initialize(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver status_led_open(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver status_led_close(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver status_led_read(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver status_led_write(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver status_led_control(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,95 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _SYSTEM_DRIVER_H
#define _SYSTEM_DRIVER_H
/* Definitions */
/* IOCTL Definitions */
#define IOCTL_SYSTEM_SOFTWARE_VERSION 0x00
#define IOCTL_SYSTEM_RESET 0x01
#define VERSION_SIZE 20
/* Global Structure definitions */
typedef struct SystemControlStruct
{
char version[VERSION_SIZE];
}system_control_t;
#ifdef __cplusplus
extern "C" {
#endif
#define SYSTEM_DRIVER_TABLE_ENTRY \
{ system_initialize, system_open, system_close, \
system_read, system_write, system_control }
rtems_device_driver system_initialize(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver system_open(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver system_close(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver system_read(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver system_write(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver system_control(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,225 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <bsp.h>
#include <stdio.h>
#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/error.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <bsp/fatal.h>
#include <bsp/irq.h>
#include <bsp/niosv.h>
#include <rtems/score/riscv-utility.h>
/* Local Definitaions */
/* Local Structures */
/* Local Functions */
static void status_led_turn_on( uint32_t index );
static void status_led_turn_off( uint32_t index );
/* Local Variables */
/* status_led_initialize --
* This routine registers the status led device
*
* PARAMETERS:
* major - major led device number
* minor - minor led device number (not used)
* arg - device initialize argument
*
* RETURNS:
* RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly)
*/
rtems_device_driver status_led_initialize (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
/* Local Variables */
rtems_status_code status;
/*
* Register the devices
*/
status = rtems_io_register_name ("/dev/status_led", major, minor );
assert( status == RTEMS_SUCCESSFUL );
return RTEMS_SUCCESSFUL;
}
/* status_led_open --
* Open status led device.
*
* PARAMETERS:
* major - major device number for led devices
* minor - minor device number for led
* arg - device opening argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver status_led_open (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/* status_led_close --
* Close status led device.
*
* PARAMETERS:
* major - major device number for led devices
* minor - minor device number for led
* arg - device close argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver status_led_close (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/* status_led_read --
* Read from the status led device
*
* PARAMETERS:
* major - major device number for led devices
* minor - minor device number for led
* arg - device read argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver status_led_read (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/* status_led_write --
* Write to the status led device
*
* PARAMETERS:
* major - major device number for led devices
* minor - minor device number for led
* arg - device write argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver status_led_write (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/* status_led_control --
* Handle status led device I/O control (IOCTL)
*
* PARAMETERS:
* major - major device number for led devices
* minor - minor device number for led
* arg - device ioctl argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver status_led_control (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
/* Local Varaibles */
rtems_libio_ioctl_args_t *args = arg;
status_led_control_t *ctrl;
/* Get Data */
ctrl = ( status_led_control_t * )args->buffer;
args->ioctl_return = 0;
/* Parse Command */
switch( args->command )
{
case IOCTL_STATUS_LED_TURN_ON :
status_led_turn_on(ctrl->led_mask);
break;
case IOCTL_STATUS_LED_TURN_OFF :
status_led_turn_off(ctrl->led_mask);
break;
default :
args->ioctl_return = -1;
break;
}
/* OK */
return RTEMS_SUCCESSFUL;
}
/* status_led_turn_on --
* Turns the LED on
*
* PARAMETERS:
*
* RETURNS:
*
*/
void status_led_turn_on( uint32_t mask )
{
LED_PIO_REGS->outclear = mask;
}
/* status_led_turn_off --
* Turns the LED on
*
* PARAMETERS:
*
* RETURNS:
*
*/
void status_led_turn_off( uint32_t mask )
{
LED_PIO_REGS->outset = mask;
}

View File

@@ -0,0 +1,218 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <bsp.h>
#include <bsp/bootcard.h>
#include <stdio.h>
#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/error.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <bsp/fatal.h>
#include <bsp/irq.h>
#include <bsp/niosv.h>
#include <rtems/score/riscv-utility.h>
/* Local Definitaions */
#define FILE_HEADER_EPCQ_OFFSET 0x100000
#define FILE_HEADER_VER_SIZE_VERSION 11
/* Local Structures */
typedef struct
{
uint32_t offset;
uint32_t size;
uint32_t crc;
char version[FILE_HEADER_VER_SIZE_VERSION];
}file_header_t;
/* Local Functions */
/* Local Variables */
static char software_version[VERSION_SIZE];
/* system_initialize --
* This routine registers the system device
*
* PARAMETERS:
* major - major led device number
* minor - miled led device number (not used)
* arg - device initialize argument
*
* RETURNS:
* RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly)
*/
rtems_device_driver system_initialize (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
/* Local Variables */
rtems_status_code status;
file_header_t fhead;
/*
* Register the devices
*/
status = rtems_io_register_name ("/dev/system", major, minor );
assert( status == RTEMS_SUCCESSFUL );
/* read the file header information */
epcq_read_buffer(
FILE_HEADER_EPCQ_OFFSET,
( uint8_t * )&fhead,
sizeof( fhead )
);
memset( &software_version[0], 0, sizeof( software_version ));
strncpy( software_version, fhead.version, FILE_HEADER_VER_SIZE_VERSION );
return RTEMS_SUCCESSFUL;
}
/* system_open --
* Open system device.
*
* PARAMETERS:
* major - major device number for led devices
* minor - miled device number for led
* arg - device opening argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver system_open (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/* system_close --
* Close system device.
*
* PARAMETERS:
* major - major device number for led devices
* minor - miled device number for led
* arg - device close argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver system_close (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/* system_read --
* Read from the system device
*
* PARAMETERS:
* major - major device number for led devices
* minor - miled device number for led
* arg - device read argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver system_read (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/* system_write --
* Write to the system device
*
* PARAMETERS:
* major - major device number for led devices
* minor - miled device number for led
* arg - device write argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver system_write (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/* system_control --
* Handle system I/O control (IOCTL)
*
* PARAMETERS:
* major - major device number for system devices
* minor - miled device number for system
* arg - device ioctl argument
*
* RETURNS:
* RTEMS error code
*/
rtems_device_driver system_control (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
/* Local Varaibles */
rtems_libio_ioctl_args_t *args = arg;
system_control_t *ctrl;
/* Get Data */
ctrl = ( system_control_t * )args->buffer;
args->ioctl_return = 0;
/* Parse Command */
switch( args->command ) {
case IOCTL_SYSTEM_SOFTWARE_VERSION :
strcpy( ctrl->version, software_version );
break;
case IOCTL_SYSTEM_RESET :
bsp_reset( ( rtems_fatal_source )0, ( rtems_fatal_code )0 );
break;
default :
args->ioctl_return = -1;
break;
}
/* OK */
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,43 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2024 Kevin Kirspel
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bsp/bootcard.h>
#include <bsp/niosv.h>
void bsp_reset(rtems_fatal_source source, rtems_fatal_code code)
{
(void) source;
(void) code;
/*
* The following line interferes with successfully executing RTEMS tests.
* Uncomment in real systems.
*/
/* WATCHDOG_REGS->control = ALTERA_AVALON_TIMER_CONTROL_START_MSK; */
for(;;);
}