summaryrefslogtreecommitdiffstats
path: root/bsps/shared
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/shared')
-rw-r--r--bsps/shared/cache/cacheimpl.h46
-rw-r--r--bsps/shared/dev/btimer/btimer-cpucounter.c2
-rw-r--r--bsps/shared/dev/clock/arm-generic-timer.c21
-rw-r--r--bsps/shared/dev/clock/bcm2835-system-timer.c94
-rw-r--r--bsps/shared/dev/clock/clockimpl.h77
-rw-r--r--bsps/shared/dev/clock/xil-ttc.c214
-rw-r--r--bsps/shared/dev/cpucounter/cpucounterfrequency.c2
-rw-r--r--bsps/shared/dev/cpucounter/cpucounterread.c2
-rw-r--r--bsps/shared/dev/display/disp_fonts.h2
-rw-r--r--bsps/shared/dev/display/disp_hcms29xx.c2
-rw-r--r--bsps/shared/dev/display/font_hcms29xx.c2
-rw-r--r--bsps/shared/dev/display/font_hcms29xx.h2
-rw-r--r--bsps/shared/dev/dma/fsl-edma.c4
-rw-r--r--bsps/shared/dev/getentropy/getentropy-cpucounter.c2
-rw-r--r--bsps/shared/dev/i2c/cadence-i2c.c3
-rw-r--r--bsps/shared/dev/i2c/i2c-sc620.c2
-rw-r--r--bsps/shared/dev/i2c/spi-flash-m25p40.c2
-rw-r--r--bsps/shared/dev/i2c/spi-fram-fm25l256.c2
-rw-r--r--bsps/shared/dev/i2c/spi-memdrv.c2
-rw-r--r--bsps/shared/dev/i2c/spi-sd-card.c2
-rw-r--r--bsps/shared/dev/ide/ata_util.c2
-rw-r--r--bsps/shared/dev/irq/arm-gicv2-get-attributes.c7
-rw-r--r--bsps/shared/dev/irq/arm-gicv2-zynqmp.c6
-rw-r--r--bsps/shared/dev/irq/arm-gicv2.c42
-rw-r--r--bsps/shared/dev/irq/arm-gicv3.c35
-rw-r--r--bsps/shared/dev/nand/VERSION24
-rw-r--r--bsps/shared/dev/nand/xnandpsu.c3027
-rw-r--r--bsps/shared/dev/nand/xnandpsu_bbm.c1001
-rw-r--r--bsps/shared/dev/nand/xnandpsu_onfi.c91
-rw-r--r--bsps/shared/dev/rtc/mcp7940m.c361
-rw-r--r--bsps/shared/dev/serial/arm-pl011.c2
-rw-r--r--bsps/shared/dev/serial/console-output-char.c2
-rw-r--r--bsps/shared/dev/serial/console-polled.c2
-rw-r--r--bsps/shared/dev/serial/console-termios-init.c2
-rw-r--r--bsps/shared/dev/serial/console-termios.c2
-rw-r--r--bsps/shared/dev/serial/getserialmouseps2.c2
-rw-r--r--bsps/shared/dev/serial/legacy-console.c6
-rw-r--r--bsps/shared/dev/serial/uart-output-char.c2
-rw-r--r--bsps/shared/dev/serial/zynq-uart-kernel-io.c88
-rw-r--r--bsps/shared/dev/serial/zynq-uart-polled.c43
-rw-r--r--bsps/shared/dev/serial/zynq-uart.c21
-rw-r--r--bsps/shared/dev/spi/VERSION29
-rw-r--r--bsps/shared/dev/spi/xqspipsu-flash-helper.c2341
-rw-r--r--bsps/shared/dev/spi/xqspipsu.c1086
-rw-r--r--bsps/shared/dev/spi/xqspipsu_control.c282
-rw-r--r--bsps/shared/dev/spi/xqspipsu_hw.c768
-rw-r--r--bsps/shared/dev/spi/xqspipsu_options.c532
-rw-r--r--bsps/shared/doxygen.h8
-rw-r--r--bsps/shared/freebsd/stand/efi/include/README36
-rw-r--r--bsps/shared/freebsd/stand/efi/include/amd64/efibind.h275
-rw-r--r--bsps/shared/freebsd/stand/efi/include/efi.h87
-rw-r--r--bsps/shared/freebsd/stand/efi/include/efiapi.h1204
-rw-r--r--bsps/shared/freebsd/stand/efi/include/eficon.h527
-rw-r--r--bsps/shared/freebsd/stand/efi/include/eficonsctl.h134
-rw-r--r--bsps/shared/freebsd/stand/efi/include/efidef.h224
-rw-r--r--bsps/shared/freebsd/stand/efi/include/efidevp.h511
-rw-r--r--bsps/shared/freebsd/stand/efi/include/efierr.h68
-rw-r--r--bsps/shared/freebsd/stand/efi/include/efigop.h121
-rw-r--r--bsps/shared/freebsd/stand/efi/include/efilib.h172
-rw-r--r--bsps/shared/freebsd/stand/efi/libefi/libefi.c63
-rw-r--r--bsps/shared/freebsd/stand/efi/libefi/wchar.c73
-rw-r--r--bsps/shared/grlib/1553/b1553brm.c27
-rw-r--r--bsps/shared/grlib/1553/b1553rt.c27
-rw-r--r--bsps/shared/grlib/1553/gr1553b.c25
-rw-r--r--bsps/shared/grlib/1553/gr1553bc.c25
-rw-r--r--bsps/shared/grlib/1553/gr1553bm.c25
-rw-r--r--bsps/shared/grlib/1553/gr1553rt.c25
-rw-r--r--bsps/shared/grlib/amba/ahbstat.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_alloc.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_count.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_depth.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_find_by_idx.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_freq.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_names.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_old.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_parent.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_show.c25
-rw-r--r--bsps/shared/grlib/analog/gradcdac.c27
-rw-r--r--bsps/shared/grlib/ascs/grascs.c25
-rw-r--r--bsps/shared/grlib/btimer/gptimer.c203
-rw-r--r--bsps/shared/grlib/btimer/tlib.c25
-rw-r--r--bsps/shared/grlib/btimer/tlib_ckinit.c29
-rw-r--r--bsps/shared/grlib/can/canbtrs.c2
-rw-r--r--bsps/shared/grlib/can/canmux.c25
-rw-r--r--bsps/shared/grlib/can/grcan.c25
-rw-r--r--bsps/shared/grlib/can/grcan_internal.h27
-rw-r--r--bsps/shared/grlib/can/grcanfd.c25
-rw-r--r--bsps/shared/grlib/can/grcanstd.c25
-rw-r--r--bsps/shared/grlib/can/occan.c27
-rw-r--r--bsps/shared/grlib/can/satcan.c25
-rw-r--r--bsps/shared/grlib/drvmgr/ambapp_bus.c25
-rw-r--r--bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c42
-rw-r--r--bsps/shared/grlib/drvmgr/get_resarray_count.c25
-rw-r--r--bsps/shared/grlib/gpio/gpiolib.c25
-rw-r--r--bsps/shared/grlib/gpio/grgpio.c29
-rw-r--r--bsps/shared/grlib/i2c/i2cmst.c27
-rw-r--r--bsps/shared/grlib/iommu/griommu.c25
-rw-r--r--bsps/shared/grlib/irq/genirq.c25
-rw-r--r--bsps/shared/grlib/l2c/l2c.c25
-rw-r--r--bsps/shared/grlib/mem/mctrl.c25
-rw-r--r--bsps/shared/grlib/pci/gr_701.c25
-rw-r--r--bsps/shared/grlib/pci/gr_rasta_adcdac.c25
-rw-r--r--bsps/shared/grlib/pci/gr_rasta_io.c25
-rw-r--r--bsps/shared/grlib/pci/gr_rasta_spw_router.c25
-rw-r--r--bsps/shared/grlib/pci/gr_rasta_tmtc.c25
-rw-r--r--bsps/shared/grlib/pci/gr_tmtc_1553.c25
-rw-r--r--bsps/shared/grlib/pci/grpci.c25
-rw-r--r--bsps/shared/grlib/pci/grpci2.c25
-rw-r--r--bsps/shared/grlib/pci/grpci2dma.c25
-rw-r--r--bsps/shared/grlib/pci/pcif.c25
-rw-r--r--bsps/shared/grlib/pwm/grpwm.c27
-rw-r--r--bsps/shared/grlib/scrub/memscrub.c25
-rw-r--r--bsps/shared/grlib/slink/grslink.c25
-rw-r--r--bsps/shared/grlib/spi/spictrl.c27
-rw-r--r--bsps/shared/grlib/spw/grspw.c27
-rw-r--r--bsps/shared/grlib/spw/grspw_pkt.c25
-rw-r--r--bsps/shared/grlib/spw/grspw_router.c25
-rw-r--r--bsps/shared/grlib/spw/spwtdp.c25
-rw-r--r--bsps/shared/grlib/stat/l4stat.c25
-rw-r--r--bsps/shared/grlib/time/grctm.c25
-rw-r--r--bsps/shared/grlib/time/spwcuc.c25
-rw-r--r--bsps/shared/grlib/tmtc/grtc.c27
-rw-r--r--bsps/shared/grlib/tmtc/grtm.c27
-rw-r--r--bsps/shared/grlib/uart/apbuart_cons.c164
-rw-r--r--bsps/shared/grlib/uart/apbuart_polled.c77
-rw-r--r--bsps/shared/grlib/uart/apbuart_termios.c74
-rw-r--r--bsps/shared/grlib/uart/cons.c25
-rw-r--r--bsps/shared/irq/irq-affinity.c5
-rw-r--r--bsps/shared/irq/irq-default-handler.c4
-rw-r--r--bsps/shared/irq/irq-default.c4
-rw-r--r--bsps/shared/irq/irq-enable-disable.c4
-rw-r--r--bsps/shared/irq/irq-entry-remove.c10
-rw-r--r--bsps/shared/irq/irq-generic.c54
-rw-r--r--bsps/shared/irq/irq-handler-install.c4
-rw-r--r--bsps/shared/irq/irq-handler-iterate.c8
-rw-r--r--bsps/shared/irq/irq-handler-remove.c4
-rw-r--r--bsps/shared/irq/irq-info.c4
-rw-r--r--bsps/shared/irq/irq-legacy.c4
-rw-r--r--bsps/shared/irq/irq-lock.c4
-rw-r--r--bsps/shared/irq/irq-raise-clear.c4
-rw-r--r--bsps/shared/irq/irq-record.c97
-rw-r--r--bsps/shared/irq/irq-server.c4
-rw-r--r--bsps/shared/irq/irq-shell.c4
-rw-r--r--bsps/shared/rtems-version.c9
-rw-r--r--bsps/shared/start/bsp-fdt.c10
-rw-r--r--bsps/shared/start/bsp-uboot-board-info.c2
-rw-r--r--bsps/shared/start/bspfatal-default.c11
-rw-r--r--bsps/shared/start/bspgetworkarea-default.c3
-rw-r--r--bsps/shared/start/gettargethash-default.c2
-rw-r--r--bsps/shared/start/mallocinitmulti.c2
-rw-r--r--bsps/shared/start/mallocinitone.c2
-rw-r--r--bsps/shared/start/stackalloc.c2
-rw-r--r--bsps/shared/start/wkspaceinitmulti.c2
-rw-r--r--bsps/shared/start/wkspaceinitone.c2
-rw-r--r--bsps/shared/xil/VERSION20
-rw-r--r--bsps/shared/xil/arm/ARMv8/xil_cache.c732
-rw-r--r--bsps/shared/xil/arm/cortexr5/xil_cache.c561
-rw-r--r--bsps/shared/xil/arm/cortexr5/xil_mpu.c645
-rw-r--r--bsps/shared/xil/xil_assert.c126
-rw-r--r--bsps/shared/xil/xil_mem.c70
161 files changed, 17729 insertions, 601 deletions
diff --git a/bsps/shared/cache/cacheimpl.h b/bsps/shared/cache/cacheimpl.h
index 16fe59d804..ddd125aa87 100644
--- a/bsps/shared/cache/cacheimpl.h
+++ b/bsps/shared/cache/cacheimpl.h
@@ -1,7 +1,16 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplClassicCache
+ *
+ * @brief This header file contains the implementation of the
+ * @ref RTEMSAPIClassicCache.
+ */
+
/*
* Cache Manager
*
- * Copyright (C) 2014, 2018 embedded brains GmbH
+ * Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
@@ -11,10 +20,12 @@
* http://www.rtems.org/license/LICENSE.
*/
-/*
- * The functions in this file implement the API to the RTEMS Cache Manager.
- * This file is intended to be included in a cache implemention source file
- * provided by the architecture or BSP, e.g.
+/**
+ * @file
+ *
+ * The functions in this file implement the API to the
+ * @ref RTEMSAPIClassicCache. This file is intended to be included in a cache
+ * implemention source file provided by the architecture or BSP, e.g.
*
* - bsps/${RTEMS_CPU}/shared/cache/cache.c
* - bsps/${RTEMS_CPU}/${RTEMS_BSP_FAMILY}/start/cache.c
@@ -22,25 +33,33 @@
* In this file a couple of defines and inline functions may be provided and
* afterwards this file is included, e.g.
*
+ * @code
* #define CPU_DATA_CACHE_ALIGNMENT XYZ
* ...
* #include "../../../bsps/shared/cache/cacheimpl.h"
+ * @endcode
*
* The cache implementation source file shall define
*
+ * @code
* #define CPU_DATA_CACHE_ALIGNMENT <POSITIVE INTEGER>
+ * @endcode
*
* to enable the data cache support.
*
* The cache implementation source file shall define
*
+ * @code
* #define CPU_INSTRUCTION_CACHE_ALIGNMENT <POSITIVE INTEGER>
+ * @endcode
*
* to enable the instruction cache support.
*
* The cache implementation source file shall define
*
+ * @code
* #define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
+ * @endcode
*
* if it provides cache maintenance functions which operate on multiple lines.
* Otherwise a generic loop with single line operations will be used. It is
@@ -49,28 +68,36 @@
*
* The cache implementation source file shall define
*
+ * @code
* #define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
+ * @endcode
*
* if it provides functions to get the data and instruction cache sizes by
* level.
*
* The cache implementation source file shall define
*
+ * @code
* #define CPU_CACHE_SUPPORT_PROVIDES_INSTRUCTION_SYNC_FUNCTION
+ * @endcode
*
* if special instructions must be used to synchronize the instruction caches
* after a code change.
*
* The cache implementation source file shall define
*
+ * @code
* #define CPU_CACHE_SUPPORT_PROVIDES_DISABLE_DATA
+ * @endcode
*
* if an external implementation of rtems_cache_disable_data() is provided,
* e.g. as an implementation in assembly code.
*
* The cache implementation source file shall define
*
+ * @code
* #define CPU_CACHE_NO_INSTRUCTION_CACHE_SNOOPING
+ * @endcode
*
* if the hardware provides no instruction cache snooping and the instruction
* cache invalidation needs software support.
@@ -98,6 +125,14 @@
#error "CPU_INSTRUCTION_CACHE_ALIGNMENT is greater than CPU_CACHE_LINE_BYTES"
#endif
+/**
+ * @defgroup RTEMSImplClassicCache Cache Manager
+ *
+ * @ingroup RTEMSImplClassic
+ *
+ * @brief This group contains the Cache Manager implementation.
+ */
+
/*
* THESE FUNCTIONS ONLY HAVE BODIES IF WE HAVE A DATA CACHE
*/
@@ -283,6 +318,7 @@ static void smp_cache_inst_inv(void *arg)
static void smp_cache_inst_inv_all(void *arg)
{
+ (void) arg;
_CPU_cache_invalidate_entire_instruction();
}
diff --git a/bsps/shared/dev/btimer/btimer-cpucounter.c b/bsps/shared/dev/btimer/btimer-cpucounter.c
index 3698778913..8757cb844b 100644
--- a/bsps/shared/dev/btimer/btimer-cpucounter.c
+++ b/bsps/shared/dev/btimer/btimer-cpucounter.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2017 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/clock/arm-generic-timer.c b/bsps/shared/dev/clock/arm-generic-timer.c
index 07a31fb3b7..ba159f6833 100644
--- a/bsps/shared/dev/clock/arm-generic-timer.c
+++ b/bsps/shared/dev/clock/arm-generic-timer.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2017 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -54,15 +54,12 @@ typedef struct {
static arm_gt_clock_context arm_gt_clock_instance;
-/* This is defined in dev/clock/clockimpl.h */
-void Clock_isr(rtems_irq_hdl_param arg);
-
-static void arm_gt_clock_at_tick(void)
+static void arm_gt_clock_at_tick(arm_gt_clock_context *ctx)
{
uint64_t cval;
uint32_t interval;
- interval = arm_gt_clock_instance.interval;
+ interval = ctx->interval;
cval = arm_gt_clock_get_compare_value();
cval += interval;
arm_gt_clock_set_compare_value(cval);
@@ -71,7 +68,7 @@ static void arm_gt_clock_at_tick(void)
#endif /* ARM_GENERIC_TIMER_UNMASK_AT_TICK */
}
-static void arm_gt_clock_handler_install(void)
+static void arm_gt_clock_handler_install(rtems_interrupt_handler handler)
{
rtems_status_code sc;
@@ -79,8 +76,8 @@ static void arm_gt_clock_handler_install(void)
arm_gt_clock_instance.irq,
"Clock",
RTEMS_INTERRUPT_UNIQUE,
- (rtems_interrupt_handler) Clock_isr,
- NULL
+ handler,
+ &arm_gt_clock_instance
);
if (sc != RTEMS_SUCCESSFUL) {
bsp_fatal(BSP_ARM_FATAL_GENERIC_TIMER_CLOCK_IRQ_INSTALL);
@@ -185,14 +182,14 @@ RTEMS_SYSINIT_ITEM(
RTEMS_SYSINIT_ORDER_FIRST
);
-#define Clock_driver_support_at_tick() \
- arm_gt_clock_at_tick()
+#define Clock_driver_support_at_tick(arg) \
+ arm_gt_clock_at_tick(arg)
#define Clock_driver_support_initialize_hardware() \
arm_gt_clock_initialize()
#define Clock_driver_support_install_isr(isr) \
- arm_gt_clock_handler_install()
+ arm_gt_clock_handler_install(isr)
/* Include shared source clock driver code */
#include "../../shared/dev/clock/clockimpl.h"
diff --git a/bsps/shared/dev/clock/bcm2835-system-timer.c b/bsps/shared/dev/clock/bcm2835-system-timer.c
new file mode 100644
index 0000000000..bb8490d03a
--- /dev/null
+++ b/bsps/shared/dev/clock/bcm2835-system-timer.c
@@ -0,0 +1,94 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSDriverClockImpl
+ *
+ * @brief This source file contains the implementation of the BCM2835 Clock
+ * Driver.
+ */
+
+/*
+ * Copyright (c) 2013 Alan Cudmore
+ * Copyright (c) 2016 Pavel Pisa
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.org/license/LICENSE
+ *
+*/
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/raspberrypi.h>
+#include <rtems/timecounter.h>
+
+static struct timecounter raspberrypi_tc;
+
+static uint32_t raspberrypi_clock_get_timecount(struct timecounter *tc)
+{
+ return BCM2835_REG(BCM2835_GPU_TIMER_CLO);
+}
+
+static void raspberrypi_clock_at_tick(void)
+{
+ uint32_t act_val;
+ uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_C3);
+ next_cmp += rtems_configuration_get_microseconds_per_tick();
+ BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
+ act_val = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
+
+ /*
+ * Clear interrupt only if there is time left to the next tick.
+ * If time of the next tick has already passed then interrupt
+ * request stays active and fires immediately after current tick
+ * processing is finished.
+ */
+ if ((int32_t)(next_cmp - act_val) > 0)
+ BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
+}
+
+static void raspberrypi_clock_handler_install_isr(
+ rtems_interrupt_handler clock_isr
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ sc = rtems_interrupt_handler_install(
+ BCM2835_IRQ_ID_GPU_TIMER_M3,
+ "Clock",
+ RTEMS_INTERRUPT_UNIQUE,
+ clock_isr,
+ NULL
+ );
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ rtems_fatal_error_occurred(0xdeadbeef);
+ }
+}
+
+static void raspberrypi_clock_initialize_hardware(void)
+{
+ uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
+ next_cmp += rtems_configuration_get_microseconds_per_tick();
+ BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
+ BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
+
+ raspberrypi_tc.tc_get_timecount = raspberrypi_clock_get_timecount;
+ raspberrypi_tc.tc_counter_mask = 0xffffffff;
+ raspberrypi_tc.tc_frequency = 1000000; /* 1 MHz */
+ raspberrypi_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&raspberrypi_tc);
+}
+
+#define Clock_driver_support_at_tick(arg) raspberrypi_clock_at_tick()
+
+#define Clock_driver_support_initialize_hardware() raspberrypi_clock_initialize_hardware()
+
+#define Clock_driver_support_install_isr(clock_isr) \
+ raspberrypi_clock_handler_install_isr(clock_isr)
+
+#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1
+
+#include "../../../shared/dev/clock/clockimpl.h"
diff --git a/bsps/shared/dev/clock/clockimpl.h b/bsps/shared/dev/clock/clockimpl.h
index ccf6d3ab60..b27f7c15bc 100644
--- a/bsps/shared/dev/clock/clockimpl.h
+++ b/bsps/shared/dev/clock/clockimpl.h
@@ -3,9 +3,12 @@
/**
* @file
*
- * @ingroup bsp_clock
+ * @ingroup RTEMSDriverClockImpl
*
- * @brief Clock Tick Device Driver Shell
+ * @brief This header file contains the shared Clock Driver implementation.
+ *
+ * This header file shall only be included by a particular Clock Driver
+ * implementation source file.
*/
/*
@@ -39,27 +42,35 @@
#include <bsp.h>
#include <rtems/clockdrv.h>
#include <rtems/score/percpu.h>
+#include <rtems/score/processormaskimpl.h>
#include <rtems/score/smpimpl.h>
#include <rtems/score/timecounter.h>
#include <rtems/score/thread.h>
#include <rtems/score/watchdogimpl.h>
-#ifdef Clock_driver_nanoseconds_since_last_tick
-#error "Update driver to use the timecounter instead of nanoseconds extension"
-#endif
-
/**
- * @defgroup bsp_clock Clock Support
- *
- * @ingroup RTEMSBSPsShared
+ * @defgroup RTEMSDriverClockImpl Clock Driver Implementation
*
- * @brief Clock support
+ * @ingroup RTEMSDriverClock
*
+ * @brief This group contains the Clock Driver implementation.
*/
+
+#ifdef Clock_driver_nanoseconds_since_last_tick
+#error "Update driver to use the timecounter instead of nanoseconds extension"
+#endif
+
#if CLOCK_DRIVER_USE_FAST_IDLE && CLOCK_DRIVER_ISRS_PER_TICK
#error "Fast Idle PLUS n ISRs per tick is not supported"
#endif
+#if defined(BSP_FEATURE_IRQ_EXTENSION) || \
+ (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
+typedef void * Clock_isr_argument;
+#else
+typedef rtems_vector_number Clock_isr_argument;
+#endif
+
/**
* @brief Do nothing by default.
*/
@@ -78,7 +89,7 @@
* @brief Do nothing by default.
*/
#ifndef Clock_driver_support_at_tick
- #define Clock_driver_support_at_tick()
+ #define Clock_driver_support_at_tick( arg ) do { (void) arg; } while (0)
#endif
/**
@@ -93,8 +104,9 @@
* instead of the default.
*/
#ifndef Clock_driver_timecounter_tick
-static void Clock_driver_timecounter_tick( void )
+static void Clock_driver_timecounter_tick( Clock_isr_argument arg )
{
+ (void) arg;
#if defined(CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER)
rtems_clock_tick();
#elif defined(RTEMS_SMP) && defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
@@ -136,25 +148,31 @@ volatile uint32_t Clock_driver_ticks;
#error "Clock_driver_support_shutdown_hardware() is no longer supported"
#endif
+#if CLOCK_DRIVER_USE_FAST_IDLE
+static bool _Clock_Has_watchdogs(const Per_CPU_Control *cpu)
+{
+ size_t i;
+
+ for (i = 0; i < RTEMS_ARRAY_SIZE(cpu->Watchdog.Header); ++i) {
+ if (_Watchdog_Header_first(&cpu->Watchdog.Header[i]) != NULL) {
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif
+
/**
* @brief Clock_isr
*
* This is the clock tick interrupt handler.
*
- * @param vector Vector number.
+ * @param arg is the clock interrupt handler argument.
*/
-#if defined(BSP_FEATURE_IRQ_EXTENSION) || \
- (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
-void Clock_isr(void *arg);
-void Clock_isr(void *arg)
+void Clock_isr( Clock_isr_argument arg );
+void Clock_isr( Clock_isr_argument arg )
{
-#else
-rtems_isr Clock_isr(rtems_vector_number vector);
-rtems_isr Clock_isr(
- rtems_vector_number vector
-)
-{
-#endif
/*
* Accurate count of ISRs
*/
@@ -162,7 +180,7 @@ rtems_isr Clock_isr(
#if CLOCK_DRIVER_USE_FAST_IDLE
{
- Clock_driver_timecounter_tick();
+ Clock_driver_timecounter_tick( arg );
if (_SMP_Get_processor_maximum() == 1) {
struct timecounter *tc;
@@ -179,6 +197,7 @@ rtems_isr Clock_isr(
cpu_self->thread_dispatch_disable_level == cpu_self->isr_nest_level
&& cpu_self->heir == cpu_self->executing
&& cpu_self->executing->is_idle
+ && _Clock_Has_watchdogs(cpu_self)
) {
ISR_lock_Context lock_context;
@@ -191,7 +210,7 @@ rtems_isr Clock_isr(
}
}
- Clock_driver_support_at_tick();
+ Clock_driver_support_at_tick( arg );
}
#else
/*
@@ -199,14 +218,14 @@ rtems_isr Clock_isr(
*
* The counter/timer may or may not be set to automatically reload.
*/
- Clock_driver_support_at_tick();
+ Clock_driver_support_at_tick( arg );
#if CLOCK_DRIVER_ISRS_PER_TICK
/*
* The driver is multiple ISRs per clock tick.
*/
if ( !Clock_driver_isrs ) {
- Clock_driver_timecounter_tick();
+ Clock_driver_timecounter_tick( arg );
Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
}
@@ -215,7 +234,7 @@ rtems_isr Clock_isr(
/*
* The driver is one ISR per clock tick.
*/
- Clock_driver_timecounter_tick();
+ Clock_driver_timecounter_tick( arg );
#endif
#endif
}
diff --git a/bsps/shared/dev/clock/xil-ttc.c b/bsps/shared/dev/clock/xil-ttc.c
new file mode 100644
index 0000000000..624845d71c
--- /dev/null
+++ b/bsps/shared/dev/clock/xil-ttc.c
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSDriverClockXilTTC
+ *
+ * @brief This source file contains a Clock Driver implementation using the
+ * Xilinx Triple Timer Counter (TTC).
+ */
+
+/*
+ * Copyright (C) 2024 embedded brains GmbH & Co. KG
+ * Copyright (C) 2023 Reflex Aerospace GmbH
+ *
+ * Written by Philip Kirkpatrick <p.kirkpatrick@reflexaerospace.com>
+ *
+ * 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/irq.h>
+#include <bsp/fatal.h>
+#include <dev/clock/xttcps_hw.h>
+#include <rtems/sysinit.h>
+#include <rtems/timecounter.h>
+
+#if XTTCPS_COUNT_VALUE_MASK != UINT32_MAX
+#error "unexpected XTTCPS_COUNT_VALUE_MASK value"
+#endif
+
+/**
+ * @defgroup RTEMSDriverClockXilTTC \
+ * Xilinx Triple Timer Counter (TTC) Clock Driver
+ *
+ * @ingroup RTEMSDriverClockImpl
+ *
+ * @brief This group contains the Xilinx Triple Timer Counter (TTC) Clock
+ * Driver implementation.
+ *
+ * @{
+ */
+
+uint32_t _CPU_Counter_frequency( void )
+{
+ return XIL_CLOCK_TTC_REFERENCE_CLOCK;
+}
+
+CPU_Counter_ticks _CPU_Counter_read(void)
+{
+ return XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET);
+}
+
+static void xil_ttc_initialize(void)
+{
+ /* Do not use a prescaler to get a high resolution time source */
+ XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_CLK_CNTRL_OFFSET, 0);
+
+ /* Disable interupts */
+ XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_IER_OFFSET, 0);
+
+ /*
+ * Enable the timer, do not enable waveform output, increment up, use
+ * overflow mode, enable match mode.
+ */
+ XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_CNT_CNTRL_OFFSET,
+ XTTCPS_CNT_CNTRL_EN_WAVE_MASK | XTTCPS_CNT_CNTRL_MATCH_MASK);
+}
+
+RTEMS_SYSINIT_ITEM(
+ xil_ttc_initialize,
+ RTEMS_SYSINIT_CPU_COUNTER,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
+
+typedef struct {
+ struct timecounter base;
+ uint32_t irq_match_interval;
+} xil_ttc_timecounter;
+
+static xil_ttc_timecounter xil_ttc_clock_instance;
+
+static uint32_t xil_ttc_get_timecount(struct timecounter *tc)
+{
+ (void) tc;
+ return XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET);
+}
+
+static void xil_ttc_clock_driver_support_initialize_hardware(void)
+{
+ xil_ttc_timecounter *tc;
+ uint64_t frequency;
+ uint32_t irq_match_interval;
+ uint32_t count;
+
+ tc = &xil_ttc_clock_instance;
+ frequency = XIL_CLOCK_TTC_REFERENCE_CLOCK;
+ irq_match_interval = (uint32_t)
+ ((frequency * rtems_configuration_get_microseconds_per_tick()) / 1000000);
+
+ /* Setup match register to generate clock interrupts */
+ count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET);
+ XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET,
+ count + irq_match_interval);
+
+ /* Clear interupts (clear on read) */
+ (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET);
+
+ /* Enable interupt for match register */
+ XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_IER_OFFSET,
+ XTTCPS_IXR_MATCH_0_MASK);
+
+ /* Install timecounter */
+ tc->irq_match_interval = irq_match_interval;
+ tc->base.tc_counter_mask = UINT32_MAX;
+ tc->base.tc_frequency = XIL_CLOCK_TTC_REFERENCE_CLOCK;
+ tc->base.tc_get_timecount = xil_ttc_get_timecount;
+ tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&tc->base);
+}
+
+static void xil_ttc_clock_driver_support_at_tick(xil_ttc_timecounter *tc)
+{
+ uint32_t irq_match_interval;
+ uint32_t count;
+ uint32_t match;
+
+ irq_match_interval = tc->irq_match_interval;
+
+ /* Update match register */
+ match = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET);
+ match += irq_match_interval;
+ XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, match);
+
+ /* Clear interupts (clear on read) */
+ (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET);
+
+ /* Check that the new match value is in the future */
+ count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET);
+
+ while (RTEMS_PREDICT_FALSE(match - count > irq_match_interval)) {
+ /*
+ * Tick misses may happen if interrupts are disabled for an extremly long
+ * period or while debugging.
+ */
+ rtems_timecounter_tick();
+
+ /* Update match register */
+ match += irq_match_interval;
+ XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, match);
+
+ /* Clear interupts (clear on read) */
+ (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET);
+
+ /* Maybe the new match value is now in the future */
+ count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET);
+ }
+}
+
+static rtems_interrupt_entry xil_ttc_interrupt_entry;
+
+static void xil_ttc_clock_driver_support_install_isr(
+ rtems_interrupt_handler handler
+)
+{
+ rtems_status_code sc;
+
+ rtems_interrupt_entry_initialize(
+ &xil_ttc_interrupt_entry,
+ handler,
+ &xil_ttc_clock_instance,
+ "Clock"
+ );
+ sc = rtems_interrupt_entry_install(
+ XIL_CLOCK_TTC_IRQ,
+ RTEMS_INTERRUPT_UNIQUE,
+ &xil_ttc_interrupt_entry
+ );
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ bsp_fatal(XIL_FATAL_TTC_IRQ_INSTALL);
+ }
+}
+
+#define Clock_driver_support_at_tick(arg) \
+ xil_ttc_clock_driver_support_at_tick(arg)
+
+#define Clock_driver_support_initialize_hardware \
+ xil_ttc_clock_driver_support_initialize_hardware
+
+#define Clock_driver_support_install_isr(isr) \
+ xil_ttc_clock_driver_support_install_isr(isr)
+
+/** @} */
+
+#include "../../../shared/dev/clock/clockimpl.h"
diff --git a/bsps/shared/dev/cpucounter/cpucounterfrequency.c b/bsps/shared/dev/cpucounter/cpucounterfrequency.c
index fcc4cdbc33..96a4078889 100644
--- a/bsps/shared/dev/cpucounter/cpucounterfrequency.c
+++ b/bsps/shared/dev/cpucounter/cpucounterfrequency.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2018 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/cpucounter/cpucounterread.c b/bsps/shared/dev/cpucounter/cpucounterread.c
index f27784f9a7..f4e6e77fc1 100644
--- a/bsps/shared/dev/cpucounter/cpucounterread.c
+++ b/bsps/shared/dev/cpucounter/cpucounterread.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/display/disp_fonts.h b/bsps/shared/dev/display/disp_fonts.h
index 6705f8d164..e6023721ee 100644
--- a/bsps/shared/dev/display/disp_fonts.h
+++ b/bsps/shared/dev/display/disp_fonts.h
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2008 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2008 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/display/disp_hcms29xx.c b/bsps/shared/dev/display/disp_hcms29xx.c
index e22dc10f21..4e221a1a94 100644
--- a/bsps/shared/dev/display/disp_hcms29xx.c
+++ b/bsps/shared/dev/display/disp_hcms29xx.c
@@ -8,7 +8,7 @@
*/
/*
- * Copyright (c) 2008 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2008 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/display/font_hcms29xx.c b/bsps/shared/dev/display/font_hcms29xx.c
index a60e665b4b..43596923a8 100644
--- a/bsps/shared/dev/display/font_hcms29xx.c
+++ b/bsps/shared/dev/display/font_hcms29xx.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2008 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2008 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/display/font_hcms29xx.h b/bsps/shared/dev/display/font_hcms29xx.h
index ca5e0fd055..d390b9c90b 100644
--- a/bsps/shared/dev/display/font_hcms29xx.h
+++ b/bsps/shared/dev/display/font_hcms29xx.h
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2008 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2008 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/dma/fsl-edma.c b/bsps/shared/dev/dma/fsl-edma.c
index b3e1bb2fc5..c8b812c1a5 100644
--- a/bsps/shared/dev/dma/fsl-edma.c
+++ b/bsps/shared/dev/dma/fsl-edma.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (C) 2008-2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2008, 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,7 +40,7 @@
#include <bsp/fatal.h>
#include <bsp/irq.h>
#ifdef LIBBSP_ARM_IMXRT_BSP_H
-#include <MIMXRT1052.h>
+#include <fsl_device_registers.h>
#endif
#define EDMA_CHANNELS_PER_GROUP 32U
diff --git a/bsps/shared/dev/getentropy/getentropy-cpucounter.c b/bsps/shared/dev/getentropy/getentropy-cpucounter.c
index d5b2edeb13..44a2573f50 100644
--- a/bsps/shared/dev/getentropy/getentropy-cpucounter.c
+++ b/bsps/shared/dev/getentropy/getentropy-cpucounter.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2017 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/i2c/cadence-i2c.c b/bsps/shared/dev/i2c/cadence-i2c.c
index 91774fb926..67dec0da46 100644
--- a/bsps/shared/dev/i2c/cadence-i2c.c
+++ b/bsps/shared/dev/i2c/cadence-i2c.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2014 embedded brains GmbH
+ * Copyright (C) 2014 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,7 +28,6 @@
#include <dev/i2c/cadence-i2c.h>
#include <dev/i2c/cadence-i2c-regs.h>
-#include <rtems/irq-extension.h>
#include <rtems/score/assert.h>
#include <dev/i2c/i2c.h>
diff --git a/bsps/shared/dev/i2c/i2c-sc620.c b/bsps/shared/dev/i2c/i2c-sc620.c
index 8840a77f24..ed360086d8 100644
--- a/bsps/shared/dev/i2c/i2c-sc620.c
+++ b/bsps/shared/dev/i2c/i2c-sc620.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2013 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/i2c/spi-flash-m25p40.c b/bsps/shared/dev/i2c/spi-flash-m25p40.c
index 66d893cb09..9f6189cd3c 100644
--- a/bsps/shared/dev/i2c/spi-flash-m25p40.c
+++ b/bsps/shared/dev/i2c/spi-flash-m25p40.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2007 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2007 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/i2c/spi-fram-fm25l256.c b/bsps/shared/dev/i2c/spi-fram-fm25l256.c
index f85ac0d4bf..e1ff15e5b3 100644
--- a/bsps/shared/dev/i2c/spi-fram-fm25l256.c
+++ b/bsps/shared/dev/i2c/spi-fram-fm25l256.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2008 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2008 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/i2c/spi-memdrv.c b/bsps/shared/dev/i2c/spi-memdrv.c
index 55460d30a4..d890b9e41a 100644
--- a/bsps/shared/dev/i2c/spi-memdrv.c
+++ b/bsps/shared/dev/i2c/spi-memdrv.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2008 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2008 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/i2c/spi-sd-card.c b/bsps/shared/dev/i2c/spi-sd-card.c
index 0375e72be5..36a2721bb9 100644
--- a/bsps/shared/dev/i2c/spi-sd-card.c
+++ b/bsps/shared/dev/i2c/spi-sd-card.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2008, 2018 embedded brains GmbH
+ * Copyright (C) 2008, 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/ide/ata_util.c b/bsps/shared/dev/ide/ata_util.c
index 68e0f0bbe5..5fd286cdc5 100644
--- a/bsps/shared/dev/ide/ata_util.c
+++ b/bsps/shared/dev/ide/ata_util.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 embedded brains GmbH.
+ * Copyright (c) 2010 embedded brains GmbH & Co. KG
*
* Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
* Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
diff --git a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c
index 8a1351bbe5..613174bb3a 100644
--- a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c
+++ b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c
@@ -3,13 +3,14 @@
/**
* @file
*
- * @ingroup RTEMSBSPsShared
+ * @ingroup DevIRQGIC
*
- * @brief This source file contains the interrupt get attribute implementation.
+ * @brief This source file contains the implementation of
+ * bsp_interrupt_get_attributes() for the GICv2.
*/
/*
- * Copyright (c) 2013, 2021 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2013, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c
index ee4479155a..bb9bfafb48 100644
--- a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c
+++ b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c
@@ -3,9 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSBSPsShared
+ * @ingroup DevIRQGIC
*
- * @brief This source file contains the interrupt get attribute implementation.
+ * @brief This source file contains the implementation of
+ * bsp_interrupt_get_attributes() for the GICv2 of Xilinx Zynq UltraScale+
+ * MPSoC and RFSoC devices.
*/
/*
diff --git a/bsps/shared/dev/irq/arm-gicv2.c b/bsps/shared/dev/irq/arm-gicv2.c
index 42fed8a762..263278148b 100644
--- a/bsps/shared/dev/irq/arm-gicv2.c
+++ b/bsps/shared/dev/irq/arm-gicv2.c
@@ -1,7 +1,16 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup DevIRQGIC
+ *
+ * @brief This source file contains the implementation of the generic GICv2
+ * support.
+ */
+
/*
- * Copyright (c) 2013, 2021 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2013, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,9 +37,17 @@
#include <dev/irq/arm-gic.h>
#include <dev/irq/arm-gic-arch.h>
-#include <bsp/irq.h>
#include <bsp/irq-generic.h>
#include <bsp/start.h>
+#include <rtems/score/processormaskimpl.h>
+
+/*
+ * The GIC architecture reserves interrupt ID numbers 1020 to 1023 for special
+ * purposes.
+ */
+#if BSP_INTERRUPT_VECTOR_COUNT >= 1020
+#error "BSP_INTERRUPT_VECTOR_COUNT is too large"
+#endif
#define GIC_CPUIF ((volatile gic_cpuif *) BSP_ARM_GIC_CPUIF_BASE)
@@ -66,12 +83,19 @@
void bsp_interrupt_dispatch(void)
{
volatile gic_cpuif *cpuif = GIC_CPUIF;
- uint32_t icciar = cpuif->icciar;
- rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
- rtems_vector_number spurious = 1023;
- if (vector != spurious) {
- arm_interrupt_handler_dispatch(vector);
+ while (true) {
+ uint32_t icciar = cpuif->icciar;
+ rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
+ uint32_t status;
+
+ if (!bsp_interrupt_is_valid_vector(vector)) {
+ break;
+ }
+
+ status = arm_interrupt_enable_interrupts();
+ bsp_interrupt_handler_dispatch_unchecked(vector);
+ arm_interrupt_restore_interrupts(status);
cpuif->icceoir = icciar;
}
@@ -320,6 +344,7 @@ rtems_status_code arm_gic_irq_get_group(
return sc;
}
+#ifdef RTEMS_SMP
rtems_status_code bsp_interrupt_set_affinity(
rtems_vector_number vector,
const Processor_mask *affinity
@@ -379,6 +404,7 @@ rtems_status_code bsp_interrupt_get_affinity(
_Processor_mask_From_uint32_t(affinity, targets, 0);
return RTEMS_SUCCESSFUL;
}
+#endif
void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets)
{
@@ -392,9 +418,11 @@ void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets)
| GIC_DIST_ICDSGIR_SGIINTID(vector);
}
+#ifdef RTEMS_SMP
uint32_t arm_gic_irq_processor_count(void)
{
volatile gic_dist *dist = ARM_GIC_DIST;
return GIC_DIST_ICDICTR_CPU_NUMBER_GET(dist->icdictr) + 1;
}
+#endif
diff --git a/bsps/shared/dev/irq/arm-gicv3.c b/bsps/shared/dev/irq/arm-gicv3.c
index 4772ff5db4..958b1061bd 100644
--- a/bsps/shared/dev/irq/arm-gicv3.c
+++ b/bsps/shared/dev/irq/arm-gicv3.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevIRQGIC
*
+ * @brief This source file contains the implementation of the generic GICv3
+ * support.
+ */
+
+/*
* Copyright (C) 2019 On-Line Applications Research Corporation (OAR)
*
* Redistribution and use in source and binary forms, with or without
@@ -27,18 +36,24 @@
#include <dev/irq/arm-gicv3.h>
-#include <bsp/irq.h>
#include <bsp/irq-generic.h>
#include <bsp/start.h>
+#include <rtems/score/processormaskimpl.h>
void bsp_interrupt_dispatch(void)
{
- uint32_t icciar = READ_SR(ICC_IAR1);
- rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
- rtems_vector_number spurious = 1023;
+ while (true) {
+ uint32_t icciar = READ_SR(ICC_IAR1);
+ rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
+ uint32_t status;
- if (vector != spurious) {
- arm_interrupt_handler_dispatch(vector);
+ if (!bsp_interrupt_is_valid_vector(vector)) {
+ break;
+ }
+
+ status = arm_interrupt_enable_interrupts();
+ bsp_interrupt_handler_dispatch_unchecked(vector);
+ arm_interrupt_restore_interrupts(status);
WRITE_SR(ICC_EOIR1, icciar);
}
@@ -242,6 +257,7 @@ rtems_status_code arm_gic_irq_get_priority(
return sc;
}
+#ifdef RTEMS_SMP
rtems_status_code bsp_interrupt_set_affinity(
rtems_vector_number vector,
const Processor_mask *affinity
@@ -274,12 +290,14 @@ rtems_status_code bsp_interrupt_get_affinity(
_Processor_mask_From_uint32_t(affinity, targets, 0);
return RTEMS_SUCCESSFUL;
}
+#endif
void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets)
{
gicv3_trigger_sgi(vector, targets);
}
+#ifdef RTEMS_SMP
uint32_t arm_gic_irq_processor_count(void)
{
volatile gic_dist *dist = ARM_GIC_DIST;
@@ -306,3 +324,4 @@ uint32_t arm_gic_irq_processor_count(void)
return cpu_count;
}
+#endif
diff --git a/bsps/shared/dev/nand/VERSION b/bsps/shared/dev/nand/VERSION
new file mode 100644
index 0000000000..5e4eb00fe9
--- /dev/null
+++ b/bsps/shared/dev/nand/VERSION
@@ -0,0 +1,24 @@
+The information in this file describes the source of files in
+bsps/shared/dev/nand/ and bsps/include/dev/nand/.
+
+Import from:
+
+https://github.com/Xilinx/embeddedsw.git
+
+commit 5330a64c8efd14f0eef09befdbb8d3d738c33ec2
+Refs: <xilinx_v2022.2>
+Author: Nicole Baze <nicole.baze@xilinx.com>
+AuthorDate: Mon Oct 3 13:27:19 2022 -0700
+Commit: Siva Addepalli <sivaprasad.addepalli@xilinx.com>
+CommitDate: Fri Oct 7 10:26:16 2022 +0530
+
+ xilpm: versal: server: Fix bug in AIE2 zeroization
+
+ There is a bug in AIE2 zeriozation function when polling for memory
+ zeroization complete. Currently the entire memory register is being
+ checked against zero but instead we need to check the bits specific
+ to the memory tiles. This patch updates the zeroization check by
+ adding a mask so that only the desired bits are checked for zero.
+
+ Signed-off-by: Nicole Baze <nicole.baze@xilinx.com>
+ Acked-by: Jesus De Haro <jesus.de-haro@xilinx.com>
diff --git a/bsps/shared/dev/nand/xnandpsu.c b/bsps/shared/dev/nand/xnandpsu.c
new file mode 100644
index 0000000000..79025f3c04
--- /dev/null
+++ b/bsps/shared/dev/nand/xnandpsu.c
@@ -0,0 +1,3027 @@
+/******************************************************************************
+* Copyright (C) 2015 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xnandpsu.c
+* @addtogroup Overview
+* @{
+*
+* This file contains the implementation of the interface functions for
+* XNandPsu driver. Refer to the header file xnandpsu.h for more detailed
+* information.
+*
+* This module supports for NAND flash memory devices that conform to the
+* "Open NAND Flash Interface" (ONFI) 3.0 Specification. This modules
+* implements basic flash operations like read, write and erase.
+*
+* @note Driver has been renamed to nandpsu after change in
+* naming convention.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- ---------- -----------------------------------------------
+* 1.0 nm 05/06/2014 First release
+* 2.0 sb 01/12/2015 Removed Null checks for Buffer passed
+* as parameter to Read API's
+* - XNandPsu_Read()
+* - XNandPsu_ReadPage
+* Modified
+* - XNandPsu_SetFeature()
+* - XNandPsu_GetFeature()
+* and made them public.
+* Removed Failure Return for BCF Error check in
+* XNandPsu_ReadPage() and added BCH_Error counter
+* in the instance pointer structure.
+* Added XNandPsu_Prepare_Cmd API
+* Replaced
+* - XNandPsu_IntrStsEnable
+* - XNandPsu_IntrStsClear
+* - XNandPsu_IntrClear
+* - XNandPsu_SetProgramReg
+* with XNandPsu_WriteReg call
+* Modified xnandpsu.c file API's with above changes.
+* Corrected the program command for Set Feature API.
+* Modified
+* - XNandPsu_OnfiReadStatus
+* - XNandPsu_GetFeature
+* - XNandPsu_SetFeature
+* to add support for DDR mode.
+* Changed Convention for SLC/MLC
+* SLC --> HAMMING
+* MLC --> BCH
+* SlcMlc --> IsBCH
+* Removed extra DMA mode initialization from
+* the XNandPsu_CfgInitialize API.
+* Modified
+* - XNandPsu_SetEccAddrSize
+* ECC address now is calculated based upon the
+* size of spare area
+* Modified Block Erase API, removed clearing of
+* packet register before erase.
+* Clearing Data Interface Register before
+* XNandPsu_OnfiReset call.
+* Modified XNandPsu_ChangeTimingMode API supporting
+* SDR and NVDDR interface for timing modes 0 to 5.
+* Modified Bbt Signature and Version Offset value for
+* Oob and No-Oob region.
+* 1.0 kpc 17/6/2015 Added timer based timeout intsead of sw counter.
+* 1.1 mi 09/16/16 Removed compilation warnings with extra compiler flags.
+* 1.1 nsk 11/07/16 Change memcpy to Xil_MemCpy to handle word aligned
+* data access.
+* 1.2 nsk 01/19/17 Fix for the failure of reading nand first redundant
+* parameter page. CR#966603
+* 1.3 nsk 08/14/17 Added CCI support
+* 1.4 nsk 04/10/18 Added ICCARM compiler support. CR#997552.
+* 1.5 mus 11/05/18 Support 64 bit DMA addresses for Microblaze-X platform.
+* 1.5 mus 11/05/18 Updated XNandPsu_ChangeClockFreq to fix compilation
+* warnings.
+* 1.6 sd 06/02/20 Added Clock support
+* 1.6 sd 20/03/20 Added compilation flag
+* 1.8 sg 03/18/21 Added validation check for parameter page.
+* 1.9 akm 07/15/21 Initialize NandInstPtr with Data Interface & Timing mode info.
+* 1.10 akm 10/20/21 Fix gcc warnings.
+* 1.10 akm 12/21/21 Validate input parameters before use.
+* 1.10 akm 01/05/22 Remove assert checks form static and internal APIs.
+* 1.11 akm 03/31/22 Fix unused parameter warning.
+* 1.11 akm 03/31/22 Fix misleading-indentation warning.
+*
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+#include "xnandpsu.h"
+#include "xnandpsu_bbm.h"
+#include "sleep.h"
+#include "xil_mem.h"
+/************************** Constant Definitions *****************************/
+
+static const XNandPsu_EccMatrix EccMatrix[] = {
+ /* 512 byte page */
+ {XNANDPSU_PAGE_SIZE_512, 9U, 1U, XNANDPSU_HAMMING, 0x20DU, 0x3U},
+ {XNANDPSU_PAGE_SIZE_512, 9U, 4U, XNANDPSU_BCH, 0x209U, 0x7U},
+ {XNANDPSU_PAGE_SIZE_512, 9U, 8U, XNANDPSU_BCH, 0x203U, 0xDU},
+ /* 2K byte page */
+ {XNANDPSU_PAGE_SIZE_2K, 9U, 1U, XNANDPSU_HAMMING, 0x834U, 0xCU},
+ {XNANDPSU_PAGE_SIZE_2K, 9U, 4U, XNANDPSU_BCH, 0x826U, 0x1AU},
+ {XNANDPSU_PAGE_SIZE_2K, 9U, 8U, XNANDPSU_BCH, 0x80cU, 0x34U},
+ {XNANDPSU_PAGE_SIZE_2K, 9U, 12U, XNANDPSU_BCH, 0x822U, 0x4EU},
+ {XNANDPSU_PAGE_SIZE_2K, 10U, 24U, XNANDPSU_BCH, 0x81cU, 0x54U},
+ /* 4K byte page */
+ {XNANDPSU_PAGE_SIZE_4K, 9U, 1U, XNANDPSU_HAMMING, 0x1068U, 0x18U},
+ {XNANDPSU_PAGE_SIZE_4K, 9U, 4U, XNANDPSU_BCH, 0x104cU, 0x34U},
+ {XNANDPSU_PAGE_SIZE_4K, 9U, 8U, XNANDPSU_BCH, 0x1018U, 0x68U},
+ {XNANDPSU_PAGE_SIZE_4K, 9U, 12U, XNANDPSU_BCH, 0x1044U, 0x9CU},
+ {XNANDPSU_PAGE_SIZE_4K, 10U, 24U, XNANDPSU_BCH, 0x1038U, 0xA8U},
+ /* 8K byte page */
+ {XNANDPSU_PAGE_SIZE_8K, 9U, 1U, XNANDPSU_HAMMING, 0x20d0U, 0x30U},
+ {XNANDPSU_PAGE_SIZE_8K, 9U, 4U, XNANDPSU_BCH, 0x2098U, 0x68U},
+ {XNANDPSU_PAGE_SIZE_8K, 9U, 8U, XNANDPSU_BCH, 0x2030U, 0xD0U},
+ {XNANDPSU_PAGE_SIZE_8K, 9U, 12U, XNANDPSU_BCH, 0x2088U, 0x138U},
+ {XNANDPSU_PAGE_SIZE_8K, 10U, 24U, XNANDPSU_BCH, 0x2070U, 0x150U},
+ /* 16K byte page */
+ {XNANDPSU_PAGE_SIZE_16K, 9U, 1U, XNANDPSU_HAMMING, 0x4460U, 0x60U},
+ {XNANDPSU_PAGE_SIZE_16K, 9U, 4U, XNANDPSU_BCH, 0x43f0U, 0xD0U},
+ {XNANDPSU_PAGE_SIZE_16K, 9U, 8U, XNANDPSU_BCH, 0x4320U, 0x1A0U},
+ {XNANDPSU_PAGE_SIZE_16K, 9U, 12U, XNANDPSU_BCH, 0x4250U, 0x270U},
+ {XNANDPSU_PAGE_SIZE_16K, 10U, 24U, XNANDPSU_BCH, 0x4220U, 0x2A0U}
+};
+
+/**************************** Type Definitions *******************************/
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static s32 XNandPsu_FlashInit(XNandPsu *InstancePtr);
+
+static s32 XNandPsu_InitGeometry(XNandPsu *InstancePtr, OnfiParamPage *Param);
+
+static void XNandPsu_InitFeatures(XNandPsu *InstancePtr, OnfiParamPage *Param);
+
+static void XNandPsu_InitDataInterface(XNandPsu *InstancePtr, OnfiParamPage *Param);
+
+static void XNandPsu_InitTimingMode(XNandPsu *InstancePtr, OnfiParamPage *Param);
+
+static s32 XNandPsu_PollRegTimeout(XNandPsu *InstancePtr, u32 RegOffset,
+ u32 Mask, u32 Timeout);
+
+static void XNandPsu_SetPktSzCnt(XNandPsu *InstancePtr, u32 PktSize,
+ u32 PktCount);
+
+static void XNandPsu_SetPageColAddr(XNandPsu *InstancePtr, u32 Page, u16 Col);
+
+static void XNandPsu_SetPageSize(XNandPsu *InstancePtr);
+
+static void XNandPsu_SelectChip(XNandPsu *InstancePtr, u32 Target);
+
+static s32 XNandPsu_OnfiReset(XNandPsu *InstancePtr, u32 Target);
+
+static s32 XNandPsu_OnfiReadStatus(XNandPsu *InstancePtr, u32 Target,
+ u16 *OnfiStatus);
+
+static s32 XNandPsu_OnfiReadId(XNandPsu *InstancePtr, u32 Target, u8 IdAddr,
+ u32 IdLen, u8 *Buf);
+
+static s32 XNandPsu_OnfiReadParamPage(XNandPsu *InstancePtr, u32 Target,
+ u8 *Buf);
+
+static s32 XNandPsu_ProgramPage(XNandPsu *InstancePtr, u32 Target, u32 Page,
+ u32 Col, u8 *Buf);
+
+static s32 XNandPsu_ReadPage(XNandPsu *InstancePtr, u32 Target, u32 Page,
+ u32 Col, u8 *Buf);
+
+static s32 XNandPsu_CheckOnDie(XNandPsu *InstancePtr);
+
+static void XNandPsu_SetEccAddrSize(XNandPsu *InstancePtr);
+
+static s32 XNandPsu_ChangeReadColumn(XNandPsu *InstancePtr, u32 Target,
+ u32 Col, u32 PktSize, u32 PktCount,
+ u8 *Buf);
+
+static s32 XNandPsu_ChangeWriteColumn(XNandPsu *InstancePtr, u32 Target,
+ u32 Col, u32 PktSize, u32 PktCount,
+ u8 *Buf);
+
+static s32 XNandPsu_InitExtEcc(XNandPsu *InstancePtr, OnfiExtPrmPage *ExtPrm);
+
+static s32 XNandPsu_Data_ReadWrite(XNandPsu *InstancePtr, u8* Buf, u32 PktCount,
+ u32 PktSize, u32 Operation, u8 DmaMode);
+
+static s32 XNandPsu_WaitFor_Transfer_Complete(XNandPsu *InstancePtr);
+
+static s32 XNandPsu_Device_Ready(XNandPsu *InstancePtr, u32 Target);
+
+static void XNandPsu_Fifo_Read(XNandPsu *InstancePtr, u8* Buf, u32 Size);
+
+static void XNandPsu_Fifo_Write(XNandPsu *InstancePtr, u8* Buf, u32 Size);
+
+static void XNandPsu_Update_DmaAddr(XNandPsu *InstancePtr, u8* Buf);
+/*****************************************************************************/
+/**
+*
+* This function initializes a specific XNandPsu instance. This function must
+* be called prior to using the NAND flash device to read or write any data.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param ConfigPtr points to XNandPsu device configuration structure.
+* @param EffectiveAddr is the base address of NAND flash controller.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+* @note The user needs to first call the XNandPsu_LookupConfig() API
+* which returns the Configuration structure pointer which is
+* passed as a parameter to the XNandPsu_CfgInitialize() API.
+*
+******************************************************************************/
+s32 XNandPsu_CfgInitialize(XNandPsu *InstancePtr, XNandPsu_Config *ConfigPtr,
+ u32 EffectiveAddr)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(ConfigPtr != NULL);
+
+ s32 Status = XST_FAILURE;
+
+ /* Initialize InstancePtr Config structure */
+ InstancePtr->Config.DeviceId = ConfigPtr->DeviceId;
+ InstancePtr->Config.BaseAddress = EffectiveAddr;
+ InstancePtr->Config.IsCacheCoherent = ConfigPtr->IsCacheCoherent;
+#if defined (XCLOCKING)
+ InstancePtr->Config.RefClk = ConfigPtr->RefClk;
+#endif
+ /* Operate in Polling Mode */
+ InstancePtr->Mode = XNANDPSU_POLLING;
+ /* Enable MDMA mode by default */
+ InstancePtr->DmaMode = XNANDPSU_MDMA;
+ InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
+
+#ifdef __rtems__
+ /* Set page cache to unavailable */
+ InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_UNAVAILABLE;
+#endif
+
+ /* Initialize the NAND flash targets */
+ Status = XNandPsu_FlashInit(InstancePtr);
+ if (Status != XST_SUCCESS) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Flash init failed\r\n",__func__);
+#endif
+ goto Out;
+ }
+ /* Set ECC mode */
+ if (InstancePtr->Features.EzNand != 0U) {
+ InstancePtr->EccMode = XNANDPSU_EZNAND;
+ } else if (InstancePtr->Features.OnDie != 0U) {
+ InstancePtr->EccMode = XNANDPSU_ONDIE;
+ } else {
+ InstancePtr->EccMode = XNANDPSU_HWECC;
+ }
+
+ /* Initialize Ecc Error flip counters */
+ InstancePtr->Ecc_Stat_PerPage_flips = 0U;
+ InstancePtr->Ecc_Stats_total_flips = 0U;
+
+ /*
+ * Scan for the bad block table(bbt) stored in the flash & load it in
+ * memory(RAM). If bbt is not found, create bbt by scanning factory
+ * marked bad blocks and store it in last good blocks of flash.
+ */
+ XNandPsu_InitBbtDesc(InstancePtr);
+ Status = XNandPsu_ScanBbt(InstancePtr);
+ if (Status != XST_SUCCESS) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: BBT scan failed\r\n",__func__);
+#endif
+ goto Out;
+ }
+
+#ifdef __rtems__
+ /* Set page cache to none */
+ InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_NONE;
+#endif
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function initializes the NAND flash and gets the geometry information.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_FlashInit(XNandPsu *InstancePtr)
+{
+ u32 Target;
+ u8 Id[ONFI_SIG_LEN] = {0U};
+ OnfiParamPage Param[ONFI_MND_PRM_PGS] = {0U};
+ s32 Status = XST_FAILURE;
+ u32 Index;
+ u32 Crc;
+ u32 PrmPgOff;
+ u32 PrmPgLen;
+#ifdef __ICCARM__
+#pragma pack(push, 1)
+ OnfiExtPrmPage ExtParam = {0U};
+#pragma pack(pop)
+#else
+ OnfiExtPrmPage ExtParam __attribute__ ((aligned(64))) = {0U};
+#endif
+
+ /* Clear Data Interface Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_DATA_INTF_OFFSET, 0U);
+
+ /* Clear DMA Buffer Boundary Register */
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_DMA_BUF_BND_OFFSET, 0U);
+
+ for (Target = 0U; Target < XNANDPSU_MAX_TARGETS; Target++) {
+ /* Reset the Target */
+ Status = XNandPsu_OnfiReset(InstancePtr, Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Read ONFI ID */
+ Status = XNandPsu_OnfiReadId(InstancePtr, Target,
+ ONFI_READ_ID_ADDR,
+ ONFI_SIG_LEN,
+ (u8 *)&Id[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ if (!IS_ONFI(Id)) {
+ if (Target == 0U) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: ONFI ID doesn't match\r\n",
+ __func__);
+#endif
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ }
+
+ /* Read Parameter Page */
+ Status = XNandPsu_OnfiReadParamPage(InstancePtr,
+ Target, (u8 *)&Param[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ for(Index = 0U; Index < ONFI_MND_PRM_PGS; Index++){
+ /* Check CRC */
+ Crc = XNandPsu_OnfiParamPageCrc((u8*)&Param[Index], 0U,
+ ONFI_CRC_LEN);
+ if (Crc != Param[Index].Crc) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: ONFI parameter page (%d) crc check failed\r\n",
+ __func__, Index);
+#endif
+ continue;
+ } else {
+ break;
+ }
+ }
+ if (Index >= ONFI_MND_PRM_PGS) {
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ /* Fill Geometry for the first target */
+ if (Target == 0U) {
+ Status = XNandPsu_InitGeometry(InstancePtr, &Param[Index]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ XNandPsu_InitDataInterface(InstancePtr, &Param[Index]);
+ XNandPsu_InitTimingMode(InstancePtr, &Param[Index]);
+ XNandPsu_InitFeatures(InstancePtr, &Param[Index]);
+ if ((!InstancePtr->Features.EzNand) != 0U) {
+ Status =XNandPsu_CheckOnDie(InstancePtr);
+ if (Status != XST_SUCCESS) {
+ InstancePtr->Features.OnDie = 0U;
+ }
+ }
+ if ((InstancePtr->Geometry.NumBitsECC == 0xFFU) &&
+ (InstancePtr->Features.ExtPrmPage != 0U)) {
+ /* ONFI 3.1 section 5.7.1.6 & 5.7.1.7 */
+ PrmPgLen = (u32)Param[Index].ExtParamPageLen * 16U;
+ PrmPgOff = (u32)((u32)Param[Index].NumOfParamPages *
+ ONFI_PRM_PG_LEN) + (Index * (u32)PrmPgLen);
+
+ Status = XNandPsu_ChangeReadColumn(
+ InstancePtr, Target,
+ PrmPgOff, PrmPgLen, 1U,
+ (u8 *)(void *)&ExtParam);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Check CRC */
+ Crc = XNandPsu_OnfiParamPageCrc(
+ (u8 *)&ExtParam,
+ 2U, PrmPgLen);
+ if (Crc != ExtParam.Crc) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: ONFI extended parameter page (%d) crc check failed\r\n",
+ __func__, Index);
+#endif
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ /* Initialize Extended ECC info */
+ Status = XNandPsu_InitExtEcc(
+ InstancePtr,
+ &ExtParam);
+ if (Status != XST_SUCCESS) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Init extended ecc failed\r\n",__func__);
+#endif
+ goto Out;
+ }
+ }
+ /* Configure ECC settings */
+ XNandPsu_SetEccAddrSize(InstancePtr);
+ }
+ InstancePtr->Geometry.NumTargets++;
+ }
+ /* Calculate total number of blocks and total size of flash */
+ InstancePtr->Geometry.NumPages = InstancePtr->Geometry.NumTargets *
+ InstancePtr->Geometry.NumTargetPages;
+ InstancePtr->Geometry.NumBlocks = InstancePtr->Geometry.NumTargets *
+ InstancePtr->Geometry.NumTargetBlocks;
+ InstancePtr->Geometry.DeviceSize =
+ (u64)InstancePtr->Geometry.NumTargets *
+ InstancePtr->Geometry.TargetSize;
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function initializes the geometry information from ONFI parameter page.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Param is pointer to the ONFI parameter page.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_InitGeometry(XNandPsu *InstancePtr, OnfiParamPage *Param)
+{
+ s32 Status = XST_FAILURE;
+
+ if (Param->BytesPerPage > XNANDPSU_MAX_PAGE_SIZE) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Invalid Bytes Per Page %d\r\n",
+ __func__, Param->BytesPerPage);
+#endif
+ goto Out;
+ }
+ InstancePtr->Geometry.BytesPerPage = Param->BytesPerPage;
+
+
+ if (Param->SpareBytesPerPage > XNANDPSU_MAX_SPARE_SIZE) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Invalid Spare Bytes Per Page %d\r\n",
+ __func__, Param->SpareBytesPerPage);
+#endif
+ goto Out;
+ }
+ InstancePtr->Geometry.SpareBytesPerPage = Param->SpareBytesPerPage;
+
+ if (Param->PagesPerBlock > XNANDPSU_MAX_PAGES_PER_BLOCK) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Invalid Page Count Per Block %d\r\n",
+ __func__, Param->PagesPerBlock);
+#endif
+ goto Out;
+ }
+ InstancePtr->Geometry.PagesPerBlock = Param->PagesPerBlock;
+
+
+ if (Param->BlocksPerLun > XNANDPSU_MAX_BLOCKS) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Invalid block count per LUN %d\r\n",
+ __func__, Param->BlocksPerLun);
+#endif
+ goto Out;
+ }
+ InstancePtr->Geometry.BlocksPerLun = Param->BlocksPerLun;
+
+ if (Param->NumLuns > XNANDPSU_MAX_LUNS) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Invalid LUN count %d\r\n",
+ __func__, Param->NumLuns);
+#endif
+ goto Out;
+ }
+ InstancePtr->Geometry.NumLuns = Param->NumLuns;
+
+ InstancePtr->Geometry.RowAddrCycles = Param->AddrCycles & 0xFU;
+ InstancePtr->Geometry.ColAddrCycles = (Param->AddrCycles >> 4U) & 0xFU;
+ InstancePtr->Geometry.NumBitsPerCell = Param->BitsPerCell;
+ InstancePtr->Geometry.NumBitsECC = Param->EccBits;
+ InstancePtr->Geometry.BlockSize = (Param->PagesPerBlock *
+ Param->BytesPerPage);
+ InstancePtr->Geometry.NumTargetBlocks = (Param->BlocksPerLun *
+ (u32)Param->NumLuns);
+ InstancePtr->Geometry.NumTargetPages = (Param->BlocksPerLun *
+ (u32)Param->NumLuns *
+ Param->PagesPerBlock);
+ InstancePtr->Geometry.TargetSize = ((u64)Param->BlocksPerLun *
+ (u64)Param->NumLuns *
+ (u64)Param->PagesPerBlock *
+ (u64)Param->BytesPerPage);
+ InstancePtr->Geometry.EccCodeWordSize = 9U; /* 2 power of 9 = 512 */
+ if (InstancePtr->Geometry.NumTargetBlocks > XNANDPSU_MAX_BLOCKS)
+ xil_printf("!!! Device contains more blocks than the max defined blocks in driver\r\n");
+
+#ifdef XNANDPSU_DEBUG
+ xil_printf("Manufacturer: %s\r\n", Param->DeviceManufacturer);
+ xil_printf("Device Model: %s\r\n", Param->DeviceModel);
+ xil_printf("Jedec ID: 0x%x\r\n", Param->JedecManufacturerId);
+ xil_printf("Bytes Per Page: 0x%x\r\n", Param->BytesPerPage);
+ xil_printf("Spare Bytes Per Page: 0x%x\r\n", Param->SpareBytesPerPage);
+ xil_printf("Pages Per Block: 0x%x\r\n", Param->PagesPerBlock);
+ xil_printf("Blocks Per LUN: 0x%x\r\n", Param->BlocksPerLun);
+ xil_printf("Number of LUNs: 0x%x\r\n", Param->NumLuns);
+ xil_printf("Number of bits per cell: 0x%x\r\n", Param->BitsPerCell);
+ xil_printf("Number of ECC bits: 0x%x\r\n", Param->EccBits);
+ xil_printf("Block Size: 0x%x\r\n", InstancePtr->Geometry.BlockSize);
+
+ xil_printf("Number of Target Blocks: 0x%x\r\n",
+ InstancePtr->Geometry.NumTargetBlocks);
+ xil_printf("Number of Target Pages: 0x%x\r\n",
+ InstancePtr->Geometry.NumTargetPages);
+
+#endif
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function initializes the feature list from ONFI parameter page.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Param is pointer to ONFI parameter page buffer.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_InitFeatures(XNandPsu *InstancePtr, OnfiParamPage *Param)
+{
+ InstancePtr->Features.NvDdr = ((Param->Features & (1U << 5)) != 0U) ?
+ 1U : 0U;
+ InstancePtr->Features.EzNand = ((Param->Features & (1U << 9)) != 0U) ?
+ 1U : 0U;
+ InstancePtr->Features.ExtPrmPage = ((Param->Features & (1U << 7)) != 0U) ?
+ 1U : 0U;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function initializes the Data Interface from ONFI parameter page.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Param is pointer to ONFI parameter page buffer.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_InitDataInterface(XNandPsu *InstancePtr, OnfiParamPage *Param)
+{
+ if (Param->NVDDRTimingMode)
+ InstancePtr->DataInterface = XNANDPSU_NVDDR;
+ else if (Param->SDRTimingMode)
+ InstancePtr->DataInterface = XNANDPSU_SDR;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function initializes the Timing mode from ONFI parameter page.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Param is pointer to ONFI parameter page buffer.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_InitTimingMode(XNandPsu *InstancePtr, OnfiParamPage *Param)
+{
+ s8 Mode;
+ u8 TimingMode = (u8)(Param->SDRTimingMode);
+
+ if (InstancePtr->DataInterface == XNANDPSU_NVDDR)
+ TimingMode = Param->NVDDRTimingMode;
+
+ for(Mode = XNANDPSU_MAX_TIMING_MODE; Mode >= 0; Mode--) {
+ if (TimingMode & (0x01 << Mode)) {
+ InstancePtr->TimingMode = Mode;
+ break;
+ } else {
+ continue;
+ }
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function checks if the flash supports on-die ECC.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Param is pointer to ONFI parameter page.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_CheckOnDie(XNandPsu *InstancePtr)
+{
+ s32 Status = XST_FAILURE;
+ u8 JedecId[2] = {0U};
+ u8 EccSetFeature[4] = {0x08U, 0x00U, 0x00U, 0x00U};
+ u8 EccGetFeature[4] ={0U};
+
+ /*
+ * Check if this flash supports On-Die ECC.
+ * For more information, refer to Micron TN2945.
+ * Micron Flash: MT29F1G08ABADA, MT29F1G08ABBDA
+ * MT29F1G16ABBDA,
+ * MT29F2G08ABBEA, MT29F2G16ABBEA,
+ * MT29F2G08ABAEA, MT29F2G16ABAEA,
+ * MT29F4G08ABBDA, MT29F4G16ABBDA,
+ * MT29F4G08ABADA, MT29F4G16ABADA,
+ * MT29F8G08ADBDA, MT29F8G16ADBDA,
+ * MT29F8G08ADADA, MT29F8G16ADADA
+ */
+
+ /* Read JEDEC ID */
+ Status = XNandPsu_OnfiReadId(InstancePtr, 0U, 0x00U, 2U, &JedecId[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ if ((JedecId[0] == 0x2CU) &&
+ /* 1 Gb flash devices */
+ ((JedecId[1] == 0xF1U) ||
+ (JedecId[1] == 0xA1U) ||
+ (JedecId[1] == 0xB1U) ||
+ /* 2 Gb flash devices */
+ (JedecId[1] == 0xAAU) ||
+ (JedecId[1] == 0xBAU) ||
+ (JedecId[1] == 0xDAU) ||
+ (JedecId[1] == 0xCAU) ||
+ /* 4 Gb flash devices */
+ (JedecId[1] == 0xACU) ||
+ (JedecId[1] == 0xBCU) ||
+ (JedecId[1] == 0xDCU) ||
+ (JedecId[1] == 0xCCU) ||
+ /* 8 Gb flash devices */
+ (JedecId[1] == 0xA3U) ||
+ (JedecId[1] == 0xB3U) ||
+ (JedecId[1] == 0xD3U) ||
+ (JedecId[1] == 0xC3U))) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Ondie flash detected, jedec id 0x%x 0x%x\r\n",
+ __func__, JedecId[0], JedecId[1]);
+#endif
+ /* On-Die Set Feature */
+ Status = XNandPsu_SetFeature(InstancePtr, 0U, 0x90U,
+ &EccSetFeature[0]);
+ if (Status != XST_SUCCESS) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Ondie set_feature failed\r\n",
+ __func__);
+#endif
+ goto Out;
+ }
+ /* Check to see if ECC feature is set */
+ Status = XNandPsu_GetFeature(InstancePtr, 0U, 0x90U,
+ &EccGetFeature[0]);
+ if (Status != XST_SUCCESS) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Ondie get_feature failed\r\n",
+ __func__);
+#endif
+ goto Out;
+ }
+ if ((EccGetFeature[0] & 0x08U) != 0U) {
+ InstancePtr->Features.OnDie = 1U;
+ Status = XST_SUCCESS;
+ }
+ } else {
+ /* On-Die flash not found */
+ Status = XST_FAILURE;
+ }
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables DMA mode of controller operation.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+void XNandPsu_EnableDmaMode(XNandPsu *InstancePtr)
+{
+ /* Assert the input arguments. */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ InstancePtr->DmaMode = XNANDPSU_MDMA;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function disables DMA mode of driver/controller operation.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+void XNandPsu_DisableDmaMode(XNandPsu *InstancePtr)
+{
+ /* Assert the input arguments. */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ InstancePtr->DmaMode = XNANDPSU_PIO;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables ECC mode of driver/controller operation.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+void XNandPsu_EnableEccMode(XNandPsu *InstancePtr)
+{
+ /* Assert the input arguments. */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ InstancePtr->EccMode = XNANDPSU_HWECC;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function disables ECC mode of driver/controller operation.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+void XNandPsu_DisableEccMode(XNandPsu *InstancePtr)
+{
+ /* Assert the input arguments. */
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ InstancePtr->EccMode = XNANDPSU_NONE;
+}
+
+#ifdef __rtems__
+#include <rtems/rtems/clock.h>
+static void udelay( void )
+{
+ uint64_t time = rtems_clock_get_uptime_nanoseconds() + 1000;
+ while (1) {
+ uint64_t newtime = rtems_clock_get_uptime_nanoseconds();
+ if (newtime > time) {
+ break;
+ }
+ }
+}
+#define usleep(x) udelay()
+#endif
+
+/*****************************************************************************/
+/**
+*
+* This function polls for a register bit set status till the timeout.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param RegOffset is the offset of register.
+* @param Mask is the bitmask.
+* @param Timeout is the timeout value.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_PollRegTimeout(XNandPsu *InstancePtr, u32 RegOffset,
+ u32 Mask, u32 Timeout)
+{
+ s32 Status = XST_FAILURE;
+ volatile u32 RegVal;
+ u32 TimeoutVar = Timeout;
+
+ while (TimeoutVar > 0U) {
+ RegVal = XNandPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ RegOffset) & Mask;
+ if (RegVal != 0U) {
+ break;
+ }
+ TimeoutVar--;
+ usleep(1);
+ }
+
+ if (TimeoutVar <= 0U) {
+ Status = XST_FAILURE;
+ } else {
+ Status = XST_SUCCESS;
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets packet size and packet count values in packet register.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param PktSize is the packet size.
+* @param PktCount is the packet count.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_SetPktSzCnt(XNandPsu *InstancePtr, u32 PktSize,
+ u32 PktCount)
+{
+ /* Update Packet Register with pkt size and count */
+ XNandPsu_ReadModifyWrite(InstancePtr, XNANDPSU_PKT_OFFSET,
+ ((u32)XNANDPSU_PKT_PKT_SIZE_MASK |
+ (u32)XNANDPSU_PKT_PKT_CNT_MASK),
+ ((PktSize & XNANDPSU_PKT_PKT_SIZE_MASK) |
+ ((PktCount << XNANDPSU_PKT_PKT_CNT_SHIFT) &
+ XNANDPSU_PKT_PKT_CNT_MASK)));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets Page and Column values in the Memory address registers.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Page is the page value.
+* @param Col is the column value.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_SetPageColAddr(XNandPsu *InstancePtr, u32 Page, u16 Col)
+{
+ /* Program Memory Address Register 1 */
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_MEM_ADDR1_OFFSET,
+ (((u32)Col & XNANDPSU_MEM_ADDR1_COL_ADDR_MASK) |
+ ((Page << (u32)XNANDPSU_MEM_ADDR1_PG_ADDR_SHIFT) &
+ XNANDPSU_MEM_ADDR1_PG_ADDR_MASK)));
+ /* Program Memory Address Register 2 */
+ XNandPsu_ReadModifyWrite(InstancePtr, XNANDPSU_MEM_ADDR2_OFFSET,
+ XNANDPSU_MEM_ADDR2_MEM_ADDR_MASK,
+ ((Page >> XNANDPSU_MEM_ADDR1_PG_ADDR_SHIFT) &
+ XNANDPSU_MEM_ADDR2_MEM_ADDR_MASK));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets the size of page in Command Register.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_SetPageSize(XNandPsu *InstancePtr)
+{
+ u32 PageSizeMask = 0;
+ u32 PageSize = InstancePtr->Geometry.BytesPerPage;
+
+ /* Calculate page size mask */
+ switch(PageSize) {
+ case XNANDPSU_PAGE_SIZE_512:
+ PageSizeMask = (0U << XNANDPSU_CMD_PG_SIZE_SHIFT);
+ break;
+ case XNANDPSU_PAGE_SIZE_2K:
+ PageSizeMask = (1U << XNANDPSU_CMD_PG_SIZE_SHIFT);
+ break;
+ case XNANDPSU_PAGE_SIZE_4K:
+ PageSizeMask = (2U << XNANDPSU_CMD_PG_SIZE_SHIFT);
+ break;
+ case XNANDPSU_PAGE_SIZE_8K:
+ PageSizeMask = (3U << XNANDPSU_CMD_PG_SIZE_SHIFT);
+ break;
+ case XNANDPSU_PAGE_SIZE_16K:
+ PageSizeMask = (4U << XNANDPSU_CMD_PG_SIZE_SHIFT);
+ break;
+ case XNANDPSU_PAGE_SIZE_1K_16BIT:
+ PageSizeMask = (5U << XNANDPSU_CMD_PG_SIZE_SHIFT);
+ break;
+ default:
+ /* Not supported */
+ break;
+ }
+ /* Update Command Register */
+ XNandPsu_ReadModifyWrite(InstancePtr, XNANDPSU_CMD_OFFSET,
+ XNANDPSU_CMD_PG_SIZE_MASK, PageSizeMask);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setup the Ecc Register.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_SetEccAddrSize(XNandPsu *InstancePtr)
+{
+ u32 PageSize = InstancePtr->Geometry.BytesPerPage;
+ u32 CodeWordSize = InstancePtr->Geometry.EccCodeWordSize;
+ u32 NumEccBits = InstancePtr->Geometry.NumBitsECC;
+ u32 Index;
+ u32 Found = 0U;
+ u8 BchModeVal;
+
+ for (Index = 0U; Index < (sizeof(EccMatrix)/sizeof(XNandPsu_EccMatrix));
+ Index++) {
+ if ((EccMatrix[Index].PageSize == PageSize) &&
+ (EccMatrix[Index].CodeWordSize >= CodeWordSize)) {
+ if (EccMatrix[Index].NumEccBits >= NumEccBits) {
+ Found = Index;
+ break;
+ }
+ else {
+ Found = Index;
+ }
+ }
+ }
+
+ if (Found != 0U) {
+ if(InstancePtr->Geometry.SpareBytesPerPage < 64U) {
+ InstancePtr->EccCfg.EccAddr = (u16)PageSize;
+ }
+ else {
+ InstancePtr->EccCfg.EccAddr = ((u16)PageSize +
+ (InstancePtr->Geometry.SpareBytesPerPage
+ - EccMatrix[Found].EccSize));
+ }
+ InstancePtr->EccCfg.EccSize = EccMatrix[Found].EccSize;
+ InstancePtr->EccCfg.NumEccBits = EccMatrix[Found].NumEccBits;
+ InstancePtr->EccCfg.CodeWordSize =
+ EccMatrix[Found].CodeWordSize;
+#ifdef XNANDPSU_DEBUG
+ xil_printf("ECC: addr 0x%x size 0x%x numbits %d "
+ "codesz %d\r\n",
+ InstancePtr->EccCfg.EccAddr,
+ InstancePtr->EccCfg.EccSize,
+ InstancePtr->EccCfg.NumEccBits,
+ InstancePtr->EccCfg.CodeWordSize);
+#endif
+ if (EccMatrix[Found].IsBCH == XNANDPSU_HAMMING) {
+ InstancePtr->EccCfg.IsBCH = 0U;
+ } else {
+ InstancePtr->EccCfg.IsBCH = 1U;
+ }
+ /* Write ECC register */
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ (u32)XNANDPSU_ECC_OFFSET,
+ ((u32)InstancePtr->EccCfg.EccAddr |
+ ((u32)InstancePtr->EccCfg.EccSize << (u32)16) |
+ ((u32)InstancePtr->EccCfg.IsBCH << (u32)27)));
+
+ if (EccMatrix[Found].IsBCH == XNANDPSU_BCH) {
+ /* Write memory address register 2 */
+ switch(InstancePtr->EccCfg.NumEccBits) {
+ case 16U:
+ BchModeVal = 0x0U;
+ break;
+ case 12U:
+ BchModeVal = 0x1U;
+ break;
+ case 8U:
+ BchModeVal = 0x2U;
+ break;
+ case 4U:
+ BchModeVal = 0x3U;
+ break;
+ case 24U:
+ BchModeVal = 0x4U;
+ break;
+ default:
+ BchModeVal = 0x0U;
+ break;
+ }
+ XNandPsu_ReadModifyWrite(InstancePtr,
+ XNANDPSU_MEM_ADDR2_OFFSET,
+ XNANDPSU_MEM_ADDR2_NFC_BCH_MODE_MASK,
+ ((u32)BchModeVal <<
+ (u32)XNANDPSU_MEM_ADDR2_NFC_BCH_MODE_SHIFT));
+ }
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setup the Ecc Spare Command Register.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_SetEccSpareCmd(XNandPsu *InstancePtr, u16 SpareCmd,
+ u8 AddrCycles)
+{
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ (u32)XNANDPSU_ECC_SPR_CMD_OFFSET,
+ (u32)SpareCmd | ((u32)AddrCycles << 28U));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets the chip select value in memory address2 register.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_SelectChip(XNandPsu *InstancePtr, u32 Target)
+{
+#if defined (XCLOCKING)
+ Xil_ClockEnable(InstancePtr->Config.RefClk);
+#endif
+ /* Update Memory Address2 register with chip select */
+ XNandPsu_ReadModifyWrite(InstancePtr, XNANDPSU_MEM_ADDR2_OFFSET,
+ XNANDPSU_MEM_ADDR2_CHIP_SEL_MASK,
+ ((Target << XNANDPSU_MEM_ADDR2_CHIP_SEL_SHIFT) &
+ XNANDPSU_MEM_ADDR2_CHIP_SEL_MASK));
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI Reset command to the flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_OnfiReset(XNandPsu *InstancePtr, u32 Target)
+{
+ s32 Status = XST_FAILURE;
+
+ /* Enable Transfer Complete Interrupt in Interrupt Status Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK);
+ /* Program Command Register */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RST, ONFI_CMD_INVALID, 0U,
+ 0U, 0U);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Set Reset in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET, XNANDPSU_PROG_RST_MASK);
+
+ /* Poll for Transfer Complete event */
+ Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr);
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI Read Status command to the flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param OnfiStatus is the ONFI status value to return.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_OnfiReadStatus(XNandPsu *InstancePtr, u32 Target,
+ u16 *OnfiStatus)
+{
+ s32 Status = XST_FAILURE;
+
+ /* Enable Transfer Complete Interrupt in Interrupt Status Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK);
+ /* Program Command Register */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD_STS, ONFI_CMD_INVALID,
+ 0U, 0U, 0U);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Program Packet Size and Packet Count */
+ if(InstancePtr->DataInterface == XNANDPSU_SDR)
+ XNandPsu_SetPktSzCnt(InstancePtr, 1U, 1U);
+ else
+ XNandPsu_SetPktSzCnt(InstancePtr, 2U, 1U);
+
+ /* Set Read Status in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_STS_MASK);
+ /* Poll for Transfer Complete event */
+ Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr);
+ /* Read Flash Status */
+ *OnfiStatus = (u16) XNandPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_FLASH_STS_OFFSET);
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI Read ID command to the flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param Buf is the ONFI ID value to return.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_OnfiReadId(XNandPsu *InstancePtr, u32 Target, u8 IdAddr,
+ u32 IdLen, u8 *Buf)
+{
+ s32 Status = XST_FAILURE;
+ u32 Index;
+ u32 Rem;
+ u32 RegVal;
+ u32 RemIdx;
+
+ u32 *BufPtr = (u32 *)(void *)Buf;
+
+ /*
+ * Enable Buffer Read Ready Interrupt in Interrupt Status Enable
+ * Register
+ */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK);
+ /* Program Command */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD_ID, ONFI_CMD_INVALID, 0U,
+ 0U, ONFI_READ_ID_ADDR_CYCLES);
+
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, 0U, IdAddr);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, IdLen, 1U);
+ /* Set Read ID in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_ID_MASK);
+
+ /* Poll for Buffer Read Ready event */
+ Status = XNandPsu_PollRegTimeout(
+ InstancePtr,
+ XNANDPSU_INTR_STS_OFFSET,
+ XNANDPSU_INTR_STS_BUFF_RD_RDY_STS_EN_MASK,
+ XNANDPSU_INTR_POLL_TIMEOUT);
+ if (Status != XST_SUCCESS) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Poll for buf read ready timeout\r\n",
+ __func__);
+#endif
+ goto Out;
+ }
+ /*
+ * Enable Transfer Complete Interrupt in Interrupt
+ * Status Enable Register
+ */
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK);
+
+ /*
+ * Clear Buffer Read Ready Interrupt in Interrupt Status
+ * Register
+ */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_OFFSET,
+ XNANDPSU_INTR_STS_BUFF_RD_RDY_STS_EN_MASK);
+ /* Read Packet Data from Data Port Register */
+ for (Index = 0U; Index < (IdLen/4); Index++) {
+ *(BufPtr+Index) = XNandPsu_ReadReg(
+ InstancePtr->Config.BaseAddress,
+ XNANDPSU_BUF_DATA_PORT_OFFSET);
+ }
+ Rem = IdLen % 4;
+ if (Rem != 0U) {
+ RegVal = XNandPsu_ReadReg(
+ InstancePtr->Config.BaseAddress,
+ XNANDPSU_BUF_DATA_PORT_OFFSET);
+ for (RemIdx = 0U; RemIdx < Rem; RemIdx++) {
+ *(Buf + (Index * 4U) + RemIdx) = (u8) (RegVal >>
+ (RemIdx * 8U)) & 0xFFU;
+ }
+ }
+
+ Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr);
+
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends the ONFI Read Parameter Page command to flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param PrmIndex is the index of parameter page.
+* @param Buf is the parameter page information to return.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_OnfiReadParamPage(XNandPsu *InstancePtr, u32 Target,
+ u8 *Buf)
+{
+ s32 Status = XST_FAILURE;
+
+ /*
+ * Enable Buffer Read Ready Interrupt in Interrupt Status Enable
+ * Register
+ */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK);
+ /* Program Command */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD_PRM_PG, ONFI_CMD_INVALID,
+ 0U, 0U, ONFI_PRM_PG_ADDR_CYCLES);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, 0U, 0U);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, ONFI_MND_PRM_PGS*ONFI_PRM_PG_LEN, 1U);
+ /* Set Read Parameter Page in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_PRM_PG_MASK);
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, 1U, ONFI_MND_PRM_PGS*ONFI_PRM_PG_LEN, 0, 0);
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function returns the length including bad blocks from a given offset and
+* length.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @param Offset is the flash data address to read from.
+* @param Length is number of bytes to read.
+*
+* @return
+* - Return actual length including bad blocks.
+*
+* @note None.
+*
+******************************************************************************/
+static s32 XNandPsu_CalculateLength(XNandPsu *InstancePtr, u64 Offset,
+ u64 Length)
+{
+ s32 Status;
+ u32 BlockSize;
+ u32 BlockLen;
+ u32 Block;
+ u64 TempLen = 0;
+ u64 OffsetVar = Offset;
+
+ BlockSize = InstancePtr->Geometry.BlockSize;
+
+ while (TempLen < Length) {
+ Block = (u32)(OffsetVar/BlockSize);
+ BlockLen = BlockSize - (u32)(OffsetVar % BlockSize);
+ if (OffsetVar >= InstancePtr->Geometry.DeviceSize) {
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ /* Check if the block is bad */
+ Status = XNandPsu_IsBlockBad(InstancePtr, Block);
+ if (Status != XST_SUCCESS) {
+ /* Good block */
+ TempLen += BlockLen;
+ }
+ OffsetVar += BlockLen;
+ }
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function writes to the flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Offset is the starting offset of flash to write.
+* @param Length is the number of bytes to write.
+* @param SrcBuf is the source data buffer to write.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+s32 XNandPsu_Write(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *SrcBuf)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(SrcBuf != NULL);
+ Xil_AssertNonvoid(Length != 0U);
+ Xil_AssertNonvoid((Offset + Length) <=
+ InstancePtr->Geometry.DeviceSize);
+
+ s32 Status = XST_FAILURE;
+ u32 Page;
+ u32 Col;
+ u32 Target;
+ u32 Block;
+ u32 PartialBytes = 0;
+ u32 NumBytes;
+ u32 RemLen;
+ u8 *BufPtr;
+ u8 *SrcBufPtr = (u8 *)SrcBuf;
+ u64 OffsetVar = Offset;
+ u64 LengthVar = Length;
+
+ /*
+ * Check if write operation exceeds flash size when including
+ * bad blocks.
+ */
+ Status = XNandPsu_CalculateLength(InstancePtr, OffsetVar, LengthVar);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+#ifdef __rtems__
+ if (InstancePtr->PartialDataPageIndex != XNANDPSU_PAGE_CACHE_UNAVAILABLE) {
+ /* All writes invalidate the page cache */
+ InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_NONE;
+ }
+#endif
+ while (LengthVar > 0U) {
+ Block = (u32) (OffsetVar/InstancePtr->Geometry.BlockSize);
+ /*
+ * Skip the bad blocks. Increment the offset by block size.
+ * For better results, always program the flash starting at
+ * a block boundary.
+ */
+ if (XNandPsu_IsBlockBad(InstancePtr, Block) == XST_SUCCESS) {
+ OffsetVar += (u64)InstancePtr->Geometry.BlockSize;
+ continue;
+ }
+ /* Calculate Page and Column address values */
+ Page = (u32) (OffsetVar/InstancePtr->Geometry.BytesPerPage);
+ Col = (u32) (OffsetVar &
+ (InstancePtr->Geometry.BytesPerPage - 1U));
+ PartialBytes = 0U;
+ /*
+ * Check if partial write.
+ * If column address is > 0 or Length is < page size
+ */
+ if ((Col > 0U) ||
+ (LengthVar < InstancePtr->Geometry.BytesPerPage)) {
+ RemLen = InstancePtr->Geometry.BytesPerPage - Col;
+ PartialBytes = (RemLen < (u32)LengthVar) ?
+ RemLen : (u32)LengthVar;
+ }
+
+ Target = (u32) (OffsetVar/InstancePtr->Geometry.TargetSize);
+#ifdef __rtems__
+ {
+#else
+ if (Page > InstancePtr->Geometry.NumTargetPages) {
+#endif
+ Page %= InstancePtr->Geometry.NumTargetPages;
+ }
+
+ /* Check if partial write */
+ if (PartialBytes > 0U) {
+ BufPtr = &InstancePtr->PartialDataBuf[0];
+ (void)memset(BufPtr, 0xFF,
+ InstancePtr->Geometry.BytesPerPage);
+ (void)Xil_MemCpy(BufPtr + Col, SrcBufPtr, PartialBytes);
+
+ NumBytes = PartialBytes;
+ } else {
+ BufPtr = (u8 *)SrcBufPtr;
+ NumBytes = (InstancePtr->Geometry.BytesPerPage <
+ (u32)LengthVar) ?
+ InstancePtr->Geometry.BytesPerPage :
+ (u32)LengthVar;
+ }
+ /* Program page */
+ Status = XNandPsu_ProgramPage(InstancePtr, Target, Page, 0U,
+ BufPtr);
+ if (Status != XST_SUCCESS)
+ goto Out;
+
+ Status = XNandPsu_Device_Ready(InstancePtr, Target);
+ if (Status != XST_SUCCESS)
+ goto Out;
+
+ SrcBufPtr += NumBytes;
+ OffsetVar += NumBytes;
+ LengthVar -= NumBytes;
+ }
+
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function reads from the flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Offset is the starting offset of flash to read.
+* @param Length is the number of bytes to read.
+* @param DestBuf is the destination data buffer to fill in.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+s32 XNandPsu_Read(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *DestBuf)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(DestBuf != NULL);
+ Xil_AssertNonvoid(Length != 0U);
+ Xil_AssertNonvoid((Offset + Length) <=
+ InstancePtr->Geometry.DeviceSize);
+
+ s32 Status = XST_FAILURE;
+ u32 Page;
+ u32 Col;
+ u32 Target;
+ u32 Block;
+ u32 PartialBytes = 0U;
+ u32 RemLen;
+ u32 NumBytes;
+ u8 *BufPtr;
+ u8 *DestBufPtr = (u8 *)DestBuf;
+ u64 OffsetVar = Offset;
+ u64 LengthVar = Length;
+
+ /*
+ * Check if read operation exceeds flash size when including
+ * bad blocks.
+ */
+ Status = XNandPsu_CalculateLength(InstancePtr, OffsetVar, LengthVar);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ while (LengthVar > 0U) {
+ Block = (u32)(OffsetVar/InstancePtr->Geometry.BlockSize);
+ /*
+ * Skip the bad block. Increment the offset by block size.
+ * The flash programming utility must make sure to start
+ * writing always at a block boundary and skip blocks if any.
+ */
+ if (XNandPsu_IsBlockBad(InstancePtr, Block) == XST_SUCCESS) {
+ OffsetVar += (u64)InstancePtr->Geometry.BlockSize;
+ continue;
+ }
+ /* Calculate Page and Column address values */
+ Page = (u32) (OffsetVar/InstancePtr->Geometry.BytesPerPage);
+ Col = (u32) (OffsetVar &
+ (InstancePtr->Geometry.BytesPerPage - 1U));
+ PartialBytes = 0U;
+ /*
+ * Check if partial write.
+ * If column address is > 0 or Length is < page size
+ */
+ if ((Col > 0U) ||
+ (LengthVar < InstancePtr->Geometry.BytesPerPage)) {
+ RemLen = InstancePtr->Geometry.BytesPerPage - Col;
+ PartialBytes = ((u32)RemLen < (u32)LengthVar) ?
+ (u32)RemLen : (u32)LengthVar;
+ }
+
+ Target = (u32) (OffsetVar/InstancePtr->Geometry.TargetSize);
+#ifdef __rtems__
+ {
+#else
+ if (Page > InstancePtr->Geometry.NumTargetPages) {
+#endif
+ Page %= InstancePtr->Geometry.NumTargetPages;
+ }
+ /* Check if partial read */
+ if (PartialBytes > 0U) {
+ BufPtr = &InstancePtr->PartialDataBuf[0];
+ NumBytes = PartialBytes;
+ } else {
+ BufPtr = DestBufPtr;
+ NumBytes = (InstancePtr->Geometry.BytesPerPage <
+ (u32)LengthVar) ?
+ InstancePtr->Geometry.BytesPerPage :
+ (u32)LengthVar;
+ }
+#ifdef __rtems__
+ if (Page == InstancePtr->PartialDataPageIndex) {
+ /*
+ * This is a whole page read for the currently cached
+ * page. It will not be taken care of below, so perform
+ * the copy here.
+ */
+ if (PartialBytes == 0U) {
+ (void)Xil_MemCpy(DestBufPtr,
+ &InstancePtr->PartialDataBuf[0],
+ NumBytes);
+ }
+ } else {
+#endif
+ /* Read page */
+ Status = XNandPsu_ReadPage(InstancePtr, Target, Page, 0U,
+ BufPtr);
+#ifdef __rtems__
+ if (PartialBytes > 0U &&
+ InstancePtr->PartialDataPageIndex != XNANDPSU_PAGE_CACHE_UNAVAILABLE) {
+ /*
+ * Partial read into page cache. Update the
+ * cached page index.
+ */
+ InstancePtr->PartialDataPageIndex = Page;
+ }
+ }
+#endif
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ if (PartialBytes > 0U) {
+ (void)Xil_MemCpy(DestBufPtr, BufPtr + Col, NumBytes);
+#ifdef __rtems__
+ /* The destination buffer is touched by hardware, synchronize */
+ if (InstancePtr->Config.IsCacheCoherent == 0) {
+ Xil_DCacheFlushRange((INTPTR)(void *)DestBufPtr, NumBytes);
+ }
+#endif
+ }
+ DestBufPtr += NumBytes;
+ OffsetVar += NumBytes;
+ LengthVar -= NumBytes;
+ }
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function erases the flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Offset is the starting offset of flash to erase.
+* @param Length is the number of bytes to erase.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note
+* The Offset and Length should be aligned to block size boundary
+* to get better results.
+*
+******************************************************************************/
+s32 XNandPsu_Erase(XNandPsu *InstancePtr, u64 Offset, u64 Length)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(Length != 0U);
+ Xil_AssertNonvoid((Offset + Length) <=
+ InstancePtr->Geometry.DeviceSize);
+
+ s32 Status = XST_FAILURE;
+ u32 Target = 0;
+ u32 StartBlock;
+ u32 NumBlocks = 0;
+ u32 Block;
+ u32 AlignOff;
+ u32 EraseLen;
+ u32 BlockRemLen;
+ u64 OffsetVar = Offset;
+ u64 LengthVar = Length;
+
+ /*
+ * Check if erase operation exceeds flash size when including
+ * bad blocks.
+ */
+ Status = XNandPsu_CalculateLength(InstancePtr, OffsetVar, LengthVar);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Calculate number of blocks to erase */
+ StartBlock = (u32) (OffsetVar/InstancePtr->Geometry.BlockSize);
+
+ while (LengthVar > 0U) {
+ Block = (u32) (OffsetVar/InstancePtr->Geometry.BlockSize);
+ if (XNandPsu_IsBlockBad(InstancePtr, Block) ==
+ XST_SUCCESS) {
+ OffsetVar += (u64)InstancePtr->Geometry.BlockSize;
+ NumBlocks++;
+ continue;
+ }
+
+ AlignOff = (u32)OffsetVar &
+ (InstancePtr->Geometry.BlockSize - (u32)1);
+ if (AlignOff > 0U) {
+ BlockRemLen = InstancePtr->Geometry.BlockSize -
+ AlignOff;
+ EraseLen = (BlockRemLen < (u32)LengthVar) ?
+ BlockRemLen :(u32)LengthVar;
+ } else {
+ EraseLen = (InstancePtr->Geometry.BlockSize <
+ (u32)LengthVar) ?
+ InstancePtr->Geometry.BlockSize:
+ (u32)LengthVar;
+ }
+ NumBlocks++;
+ OffsetVar += EraseLen;
+ LengthVar -= EraseLen;
+ }
+
+ for (Block = StartBlock; Block < (StartBlock + NumBlocks); Block++) {
+ Target = Block/InstancePtr->Geometry.NumTargetBlocks;
+#ifdef __rtems__
+ u32 ModBlock = Block % InstancePtr->Geometry.NumTargetBlocks;
+#else
+ Block %= InstancePtr->Geometry.NumTargetBlocks;
+#endif
+ /* Don't erase bad block */
+ if (XNandPsu_IsBlockBad(InstancePtr, Block) ==
+ XST_SUCCESS)
+ continue;
+ /* Block Erase */
+#ifdef __rtems__
+ Status = XNandPsu_EraseBlock(InstancePtr, Target, ModBlock);
+#else
+ Status = XNandPsu_EraseBlock(InstancePtr, Target, Block);
+#endif
+ if (Status != XST_SUCCESS)
+ goto Out;
+
+ Status = XNandPsu_Device_Ready(InstancePtr, Target);
+ if (Status != XST_SUCCESS)
+ goto Out;
+
+ }
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI Program Page command to flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param Page is the page address value to program.
+* @param Col is the column address value to program.
+* @param Buf is the data buffer to program.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_ProgramPage(XNandPsu *InstancePtr, u32 Target, u32 Page,
+ u32 Col, u8 *Buf)
+{
+ u32 PktSize;
+ u32 PktCount;
+ s32 Status = XST_FAILURE;
+ u32 IsrValue;
+ u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles +
+ InstancePtr->Geometry.ColAddrCycles;
+
+ if (InstancePtr->EccCfg.CodeWordSize > 9U) {
+ PktSize = 1024U;
+ } else {
+ PktSize = 512U;
+ }
+ PktCount = InstancePtr->Geometry.BytesPerPage/PktSize;
+
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_PG_PROG1, ONFI_CMD_PG_PROG2,
+ 1U, 1U, (u8)AddrCycles);
+
+ if (InstancePtr->DmaMode == XNANDPSU_MDMA) {
+ IsrValue = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK |
+ XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK;
+ if (InstancePtr->Config.IsCacheCoherent == 0) {
+ Xil_DCacheFlushRange((INTPTR)(void *)Buf, (PktSize * PktCount));
+ }
+ XNandPsu_Update_DmaAddr(InstancePtr, Buf);
+ } else {
+ IsrValue = XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK;
+ }
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, IsrValue);
+ /* Program Page Size */
+ XNandPsu_SetPageSize(InstancePtr);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, Page, (u16)Col);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Set ECC */
+ if (InstancePtr->EccMode == XNANDPSU_HWECC) {
+ XNandPsu_SetEccSpareCmd(InstancePtr, ONFI_CMD_CHNG_WR_COL,
+ InstancePtr->Geometry.ColAddrCycles);
+ }
+ /* Set Page Program in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_PG_PROG_MASK);
+
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 1, 1);
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI Program Page command to flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Page is the page address value to program.
+* @param Buf is the data buffer to program.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+s32 XNandPsu_WriteSpareBytes(XNandPsu *InstancePtr, u32 Page, u8 *Buf)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(Page < InstancePtr->Geometry.NumPages);
+ Xil_AssertNonvoid(Buf != NULL);
+
+ u32 PktCount = 1U;
+ u16 PreEccSpareCol = 0U;
+ u16 PreEccSpareWrCnt = 0U;
+ u16 PostEccSpareCol = 0U;
+ u16 PostEccSpareWrCnt = 0U;
+ u32 PostWrite = 0U;
+ OnfiCmdFormat Cmd;
+ s32 Status = XST_FAILURE;
+ u32 RegVal;
+ u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles +
+ InstancePtr->Geometry.ColAddrCycles;
+ u32 Col = InstancePtr->Geometry.BytesPerPage;
+ u32 Target = Page/InstancePtr->Geometry.NumTargetPages;
+ u32 PktSize = InstancePtr->Geometry.SpareBytesPerPage;
+ u32 *BufPtr = (u32 *)(void *)Buf;
+ u32 PageVar = Page;
+
+ PageVar %= InstancePtr->Geometry.NumTargetPages;
+
+ if (InstancePtr->EccMode == XNANDPSU_HWECC) {
+ /* Calculate ECC free positions before and after ECC code */
+ PreEccSpareCol = 0x0U;
+ PreEccSpareWrCnt = InstancePtr->EccCfg.EccAddr -
+ (u16)InstancePtr->Geometry.BytesPerPage;
+
+ PostEccSpareCol = PreEccSpareWrCnt +
+ InstancePtr->EccCfg.EccSize;
+ PostEccSpareWrCnt = InstancePtr->Geometry.SpareBytesPerPage -
+ PostEccSpareCol;
+
+ PreEccSpareWrCnt = (PreEccSpareWrCnt/4U) * 4U;
+ PostEccSpareWrCnt = (PostEccSpareWrCnt/4U) * 4U;
+
+ if (PreEccSpareWrCnt > 0U) {
+ PktSize = PreEccSpareWrCnt;
+ PktCount = 1U;
+ Col = InstancePtr->Geometry.BytesPerPage +
+ PreEccSpareCol;
+ BufPtr = (u32 *)(void *)Buf;
+ if (PostEccSpareWrCnt > 0U) {
+ PostWrite = 1U;
+ }
+ } else if (PostEccSpareWrCnt > 0U) {
+ PktSize = PostEccSpareWrCnt;
+ PktCount = 1U;
+ Col = InstancePtr->Geometry.BytesPerPage +
+ PostEccSpareCol;
+ BufPtr = (u32 *)(Buf + Col);
+ } else {
+ /* No free spare bytes available for writing */
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ }
+
+ if (InstancePtr->DmaMode == XNANDPSU_MDMA) {
+ RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK;
+ if (InstancePtr->Config.IsCacheCoherent == 0) {
+ Xil_DCacheFlushRange((INTPTR)(void *)BufPtr, (PktSize * PktCount));
+ }
+ XNandPsu_Update_DmaAddr(InstancePtr, (u8 *)BufPtr);
+ } else {
+ RegVal = XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK;
+ }
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, RegVal);
+ /* Program Command hack for change write column */
+ if (PostWrite > 0U) {
+ Cmd.Command1 = 0x80U;
+ Cmd.Command2 = 0x00U;
+ XNandPsu_Prepare_Cmd(InstancePtr, Cmd.Command1, Cmd.Command2,
+ 0U , 1U, (u8)AddrCycles);
+
+ } else {
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_PG_PROG1,
+ ONFI_CMD_PG_PROG2, 0U , 1U, (u8)AddrCycles);
+ }
+ /* Program Page Size */
+ XNandPsu_SetPageSize(InstancePtr);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, PageVar, (u16)Col);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Set Page Program in Program Register */
+ if (PostWrite > 0U) {
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,((u32)XNANDPSU_PROG_PG_PROG_MASK |
+ (u32)XNANDPSU_PROG_CHNG_ROW_ADDR_MASK));
+ } else {
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_PG_PROG_MASK);
+ }
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, (u8 *)BufPtr, PktCount,
+ PktSize, 1, 1);
+
+ if (InstancePtr->EccMode == XNANDPSU_HWECC) {
+ if (PostWrite > 0U) {
+ BufPtr = (u32 *)(Buf + PostEccSpareCol);
+ Status = XNandPsu_ChangeWriteColumn(InstancePtr,
+ Target,
+ PostEccSpareCol, PostEccSpareWrCnt, 1U,
+ (u8 *)(void *)BufPtr);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ }
+ }
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI Read Page command to flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param Page is the page address value to read.
+* @param Col is the column address value to read.
+* @param Buf is the data buffer to fill in.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_ReadPage(XNandPsu *InstancePtr, u32 Target, u32 Page,
+ u32 Col, u8 *Buf)
+{
+ u32 PktSize;
+ u32 PktCount;
+ s32 Status = XST_FAILURE;
+ u32 RegVal;
+ u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles +
+ InstancePtr->Geometry.ColAddrCycles;
+
+ if (InstancePtr->EccCfg.CodeWordSize > 9U) {
+ PktSize = 1024U;
+ } else {
+ PktSize = 512U;
+ }
+ PktCount = InstancePtr->Geometry.BytesPerPage/PktSize;
+
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD1, ONFI_CMD_RD2,
+ 1U, 1U, (u8)AddrCycles);
+
+ if (InstancePtr->DmaMode == XNANDPSU_MDMA) {
+ RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK |
+ XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK;
+ if (InstancePtr->Config.IsCacheCoherent == 0) {
+ Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount));
+ }
+ XNandPsu_Update_DmaAddr(InstancePtr, Buf);
+ } else {
+ RegVal = XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK;
+ }
+ /* Enable Single bit error and Multi bit error */
+ if (InstancePtr->EccMode == XNANDPSU_HWECC)
+ RegVal |= XNANDPSU_INTR_STS_EN_MUL_BIT_ERR_STS_EN_MASK |
+ XNANDPSU_INTR_STS_EN_ERR_INTR_STS_EN_MASK;
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, RegVal);
+ /* Program Page Size */
+ XNandPsu_SetPageSize(InstancePtr);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, Page, (u16)Col);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Set ECC */
+ if (InstancePtr->EccMode == XNANDPSU_HWECC) {
+ XNandPsu_SetEccSpareCmd(InstancePtr,
+ (ONFI_CMD_CHNG_RD_COL1 |
+ (ONFI_CMD_CHNG_RD_COL2 << (u8)8U)),
+ InstancePtr->Geometry.ColAddrCycles);
+ }
+
+ /* Set Read command in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_MASK);
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 1);
+
+#ifdef __rtems__
+ if (InstancePtr->DmaMode == XNANDPSU_MDMA) {
+ if (InstancePtr->Config.IsCacheCoherent == 0) {
+ Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount));
+ }
+ }
+#endif
+
+ /* Check ECC Errors */
+ if (InstancePtr->EccMode == XNANDPSU_HWECC) {
+ /* Hamming Multi Bit Errors */
+ if (((u32)XNandPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_INTR_STS_OFFSET) &
+ (u32)XNANDPSU_INTR_STS_MUL_BIT_ERR_STS_EN_MASK) != 0U) {
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_OFFSET,
+ XNANDPSU_INTR_STS_MUL_BIT_ERR_STS_EN_MASK);
+
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: ECC Hamming multi bit error\r\n",
+ __func__);
+#endif
+ InstancePtr->Ecc_Stat_PerPage_flips =
+ ((XNandPsu_ReadReg(
+ InstancePtr->Config.BaseAddress,
+ XNANDPSU_ECC_ERR_CNT_OFFSET) &
+ 0x1FF00U) >> 8U);
+ InstancePtr->Ecc_Stats_total_flips +=
+ InstancePtr->Ecc_Stat_PerPage_flips;
+ Status = XST_FAILURE;
+ }
+ /* Hamming Single Bit or BCH Errors */
+ if (((u32)XNandPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_INTR_STS_OFFSET) &
+ (u32)XNANDPSU_INTR_STS_ERR_INTR_STS_EN_MASK) != 0U) {
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_OFFSET,
+ XNANDPSU_INTR_STS_ERR_INTR_STS_EN_MASK);
+
+ if (InstancePtr->EccCfg.IsBCH == 1U) {
+ InstancePtr->Ecc_Stat_PerPage_flips =
+ ((XNandPsu_ReadReg(
+ InstancePtr->Config.BaseAddress,
+ XNANDPSU_ECC_ERR_CNT_OFFSET)&
+ 0x1FF00U) >> 8U);
+ InstancePtr->Ecc_Stats_total_flips +=
+ InstancePtr->Ecc_Stat_PerPage_flips;
+ Status = XST_SUCCESS;
+ }
+ }
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function reads spare bytes from flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Page is the page address value to read.
+* @param Buf is the data buffer to fill in.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+s32 XNandPsu_ReadSpareBytes(XNandPsu *InstancePtr, u32 Page, u8 *Buf)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(Page < InstancePtr->Geometry.NumPages);
+ Xil_AssertNonvoid(Buf != NULL);
+
+ u32 PktCount = 1U;
+ s32 Status = XST_FAILURE;
+ u32 RegVal;
+ u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles +
+ InstancePtr->Geometry.ColAddrCycles;
+ u32 Col = InstancePtr->Geometry.BytesPerPage;
+ u32 Target = Page/InstancePtr->Geometry.NumTargetPages;
+ u32 PktSize = InstancePtr->Geometry.SpareBytesPerPage;
+ u32 PageVar = Page;
+
+ PageVar %= InstancePtr->Geometry.NumTargetPages;
+
+ if (InstancePtr->DmaMode == XNANDPSU_MDMA) {
+ RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK;
+ if (InstancePtr->Config.IsCacheCoherent == 0) {
+ Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount));
+ }
+ XNandPsu_Update_DmaAddr(InstancePtr, Buf);
+ } else {
+ RegVal = XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK;
+ }
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, RegVal);
+ /* Program Command */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_RD1, ONFI_CMD_RD2, 0U,
+ 1U, (u8)AddrCycles);
+ /* Program Page Size */
+ XNandPsu_SetPageSize(InstancePtr);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, PageVar, (u16)Col);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Set Read command in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_MASK);
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 1);
+
+#ifdef __rtems__
+ if (InstancePtr->DmaMode == XNANDPSU_MDMA) {
+ if (InstancePtr->Config.IsCacheCoherent == 0) {
+ Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount));
+ }
+ }
+#endif
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI block erase command to the flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param Block is the block to erase.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+s32 XNandPsu_EraseBlock(XNandPsu *InstancePtr, u32 Target, u32 Block)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(Target < XNANDPSU_MAX_TARGETS);
+#ifdef __rtems__
+ Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumTargetBlocks);
+#else
+ Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks);
+#endif
+
+ s32 Status = XST_FAILURE;
+ u32 Page;
+ u32 ErasePage;
+ u32 EraseCol;
+ u32 AddrCycles = InstancePtr->Geometry.RowAddrCycles;
+
+ Page = Block * InstancePtr->Geometry.PagesPerBlock;
+ ErasePage = (Page >> 16U) & 0xFFFFU;
+ EraseCol = Page & 0xFFFFU;
+
+ /*
+ * Enable Transfer Complete Interrupt in Interrupt Status Enable
+ * Register
+ */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK);
+
+ /* Program Command */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_BLK_ERASE1,
+ ONFI_CMD_BLK_ERASE2, 0U , 0U, (u8)AddrCycles);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, ErasePage, (u16)EraseCol);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Set Block Erase in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_BLK_ERASE_MASK);
+ /* Poll for Transfer Complete event */
+ Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr);
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI Get Feature command to flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param Feature is the feature selector.
+* @param Buf is the buffer to fill feature value.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+s32 XNandPsu_GetFeature(XNandPsu *InstancePtr, u32 Target, u8 Feature,
+ u8 *Buf)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY)
+ Xil_AssertNonvoid(Buf != NULL);
+ Xil_AssertNonvoid(Target < XNANDPSU_MAX_TARGETS);
+
+ s32 Status;
+ u32 PktSize = 4;
+ u32 PktCount = 1;
+
+ if (InstancePtr->DataInterface == XNANDPSU_NVDDR) {
+ PktSize = 8U;
+ }
+
+ /*
+ * Enable Buffer Read Ready Interrupt in Interrupt Status
+ * Enable Register
+ */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK);
+ /* Program Command */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_GET_FEATURES,
+ ONFI_CMD_INVALID, 0U, 0U, 1U);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, 0x0U, Feature);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount);
+ /* Set Read Parameter Page in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_GET_FEATURES_MASK);
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 0);
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sends ONFI Set Feature command to flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param Feature is the feature selector.
+* @param Buf is the feature value to send.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+s32 XNandPsu_SetFeature(XNandPsu *InstancePtr, u32 Target, u8 Feature,
+ u8 *Buf)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY)
+ Xil_AssertNonvoid(Buf != NULL);
+ Xil_AssertNonvoid(Target < XNANDPSU_MAX_TARGETS);
+
+ s32 Status;
+ u32 PktSize = 4U;
+ u32 PktCount = 1U;
+
+ if (InstancePtr->DataInterface == XNANDPSU_NVDDR) {
+ PktSize = 8U;
+ }
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, 0U);
+
+ /*
+ * Enable Buffer Write Ready Interrupt in Interrupt Status
+ * Enable Register
+ */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK);
+
+ /* Program Command */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_SET_FEATURES,
+ ONFI_CMD_INVALID, 0U , 0U, 1U);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, 0x0U, Feature);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount);
+ /* Set Read Parameter Page in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_SET_FEATURES_MASK);
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 1, 0);
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function changes clock frequency of flash controller.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param ClockFreq is the clock frequency to change.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_ChangeClockFreq(XNandPsu *InstancePtr, u32 ClockFreq)
+{
+ (void) InstancePtr;
+ (void) ClockFreq;
+
+ /* Not implemented */
+}
+/*****************************************************************************/
+/**
+*
+* This function changes the data interface and timing mode.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param NewIntf is the new data interface.
+* @param NewMode is the new timing mode.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+s32 XNandPsu_ChangeTimingMode(XNandPsu *InstancePtr,
+ XNandPsu_DataInterface NewIntf,
+ XNandPsu_TimingMode NewMode)
+{
+ /* Assert the input arguments. */
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ s32 Status = XST_SUCCESS;
+ u32 Target;
+ u32 RegVal;
+ u8 Buf[4] = {0U};
+ u32 *Feature = (u32 *)(void *)&Buf[0];
+ u32 SetFeature = 0U;
+ u32 NewModeVar = (u32)NewMode;
+
+ /* Check for valid input arguments */
+ if(((NewIntf != XNANDPSU_SDR) && (NewIntf != XNANDPSU_NVDDR)) ||
+ (NewModeVar > 5U)){
+ Status = XST_FAILURE;
+ goto Out;
+ }
+
+ if(NewIntf == XNANDPSU_NVDDR){
+ NewModeVar = NewModeVar | (u32)0x10;
+ }
+ /* Get current data interface type and timing mode */
+ XNandPsu_DataInterface CurIntf = InstancePtr->DataInterface;
+ XNandPsu_TimingMode CurMode = InstancePtr->TimingMode;
+
+ /* Check if the flash is in same mode */
+ if ((CurIntf == NewIntf) && (CurMode == NewModeVar)) {
+ Status = XST_SUCCESS;
+ goto Out;
+ }
+
+ if ((CurIntf == XNANDPSU_NVDDR) && (NewIntf == XNANDPSU_SDR)) {
+
+ NewModeVar = XNANDPSU_SDR0;
+
+ /* Change the clock frequency */
+ XNandPsu_ChangeClockFreq(InstancePtr, XNANDPSU_SDR_CLK);
+
+ /* Update Data Interface Register */
+ RegVal = ((NewModeVar % 6U) << ((NewIntf == XNANDPSU_NVDDR) ? 3U : 0U)) |
+ ((u32)NewIntf << XNANDPSU_DATA_INTF_DATA_INTF_SHIFT);
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_DATA_INTF_OFFSET, RegVal);
+
+ for (Target = 0U; Target < InstancePtr->Geometry.NumTargets;
+ Target++) {
+ Status = XNandPsu_OnfiReset(InstancePtr, Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ }
+
+ /* Set Feature */
+ for (Target = 0U; Target < InstancePtr->Geometry.NumTargets;
+ Target++) {
+ Status = XNandPsu_SetFeature(InstancePtr, Target, 0x01U,
+ (u8 *)(void *)&NewModeVar);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ }
+
+ InstancePtr->DataInterface = NewIntf;
+ InstancePtr->TimingMode = NewModeVar;
+
+ for (Target = 0U; Target < InstancePtr->Geometry.NumTargets;
+ Target++) {
+ Status = XNandPsu_GetFeature(InstancePtr, Target, 0x01U,
+ &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Check if set_feature was successful */
+ if (*Feature != NewModeVar) {
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ }
+
+ goto Out;
+ }
+
+ SetFeature = NewModeVar;
+ if((CurIntf == XNANDPSU_NVDDR) && (NewIntf == XNANDPSU_NVDDR)){
+ SetFeature |= SetFeature << 8U;
+ }
+ /* Set Feature */
+ for (Target = 0U; Target < InstancePtr->Geometry.NumTargets;
+ Target++) {
+ Status = XNandPsu_SetFeature(InstancePtr, Target, 0x01U,
+ (u8 *)(void *)&SetFeature);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ }
+
+ InstancePtr->DataInterface = NewIntf;
+ InstancePtr->TimingMode = NewModeVar;
+ /* Update Data Interface Register */
+ RegVal = ((NewMode % 6U) << ((NewIntf == XNANDPSU_NVDDR) ? 3U : 0U)) |
+ ((u32)NewIntf << XNANDPSU_DATA_INTF_DATA_INTF_SHIFT);
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_DATA_INTF_OFFSET, RegVal);
+
+ /* Get Feature */
+ for (Target = 0U; Target < InstancePtr->Geometry.NumTargets;
+ Target++) {
+ Status = XNandPsu_GetFeature(InstancePtr, Target, 0x01U,
+ &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ /* Check if set_feature was successful */
+ if (*Feature != NewModeVar) {
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ }
+
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function issues change read column and reads the data into buffer
+* specified by user.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param Col is the coulmn address.
+* @param PktSize is the number of bytes to read.
+* @param PktCount is the number of transactions to read.
+* @param Buf is the data buffer to fill in.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_ChangeReadColumn(XNandPsu *InstancePtr, u32 Target,
+ u32 Col, u32 PktSize, u32 PktCount,
+ u8 *Buf)
+{
+ s32 Status = XST_FAILURE;
+ u32 RegVal;
+ u32 AddrCycles = InstancePtr->Geometry.ColAddrCycles;
+
+ if (InstancePtr->DmaMode == XNANDPSU_MDMA) {
+ RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK |
+ XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK;
+ Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount));
+ XNandPsu_Update_DmaAddr(InstancePtr, Buf);
+ } else {
+ RegVal = XNANDPSU_INTR_STS_EN_BUFF_RD_RDY_STS_EN_MASK;
+ }
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, RegVal);
+ /* Program Command */
+ XNandPsu_Prepare_Cmd(InstancePtr, ONFI_CMD_CHNG_RD_COL1,
+ ONFI_CMD_CHNG_RD_COL2, 0U , 1U, (u8)AddrCycles);
+ /* Program Page Size */
+ XNandPsu_SetPageSize(InstancePtr);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, 0U, (u16)Col);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Set Read command in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_RD_MASK);
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 1);
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function issues change read column and reads the data into buffer
+* specified by user.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chip select value.
+* @param Col is the coulmn address.
+* @param PktSize is the number of bytes to read.
+* @param PktCount is the number of transactions to read.
+* @param Buf is the data buffer to fill in.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_ChangeWriteColumn(XNandPsu *InstancePtr, u32 Target,
+ u32 Col, u32 PktSize, u32 PktCount,
+ u8 *Buf)
+{
+ s32 Status = XST_FAILURE;
+ OnfiCmdFormat OnfiCommand;
+ u32 RegVal;
+ u32 AddrCycles = InstancePtr->Geometry.ColAddrCycles;
+
+ if (PktCount == 0U) {
+ return XST_SUCCESS;
+ }
+
+ if (InstancePtr->DmaMode == XNANDPSU_MDMA) {
+ RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK |
+ XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK;
+#ifdef __rtems__
+ if (InstancePtr->Config.IsCacheCoherent == 0) {
+ Xil_DCacheFlushRange((INTPTR)(void *)Buf, (PktSize * PktCount));
+ }
+#endif
+ XNandPsu_Update_DmaAddr(InstancePtr, Buf);
+ } else {
+ RegVal = XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK;
+ }
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, RegVal);
+ /* Change write column hack */
+ OnfiCommand.Command1 = 0x85U;
+ OnfiCommand.Command2 = 0x10U;
+ XNandPsu_Prepare_Cmd(InstancePtr, OnfiCommand.Command1,
+ OnfiCommand.Command2, 0U , 0U, (u8)AddrCycles);
+
+ /* Program Page Size */
+ XNandPsu_SetPageSize(InstancePtr);
+ /* Program Column, Page, Block address */
+ XNandPsu_SetPageColAddr(InstancePtr, 0U, (u16)Col);
+ /* Program Packet Size and Packet Count */
+ XNandPsu_SetPktSzCnt(InstancePtr, PktSize, PktCount);
+ /* Program Memory Address Register2 for chip select */
+ XNandPsu_SelectChip(InstancePtr, Target);
+ /* Set Page Program in Program Register */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_PROG_OFFSET,XNANDPSU_PROG_CHNG_ROW_ADDR_END_MASK);
+
+ Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 1, 0);
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function initializes extended parameter page ECC information.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param ExtPrm is the Extended parameter page buffer.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_InitExtEcc(XNandPsu *InstancePtr, OnfiExtPrmPage *ExtPrm)
+{
+ s32 Status = XST_FAILURE;
+ u32 Offset = 0U;
+ u32 Found = 0U;
+ OnfiExtEccBlock *EccBlock;
+
+ if (ExtPrm->Section0Type != 0x2U) {
+ Offset += (u32)ExtPrm->Section0Len;
+ if (ExtPrm->Section1Type != 0x2U) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Extended ECC section not found\r\n",__func__);
+#endif
+ Status = XST_FAILURE;
+ } else {
+ Found = 1U;
+ }
+ } else {
+ Found = 1U;
+ }
+
+ if (Found != 0U) {
+ EccBlock = (OnfiExtEccBlock *)&ExtPrm->SectionData[Offset];
+ Xil_AssertNonvoid(EccBlock != NULL);
+ if (EccBlock->CodeWordSize == 0U) {
+ Status = XST_FAILURE;
+ } else {
+ InstancePtr->Geometry.NumBitsECC =
+ EccBlock->NumEccBits;
+ InstancePtr->Geometry.EccCodeWordSize =
+ (u32)EccBlock->CodeWordSize;
+ Status = XST_SUCCESS;
+ }
+ }
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function prepares command to be written into command register.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Cmd1 is the first Onfi Command.
+* @param Cmd2 is the second Onfi Command.
+* @param EccState is the flag to set Ecc State.
+* @param DmaMode is the flag to set DMA mode.
+* @param AddrCycles is the number of Address Cycles.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+void XNandPsu_Prepare_Cmd(XNandPsu *InstancePtr, u8 Cmd1, u8 Cmd2, u8 EccState,
+ u8 DmaMode, u8 AddrCycles)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+
+ u32 RegValue = 0U;
+
+ RegValue = (u32)Cmd1 | (((u32)Cmd2 << (u32)XNANDPSU_CMD_CMD2_SHIFT) &
+ (u32)XNANDPSU_CMD_CMD2_MASK);
+
+ if ((EccState != 0U) && (InstancePtr->EccMode == XNANDPSU_HWECC)) {
+ RegValue |= 1U << XNANDPSU_CMD_ECC_ON_SHIFT;
+ }
+
+ if ((DmaMode != 0U) && (InstancePtr->DmaMode == XNANDPSU_MDMA)) {
+ RegValue |= XNANDPSU_MDMA << XNANDPSU_CMD_DMA_EN_SHIFT;
+ }
+
+ if (AddrCycles != 0U) {
+ RegValue |= (u32)AddrCycles <<
+ (u32)XNANDPSU_CMD_ADDR_CYCLES_SHIFT;
+ }
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_CMD_OFFSET, RegValue);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function Read/Writes data from the nand controller.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Buf is the data buffer.
+* @param PktCount is the number packet chunks.
+* @param PktSize is the size of the packet.
+* @param Operation is 1 for write and 0 for read.
+* @param DmaMode is 1 for Dma and 0 for PIO.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_Data_ReadWrite(XNandPsu *InstancePtr, u8* Buf, u32 PktCount,
+ u32 PktSize, u32 Operation, u8 DmaMode)
+{
+ u32 BufRwCnt = 0U;
+ s32 Status = XST_FAILURE;
+ u32 Event = XNANDPSU_INTR_STS_BUFF_RD_RDY_STS_EN_MASK;
+
+ if ((DmaMode != 0U) && (InstancePtr->DmaMode == XNANDPSU_MDMA))
+ goto DmaDone;
+
+ if (Operation)
+ Event = XNANDPSU_INTR_STS_BUFF_WR_RDY_STS_EN_MASK;
+
+ while (BufRwCnt < PktCount) {
+ /* Poll for Buffer Write Ready event */
+ Status = XNandPsu_PollRegTimeout(InstancePtr,
+ XNANDPSU_INTR_STS_OFFSET, Event,
+ XNANDPSU_INTR_POLL_TIMEOUT);
+ if (Status != XST_SUCCESS) {
+ xil_printf("%s: Poll for buf write ready timeout\r\n",
+ __func__);
+ goto Out;
+ }
+
+ /* Increment Buffer Write Interrupt Count */
+ BufRwCnt++;
+
+ if (BufRwCnt == PktCount)
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET,
+ XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK);
+
+ else
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, 0U);
+ /*
+ * Clear Buffer Write Ready Interrupt in Interrupt Status
+ * Register
+ */
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_OFFSET, Event);
+ /* Write Packet Data to Data Port Register */
+ if (Operation)
+ XNandPsu_Fifo_Write(InstancePtr, Buf, PktSize);
+ else
+ XNandPsu_Fifo_Read(InstancePtr, Buf, PktSize);
+
+ Buf += PktSize;
+
+ if (BufRwCnt < PktCount)
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, Event);
+ else
+ break;
+ }
+
+DmaDone:
+ Status = XNandPsu_WaitFor_Transfer_Complete(InstancePtr);
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function writes data to the fifo.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Buf is the buffer pointer.
+* @param Size of the Buffer.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_Fifo_Write(XNandPsu *InstancePtr, u8* Buffer, u32 Size)
+{
+ u32 *BufPtr = (u32 *)(void *)Buffer;
+ u32 Index;
+
+ for (Index = 0U; Index < Size/4U; Index++)
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_BUF_DATA_PORT_OFFSET,
+ BufPtr[Index]);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function reads data from the fifo.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Buf is the buffer pointer.
+* @param Size of the Buffer.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_Fifo_Read(XNandPsu *InstancePtr, u8* Buf, u32 Size)
+{
+ u32 *BufPtr = (u32 *)(void *)Buf;
+ u32 Index;
+
+ for (Index = 0U; Index < Size/4U; Index++)
+ BufPtr[Index] = XNandPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_BUF_DATA_PORT_OFFSET);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function configures the given dma address to the controller.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Buf is the buffer pointer.
+*
+* @return
+* None
+*
+* @note None
+*
+******************************************************************************/
+static void XNandPsu_Update_DmaAddr(XNandPsu *InstancePtr, u8* Buf)
+{
+#if defined(__aarch64__) || defined(__arch64__)
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_DMA_SYS_ADDR1_OFFSET,
+ (u32) (((INTPTR)Buf >> 32U) & 0xFFFFFFFFU));
+#endif
+ XNandPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XNANDPSU_DMA_SYS_ADDR0_OFFSET,
+ (u32) ((INTPTR)(void *)Buf & 0xFFFFFFFFU));
+
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits for the device ready stataus.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Target is the chipselect value.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note None
+*
+******************************************************************************/
+static s32 XNandPsu_Device_Ready(XNandPsu *InstancePtr, u32 Target)
+{
+ s32 Status = XST_SUCCESS;
+ u16 OnfiStatus = 0U;
+
+ do {
+ Status = XNandPsu_OnfiReadStatus(InstancePtr, Target,
+ &OnfiStatus);
+ if (Status != XST_SUCCESS)
+ goto Out;
+ if ((OnfiStatus & (1U << 6U)) != 0U) {
+ if ((OnfiStatus & (1U << 0U)) != 0U) {
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ }
+ } while (((OnfiStatus >> 6U) & 0x1U) == 0U);
+
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits for the transfer complete event.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if failed.
+*
+* @note Expects that transfer complete event was set before calling
+* this function.
+*
+******************************************************************************/
+static s32 XNandPsu_WaitFor_Transfer_Complete(XNandPsu *InstancePtr)
+{
+s32 Status = XST_FAILURE;
+
+ /* Poll for Transfer Complete event */
+ Status = XNandPsu_PollRegTimeout(
+ InstancePtr,
+ XNANDPSU_INTR_STS_OFFSET,
+ XNANDPSU_INTR_STS_TRANS_COMP_STS_EN_MASK,
+ XNANDPSU_INTR_POLL_TIMEOUT);
+ if (Status != XST_SUCCESS) {
+ xil_printf("%s: Poll for xfer complete timeout\r\n", __func__);
+ goto Out;
+ }
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_EN_OFFSET, 0U);
+
+ XNandPsu_WriteReg((InstancePtr)->Config.BaseAddress,
+ XNANDPSU_INTR_STS_OFFSET,
+ XNANDPSU_INTR_STS_TRANS_COMP_STS_EN_MASK);
+#if defined (XCLOCKING)
+ Xil_ClockDisable(InstancePtr->Config.RefClk);
+#endif
+Out:
+ return Status;
+}
+/** @} */
diff --git a/bsps/shared/dev/nand/xnandpsu_bbm.c b/bsps/shared/dev/nand/xnandpsu_bbm.c
new file mode 100644
index 0000000000..40cf798965
--- /dev/null
+++ b/bsps/shared/dev/nand/xnandpsu_bbm.c
@@ -0,0 +1,1001 @@
+/******************************************************************************
+* Copyright (C) 2015 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xnandpsu_bbm.c
+* @addtogroup Overview
+* @{
+*
+* This file implements the Bad Block Management (BBM) functionality.
+* See xnandpsu_bbm.h for more details.
+*
+* @note None
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- ---------- -----------------------------------------------
+* 1.0 nm 05/06/2014 First release
+* 2.0 sb 01/12/2015 Added support for writing BBT signature and version
+* in page section by enabling XNANDPSU_BBT_NO_OOB.
+* Modified Bbt Signature and Version Offset value for
+* Oob and No-Oob region.
+* 1.1 nsk 11/07/16 Change memcpy to Xil_MemCpy to handle word aligned
+* data access.
+* 1.4 nsk 04/10/18 Added ICCARM compiler support.
+* 1.10 akm 01/05/22 Remove assert checks form static and internal APIs.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+#include <string.h> /**< For Xil_MemCpy and memset */
+#include "xil_types.h"
+#include "xnandpsu.h"
+#include "xnandpsu_bbm.h"
+#include "xil_mem.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+static s32 XNandPsu_ReadBbt(XNandPsu *InstancePtr, u32 Target);
+
+static s32 XNandPsu_SearchBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc,
+ u32 Target);
+
+static void XNandPsu_CreateBbt(XNandPsu *InstancePtr, u32 Target);
+
+static void XNandPsu_ConvertBbt(XNandPsu *InstancePtr, u8 *Buf, u32 Target);
+
+static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc,
+ XNandPsu_BbtDesc *MirrorDesc, u32 Target);
+
+static s32 XNandPsu_MarkBbt(XNandPsu* InstancePtr, XNandPsu_BbtDesc *Desc,
+ u32 Target);
+
+#ifndef __rtems__
+static s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target);
+#endif
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+/**
+* This function initializes the Bad Block Table(BBT) descriptors with a
+* predefined pattern for searching Bad Block Table(BBT) in flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* - NONE
+*
+******************************************************************************/
+void XNandPsu_InitBbtDesc(XNandPsu *InstancePtr)
+{
+ u32 Index;
+
+ /* Initialize primary Bad Block Table(BBT) */
+ for (Index = 0U; Index < XNANDPSU_MAX_TARGETS; Index++) {
+ InstancePtr->BbtDesc.PageOffset[Index] =
+ XNANDPSU_BBT_DESC_PAGE_OFFSET;
+ }
+ if (InstancePtr->EccMode == XNANDPSU_ONDIE) {
+ InstancePtr->BbtDesc.SigOffset = XNANDPSU_ONDIE_SIG_OFFSET;
+ InstancePtr->BbtDesc.VerOffset = XNANDPSU_ONDIE_VER_OFFSET;
+ } else {
+ InstancePtr->BbtDesc.SigOffset = XNANDPSU_BBT_DESC_SIG_OFFSET;
+ InstancePtr->BbtDesc.VerOffset = XNANDPSU_BBT_DESC_VER_OFFSET;
+ }
+ InstancePtr->BbtDesc.SigLength = XNANDPSU_BBT_DESC_SIG_LEN;
+ InstancePtr->BbtDesc.MaxBlocks = XNANDPSU_BBT_DESC_MAX_BLOCKS;
+ (void)strcpy(&InstancePtr->BbtDesc.Signature[0], "Bbt0");
+ for (Index = 0U; Index < XNANDPSU_MAX_TARGETS; Index++) {
+ InstancePtr->BbtDesc.Version[Index] = 0U;
+ }
+ InstancePtr->BbtDesc.Valid = 0U;
+
+ /* Assuming that the flash device will have at least 4 blocks. */
+ if (InstancePtr->Geometry.NumTargetBlocks <= InstancePtr->
+ BbtDesc.MaxBlocks){
+ InstancePtr->BbtDesc.MaxBlocks = 4U;
+ }
+
+ /* Initialize mirror Bad Block Table(BBT) */
+ for (Index = 0U; Index < XNANDPSU_MAX_TARGETS; Index++) {
+ InstancePtr->BbtMirrorDesc.PageOffset[Index] =
+ XNANDPSU_BBT_DESC_PAGE_OFFSET;
+ }
+ if (InstancePtr->EccMode == XNANDPSU_ONDIE) {
+ InstancePtr->BbtMirrorDesc.SigOffset =
+ XNANDPSU_ONDIE_SIG_OFFSET;
+ InstancePtr->BbtMirrorDesc.VerOffset =
+ XNANDPSU_ONDIE_VER_OFFSET;
+ } else {
+ InstancePtr->BbtMirrorDesc.SigOffset =
+ XNANDPSU_BBT_DESC_SIG_OFFSET;
+ InstancePtr->BbtMirrorDesc.VerOffset =
+ XNANDPSU_BBT_DESC_VER_OFFSET;
+ }
+ InstancePtr->BbtMirrorDesc.SigLength = XNANDPSU_BBT_DESC_SIG_LEN;
+ InstancePtr->BbtMirrorDesc.MaxBlocks = XNANDPSU_BBT_DESC_MAX_BLOCKS;
+ (void)strcpy(&InstancePtr->BbtMirrorDesc.Signature[0], "1tbB");
+ for (Index = 0U; Index < XNANDPSU_MAX_TARGETS; Index++) {
+ InstancePtr->BbtMirrorDesc.Version[Index] = 0U;
+ }
+ InstancePtr->BbtMirrorDesc.Valid = 0U;
+
+ /* Assuming that the flash device will have at least 4 blocks. */
+ if (InstancePtr->Geometry.NumTargetBlocks <= InstancePtr->
+ BbtMirrorDesc.MaxBlocks){
+ InstancePtr->BbtMirrorDesc.MaxBlocks = 4U;
+ }
+
+ /* Initialize Bad block search pattern structure */
+ if (InstancePtr->Geometry.BytesPerPage > 512U) {
+ /* For flash page size > 512 bytes */
+ InstancePtr->BbPattern.Options = XNANDPSU_BBT_SCAN_2ND_PAGE;
+ InstancePtr->BbPattern.Offset =
+ XNANDPSU_BB_PTRN_OFF_LARGE_PAGE;
+ InstancePtr->BbPattern.Length =
+ XNANDPSU_BB_PTRN_LEN_LARGE_PAGE;
+ } else {
+ InstancePtr->BbPattern.Options = XNANDPSU_BBT_SCAN_2ND_PAGE;
+ InstancePtr->BbPattern.Offset =
+ XNANDPSU_BB_PTRN_OFF_SML_PAGE;
+ InstancePtr->BbPattern.Length =
+ XNANDPSU_BB_PTRN_LEN_SML_PAGE;
+ }
+ for(Index = 0U; Index < XNANDPSU_BB_PTRN_LEN_LARGE_PAGE; Index++) {
+ InstancePtr->BbPattern.Pattern[Index] = XNANDPSU_BB_PATTERN;
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function scans the NAND flash for factory marked bad blocks and creates
+* a RAM based Bad Block Table(BBT).
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* - NONE
+*
+******************************************************************************/
+static void XNandPsu_CreateBbt(XNandPsu *InstancePtr, u32 Target)
+{
+ u32 BlockIndex;
+ u32 PageIndex;
+ u32 Length;
+ u32 BlockOffset;
+ u8 BlockShift;
+ u32 NumPages;
+ u32 Page;
+#ifdef __ICCARM__
+#pragma pack(push, 1)
+ u8 Buf[XNANDPSU_MAX_SPARE_SIZE] = {0U};
+#pragma pack(pop)
+#else
+ u8 Buf[XNANDPSU_MAX_SPARE_SIZE] __attribute__ ((aligned(64))) = {0U};
+#endif
+ u32 StartBlock = Target * InstancePtr->Geometry.NumTargetBlocks;
+ u32 NumBlocks = InstancePtr->Geometry.NumTargetBlocks;
+ s32 Status;
+
+ /* Number of pages to search for bad block pattern */
+ if ((InstancePtr->BbPattern.Options & XNANDPSU_BBT_SCAN_2ND_PAGE) != 0U)
+ {
+ NumPages = 2U;
+ } else {
+ NumPages = 1U;
+ }
+ /* Scan all the blocks for factory marked bad blocks */
+ for(BlockIndex = StartBlock; BlockIndex < (StartBlock + NumBlocks);
+ BlockIndex++) {
+ /* Block offset in Bad Block Table(BBT) entry */
+ BlockOffset = BlockIndex >> XNANDPSU_BBT_BLOCK_SHIFT;
+ /* Block shift value in the byte */
+ BlockShift = XNandPsu_BbtBlockShift(BlockIndex);
+ Page = BlockIndex * InstancePtr->Geometry.PagesPerBlock;
+ /* Search for the bad block pattern */
+ for(PageIndex = 0U; PageIndex < NumPages; PageIndex++) {
+ Status = XNandPsu_ReadSpareBytes(InstancePtr,
+ (Page + PageIndex), &Buf[0]);
+
+ if (Status != XST_SUCCESS) {
+ /* Marking as bad block */
+ InstancePtr->Bbt[BlockOffset] |=
+ (u8)(XNANDPSU_BLOCK_FACTORY_BAD <<
+ BlockShift);
+ break;
+ }
+ /*
+ * Read the spare bytes to check for bad block
+ * pattern
+ */
+ for(Length = 0U; Length <
+ InstancePtr->BbPattern.Length; Length++) {
+ if (Buf[InstancePtr->BbPattern.Offset + Length]
+ !=
+ InstancePtr->BbPattern.Pattern[Length])
+ {
+ /* Bad block found */
+ InstancePtr->Bbt[BlockOffset] |=
+ (u8)
+ (XNANDPSU_BLOCK_FACTORY_BAD <<
+ BlockShift);
+ break;
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/**
+* This function reads the Bad Block Table(BBT) if present in flash. If not it
+* scans the flash for detecting factory marked bad blocks and creates a bad
+* block table and write the Bad Block Table(BBT) into the flash.
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+s32 XNandPsu_ScanBbt(XNandPsu *InstancePtr)
+{
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY)
+
+ s32 Status;
+ u32 Index;
+ u32 BbtLen;
+
+ /* Zero the RAM based Bad Block Table(BBT) entries */
+ BbtLen = InstancePtr->Geometry.NumBlocks >>
+ XNANDPSU_BBT_BLOCK_SHIFT;
+ (void)memset(&InstancePtr->Bbt[0], 0, BbtLen);
+
+ for (Index = 0U; Index < InstancePtr->Geometry.NumTargets; Index++) {
+
+ if (XNandPsu_ReadBbt(InstancePtr, Index) != XST_SUCCESS) {
+ /* Create memory based Bad Block Table(BBT) */
+ XNandPsu_CreateBbt(InstancePtr, Index);
+ /* Write the Bad Block Table(BBT) to the flash */
+ Status = XNandPsu_WriteBbt(InstancePtr,
+ &InstancePtr->BbtDesc,
+ &InstancePtr->BbtMirrorDesc, Index);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Write the Mirror Bad Block Table(BBT) to the flash */
+ Status = XNandPsu_WriteBbt(InstancePtr,
+ &InstancePtr->BbtMirrorDesc,
+ &InstancePtr->BbtDesc, Index);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /*
+ * Mark the blocks containing Bad Block Table
+ * (BBT) as Reserved
+ */
+ Status = XNandPsu_MarkBbt(InstancePtr,
+ &InstancePtr->BbtDesc,
+ Index);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ Status = XNandPsu_MarkBbt(InstancePtr,
+ &InstancePtr->BbtMirrorDesc,
+ Index);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ }
+ }
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function converts the Bad Block Table(BBT) read from the flash to the
+* RAM based Bad Block Table(BBT).
+*
+* @param InstancePtr is a pointer to the XNandPsu instance.
+* @param Buf is the buffer which contains BBT read from flash.
+*
+* @return
+* - NONE.
+*
+******************************************************************************/
+static void XNandPsu_ConvertBbt(XNandPsu *InstancePtr, u8 *Buf, u32 Target)
+{
+#ifndef __rtems__
+ u32 BlockOffset;
+ u8 BlockShift;
+ u32 Data;
+ u8 BlockType;
+ u32 BlockIndex;
+#endif
+ u32 BbtLen = InstancePtr->Geometry.NumTargetBlocks >>
+ XNANDPSU_BBT_BLOCK_SHIFT;
+#ifdef __rtems__
+ u32 BbtOffset = Target * InstancePtr->Geometry.NumTargetBlocks / XNANDPSU_BBT_ENTRY_NUM_BLOCKS;
+
+ for(u32 BbtIndex = 0; BbtIndex < BbtLen; BbtIndex++) {
+ /* Invert the byte to convert from in-flash BBT to in-memory BBT */
+ InstancePtr->Bbt[BbtIndex + BbtOffset] = ~Buf[BbtIndex];
+ }
+#else
+ u32 StartBlock = Target * InstancePtr->Geometry.NumTargetBlocks;
+
+ for(BlockOffset = StartBlock; BlockOffset < (StartBlock + BbtLen);
+ BlockOffset++) {
+ Data = *(Buf + BlockOffset);
+ /* Clear the RAM based Bad Block Table(BBT) contents */
+ InstancePtr->Bbt[BlockOffset] = 0x0U;
+ /* Loop through the every 4 blocks in the bitmap */
+ for(BlockIndex = 0U; BlockIndex < XNANDPSU_BBT_ENTRY_NUM_BLOCKS;
+ BlockIndex++) {
+ BlockShift = XNandPsu_BbtBlockShift(BlockIndex);
+ BlockType = (u8) ((Data >> BlockShift) &
+ XNANDPSU_BLOCK_TYPE_MASK);
+ switch(BlockType) {
+ case XNANDPSU_FLASH_BLOCK_FAC_BAD:
+ /* Factory bad block */
+ InstancePtr->Bbt[BlockOffset] |=
+ (u8)
+ (XNANDPSU_BLOCK_FACTORY_BAD <<
+ BlockShift);
+ break;
+ case XNANDPSU_FLASH_BLOCK_RESERVED:
+ /* Reserved block */
+ InstancePtr->Bbt[BlockOffset] |=
+ (u8)
+ (XNANDPSU_BLOCK_RESERVED <<
+ BlockShift);
+ break;
+ case XNANDPSU_FLASH_BLOCK_BAD:
+ /* Bad block due to wear */
+ InstancePtr->Bbt[BlockOffset] |=
+ (u8)(XNANDPSU_BLOCK_BAD <<
+ BlockShift);
+ break;
+ default:
+ /* Good block */
+ /* The BBT entry already defaults to
+ * zero */
+ break;
+ }
+ }
+ }
+#endif
+}
+
+/*****************************************************************************/
+/**
+* This function searches the Bad Bloock Table(BBT) in flash and loads into the
+* memory based Bad Block Table(BBT).
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+static s32 XNandPsu_ReadBbt(XNandPsu *InstancePtr, u32 Target)
+{
+ u64 Offset;
+#ifdef __ICCARM__
+#pragma pack(push, 1)
+ u8 Buf[XNANDPSU_BBT_BUF_LENGTH]= {0U};
+#pragma pack(pop)
+#else
+ u8 Buf[XNANDPSU_BBT_BUF_LENGTH] __attribute__ ((aligned(64))) = {0U};
+#endif
+ s32 Status1;
+ s32 Status2;
+ s32 Status;
+ u32 BufLen;
+
+ XNandPsu_BbtDesc *Desc = &InstancePtr->BbtDesc;
+ XNandPsu_BbtDesc *MirrorDesc = &InstancePtr->BbtMirrorDesc;
+#ifdef __rtems__
+ BufLen = InstancePtr->Geometry.NumTargetBlocks >>
+#else
+ BufLen = InstancePtr->Geometry.NumBlocks >>
+#endif
+ XNANDPSU_BBT_BLOCK_SHIFT;
+ /* Search the Bad Block Table(BBT) in flash */
+ Status1 = XNandPsu_SearchBbt(InstancePtr, Desc, Target);
+ Status2 = XNandPsu_SearchBbt(InstancePtr, MirrorDesc, Target);
+ if ((Status1 != XST_SUCCESS) && (Status2 != XST_SUCCESS)) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Bad block table not found\r\n",__func__);
+#endif
+ Status = XST_FAILURE;
+ goto Out;
+ }
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Bad block table found\r\n",__func__);
+#endif
+ /* Bad Block Table found */
+ if ((Desc->Valid != 0U) && (MirrorDesc->Valid != 0U)) {
+ /* Valid BBT & Mirror BBT found */
+ if (Desc->Version[Target] > MirrorDesc->Version[Target]) {
+ Offset = (u64)Desc->PageOffset[Target] *
+ (u64)InstancePtr->Geometry.BytesPerPage;
+ Status = XNandPsu_Read(InstancePtr, Offset, BufLen,
+ &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Convert flash BBT to memory based BBT */
+ XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target);
+ MirrorDesc->Version[Target] = Desc->Version[Target];
+
+ /* Write the BBT to Mirror BBT location in flash */
+ Status = XNandPsu_WriteBbt(InstancePtr, MirrorDesc,
+ Desc, Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ } else if (Desc->Version[Target] <
+ MirrorDesc->Version[Target]) {
+ Offset = (u64)MirrorDesc->PageOffset[Target] *
+ (u64)InstancePtr->Geometry.BytesPerPage;
+ Status = XNandPsu_Read(InstancePtr, Offset, BufLen,
+ &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Convert flash BBT to memory based BBT */
+ XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target);
+ Desc->Version[Target] = MirrorDesc->Version[Target];
+
+ /* Write the Mirror BBT to BBT location in flash */
+ Status = XNandPsu_WriteBbt(InstancePtr, Desc,
+ MirrorDesc, Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ } else {
+ /* Both are up-to-date */
+ Offset = (u64)Desc->PageOffset[Target] *
+ (u64)InstancePtr->Geometry.BytesPerPage;
+ Status = XNandPsu_Read(InstancePtr, Offset, BufLen,
+ &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Convert flash BBT to memory based BBT */
+ XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target);
+ }
+ } else if (Desc->Valid != 0U) {
+ /* Valid Primary BBT found */
+ Offset = (u64)Desc->PageOffset[Target] *
+ (u64)InstancePtr->Geometry.BytesPerPage;
+ Status = XNandPsu_Read(InstancePtr, Offset, BufLen, &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Convert flash BBT to memory based BBT */
+ XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target);
+ MirrorDesc->Version[Target] = Desc->Version[Target];
+
+ /* Write the BBT to Mirror BBT location in flash */
+ Status = XNandPsu_WriteBbt(InstancePtr, MirrorDesc, Desc,
+ Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ } else {
+ /* Valid Mirror BBT found */
+ Offset = (u64)MirrorDesc->PageOffset[Target] *
+ (u64)InstancePtr->Geometry.BytesPerPage;
+ Status = XNandPsu_Read(InstancePtr, Offset, BufLen, &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Convert flash BBT to memory based BBT */
+ XNandPsu_ConvertBbt(InstancePtr, &Buf[0], Target);
+ Desc->Version[Target] = MirrorDesc->Version[Target];
+
+ /* Write the Mirror BBT to BBT location in flash */
+ Status = XNandPsu_WriteBbt(InstancePtr, Desc, MirrorDesc,
+ Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ }
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function searches the BBT in flash.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @param Desc is the BBT descriptor pattern to search.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+static s32 XNandPsu_SearchBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc,
+ u32 Target)
+{
+ u32 StartBlock;
+ u32 SigOffset;
+ u32 VerOffset;
+ u32 MaxBlocks;
+ u32 PageOff;
+ u32 SigLength;
+#ifdef __ICCARM__
+#pragma pack(push, 1)
+ u8 Buf[XNANDPSU_MAX_SPARE_SIZE] = {0U};
+#pragma pack(pop)
+#else
+ u8 Buf[XNANDPSU_MAX_SPARE_SIZE] __attribute__ ((aligned(64))) = {0U};
+#endif
+ u32 Block;
+ u32 Offset;
+ s32 Status;
+
+ StartBlock = ((Target + (u32)1) *
+ InstancePtr->Geometry.NumTargetBlocks) - (u32)1;
+ SigOffset = Desc->SigOffset;
+ VerOffset = Desc->VerOffset;
+ MaxBlocks = Desc->MaxBlocks;
+ SigLength = Desc->SigLength;
+#ifdef __rtems__
+ Desc->Valid = 0;
+#endif
+
+ /* Read the last 4 blocks for Bad Block Table(BBT) signature */
+ for(Block = 0U; Block < MaxBlocks; Block++) {
+ PageOff = (StartBlock - Block) *
+ InstancePtr->Geometry.PagesPerBlock;
+
+ Status = XNandPsu_ReadSpareBytes(InstancePtr, PageOff, &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ continue;
+ }
+ /* Check the Bad Block Table(BBT) signature */
+ for(Offset = 0U; Offset < SigLength; Offset++) {
+ if (Buf[Offset + SigOffset] !=
+ (u8)(Desc->Signature[Offset]))
+ {
+ break; /* Check the next blocks */
+ }
+ }
+ if (Offset >= SigLength) {
+ /* Bad Block Table(BBT) found */
+ Desc->PageOffset[Target] = PageOff;
+ Desc->Version[Target] = Buf[VerOffset];
+ Desc->Valid = 1U;
+
+ Status = XST_SUCCESS;
+ goto Out;
+ }
+ }
+ /* Bad Block Table(BBT) not found */
+ Status = XST_FAILURE;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function writes Bad Block Table(BBT) from RAM to flash.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @param Desc is the BBT descriptor to be written to flash.
+* @param MirrorDesc is the mirror BBT descriptor.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc,
+ XNandPsu_BbtDesc *MirrorDesc, u32 Target)
+{
+ u64 Offset;
+ u32 Block = {0U};
+ u32 EndBlock = ((Target + (u32)1) *
+ InstancePtr->Geometry.NumTargetBlocks) - (u32)1;
+#ifdef __ICCARM__
+#pragma pack(push, 1)
+ u8 Buf[XNANDPSU_BBT_BUF_LENGTH]= {0U};
+ u8 SpareBuf[XNANDPSU_MAX_SPARE_SIZE]= {0U};
+#pragma pack(pop)
+#else
+ u8 Buf[XNANDPSU_BBT_BUF_LENGTH] __attribute__ ((aligned(64))) = {0U};
+ u8 SpareBuf[XNANDPSU_MAX_SPARE_SIZE] __attribute__ ((aligned(64))) = {0U};
+#endif
+
+#ifndef __rtems__
+ u8 Mask[4] = {0x00U, 0x01U, 0x02U, 0x03U};
+ u8 Data;
+ u32 BlockOffset;
+ u8 BlockShift;
+ s32 Status;
+ u32 BlockIndex;
+ u32 Index;
+ u8 BlockType;
+ u32 BbtLen = InstancePtr->Geometry.NumBlocks >>
+#else
+ s32 Status;
+ u32 Index;
+ u32 BbtLen = InstancePtr->Geometry.NumTargetBlocks >>
+#endif
+ XNANDPSU_BBT_BLOCK_SHIFT;
+ /* Find a valid block to write the Bad Block Table(BBT) */
+ if ((!Desc->Valid) != 0U) {
+ for(Index = 0U; Index < Desc->MaxBlocks; Index++) {
+ Block = (EndBlock - Index);
+#ifdef __rtems__
+ if (XNandPsu_IsBlockBad(InstancePtr, Block) != XST_FAILURE) {
+ continue;
+ }
+#else
+ BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT;
+ BlockShift = XNandPsu_BbtBlockShift(Block);
+ BlockType = (InstancePtr->Bbt[BlockOffset] >>
+ BlockShift) & XNANDPSU_BLOCK_TYPE_MASK;
+ switch(BlockType)
+ {
+ case XNANDPSU_BLOCK_BAD:
+ case XNANDPSU_BLOCK_FACTORY_BAD:
+ continue;
+ default:
+ /* Good Block */
+ break;
+ }
+#endif
+ Desc->PageOffset[Target] = Block *
+ InstancePtr->Geometry.PagesPerBlock;
+ if (Desc->PageOffset[Target] !=
+ MirrorDesc->PageOffset[Target]) {
+ /* Free block found */
+ Desc->Valid = 1U;
+ break;
+ }
+ }
+
+
+ /* Block not found for writing Bad Block Table(BBT) */
+ if (Index >= Desc->MaxBlocks) {
+#ifdef XNANDPSU_DEBUG
+ xil_printf("%s: Blocks unavailable for writing BBT\r\n",
+ __func__);
+#endif
+ Status = XST_FAILURE;
+ goto Out;
+ }
+ } else {
+ Block = Desc->PageOffset[Target] /
+ InstancePtr->Geometry.PagesPerBlock;
+ }
+ /* Convert the memory based BBT to flash based table */
+ (void)memset(Buf, 0xff, BbtLen);
+
+#ifdef __rtems__
+ u32 BbtTargetOffset = BbtLen * Target;
+ /* Loop through the BBT entries */
+ for(u32 BbtIndex = 0U; BbtIndex < BbtLen; BbtIndex++) {
+ /* Invert byte to convert from in-memory BBT to in-flash BBT */
+ Buf[BbtIndex] = ~InstancePtr->Bbt[BbtIndex + BbtTargetOffset];
+ }
+#else
+ /* Loop through the number of blocks */
+ for(BlockOffset = 0U; BlockOffset < BbtLen; BlockOffset++) {
+ Data = InstancePtr->Bbt[BlockOffset];
+ /* Calculate the bit mask for 4 blocks at a time in loop */
+ for(BlockIndex = 0U; BlockIndex < XNANDPSU_BBT_ENTRY_NUM_BLOCKS;
+ BlockIndex++) {
+ BlockShift = XNandPsu_BbtBlockShift(BlockIndex);
+ Buf[BlockOffset] &= ~(Mask[Data &
+ XNANDPSU_BLOCK_TYPE_MASK] <<
+ BlockShift);
+ Data >>= XNANDPSU_BBT_BLOCK_SHIFT;
+ }
+ }
+#endif
+ /* Write the Bad Block Table(BBT) to flash */
+#ifdef __rtems__
+ Status = XNandPsu_EraseBlock(InstancePtr, Target,
+ Block % InstancePtr->Geometry.NumTargetBlocks);
+#else
+ Status = XNandPsu_EraseBlock(InstancePtr, 0U, Block);
+#endif
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ /* Write the BBT to page offset */
+ Offset = (u64)Desc->PageOffset[Target] *
+ (u64)InstancePtr->Geometry.BytesPerPage;
+ Status = XNandPsu_Write(InstancePtr, Offset, BbtLen, &Buf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ /* Write the signature and version in the spare data area */
+ (void)memset(SpareBuf, 0xff, InstancePtr->Geometry.SpareBytesPerPage);
+ Status = XNandPsu_ReadSpareBytes(InstancePtr, Desc->PageOffset[Target],
+ &SpareBuf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ (void)Xil_MemCpy(SpareBuf + Desc->SigOffset, &Desc->Signature[0],
+ Desc->SigLength);
+ (void)memcpy(SpareBuf + Desc->VerOffset, &Desc->Version[Target], 1U);
+
+ Status = XNandPsu_WriteSpareBytes(InstancePtr,
+ Desc->PageOffset[Target], &SpareBuf[0]);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function updates the primary and mirror Bad Block Table(BBT) in the
+* flash.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+#ifdef __rtems__
+s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target)
+#else
+static s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target)
+#endif
+{
+ s32 Status;
+ u8 Version;
+
+ /* Update the version number */
+ Version = InstancePtr->BbtDesc.Version[Target];
+ InstancePtr->BbtDesc.Version[Target] = (u8)(((u16)Version +
+ (u16)1) % (u16)256U);
+
+ Version = InstancePtr->BbtMirrorDesc.Version[Target];
+ InstancePtr->BbtMirrorDesc.Version[Target] = (u8)(((u16)Version +
+ (u16)1) % (u16)256);
+ /* Update the primary Bad Block Table(BBT) in flash */
+ Status = XNandPsu_WriteBbt(InstancePtr, &InstancePtr->BbtDesc,
+ &InstancePtr->BbtMirrorDesc,
+ Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ /* Update the mirrored Bad Block Table(BBT) in flash */
+ Status = XNandPsu_WriteBbt(InstancePtr, &InstancePtr->BbtMirrorDesc,
+ &InstancePtr->BbtDesc,
+ Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function marks the block containing Bad Block Table as reserved
+* and updates the BBT.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @param Desc is the BBT descriptor pointer.
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+static s32 XNandPsu_MarkBbt(XNandPsu* InstancePtr, XNandPsu_BbtDesc *Desc,
+ u32 Target)
+{
+ u32 BlockIndex;
+ u32 BlockOffset;
+ u8 BlockShift;
+ u8 OldVal;
+ u8 NewVal;
+ s32 Status;
+ u32 UpdateBbt = 0U;
+ u32 Index;
+
+ /* Mark the last four blocks as Reserved */
+ BlockIndex = ((Target + (u32)1) * InstancePtr->Geometry.NumTargetBlocks) -
+#ifdef __rtems__
+ Desc->MaxBlocks;
+#else
+ Desc->MaxBlocks - (u32)1;
+#endif
+
+ for(Index = 0U; Index < Desc->MaxBlocks; Index++) {
+
+ BlockOffset = BlockIndex >> XNANDPSU_BBT_BLOCK_SHIFT;
+ BlockShift = XNandPsu_BbtBlockShift(BlockIndex);
+ OldVal = InstancePtr->Bbt[BlockOffset];
+ NewVal = (u8) (OldVal | (XNANDPSU_BLOCK_RESERVED <<
+ BlockShift));
+ InstancePtr->Bbt[BlockOffset] = NewVal;
+
+ if (OldVal != NewVal) {
+ UpdateBbt = 1U;
+ }
+ BlockIndex++;
+ }
+
+ /* Update the BBT to flash */
+ if (UpdateBbt != 0U) {
+ Status = XNandPsu_UpdateBbt(InstancePtr, Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ }
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function checks whether a block is bad or not.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+*
+* @param Block is the block number.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+s32 XNandPsu_IsBlockBad(XNandPsu *InstancePtr, u32 Block)
+{
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY)
+ Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks);
+
+ u8 Data;
+ u8 BlockShift;
+ u8 BlockType;
+ u32 BlockOffset;
+ s32 Status;
+
+ BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT;
+ BlockShift = XNandPsu_BbtBlockShift(Block);
+ Data = InstancePtr->Bbt[BlockOffset]; /* Block information in BBT */
+ BlockType = (Data >> BlockShift) & XNANDPSU_BLOCK_TYPE_MASK;
+
+ if ((BlockType != XNANDPSU_BLOCK_GOOD) &&
+ (BlockType != XNANDPSU_BLOCK_RESERVED)) {
+ Status = XST_SUCCESS;
+ }
+ else {
+ Status = XST_FAILURE;
+ }
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+* This function marks a block as bad in the RAM based Bad Block Table(BBT). It
+* also updates the Bad Block Table(BBT) in the flash.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @param Block is the block number.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block)
+#ifdef __rtems__
+{
+ return XNandPsu_MarkBlock(InstancePtr, Block, XNANDPSU_BLOCK_BAD );
+}
+
+s32 XNandPsu_MarkBlock(XNandPsu *InstancePtr, u32 Block, u8 BlockMark)
+#endif
+{
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY)
+ Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks);
+
+#ifdef __rtems__
+ BlockMark &= XNANDPSU_BLOCK_TYPE_MASK;
+#endif
+
+ u8 Data;
+ u8 BlockShift;
+ u32 BlockOffset;
+ u8 OldVal;
+ u8 NewVal;
+ s32 Status;
+ u32 Target;
+
+ Target = Block / InstancePtr->Geometry.NumTargetBlocks;
+
+ BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT;
+ BlockShift = XNandPsu_BbtBlockShift(Block);
+ Data = InstancePtr->Bbt[BlockOffset]; /* Block information in BBT */
+
+ /* Mark the block as bad in the RAM based Bad Block Table */
+ OldVal = Data;
+ Data &= ~(XNANDPSU_BLOCK_TYPE_MASK << BlockShift);
+#ifdef __rtems__
+ Data |= (BlockMark << BlockShift);
+#else
+ Data |= (XNANDPSU_BLOCK_BAD << BlockShift);
+#endif
+ NewVal = Data;
+ InstancePtr->Bbt[BlockOffset] = Data;
+
+ /* Update the Bad Block Table(BBT) in flash */
+ if (OldVal != NewVal) {
+ Status = XNandPsu_UpdateBbt(InstancePtr, Target);
+ if (Status != XST_SUCCESS) {
+ goto Out;
+ }
+ }
+
+ Status = XST_SUCCESS;
+Out:
+ return Status;
+}
+
+#ifdef __rtems__
+bool XNandPsu_StageBlockMark(XNandPsu *InstancePtr, u32 Block, u8 BlockMark)
+{
+ u8 BlockShift;
+ u32 BlockOffset;
+ u8 OldVal;
+
+ BlockMark &= XNANDPSU_BLOCK_TYPE_MASK;
+
+ BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT;
+ BlockShift = XNandPsu_BbtBlockShift(Block);
+ OldVal = InstancePtr->Bbt[BlockOffset] >> BlockShift;
+ OldVal &= XNANDPSU_BLOCK_TYPE_MASK;
+ InstancePtr->Bbt[BlockOffset] &= ~(XNANDPSU_BLOCK_TYPE_MASK << BlockShift);
+ InstancePtr->Bbt[BlockOffset] |= (BlockMark << BlockShift);
+ return BlockMark != OldVal;
+}
+#endif
+
+/** @} */
diff --git a/bsps/shared/dev/nand/xnandpsu_onfi.c b/bsps/shared/dev/nand/xnandpsu_onfi.c
new file mode 100644
index 0000000000..0009722bfe
--- /dev/null
+++ b/bsps/shared/dev/nand/xnandpsu_onfi.c
@@ -0,0 +1,91 @@
+/******************************************************************************
+* Copyright (C) 2015 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xnandpsu_onfi.c
+* @addtogroup Overview
+* @{
+*
+* This file contains the implementation of ONFI specific functions.
+*
+* @note None
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- ---------- -----------------------------------------------
+* 1.0 nm 05/06/2014 First release
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+#include "xnandpsu_onfi.h"
+#include "xnandpsu.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* This function calculates ONFI parameter page CRC.
+*
+* @param ParamBuf is a pointer to the ONFI parameter page buffer.
+* @param StartOff is the starting offset in buffer to calculate CRC.
+* @param Length is the number of bytes for which CRC is calculated.
+*
+* @return
+* CRC value.
+* @note
+* None.
+*
+******************************************************************************/
+u32 XNandPsu_OnfiParamPageCrc(u8 *ParamBuf, u32 StartOff, u32 Length)
+{
+ const u32 CrcInit = 0x4F4EU;
+ const u32 Order = 16U;
+ const u32 Polynom = 0x8005U;
+ u32 i, j, c, Bit;
+ u32 Crc = CrcInit;
+ u32 DataIn;
+ u32 DataByteCount = 0U;
+ u32 CrcMask, CrcHighBit;
+
+ CrcMask = ((u32)(((u32)1 << (Order - (u32)1)) -(u32)1) << (u32)1) | (u32)1;
+ CrcHighBit = (u32)((u32)1 << (Order - (u32)1));
+ /*
+ * CRC covers the data bytes between byte 0 and byte 253
+ * (ONFI 1.0, section 5.4.1.36)
+ */
+ for(i = StartOff; i < Length; i++) {
+ DataIn = *(ParamBuf + i);
+ c = (u32)DataIn;
+ DataByteCount++;
+ j = 0x80U;
+ while(j != 0U) {
+ Bit = Crc & CrcHighBit;
+ Crc <<= 1U;
+ if ((c & j) != 0U) {
+ Bit ^= CrcHighBit;
+ }
+ if (Bit != 0U) {
+ Crc ^= Polynom;
+ }
+ j >>= 1U;
+ }
+ Crc &= CrcMask;
+ }
+ return Crc;
+}
+/** @} */
diff --git a/bsps/shared/dev/rtc/mcp7940m.c b/bsps/shared/dev/rtc/mcp7940m.c
new file mode 100644
index 0000000000..1abc5faaad
--- /dev/null
+++ b/bsps/shared/dev/rtc/mcp7940m.c
@@ -0,0 +1,361 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * 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.
+ */
+
+/*
+ * Note: This driver implements only the basic RTC functionality of the
+ * MCP7940M. It tries not to touch any register fields except for the basic
+ * date/time fields in the get/set time functions. That way it should be
+ * possible to re-use the driver for similar RTCs by just replacing the
+ * initialization function. Suggested method for that: Add a field to the struct
+ * mcp7940m_rtc with a function pointer that points to the initialization
+ * function.
+ *
+ * All flags that are considered MCP7940M specific have a MCP7940M in the name.
+ *
+ * Only 24 hour format is supported. If this driver is the only ones who write
+ * the RTC, that shouldn't be a problem.
+ *
+ * The weekday register is not used. It has a user-defined representation anyway
+ * and therefore doesn't really matter.
+ */
+
+#include <dev/i2c/i2c.h>
+#include <libchip/mcp7940m-rtc.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/todimpl.h>
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define REG_RTCSEC 0x00u
+
+#define RTCSEC_SECBCD_SHIFT 0u
+#define RTCSEC_SECBCD_MASK (0x7fu << RTCSEC_SECBCD_SHIFT)
+#define RTCSEC_SECBCD(x) (((x) << RTCSEC_SECBCD_SHIFT) & RTCSEC_SECBCD_MASK)
+#define RTCSEC_SECBCD_GET(x) (((x) & RTCSEC_SECBCD_MASK) >> RTCSEC_SECBCD_SHIFT)
+
+#define MCP7940M_RTCSEC_ST (0x01u << 7)
+
+#define REG_RTCMIN 0x01
+
+#define RTCMIN_MINBCD_SHIFT 0u
+#define RTCMIN_MINBCD_MASK (0x7fu << RTCMIN_MINBCD_SHIFT)
+#define RTCMIN_MINBCD(x) (((x) << RTCMIN_MINBCD_SHIFT) & RTCMIN_MINBCD_MASK)
+#define RTCMIN_MINBCD_GET(x) (((x) & RTCMIN_MINBCD_MASK) >> RTCMIN_MINBCD_SHIFT)
+
+#define REG_RTCHOUR 0x02
+
+#define RTCHOUR_HRBCD12_SHIFT 0u
+#define RTCHOUR_HRBCD12_MASK (0x1fu << RTCHOUR_HRBCD12_SHIFT)
+#define RTCHOUR_HRBCD12(x) (((x) << RTCHOUR_HRBCD12_SHIFT) & RTCHOUR_HRBCD12_MASK)
+#define RTCHOUR_HRBCD12_GET(x) (((x) & RTCHOUR_HRBCD12_MASK) >> RTCHOUR_HRBCD12_SHIFT)
+
+#define RTCHOUR_HRBCD24_SHIFT 0u
+#define RTCHOUR_HRBCD24_MASK (0x3fu << RTCHOUR_HRBCD24_SHIFT)
+#define RTCHOUR_HRBCD24(x) (((x) << RTCHOUR_HRBCD24_SHIFT) & RTCHOUR_HRBCD24_MASK)
+#define RTCHOUR_HRBCD24_GET(x) (((x) & RTCHOUR_HRBCD24_MASK) >> RTCHOUR_HRBCD24_SHIFT)
+
+#define RTCHOUR_AMPM (0x01u << 5)
+#define RTCHOUR_1224 (0x01u << 6)
+
+#define REG_RTCWKDAY 0x03
+
+#define RTCWKDAY_WKDAY_SHIFT 0u
+#define RTCWKDAY_WKDAY_MASK (0x7u << RTCWKDAY_WKDAY_SHIFT)
+#define RTCWKDAY_WKDAY(x) (((x) << RTCWKDAY_WKDAY_SHIFT) & RTCWKDAY_WKDAY_MASK)
+#define RTCWKDAY_WKDAY_GET(x) (((x) & RTCWKDAY_WKDAY_MASK) >> RTCWKDAY_WKDAY_SHIFT)
+
+#define REG_RTCDATE 0x04
+
+#define RTCDATE_DATEBCD_SHIFT 0u
+#define RTCDATE_DATEBCD_MASK (0x3fu << RTCDATE_DATEBCD_SHIFT)
+#define RTCDATE_DATEBCD(x) (((x) << RTCDATE_DATEBCD_SHIFT) & RTCDATE_DATEBCD_MASK)
+#define RTCDATE_DATEBCD_GET(x) (((x) & RTCDATE_DATEBCD_MASK) >> RTCDATE_DATEBCD_SHIFT)
+
+#define REG_RTCMTH 0x05
+
+#define RTCMTH_MTHBCD_SHIFT 0u
+#define RTCMTH_MTHBCD_MASK (0x1fu << RTCMTH_MTHBCD_SHIFT)
+#define RTCMTH_MTHBCD(x) (((x) << RTCMTH_MTHBCD_SHIFT) & RTCMTH_MTHBCD_MASK)
+#define RTCMTH_MTHBCD_GET(x) (((x) & RTCMTH_MTHBCD_MASK) >> RTCMTH_MTHBCD_SHIFT)
+
+#define MCP7940M_RTCMTH_LPYR (0x01u << 5)
+
+#define REG_RTCYEAR 0x06
+
+#define RTCYEAR_YRBCD_SHIFT 0u
+#define RTCYEAR_YRBCD_MASK (0xffu << RTCYEAR_YRBCD_SHIFT)
+#define RTCYEAR_YRBCD(x) (((x) << RTCYEAR_YRBCD_SHIFT) & RTCYEAR_YRBCD_MASK)
+#define RTCYEAR_YRBCD_GET(x) (((x) & RTCYEAR_YRBCD_MASK) >> RTCYEAR_YRBCD_SHIFT)
+
+#define REG_MCP7940M_CONTROL 0x07
+
+#define MCP7940M_CONTROL_OUT (0x1u << 7)
+#define MCP7940M_CONTROL_SQWEN (0x1u << 6)
+#define MCP7940M_CONTROL_ALM1EN (0x1u << 5)
+#define MCP7940M_CONTROL_ALM0EN (0x1u << 4)
+#define MCP7940M_CONTROL_EXTOSC (0x1u << 3)
+#define MCP7940M_CONTROL_CRSTRIM (0x1u << 2)
+#define MCP7940M_CONTROL_SQWFS1 (0x1u << 1)
+#define MCP7940M_CONTROL_SQWFS0 (0x1u << 0)
+
+static inline uint8_t bcd_to_bin(uint8_t bcd)
+{
+ uint8_t bin;
+ bin = bcd & 0x0f;
+ bin += ((bcd >> 4) & 0x0f) * 10;
+ return bin;
+}
+
+static inline uint8_t bin_to_bcd(uint8_t bin)
+{
+ uint8_t bcd;
+ bcd = bin % 10;
+ bcd |= (bin / 10) << 4;
+ return bcd;
+}
+
+static struct mcp7940m_rtc *mcp7940m_get_context(int minor)
+{
+ return (struct mcp7940m_rtc *) RTC_Table[minor].pDeviceParams;
+}
+
+static int mcp7940m_i2c_read(
+ struct mcp7940m_rtc *ctx,
+ uint8_t addr,
+ uint8_t *buf,
+ size_t len
+)
+{
+ int fd;
+ int rv;
+ struct i2c_msg msgs[] = {{
+ .addr = ctx->i2c_addr,
+ .flags = 0,
+ .buf = &addr,
+ .len = 1,
+ }, {
+ .addr = ctx->i2c_addr,
+ .flags = I2C_M_RD,
+ .buf = buf,
+ .len = len,
+ }};
+ struct i2c_rdwr_ioctl_data payload = {
+ .msgs = msgs,
+ .nmsgs = sizeof(msgs)/sizeof(msgs[0]),
+ };
+
+ fd = open(ctx->i2c_bus_path, O_RDWR);
+ if (fd < 0) {
+ return fd;
+ }
+
+ rv = ioctl(fd, I2C_RDWR, &payload);
+
+ close(fd);
+
+ return rv;
+}
+
+static int mcp7940m_i2c_write(
+ struct mcp7940m_rtc *ctx,
+ uint8_t addr,
+ const uint8_t *buf,
+ size_t len
+)
+{
+ int fd;
+ int rv;
+ uint8_t writebuf[len + 1];
+ struct i2c_msg msgs[] = {{
+ .addr = ctx->i2c_addr,
+ .flags = 0,
+ .buf = writebuf,
+ .len = len + 1,
+ }};
+ struct i2c_rdwr_ioctl_data payload = {
+ .msgs = msgs,
+ .nmsgs = sizeof(msgs)/sizeof(msgs[0]),
+ };
+
+ writebuf[0] = addr;
+ memcpy(&writebuf[1], buf, len);
+
+ fd = open(ctx->i2c_bus_path, O_RDWR);
+ if (fd < 0) {
+ return fd;
+ }
+
+ rv = ioctl(fd, I2C_RDWR, &payload);
+
+ close(fd);
+
+ return rv;
+}
+
+static int mcp7940m_initialize_once(struct mcp7940m_rtc *ctx)
+{
+ uint8_t reg;
+ ssize_t rv;
+
+ if (ctx->initialized) {
+ return 0;
+ }
+
+ /*
+ * Make sure that all alarms and outputs are disabled. Enable or disable
+ * oscillator.
+ *
+ * This makes sure that we can start with an uninitialized device that has a
+ * random value in the control register.
+ */
+ reg = 0;
+ if (!ctx->crystal) {
+ reg |= MCP7940M_CONTROL_EXTOSC;
+ }
+ rv = mcp7940m_i2c_write(ctx, REG_MCP7940M_CONTROL, &reg, 1);
+
+ if (rv == 0 && ctx->crystal) {
+ rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, &reg, 1);
+ if (rv == 0 && (reg & MCP7940M_RTCSEC_ST) == 0) {
+ reg |= MCP7940M_RTCSEC_ST;
+ rv = mcp7940m_i2c_write(ctx, REG_RTCSEC, &reg, 1);
+ }
+ }
+
+ ctx->initialized = true;
+
+ return rv;
+}
+
+static int mcp7940m_get_time(int minor, rtems_time_of_day *time)
+{
+ int rv = 0;
+ uint8_t buf[REG_RTCYEAR + 1];
+ struct mcp7940m_rtc *ctx = mcp7940m_get_context(minor);
+
+ if (!_System_state_Is_up(_System_state_Get())) {
+ return -1;
+ }
+
+ rtems_mutex_lock(&ctx->mutex);
+
+ rv = mcp7940m_initialize_once(ctx);
+
+ if (rv == 0) {
+ rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, buf, sizeof(buf));
+ }
+
+ if (rv == 0) {
+ unsigned year = bcd_to_bin(RTCYEAR_YRBCD_GET(buf[REG_RTCYEAR])) +
+ (TOD_BASE_YEAR / 100 * 100);
+ if (year < TOD_BASE_YEAR) {
+ year += 100;
+ }
+ time->year = year;
+ time->month = bcd_to_bin(RTCMTH_MTHBCD_GET(buf[REG_RTCMTH]));
+ time->day = bcd_to_bin(RTCDATE_DATEBCD_GET(buf[REG_RTCDATE]));
+ time->hour = bcd_to_bin(RTCHOUR_HRBCD24_GET(buf[REG_RTCHOUR]));
+ time->minute = bcd_to_bin(RTCMIN_MINBCD_GET(buf[REG_RTCMIN]));
+ time->second = bcd_to_bin(RTCSEC_SECBCD_GET(buf[REG_RTCSEC]));
+ time->ticks = 0;
+ }
+
+ rtems_mutex_unlock(&ctx->mutex);
+
+ return rv;
+}
+
+static int mcp7940m_set_time(int minor, const rtems_time_of_day *time)
+{
+ int rv = 0;
+ uint8_t buf[REG_RTCYEAR + 1];
+ struct mcp7940m_rtc *ctx = mcp7940m_get_context(minor);
+
+ if (!_System_state_Is_up(_System_state_Get())) {
+ return -1;
+ }
+
+ rtems_mutex_lock(&ctx->mutex);
+
+ rv = mcp7940m_initialize_once(ctx);
+
+ if (rv == 0) {
+ rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, buf, sizeof(buf));
+ }
+
+ if (rv == 0) {
+ /* Make sure weekday is not 0 (out of range). Otherwise it's not used. */
+ if (RTCWKDAY_WKDAY_GET(buf[REG_RTCWKDAY]) < 1) {
+ buf[REG_RTCWKDAY] &= ~RTCWKDAY_WKDAY_MASK;
+ buf[REG_RTCWKDAY] |= RTCWKDAY_WKDAY(1);
+ }
+
+ buf[REG_RTCYEAR] &= ~RTCYEAR_YRBCD_MASK;
+ buf[REG_RTCYEAR] |= RTCYEAR_YRBCD(bin_to_bcd(time->year % 100));
+
+ buf[REG_RTCMTH] &= ~RTCMTH_MTHBCD_MASK;
+ buf[REG_RTCMTH] |= RTCMTH_MTHBCD(bin_to_bcd(time->month));
+
+ buf[REG_RTCDATE] &= ~RTCDATE_DATEBCD_MASK;
+ buf[REG_RTCDATE] |= RTCDATE_DATEBCD(bin_to_bcd(time->day));
+
+ buf[REG_RTCHOUR] &= ~(RTCHOUR_HRBCD24_MASK | RTCHOUR_1224);
+ buf[REG_RTCHOUR] |= RTCHOUR_HRBCD24(bin_to_bcd(time->hour));
+
+ buf[REG_RTCMIN] &= ~RTCMIN_MINBCD_MASK;
+ buf[REG_RTCMIN] |= RTCMIN_MINBCD(bin_to_bcd(time->minute));
+
+ buf[REG_RTCSEC] &= ~RTCSEC_SECBCD_MASK;
+ buf[REG_RTCSEC] |= RTCSEC_SECBCD(bin_to_bcd(time->second));
+
+ rv = mcp7940m_i2c_write(ctx, REG_RTCSEC, buf, sizeof(buf));
+ }
+
+ rtems_mutex_unlock(&ctx->mutex);
+
+ return rv;
+}
+
+static void mcp7940m_init(int minor)
+{
+ (void) minor;
+}
+
+bool rtc_mcp7940m_probe(int minor)
+{
+ return true;
+}
+
+const rtc_fns rtc_mcp7940m_fns = {
+ .deviceInitialize = mcp7940m_init,
+ .deviceGetTime = mcp7940m_get_time,
+ .deviceSetTime = mcp7940m_set_time,
+};
diff --git a/bsps/shared/dev/serial/arm-pl011.c b/bsps/shared/dev/serial/arm-pl011.c
index f0e7031f96..e9a8e3f5a4 100644
--- a/bsps/shared/dev/serial/arm-pl011.c
+++ b/bsps/shared/dev/serial/arm-pl011.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2013, 2014 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/serial/console-output-char.c b/bsps/shared/dev/serial/console-output-char.c
index 14ad05cd8c..477fd1ffde 100644
--- a/bsps/shared/dev/serial/console-output-char.c
+++ b/bsps/shared/dev/serial/console-output-char.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2013 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/serial/console-polled.c b/bsps/shared/dev/serial/console-polled.c
index 0fc765cb64..37ad5b8f18 100644
--- a/bsps/shared/dev/serial/console-polled.c
+++ b/bsps/shared/dev/serial/console-polled.c
@@ -113,7 +113,7 @@ rtems_device_driver console_open(
NULL, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
- 0 /* outputUsesInterrupts */
+ TERMIOS_POLLED /* outputUsesInterrupts */
};
assert( minor == 0 );
diff --git a/bsps/shared/dev/serial/console-termios-init.c b/bsps/shared/dev/serial/console-termios-init.c
index da3eeaa2a7..c144549cb4 100644
--- a/bsps/shared/dev/serial/console-termios-init.c
+++ b/bsps/shared/dev/serial/console-termios-init.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2014, 2016 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/serial/console-termios.c b/bsps/shared/dev/serial/console-termios.c
index 16d5344be1..bdea1a0284 100644
--- a/bsps/shared/dev/serial/console-termios.c
+++ b/bsps/shared/dev/serial/console-termios.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2014, 2016 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/serial/getserialmouseps2.c b/bsps/shared/dev/serial/getserialmouseps2.c
index 22def46749..451a62d716 100644
--- a/bsps/shared/dev/serial/getserialmouseps2.c
+++ b/bsps/shared/dev/serial/getserialmouseps2.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2013 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/serial/legacy-console.c b/bsps/shared/dev/serial/legacy-console.c
index 7da87276b0..698439b247 100644
--- a/bsps/shared/dev/serial/legacy-console.c
+++ b/bsps/shared/dev/serial/legacy-console.c
@@ -234,7 +234,11 @@ rtems_device_driver console_open(
Callbacks.stopRemoteTx = NULL;
Callbacks.startRemoteTx = NULL;
}
- Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts;
+ if (cptr->pDeviceFns->deviceOutputUsesInterrupts) {
+ Callbacks.outputUsesInterrupts = TERMIOS_IRQ_DRIVEN;
+ } else {
+ Callbacks.outputUsesInterrupts = TERMIOS_POLLED;
+ }
/* XXX what about
* Console_Port_Tbl[minor].ulMargin,
diff --git a/bsps/shared/dev/serial/uart-output-char.c b/bsps/shared/dev/serial/uart-output-char.c
index 632aec26c3..6ec58a6588 100644
--- a/bsps/shared/dev/serial/uart-output-char.c
+++ b/bsps/shared/dev/serial/uart-output-char.c
@@ -9,7 +9,7 @@
*/
/*
- * Copyright (c) 2010-2011 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2010, 2011 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/dev/serial/zynq-uart-kernel-io.c b/bsps/shared/dev/serial/zynq-uart-kernel-io.c
new file mode 100644
index 0000000000..61b1043cd2
--- /dev/null
+++ b/bsps/shared/dev/serial/zynq-uart-kernel-io.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup zynq_uart
+ *
+ * @brief This source file contains the definition of ::BSP_output_char and
+ * ::BSP_poll_char.
+ */
+
+/*
+ * Copyright (C) 2013, 2024 embedded brains GmbH & Co. KG
+ *
+ * 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 <rtems/bspIo.h>
+
+#include <bsp.h>
+#include <dev/serial/zynq-uart-regs.h>
+#include <rtems/sysinit.h>
+
+static void zynq_uart_kernel_output_char(char c)
+{
+ volatile zynq_uart *regs =
+ (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR;
+
+ zynq_uart_write_char_polled(regs, c);
+}
+
+static int zynq_uart_kernel_poll_char(void)
+{
+ volatile zynq_uart *regs =
+ (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR;
+
+ return zynq_uart_read_char_polled(regs);
+}
+
+static void zynq_uart_kernel_early_init(char c);
+
+static void zynq_uart_kernel_init(void)
+{
+ volatile zynq_uart *regs =
+ (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR;
+
+ if (BSP_output_char != zynq_uart_kernel_early_init) {
+ return;
+ }
+
+ zynq_uart_initialize(regs);
+ BSP_output_char = zynq_uart_kernel_output_char;
+}
+
+static void zynq_uart_kernel_early_init(char c)
+{
+ zynq_uart_kernel_init();
+ zynq_uart_kernel_output_char(c);
+}
+
+BSP_output_char_function_type BSP_output_char = zynq_uart_kernel_early_init;
+
+BSP_polling_getchar_function_type BSP_poll_char = zynq_uart_kernel_poll_char;
+
+RTEMS_SYSINIT_ITEM(
+ zynq_uart_kernel_init,
+ RTEMS_SYSINIT_BSP_START,
+ RTEMS_SYSINIT_ORDER_LAST_BUT_5
+);
diff --git a/bsps/shared/dev/serial/zynq-uart-polled.c b/bsps/shared/dev/serial/zynq-uart-polled.c
index 6865fa8d6f..dbf75539f6 100644
--- a/bsps/shared/dev/serial/zynq-uart-polled.c
+++ b/bsps/shared/dev/serial/zynq-uart-polled.c
@@ -1,7 +1,16 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
*
- * Copyright (C) 2013, 2017 embedded brains GmbH
+ * @ingroup RTEMSBSPsARMZynq
+ *
+ * @brief This source file contains the implementation of the polled Zynq UART
+ * support.
+ */
+
+/*
+ * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -115,10 +124,8 @@ int zynq_cal_baud_rate(uint32_t baudrate,
return 0;
}
-void zynq_uart_initialize(rtems_termios_device_context *base)
+void zynq_uart_initialize(volatile zynq_uart *regs)
{
- zynq_uart_context *ctx = (zynq_uart_context *) base;
- volatile zynq_uart *regs = ctx->regs;
uint32_t brgr = 0x3e;
uint32_t bauddiv = 0x6;
uint32_t mode_clks = regs->mode & ZYNQ_UART_MODE_CLKS;
@@ -145,18 +152,15 @@ void zynq_uart_initialize(rtems_termios_device_context *base)
| ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8)
| mode_clks;
- while (zynq_uart_read_polled(base) >= 0) {
+ while (zynq_uart_read_char_polled(regs) >= 0) {
/* Drop */
}
- zynq_uart_reset_tx_flush(ctx);
+ zynq_uart_reset_tx_flush(regs);
}
-int zynq_uart_read_polled(rtems_termios_device_context *base)
+int zynq_uart_read_char_polled(volatile zynq_uart *regs)
{
- zynq_uart_context *ctx = (zynq_uart_context *) base;
- volatile zynq_uart *regs = ctx->regs;
-
if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) {
return -1;
} else {
@@ -164,14 +168,8 @@ int zynq_uart_read_polled(rtems_termios_device_context *base)
}
}
-void zynq_uart_write_polled(
- rtems_termios_device_context *base,
- char c
-)
+void zynq_uart_write_char_polled(volatile zynq_uart *regs, char c)
{
- zynq_uart_context *ctx = (zynq_uart_context *) base;
- volatile zynq_uart *regs = ctx->regs;
-
while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TNFUL) != 0) {
/* Wait */
}
@@ -179,13 +177,12 @@ void zynq_uart_write_polled(
regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c);
}
-void zynq_uart_reset_tx_flush(zynq_uart_context *ctx)
+void zynq_uart_reset_tx_flush(volatile zynq_uart *regs)
{
- volatile zynq_uart *regs = ctx->regs;
- int c = 4;
+ int c = 4;
while (c-- > 0)
- zynq_uart_write_polled(&ctx->base, '\r');
+ zynq_uart_write_char_polled(regs, '\r');
while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0 ||
(regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TACTIVE) != 0) {
diff --git a/bsps/shared/dev/serial/zynq-uart.c b/bsps/shared/dev/serial/zynq-uart.c
index 8ff1d25da0..0489288271 100644
--- a/bsps/shared/dev/serial/zynq-uart.c
+++ b/bsps/shared/dev/serial/zynq-uart.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2013, 2017 embedded brains GmbH
+ * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
#include <dev/serial/zynq-uart.h>
#include <dev/serial/zynq-uart-regs.h>
#include <bsp/irq.h>
+#include <rtems/termiostypes.h>
#include <bspopts.h>
@@ -66,14 +67,14 @@ static bool zynq_uart_first_open(
rtems_libio_open_close_args_t *args
)
{
-#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
zynq_uart_context *ctx = (zynq_uart_context *) base;
volatile zynq_uart *regs = ctx->regs;
+#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
rtems_status_code sc;
#endif
rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD);
- zynq_uart_initialize(base);
+ zynq_uart_initialize(regs);
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
regs->rx_fifo_trg_lvl = 1;
@@ -108,15 +109,23 @@ static void zynq_uart_last_close(
}
#endif
+#ifndef ZYNQ_CONSOLE_USE_INTERRUPTS
+static int zynq_uart_read_polled(rtems_termios_device_context *base)
+{
+ zynq_uart_context *ctx = (zynq_uart_context *) base;
+ return zynq_uart_read_char_polled(ctx->regs);
+}
+#endif
+
static void zynq_uart_write_support(
rtems_termios_device_context *base,
const char *buf,
size_t len
)
{
-#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
zynq_uart_context *ctx = (zynq_uart_context *) base;
volatile zynq_uart *regs = ctx->regs;
+#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
regs->irq_dis = ZYNQ_UART_TEMPTY;
@@ -134,9 +143,9 @@ static void zynq_uart_write_support(
regs->irq_en = ZYNQ_UART_TEMPTY;
}
#else
- ssize_t i;
+ size_t i;
for (i = 0; i < len; ++i) {
- zynq_uart_write_polled(base, buf[i]);
+ zynq_uart_write_char_polled(regs, buf[i]);
}
#endif
}
diff --git a/bsps/shared/dev/spi/VERSION b/bsps/shared/dev/spi/VERSION
new file mode 100644
index 0000000000..a0acb181b6
--- /dev/null
+++ b/bsps/shared/dev/spi/VERSION
@@ -0,0 +1,29 @@
+The information in this file describes the source of the following files in
+bsps/shared/dev/spi/ and bsps/include/dev/spi/:
+
+- xqspipsu_control.c
+- xqspipsu_control.h
+- xqspipsu_flash_config.h
+- xqspipsu_hw.c
+- xqspipsu_hw.h
+- xqspipsu_options.c
+- xqspipsu.c
+- xqspipsu.h
+
+Import from:
+
+https://github.com/Xilinx/embeddedsw.git
+
+commit 8a89579489c88ea5acd23d7d439ac928659c26cf
+Author: msreeram <manikanta.sreeram@xilinx.com>
+AuthorDate: Wed Apr 6 23:24:38 2022 -0600
+Commit: Siva Addepalli <sivaprasad.addepalli@xilinx.com>
+CommitDate: Fri Apr 8 16:47:15 2022 +0530
+
+ update license file for EmbeddedSW 2022.1 release
+
+ Update license file for EmbeddedSW 2022.1 release
+
+ Signed-off-by: Manikanta Sreeram <msreeram@xilinx.com>
+
+ Acked-by : Meena Paleti <meena.paleti@xilinx.com>
diff --git a/bsps/shared/dev/spi/xqspipsu-flash-helper.c b/bsps/shared/dev/spi/xqspipsu-flash-helper.c
new file mode 100644
index 0000000000..10e1066173
--- /dev/null
+++ b/bsps/shared/dev/spi/xqspipsu-flash-helper.c
@@ -0,0 +1,2341 @@
+/******************************************************************************
+* Copyright (C) 2018 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/**
+ * @file xqspipsu_flash_helper.c
+ *
+ * This file contains flash helper functions for the QSPIPSU driver. It
+ * consists of modified functions from Xilinx's flash example in
+ * examples/xqspipsu_generic_flash_interrupt_example.c of the qspipsu driver.
+ *
+ */
+
+#include "xqspipsu_flash_config.h"
+#include "xqspipsu-flash-helper.h"
+
+#include <rtems.h>
+
+/*
+ * Number of flash pages to be written.
+ */
+#define PAGE_COUNT 32
+
+/*
+ * Max page size to initialize write and read buffer
+ */
+#define MAX_PAGE_SIZE 1024
+
+#define TEST_ADDRESS 0x000000
+
+#define ENTER_4B 1
+#define EXIT_4B 0
+
+u8 ReadCmd;
+u8 WriteCmd;
+u8 StatusCmd;
+u8 SectorEraseCmd;
+u8 FSRFlag;
+
+static int FlashReadID(XQspiPsu *QspiPsuPtr);
+
+static int MultiDieRead(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount,
+ u8 Command,
+ u8 *WriteBfrPtr,
+ u8 *ReadBfrPtr
+);
+
+static u32 GetRealAddr(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address
+);
+
+static int BulkErase(
+ XQspiPsu *QspiPsuPtr,
+ u8 *WriteBfrPtr
+);
+
+static int DieErase(
+ XQspiPsu *QspiPsuPtr,
+ u8 *WriteBfrPtr
+);
+
+static int QspiPsuSetupIntrSystem(
+ XQspiPsu *QspiPsuInstancePtr,
+ u16 QspiPsuIntrId
+);
+
+static void QspiPsuHandler(
+ void *CallBackRef,
+ u32 StatusEvent,
+ unsigned int ByteCount
+);
+
+static int FlashEnterExit4BAddMode(
+ XQspiPsu *QspiPsuPtr,
+ unsigned int Enable
+);
+
+static int FlashEnableQuadMode(XQspiPsu *QspiPsuPtr);
+
+u8 TxBfrPtr;
+u8 ReadBfrPtr[3];
+u32 FlashMake;
+u32 FCTIndex; /* Flash configuration table index */
+
+static XQspiPsu_Msg FlashMsg[5];
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile int TransferInProgress;
+
+/*
+ * The following variable tracks any errors that occur during interrupt
+ * processing
+ */
+int Error;
+
+/*
+ * The following variable allows a test value to be added to the values that
+ * are written to the Flash such that unique values can be generated to
+ * guarantee the writes to the Flash were successful
+ */
+int Test = 1;
+
+/*
+ * The following variables are used to read and write to the flash and they
+ * are global to avoid having large buffers on the stack
+ * The buffer size accounts for maximum page size and maximum banks -
+ * for each bank separate read will be performed leading to that many
+ * (overhead+dummy) bytes
+ */
+#ifdef __ICCARM__
+#pragma data_alignment = 32
+u8 ReadBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + (DATA_OFFSET + DUMMY_SIZE)*8];
+#else
+u8 ReadBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + (DATA_OFFSET + DUMMY_SIZE)*8] __attribute__ ((aligned(64)));
+#endif
+u8 WriteBuffer[(PAGE_COUNT * MAX_PAGE_SIZE) + DATA_OFFSET];
+u8 CmdBfr[8];
+
+/*
+ * The following constants specify the max amount of data and the size of the
+ * the buffer required to hold the data and overhead to transfer the data to
+ * and from the Flash. Initialized to single flash page size.
+ */
+u32 MaxData = PAGE_COUNT*256;
+
+int QspiPsu_NOR_Initialize(
+ XQspiPsu *QspiPsuInstancePtr,
+ u16 QspiPsuIntrId
+)
+{
+ int Status;
+
+ if (QspiPsuInstancePtr == NULL) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the QspiPsu device to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific
+ */
+ Status = QspiPsuSetupIntrSystem(QspiPsuInstancePtr, QspiPsuIntrId);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the QSPIPSU that will be called from the
+ * interrupt context when an QSPIPSU status occurs, specify a pointer to
+ * the QSPIPSU driver instance as the callback reference
+ * so the handler is able to access the instance data
+ */
+ XQspiPsu_SetStatusHandler(QspiPsuInstancePtr, QspiPsuInstancePtr,
+ (XQspiPsu_StatusHandler) QspiPsuHandler);
+
+ /*
+ * Set Manual Start
+ */
+ XQspiPsu_SetOptions(QspiPsuInstancePtr, XQSPIPSU_MANUAL_START_OPTION);
+
+ /*
+ * Set the prescaler for QSPIPSU clock
+ */
+ XQspiPsu_SetClkPrescaler(QspiPsuInstancePtr, XQSPIPSU_CLK_PRESCALE_8);
+
+ XQspiPsu_SelectFlash(QspiPsuInstancePtr,
+ XQSPIPSU_SELECT_FLASH_CS_LOWER,
+ XQSPIPSU_SELECT_FLASH_BUS_LOWER);
+
+ /*
+ * Read flash ID and obtain all flash related information
+ * It is important to call the read id function before
+ * performing proceeding to any operation, including
+ * preparing the WriteBuffer
+ */
+
+ Status = FlashReadID(QspiPsuInstancePtr);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Some flash needs to enable Quad mode before using
+ * quad commands.
+ */
+ Status = FlashEnableQuadMode(QspiPsuInstancePtr);
+ if (Status != XST_SUCCESS)
+ return XST_FAILURE;
+
+ /*
+ * Address size and read command selection
+ * Micron flash on REMUS doesn't support these 4B write/erase commands
+ */
+ if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_SINGLE)
+ ReadCmd = FAST_READ_CMD;
+ else if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_DOUBLE)
+ ReadCmd = DUAL_READ_CMD;
+ else
+ ReadCmd = QUAD_READ_CMD;
+
+ WriteCmd = WRITE_CMD;
+ SectorEraseCmd = SEC_ERASE_CMD;
+
+ if ((Flash_Config_Table[FCTIndex].NumDie > 1) &&
+ (FlashMake == MICRON_ID_BYTE0)) {
+ StatusCmd = READ_FLAG_STATUS_CMD;
+ FSRFlag = 1;
+ } else {
+ StatusCmd = READ_STATUS_CMD;
+ FSRFlag = 0;
+ }
+
+ if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
+ Status = FlashEnterExit4BAddMode(QspiPsuInstancePtr, ENTER_4B);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ if (FlashMake == SPANSION_ID_BYTE0) {
+ if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_SINGLE)
+ ReadCmd = FAST_READ_CMD_4B;
+ else if(QspiPsuInstancePtr->Config.BusWidth == BUSWIDTH_DOUBLE)
+ ReadCmd = DUAL_READ_CMD_4B;
+ else
+ ReadCmd = QUAD_READ_CMD_4B;
+
+ WriteCmd = WRITE_CMD_4B;
+ SectorEraseCmd = SEC_ERASE_CMD_4B;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Callback handler.
+ *
+ * @param CallBackRef is the upper layer callback reference passed back
+ * when the callback function is invoked.
+ * @param StatusEvent is the event that just occurred.
+ * @param ByteCount is the number of bytes transferred up until the event
+ * occurred.
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ *****************************************************************************/
+static void QspiPsuHandler(
+ void *CallBackRef,
+ u32 StatusEvent,
+ unsigned int ByteCount
+)
+{
+ /*
+ * Indicate the transfer on the QSPIPSU bus is no longer in progress
+ * regardless of the status event
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ Error++;
+ }
+}
+
+int QspiPsu_NOR_RDSFDP(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount,
+ u8 **ReadBfrPtr
+)
+{
+ int Status;
+
+ *ReadBfrPtr = ReadBuffer;
+
+ CmdBfr[COMMAND_OFFSET] = READ_SFDP;
+ CmdBfr[ADDRESS_1_OFFSET] =
+ (u8)((Address & 0xFF0000) >> 16);
+ CmdBfr[ADDRESS_2_OFFSET] =
+ (u8)((Address & 0xFF00) >> 8);
+ CmdBfr[ADDRESS_3_OFFSET] =
+ (u8)(Address & 0xFF);
+
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].TxBfrPtr = CmdBfr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 4;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = NULL;
+ FlashMsg[1].ByteCount = DUMMY_CLOCKS;
+ FlashMsg[1].Flags = 0;
+
+ FlashMsg[2].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[2].TxBfrPtr = NULL;
+ FlashMsg[2].RxBfrPtr = *ReadBfrPtr;
+ FlashMsg[2].ByteCount = ByteCount;
+ FlashMsg[2].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 3);
+ if (Status != XST_SUCCESS)
+ return XST_FAILURE;
+
+ while (TransferInProgress);
+
+ rtems_cache_invalidate_multiple_data_lines(ReadBuffer, ByteCount);
+ return 0;
+}
+
+int QspiPsu_NOR_RDID(XQspiPsu *QspiPsuPtr, u8 *ReadBfrPtr, u32 ReadLen)
+{
+ int Status;
+
+ /*
+ * Read ID
+ */
+ TxBfrPtr = READ_ID;
+ FlashMsg[0].TxBfrPtr = &TxBfrPtr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = ReadBfrPtr;
+ FlashMsg[1].ByteCount = ReadLen;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ rtems_cache_invalidate_multiple_data_lines(ReadBfrPtr, ReadLen);
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Reads the flash ID and identifies the flash in FCT table.
+ *
+ * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use.
+ *
+ * @return XST_SUCCESS if successful, else XST_FAILURE.
+ *
+ * @note None.
+ *
+ *****************************************************************************/
+static int FlashReadID(XQspiPsu *QspiPsuPtr)
+{
+ u32 ReadId = 0;
+ u32 ReadLen = 3;
+ int Status;
+
+ Status = QspiPsu_NOR_RDID(QspiPsuPtr, ReadBfrPtr, ReadLen);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /* In case of dual, read both and ensure they are same make/size */
+
+ /*
+ * Deduce flash make
+ */
+ FlashMake = ReadBfrPtr[0];
+
+ ReadId = ((ReadBfrPtr[0] << 16) | (ReadBfrPtr[1] << 8) | ReadBfrPtr[2]);
+ /*
+ * Assign corresponding index in the Flash configuration table
+ */
+ Status = CalculateFCTIndex(ReadId, &FCTIndex);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ return XST_SUCCESS;
+}
+
+int QspiPsu_NOR_Write_Page(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount,
+ u8 *WriteBfrPtr
+)
+{
+ u8 WriteEnableCmd;
+ u8 ReadStatusCmd;
+ u8 FlashStatus[2];
+ u8 WriteCmdBfr[5];
+ u32 RealAddr;
+ u32 CmdByteCount;
+ int Status;
+
+ WriteEnableCmd = WRITE_ENABLE_CMD;
+ /*
+ * Translate address based on type of connection
+ * If stacked assert the slave select based on address
+ */
+ RealAddr = GetRealAddr(QspiPsuPtr, Address);
+
+ /*
+ * Send the write enable command to the Flash so that it can be
+ * written to, this needs to be sent as a separate transfer before
+ * the write
+ */
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while (TransferInProgress);
+
+ WriteCmdBfr[COMMAND_OFFSET] = WriteCmd;
+
+ /* To be used only if 4B address program cmd is supported by flash */
+ if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
+ WriteCmdBfr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF000000) >> 24);
+ WriteCmdBfr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ WriteCmdBfr[ADDRESS_3_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ WriteCmdBfr[ADDRESS_4_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ CmdByteCount = 5;
+ } else {
+ WriteCmdBfr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ WriteCmdBfr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ WriteCmdBfr[ADDRESS_3_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ CmdByteCount = 4;
+ }
+
+ FlashMsg[0].TxBfrPtr = WriteCmdBfr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = CmdByteCount;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = WriteBfrPtr;
+ FlashMsg[1].RxBfrPtr = NULL;
+ FlashMsg[1].ByteCount = ByteCount;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+
+ TransferInProgress = TRUE;
+
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while (TransferInProgress);
+
+ /*
+ * Wait for the write command to the Flash to be completed, it takes
+ * some time for the data to be written
+ */
+ while (1) {
+ ReadStatusCmd = StatusCmd;
+ FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ } else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+
+ if (FSRFlag) {
+ if ((FlashStatus[1] & 0x80) != 0) {
+ break;
+ }
+ } else {
+ if ((FlashStatus[1] & 0x01) == 0) {
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int QspiPsu_NOR_Write(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount,
+ u8 *WriteBfrPtr
+)
+{
+ int Status;
+ size_t ByteCountRemaining = ByteCount;
+ unsigned char *WriteBfrPartial = WriteBfrPtr;
+ uint32_t AddressPartial = Address;
+ uint32_t PageSize = Flash_Config_Table[FCTIndex].PageSize;
+ if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ PageSize *= 2;
+ }
+
+ while (ByteCountRemaining > 0) {
+ /* Get write boundary */
+ size_t WriteChunkLen = RTEMS_ALIGN_UP(AddressPartial + 1, PageSize);
+
+ /* Get offset to write boundary */
+ WriteChunkLen -= (size_t)AddressPartial;
+
+ /* Cap short writes */
+ if (WriteChunkLen > ByteCountRemaining) {
+ WriteChunkLen = ByteCountRemaining;
+ }
+
+ Status = QspiPsu_NOR_Write_Page(
+ QspiPsuPtr,
+ AddressPartial,
+ WriteChunkLen,
+ WriteBfrPartial
+ );
+ if ( Status != XST_SUCCESS ) {
+ return Status;
+ }
+
+ ByteCountRemaining -= WriteChunkLen;
+ AddressPartial += WriteChunkLen;
+ WriteBfrPartial += WriteChunkLen;
+ }
+ return Status;
+}
+
+int QspiPsu_NOR_Erase(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount
+)
+{
+ u8 WriteEnableCmd;
+ u8 ReadStatusCmd;
+ u8 FlashStatus[2];
+ int Sector;
+ u32 RealAddr;
+ u32 NumSect;
+ int Status;
+ u32 SectSize;
+
+ WriteEnableCmd = WRITE_ENABLE_CMD;
+
+ if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ SectSize = (Flash_Config_Table[FCTIndex]).SectSize * 2;
+ NumSect = (Flash_Config_Table[FCTIndex]).NumSect;
+ } else if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) {
+ NumSect = (Flash_Config_Table[FCTIndex]).NumSect * 2;
+ SectSize = (Flash_Config_Table[FCTIndex]).SectSize;
+ } else {
+ SectSize = (Flash_Config_Table[FCTIndex]).SectSize;
+ NumSect = (Flash_Config_Table[FCTIndex]).NumSect;
+ }
+
+ /*
+ * If erase size is same as the total size of the flash, use bulk erase
+ * command or die erase command multiple times as required
+ */
+ if (ByteCount == NumSect * SectSize) {
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_STACKED) {
+ XQspiPsu_SelectFlash(QspiPsuPtr,
+ XQSPIPSU_SELECT_FLASH_CS_LOWER,
+ XQSPIPSU_SELECT_FLASH_BUS_LOWER);
+ }
+
+ if (Flash_Config_Table[FCTIndex].NumDie == 1) {
+ /*
+ * Call Bulk erase
+ */
+ BulkErase(QspiPsuPtr, CmdBfr);
+ }
+
+ if (Flash_Config_Table[FCTIndex].NumDie > 1) {
+ /*
+ * Call Die erase
+ */
+ DieErase(QspiPsuPtr, CmdBfr);
+ }
+ /*
+ * If stacked mode, bulk erase second flash
+ */
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_STACKED) {
+
+ XQspiPsu_SelectFlash(QspiPsuPtr,
+ XQSPIPSU_SELECT_FLASH_CS_UPPER,
+ XQSPIPSU_SELECT_FLASH_BUS_LOWER);
+
+ if (Flash_Config_Table[FCTIndex].NumDie == 1) {
+ /*
+ * Call Bulk erase
+ */
+ BulkErase(QspiPsuPtr, CmdBfr);
+ }
+
+ if (Flash_Config_Table[FCTIndex].NumDie > 1) {
+ /*
+ * Call Die erase
+ */
+ DieErase(QspiPsuPtr, CmdBfr);
+ }
+ }
+
+ return 0;
+ }
+
+ /*
+ * If the erase size is less than the total size of the flash, use
+ * sector erase command
+ */
+
+ /*
+ * Calculate no. of sectors to erase based on byte count
+ */
+ u32 SectorStartBase = RTEMS_ALIGN_DOWN(Address, SectSize);
+ u32 SectorEndTop = RTEMS_ALIGN_UP(Address + ByteCount, SectSize);
+ NumSect = (SectorEndTop - SectorStartBase)/SectSize;
+
+ for (Sector = 0; Sector < NumSect; Sector++) {
+
+ /*
+ * Translate address based on type of connection
+ * If stacked assert the slave select based on address
+ */
+ RealAddr = GetRealAddr(QspiPsuPtr, Address);
+
+ /*
+ * Send the write enable command to the Flash so that it can be
+ * written to, this needs to be sent as a separate
+ * transfer before the write
+ */
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ CmdBfr[COMMAND_OFFSET] = SectorEraseCmd;
+
+ /*
+ * To be used only if 4B address sector erase cmd is
+ * supported by flash
+ */
+ if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
+ CmdBfr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF000000) >> 24);
+ CmdBfr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ CmdBfr[ADDRESS_3_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ CmdBfr[ADDRESS_4_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ FlashMsg[0].ByteCount = 5;
+ } else {
+ CmdBfr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ CmdBfr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ CmdBfr[ADDRESS_3_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ FlashMsg[0].ByteCount = 4;
+ }
+
+ FlashMsg[0].TxBfrPtr = CmdBfr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ /*
+ * Wait for the erase command to be completed
+ */
+ while (1) {
+ ReadStatusCmd = StatusCmd;
+ FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr,
+ FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ } else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+
+ if (FSRFlag) {
+ if ((FlashStatus[1] & 0x80) != 0) {
+ break;
+ }
+ } else {
+ if ((FlashStatus[1] & 0x01) == 0) {
+ break;
+ }
+ }
+ }
+ Address += SectSize;
+ }
+
+ return 0;
+}
+
+int QspiPsu_NOR_Read(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount,
+ u8 **ReadBfrPtr
+)
+{
+ u32 RealAddr;
+ u32 DiscardByteCnt;
+ u32 FlashMsgCnt;
+ int Status;
+
+ *ReadBfrPtr = ReadBuffer;
+
+ /* Check die boundary conditions if required for any flash */
+ if (Flash_Config_Table[FCTIndex].NumDie > 1) {
+
+ Status = MultiDieRead(QspiPsuPtr, Address, ByteCount, ReadCmd,
+ CmdBfr, *ReadBfrPtr);
+ if (Status != XST_SUCCESS)
+ return XST_FAILURE;
+ } else {
+ /* For Dual Stacked, split and read for boundary crossing */
+ /*
+ * Translate address based on type of connection
+ * If stacked assert the slave select based on address
+ */
+ RealAddr = GetRealAddr(QspiPsuPtr, Address);
+
+ CmdBfr[COMMAND_OFFSET] = ReadCmd;
+ if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
+ CmdBfr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF000000) >> 24);
+ CmdBfr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ CmdBfr[ADDRESS_3_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ CmdBfr[ADDRESS_4_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ DiscardByteCnt = 5;
+ } else {
+ CmdBfr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ CmdBfr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ CmdBfr[ADDRESS_3_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ DiscardByteCnt = 4;
+ }
+
+ FlashMsg[0].TxBfrPtr = CmdBfr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = DiscardByteCnt;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsgCnt = 1;
+
+ /* It is recommended to have a separate entry for dummy */
+ if (ReadCmd == FAST_READ_CMD || ReadCmd == DUAL_READ_CMD ||
+ ReadCmd == QUAD_READ_CMD || ReadCmd == FAST_READ_CMD_4B ||
+ ReadCmd == DUAL_READ_CMD_4B ||
+ ReadCmd == QUAD_READ_CMD_4B) {
+ /* Update Dummy cycles as per flash specs for QUAD IO */
+
+ /*
+ * It is recommended that Bus width value during dummy
+ * phase should be same as data phase
+ */
+ if (ReadCmd == FAST_READ_CMD ||
+ ReadCmd == FAST_READ_CMD_4B) {
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ }
+
+ if (ReadCmd == DUAL_READ_CMD ||
+ ReadCmd == DUAL_READ_CMD_4B) {
+ FlashMsg[1].BusWidth =
+ XQSPIPSU_SELECT_MODE_DUALSPI;
+ }
+
+ if (ReadCmd == QUAD_READ_CMD ||
+ ReadCmd == QUAD_READ_CMD_4B) {
+ FlashMsg[1].BusWidth =
+ XQSPIPSU_SELECT_MODE_QUADSPI;
+ }
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = NULL;
+ FlashMsg[1].ByteCount = DUMMY_CLOCKS;
+ FlashMsg[1].Flags = 0;
+
+ FlashMsgCnt++;
+ }
+
+ /* Dummy cycles need to be changed as per flash specs
+ * for QUAD IO
+ */
+ if (ReadCmd == FAST_READ_CMD || ReadCmd == FAST_READ_CMD_4B)
+ FlashMsg[FlashMsgCnt].BusWidth =
+ XQSPIPSU_SELECT_MODE_SPI;
+
+ if (ReadCmd == DUAL_READ_CMD || ReadCmd == DUAL_READ_CMD_4B)
+ FlashMsg[FlashMsgCnt].BusWidth =
+ XQSPIPSU_SELECT_MODE_DUALSPI;
+
+ if (ReadCmd == QUAD_READ_CMD || ReadCmd == QUAD_READ_CMD_4B)
+ FlashMsg[FlashMsgCnt].BusWidth =
+ XQSPIPSU_SELECT_MODE_QUADSPI;
+
+ FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].RxBfrPtr = *ReadBfrPtr;
+ FlashMsg[FlashMsgCnt].ByteCount = ByteCount;
+ FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[FlashMsgCnt].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg,
+ FlashMsgCnt + 1);
+ if (Status != XST_SUCCESS)
+ return XST_FAILURE;
+
+ while (TransferInProgress);
+
+ }
+ rtems_cache_invalidate_multiple_data_lines(ReadBuffer, ByteCount);
+ return 0;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function performs a read operation for multi die flash devices.
+ * Default setting is in DMA mode.
+ *
+ * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use.
+ * @param Address contains the address of the first sector which needs to
+ * be erased.
+ * @param ByteCount contains the total size to be erased.
+ * @param Command is the command used to read data from the flash.
+ * Supports normal, fast, dual and quad read commands.
+ * @param WriteBfrPtr is pointer to the write buffer which contains data to be
+ * transmitted
+ * @param ReadBfrPtr is pointer to the read buffer to which valid received data
+ * should be written
+ *
+ * @return XST_SUCCESS if successful, else XST_FAILURE.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+static int MultiDieRead(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount,
+ u8 Command,
+ u8 *WriteBfrPtr,
+ u8 *ReadBfrPtr
+)
+{
+ u32 RealAddr;
+ u32 DiscardByteCnt;
+ u32 FlashMsgCnt;
+ int Status;
+ u32 cur_bank = 0;
+ u32 nxt_bank = 0;
+ u32 bank_size;
+ u32 remain_len = ByteCount;
+ u32 data_len;
+ u32 transfer_len;
+ u8 *ReadBuffer = ReadBfrPtr;
+
+ /*
+ * Some flash devices like N25Q512 have multiple dies
+ * in it. Read operation in these devices is bounded
+ * by its die segment. In a continuous read, across
+ * multiple dies, when the last byte of the selected
+ * die segment is read, the next byte read is the
+ * first byte of the same die segment. This is Die
+ * cross over issue. So to handle this issue, split
+ * a read transaction, that spans across multiple
+ * banks, into one read per bank. Bank size is 16MB
+ * for single and dual stacked mode and 32MB for dual
+ * parallel mode.
+ */
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL)
+ bank_size = SIXTEENMB << 1;
+ else
+ bank_size = SIXTEENMB;
+
+ while (remain_len) {
+ cur_bank = Address / bank_size;
+ nxt_bank = (Address + remain_len) / bank_size;
+
+ if (cur_bank != nxt_bank) {
+ transfer_len = (bank_size * (cur_bank + 1)) - Address;
+ if (remain_len < transfer_len)
+ data_len = remain_len;
+ else
+ data_len = transfer_len;
+ } else {
+ data_len = remain_len;
+ }
+ /*
+ * Translate address based on type of connection
+ * If stacked assert the slave select based on address
+ */
+ RealAddr = GetRealAddr(QspiPsuPtr, Address);
+
+ WriteBfrPtr[COMMAND_OFFSET] = Command;
+ if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
+ WriteBfrPtr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF000000) >> 24);
+ WriteBfrPtr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ WriteBfrPtr[ADDRESS_3_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ WriteBfrPtr[ADDRESS_4_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ DiscardByteCnt = 5;
+ } else {
+ WriteBfrPtr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ WriteBfrPtr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ WriteBfrPtr[ADDRESS_3_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ DiscardByteCnt = 4;
+ }
+
+ FlashMsg[0].TxBfrPtr = WriteBfrPtr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = DiscardByteCnt;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsgCnt = 1;
+
+ /* It is recommended to have a separate entry for dummy */
+ if (Command == FAST_READ_CMD || Command == DUAL_READ_CMD ||
+ Command == QUAD_READ_CMD || Command == FAST_READ_CMD_4B ||
+ Command == DUAL_READ_CMD_4B ||
+ Command == QUAD_READ_CMD_4B) {
+ /* Update Dummy cycles as per flash specs for QUAD IO */
+
+ /*
+ * It is recommended that Bus width value during dummy
+ * phase should be same as data phase
+ */
+ if (Command == FAST_READ_CMD ||
+ Command == FAST_READ_CMD_4B) {
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ }
+
+ if (Command == DUAL_READ_CMD ||
+ Command == DUAL_READ_CMD_4B) {
+ FlashMsg[1].BusWidth =
+ XQSPIPSU_SELECT_MODE_DUALSPI;
+ }
+
+ if (Command == QUAD_READ_CMD ||
+ Command == QUAD_READ_CMD_4B) {
+ FlashMsg[1].BusWidth =
+ XQSPIPSU_SELECT_MODE_QUADSPI;
+ }
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = NULL;
+ FlashMsg[1].ByteCount = DUMMY_CLOCKS;
+ FlashMsg[1].Flags = 0;
+
+ FlashMsgCnt++;
+ }
+
+ /* Dummy cycles need to be changed as per flash
+ * specs for QUAD IO
+ */
+ if (Command == FAST_READ_CMD || Command == FAST_READ_CMD_4B)
+ FlashMsg[FlashMsgCnt].BusWidth =
+ XQSPIPSU_SELECT_MODE_SPI;
+
+ if (Command == DUAL_READ_CMD || Command == DUAL_READ_CMD_4B)
+ FlashMsg[FlashMsgCnt].BusWidth =
+ XQSPIPSU_SELECT_MODE_DUALSPI;
+
+ if (Command == QUAD_READ_CMD || Command == QUAD_READ_CMD_4B)
+ FlashMsg[FlashMsgCnt].BusWidth =
+ XQSPIPSU_SELECT_MODE_QUADSPI;
+
+ FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].RxBfrPtr = ReadBuffer;
+ FlashMsg[FlashMsgCnt].ByteCount = data_len;
+ FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL)
+ FlashMsg[FlashMsgCnt].Flags |=
+ XQSPIPSU_MSG_FLAG_STRIPE;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg,
+ FlashMsgCnt + 1);
+ if (Status != XST_SUCCESS)
+ return XST_FAILURE;
+
+ while (TransferInProgress);
+
+
+ ReadBuffer += data_len;
+ Address += data_len;
+ remain_len -= data_len;
+ }
+ rtems_cache_invalidate_multiple_data_lines(ReadBfrPtr, ByteCount);
+ return 0;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This functions performs a bulk erase operation when the
+ * flash device has a single die. Works for both Spansion and Micron
+ *
+ * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use.
+ * @param WriteBfrPtr is the pointer to command+address to be sent
+ *
+ * @return XST_SUCCESS if successful, else XST_FAILURE.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+static int BulkErase(
+ XQspiPsu *QspiPsuPtr,
+ u8 *WriteBfrPtr
+)
+{
+ u8 WriteEnableCmd;
+ u8 ReadStatusCmd;
+ u8 FlashStatus[2];
+ int Status;
+
+ WriteEnableCmd = WRITE_ENABLE_CMD;
+ /*
+ * Send the write enable command to the Flash so that it can be
+ * written to, this needs to be sent as a separate transfer before
+ * the write
+ */
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ WriteBfrPtr[COMMAND_OFFSET] = BULK_ERASE_CMD;
+ FlashMsg[0].TxBfrPtr = WriteBfrPtr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ /*
+ * Wait for the write command to the Flash to be completed, it takes
+ * some time for the data to be written
+ */
+ while (1) {
+ ReadStatusCmd = StatusCmd;
+ FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ } else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+
+ if (FSRFlag) {
+ if ((FlashStatus[1] & 0x80) != 0) {
+ break;
+ }
+ } else {
+ if ((FlashStatus[1] & 0x01) == 0) {
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This functions performs a die erase operation on all the die in
+ * the flash device. This function uses the die erase command for
+ * Micron 512Mbit and 1Gbit
+ *
+ * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use.
+ * @param WriteBfrPtr is the pointer to command+address to be sent
+ *
+ * @return XST_SUCCESS if successful, else XST_FAILURE.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+static int DieErase(
+ XQspiPsu *QspiPsuPtr,
+ u8 *WriteBfrPtr
+)
+{
+ u8 WriteEnableCmd;
+ u8 DieCnt;
+ u8 ReadStatusCmd;
+ u8 FlashStatus[2];
+ int Status;
+ u32 DieSize = 0;
+ u32 Address;
+ u32 RealAddr;
+ u32 SectSize = 0;
+ u32 NumSect = 0;
+
+ WriteEnableCmd = WRITE_ENABLE_CMD;
+
+ if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ SectSize = (Flash_Config_Table[FCTIndex]).SectSize * 2;
+ } else if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) {
+ NumSect = (Flash_Config_Table[FCTIndex]).NumSect * 2;
+ } else {
+ SectSize = (Flash_Config_Table[FCTIndex]).SectSize;
+ NumSect = (Flash_Config_Table[FCTIndex]).NumSect;
+ }
+ DieSize = (NumSect * SectSize) / Flash_Config_Table[FCTIndex].NumDie;
+
+ for (DieCnt = 0;
+ DieCnt < Flash_Config_Table[FCTIndex].NumDie;
+ DieCnt++) {
+ /*
+ * Send the write enable command to the Flash so that it can be
+ * written to, this needs to be sent as a separate transfer
+ * before the write
+ */
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ WriteBfrPtr[COMMAND_OFFSET] = DIE_ERASE_CMD;
+
+ Address = DieSize * DieCnt;
+ RealAddr = GetRealAddr(QspiPsuPtr, Address);
+ /*
+ * To be used only if 4B address sector erase cmd is
+ * supported by flash
+ */
+ if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
+ WriteBfrPtr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF000000) >> 24);
+ WriteBfrPtr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ WriteBfrPtr[ADDRESS_3_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ WriteBfrPtr[ADDRESS_4_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ FlashMsg[0].ByteCount = 5;
+ } else {
+ WriteBfrPtr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ WriteBfrPtr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ WriteBfrPtr[ADDRESS_3_OFFSET] =
+ (u8)(RealAddr & 0xFF);
+ FlashMsg[0].ByteCount = 4;
+ }
+ FlashMsg[0].TxBfrPtr = WriteBfrPtr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ /*
+ * Wait for the write command to the Flash to be completed,
+ * it takes some time for the data to be written
+ */
+ while (1) {
+ ReadStatusCmd = StatusCmd;
+ FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr,
+ FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ } else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+
+ if (FSRFlag) {
+ if ((FlashStatus[1] & 0x80) != 0) {
+ break;
+ }
+ } else {
+ if ((FlashStatus[1] & 0x01) == 0) {
+ break;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This functions translates the address based on the type of interconnection.
+ * In case of stacked, this function asserts the corresponding slave select.
+ *
+ * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use.
+ * @param Address which is to be accessed (for erase, write or read)
+ *
+ * @return RealAddr is the translated address - for single it is unchanged;
+ * for stacked, the lower flash size is subtracted;
+ * for parallel the address is divided by 2.
+ *
+ * @note In addition to get the actual address to work on flash this
+ * function also selects the CS and BUS based on the configuration
+ * detected.
+ *
+ ******************************************************************************/
+static u32 GetRealAddr(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address
+)
+{
+ u32 RealAddr = 0;
+
+ switch (QspiPsuPtr->Config.ConnectionMode) {
+ case XQSPIPSU_CONNECTION_MODE_SINGLE:
+ XQspiPsu_SelectFlash(QspiPsuPtr,
+ XQSPIPSU_SELECT_FLASH_CS_LOWER,
+ XQSPIPSU_SELECT_FLASH_BUS_LOWER);
+ RealAddr = Address;
+ break;
+ case XQSPIPSU_CONNECTION_MODE_STACKED:
+ /* Select lower or upper Flash based on sector address */
+ if (Address & Flash_Config_Table[FCTIndex].FlashDeviceSize) {
+
+ XQspiPsu_SelectFlash(QspiPsuPtr,
+ XQSPIPSU_SELECT_FLASH_CS_UPPER,
+ XQSPIPSU_SELECT_FLASH_BUS_LOWER);
+ /*
+ * Subtract first flash size when accessing second flash
+ */
+ RealAddr = Address &
+ (~Flash_Config_Table[FCTIndex].FlashDeviceSize);
+ }else{
+ /*
+ * Set selection to L_PAGE
+ */
+ XQspiPsu_SelectFlash(QspiPsuPtr,
+ XQSPIPSU_SELECT_FLASH_CS_LOWER,
+ XQSPIPSU_SELECT_FLASH_BUS_LOWER);
+
+ RealAddr = Address;
+
+ }
+ break;
+ case XQSPIPSU_CONNECTION_MODE_PARALLEL:
+ /*
+ * The effective address in each flash is the actual
+ * address / 2
+ */
+ XQspiPsu_SelectFlash(QspiPsuPtr,
+ XQSPIPSU_SELECT_FLASH_CS_BOTH,
+ XQSPIPSU_SELECT_FLASH_BUS_BOTH);
+ RealAddr = Address / 2;
+ break;
+ default:
+ /* RealAddr wont be assigned in this case; */
+ break;
+
+ }
+
+ return(RealAddr);
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function setups the interrupt system for a QspiPsu device.
+ *
+ * @param QspiPsuInstancePtr is a pointer to the instance of the
+ * QspiPsu device.
+ * @param QspiPsuIntrId is the interrupt Id for an QSPIPSU device.
+ *
+ * @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+static int QspiPsuSetupIntrSystem(
+ XQspiPsu *QspiPsuInstancePtr,
+ u16 QspiPsuIntrId
+)
+{
+ return rtems_interrupt_handler_install(
+ QspiPsuIntrId,
+ NULL,
+ RTEMS_INTERRUPT_UNIQUE,
+ (rtems_interrupt_handler) XQspiPsu_InterruptHandler,
+ QspiPsuInstancePtr
+ );
+}
+
+/*****************************************************************************/
+/**
+ * @brief
+ * This API enters the flash device into 4 bytes addressing mode.
+ * As per the Micron and ISSI spec, before issuing the command
+ * to enter into 4 byte addr mode, a write enable command is issued.
+ * For Macronix and Winbond flash parts write
+ * enable is not required.
+ *
+ * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use.
+ * @param Enable is a either 1 or 0 if 1 then enters 4 byte if 0 exits.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if it fails.
+ *
+ *
+ ******************************************************************************/
+static int FlashEnterExit4BAddMode(
+ XQspiPsu *QspiPsuPtr,
+ unsigned int Enable
+)
+{
+ int Status;
+ u8 WriteEnableCmd;
+ u8 Cmd;
+ u8 WriteDisableCmd;
+ u8 ReadStatusCmd;
+ u8 WriteBuffer[2] = {0};
+ u8 FlashStatus[2] = {0};
+
+ if (Enable) {
+ Cmd = ENTER_4B_ADDR_MODE;
+ } else {
+ if (FlashMake == ISSI_ID_BYTE0)
+ Cmd = EXIT_4B_ADDR_MODE_ISSI;
+ else
+ Cmd = EXIT_4B_ADDR_MODE;
+ }
+
+ switch (FlashMake) {
+ case ISSI_ID_BYTE0:
+ case MICRON_ID_BYTE0:
+ WriteEnableCmd = WRITE_ENABLE_CMD;
+ GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
+ /*
+ * Send the write enable command to the Flash so that it can be
+ * written to, this needs to be sent as a separate transfer
+ * before the write
+ */
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ break;
+
+ case SPANSION_ID_BYTE0:
+
+ /* Read Extended Addres Register */
+ WriteBuffer[0] = BANK_REG_RD;
+ FlashMsg[0].TxBfrPtr = &WriteBuffer[0];
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = &WriteBuffer[1];
+ FlashMsg[1].ByteCount = 1;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+ if (Enable) {
+ WriteBuffer[0] = BANK_REG_WR;
+ WriteBuffer[1] |= 1 << 7;
+ } else {
+ WriteBuffer[0] = BANK_REG_WR;
+ WriteBuffer[1] &= ~(0x01 << 7);
+ }
+
+ FlashMsg[0].TxBfrPtr = &WriteBuffer[0];
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[1].TxBfrPtr = &WriteBuffer[1];
+ FlashMsg[2].RxBfrPtr = NULL;
+ FlashMsg[2].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[2].Flags = XQSPIPSU_MSG_FLAG_TX;
+ FlashMsg[2].ByteCount = 1;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+ WriteBuffer[0] = BANK_REG_RD;
+ FlashMsg[0].TxBfrPtr = &WriteBuffer[0];
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = &FlashStatus[0];
+ FlashMsg[1].ByteCount = 1;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ return Status;
+
+ default:
+ /*
+ * For Macronix and Winbond flash parts
+ * Write enable command is not required.
+ */
+ break;
+ }
+
+ GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
+
+ FlashMsg[0].TxBfrPtr = &Cmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ while (1) {
+ ReadStatusCmd = StatusCmd;
+
+ FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ } else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+
+ if (FSRFlag) {
+ if ((FlashStatus[1] & 0x80) != 0) {
+ break;
+ }
+ } else {
+ if ((FlashStatus[1] & 0x01) == 0) {
+ break;
+ }
+ }
+ }
+
+ switch (FlashMake) {
+ case ISSI_ID_BYTE0:
+ case MICRON_ID_BYTE0:
+ WriteDisableCmd = WRITE_DISABLE_CMD;
+ GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
+ /*
+ * Send the write enable command to the Flash so that it can be
+ * written to, this needs to be sent as a separate transfer
+ * before the write
+ */
+ FlashMsg[0].TxBfrPtr = &WriteDisableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ break;
+
+ default:
+ /*
+ * For Macronix and Winbond flash parts
+ * Write disable command is not required.
+ */
+ break;
+ }
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+ * @brief
+ * This API enables Quad mode for the flash parts which require to enable quad
+ * mode before using Quad commands.
+ * For S25FL-L series flash parts this is required as the default configuration
+ * is x1/x2 mode.
+ *
+ * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if it fails.
+ *
+ *
+ ******************************************************************************/
+static int FlashEnableQuadMode(XQspiPsu *QspiPsuPtr)
+{
+ int Status;
+ u8 WriteEnableCmd;
+ u8 ReadStatusCmd;
+ u8 FlashStatus[2];
+ u8 StatusRegVal;
+ u8 WriteBuffer[3] = {0};
+
+ switch (FlashMake) {
+ case SPANSION_ID_BYTE0:
+ TxBfrPtr = READ_CONFIG_CMD;
+ FlashMsg[0].TxBfrPtr = &TxBfrPtr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = &WriteBuffer[2];
+ FlashMsg[1].ByteCount = 1;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr,
+ FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ WriteEnableCmd = WRITE_ENABLE_CMD;
+ /*
+ * Send the write enable command to the Flash
+ * so that it can be written to, this needs
+ * to be sent as a separate transfer before
+ * the write
+ */
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr,
+ FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
+
+ WriteBuffer[0] = WRITE_CONFIG_CMD;
+ WriteBuffer[1] |= 0x02;
+ WriteBuffer[2] |= 0x01 << 1;
+
+ FlashMsg[0].TxBfrPtr = &WriteBuffer[0];
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[1].TxBfrPtr = &WriteBuffer[1];
+ FlashMsg[1].RxBfrPtr = NULL;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr,
+ FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ while (1) {
+ TxBfrPtr = READ_STATUS_CMD;
+ FlashMsg[0].TxBfrPtr = &TxBfrPtr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr,
+ FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ }else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+
+ if ((FlashStatus[1] & 0x01) == 0x00)
+ break;
+ }
+ TxBfrPtr = READ_CONFIG_CMD;
+ FlashMsg[0].TxBfrPtr = &TxBfrPtr;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = ReadBfrPtr;
+ FlashMsg[1].ByteCount = 1;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+ break;
+ case ISSI_ID_BYTE0:
+ /*
+ * Read Status Register to a buffer
+ */
+ ReadStatusCmd = READ_STATUS_CMD;
+ FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ } else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+ /*
+ * Set Quad Enable Bit in the buffer
+ */
+ StatusRegVal = FlashStatus[1];
+ StatusRegVal |= 0x1 << QUAD_MODE_ENABLE_BIT;
+
+ /*
+ * Write enable
+ */
+ WriteEnableCmd = WRITE_ENABLE_CMD;
+ /*
+ * Send the write enable command to the Flash so that it can be
+ * written to, this needs to be sent as a separate transfer
+ * before the write
+ */
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ /*
+ * Write Status register
+ */
+ WriteBuffer[COMMAND_OFFSET] = WRITE_STATUS_CMD;
+ FlashMsg[0].TxBfrPtr = WriteBuffer;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = &StatusRegVal;
+ FlashMsg[1].RxBfrPtr = NULL;
+ FlashMsg[1].ByteCount = 1;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[1].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ /*
+ * Write Disable
+ */
+ WriteEnableCmd = WRITE_DISABLE_CMD;
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+ break;
+
+ case WINBOND_ID_BYTE0:
+ ReadStatusCmd = READ_STATUS_REG_2_CMD;
+ FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ } else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+ /*
+ * Set Quad Enable Bit in the buffer
+ */
+ StatusRegVal = FlashStatus[1];
+ StatusRegVal |= 0x1 << WB_QUAD_MODE_ENABLE_BIT;
+ /*
+ * Write Enable
+ */
+ WriteEnableCmd = WRITE_ENABLE_CMD;
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 1);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+ /*
+ * Write Status register
+ */
+ WriteBuffer[COMMAND_OFFSET] = WRITE_STATUS_REG_2_CMD;
+ FlashMsg[0].TxBfrPtr = WriteBuffer;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsg[1].TxBfrPtr = &StatusRegVal;
+ FlashMsg[1].RxBfrPtr = NULL;
+ FlashMsg[1].ByteCount = 1;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_TX;
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ while (1) {
+ ReadStatusCmd = READ_STATUS_CMD;
+ FlashMsg[0].TxBfrPtr = &ReadStatusCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ FlashMsg[1].TxBfrPtr = NULL;
+ FlashMsg[1].RxBfrPtr = FlashStatus;
+ FlashMsg[1].ByteCount = 2;
+ FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX;
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ if (FSRFlag) {
+ FlashStatus[1] &= FlashStatus[0];
+ } else {
+ FlashStatus[1] |= FlashStatus[0];
+ }
+ }
+ if ((FlashStatus[1] & 0x01) == 0x00) {
+ break;
+ }
+ }
+ /*
+ * Write Disable
+ */
+ WriteEnableCmd = WRITE_DISABLE_CMD;
+ FlashMsg[0].TxBfrPtr = &WriteEnableCmd;
+ FlashMsg[0].RxBfrPtr = NULL;
+ FlashMsg[0].ByteCount = 1;
+ FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 2);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ while (TransferInProgress);
+ break;
+
+ default:
+ /*
+ * Currently only S25FL-L series requires the
+ * Quad enable bit to be set to 1.
+ */
+ Status = XST_SUCCESS;
+ break;
+ }
+
+ return Status;
+}
+
+static int MultiDieReadEcc(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount,
+ u8 *WriteBfrPtr,
+ u8 *ReadBfrPtr
+);
+
+int QspiPsu_NOR_Read_Ecc(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u8 *ReadBfrPtr
+)
+{
+ u32 RealAddr;
+ u32 DiscardByteCnt;
+ u32 FlashMsgCnt;
+ u8 EccBuffer[16];
+ int ByteCount = sizeof(EccBuffer);
+ int Status;
+
+ /* Check die boundary conditions if required for any flash */
+ if (Flash_Config_Table[FCTIndex].NumDie > 1) {
+
+ Status = MultiDieReadEcc(QspiPsuPtr, Address, ByteCount,
+ CmdBfr, EccBuffer);
+ if (Status == XST_SUCCESS) {
+ /* All bytes are the same, so copy one return byte into the output buffer */
+ *ReadBfrPtr = EccBuffer[0];
+ }
+ return Status;
+ }
+
+ /* For Dual Stacked, split and read for boundary crossing */
+ /*
+ * Translate address based on type of connection
+ * If stacked assert the slave select based on address
+ */
+ RealAddr = GetRealAddr(QspiPsuPtr, Address);
+
+ CmdBfr[COMMAND_OFFSET] = READ_ECCSR;
+ CmdBfr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF000000) >> 24);
+ CmdBfr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ CmdBfr[ADDRESS_3_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ CmdBfr[ADDRESS_4_OFFSET] =
+ (u8)(RealAddr & 0xF0);
+ DiscardByteCnt = 5;
+
+ FlashMsgCnt = 0;
+
+ FlashMsg[FlashMsgCnt].TxBfrPtr = CmdBfr;
+ FlashMsg[FlashMsgCnt].RxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].ByteCount = DiscardByteCnt;
+ FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsgCnt++;
+
+ FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].RxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].ByteCount = DUMMY_CLOCKS;
+ FlashMsg[FlashMsgCnt].Flags = 0;
+
+ FlashMsgCnt++;
+
+ FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].RxBfrPtr = EccBuffer;
+ FlashMsg[FlashMsgCnt].ByteCount = ByteCount;
+ FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ FlashMsg[FlashMsgCnt].Flags |= XQSPIPSU_MSG_FLAG_STRIPE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg,
+ FlashMsgCnt + 1);
+ if (Status == XST_SUCCESS) {
+ while (TransferInProgress);
+
+ /* All bytes are the same, so copy one return byte into the output buffer */
+ *ReadBfrPtr = EccBuffer[0];
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function performs an ECC read operation for multi die flash devices.
+ * Default setting is in DMA mode.
+ *
+ * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use.
+ * @param Address contains the address of the first sector which needs to
+ * be erased.
+ * @param ByteCount contains the total size to be erased.
+ * @param WriteBfrPtr is pointer to the write buffer which contains data to be
+ * transmitted
+ * @param ReadBfrPtr is pointer to the read buffer to which valid received data
+ * should be written
+ *
+ * @return XST_SUCCESS if successful, else XST_FAILURE.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+static int MultiDieReadEcc(
+ XQspiPsu *QspiPsuPtr,
+ u32 Address,
+ u32 ByteCount,
+ u8 *WriteBfrPtr,
+ u8 *ReadBuffer
+)
+{
+ u32 RealAddr;
+ u32 DiscardByteCnt;
+ u32 FlashMsgCnt;
+ int Status;
+ u32 cur_bank = 0;
+ u32 nxt_bank = 0;
+ u32 bank_size;
+ u32 remain_len = ByteCount;
+ u32 data_len;
+ u32 transfer_len;
+
+ /*
+ * Some flash devices like N25Q512 have multiple dies
+ * in it. Read operation in these devices is bounded
+ * by its die segment. In a continuous read, across
+ * multiple dies, when the last byte of the selected
+ * die segment is read, the next byte read is the
+ * first byte of the same die segment. This is Die
+ * cross over issue. So to handle this issue, split
+ * a read transaction, that spans across multiple
+ * banks, into one read per bank. Bank size is 16MB
+ * for single and dual stacked mode and 32MB for dual
+ * parallel mode.
+ */
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL)
+ bank_size = SIXTEENMB << 1;
+ else
+ bank_size = SIXTEENMB;
+
+ while (remain_len) {
+ cur_bank = Address / bank_size;
+ nxt_bank = (Address + remain_len) / bank_size;
+
+ if (cur_bank != nxt_bank) {
+ transfer_len = (bank_size * (cur_bank + 1)) - Address;
+ if (remain_len < transfer_len)
+ data_len = remain_len;
+ else
+ data_len = transfer_len;
+ } else {
+ data_len = remain_len;
+ }
+ /*
+ * Translate address based on type of connection
+ * If stacked assert the slave select based on address
+ */
+ RealAddr = GetRealAddr(QspiPsuPtr, Address);
+
+ WriteBfrPtr[COMMAND_OFFSET] = READ_ECCSR;
+ WriteBfrPtr[ADDRESS_1_OFFSET] =
+ (u8)((RealAddr & 0xFF000000) >> 24);
+ WriteBfrPtr[ADDRESS_2_OFFSET] =
+ (u8)((RealAddr & 0xFF0000) >> 16);
+ WriteBfrPtr[ADDRESS_3_OFFSET] =
+ (u8)((RealAddr & 0xFF00) >> 8);
+ WriteBfrPtr[ADDRESS_4_OFFSET] =
+ (u8)(RealAddr & 0xF0);
+ DiscardByteCnt = 5;
+
+ FlashMsgCnt = 0;
+
+ FlashMsg[FlashMsgCnt].TxBfrPtr = WriteBfrPtr;
+ FlashMsg[FlashMsgCnt].RxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].ByteCount = DiscardByteCnt;
+ FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_TX;
+
+ FlashMsgCnt++;
+
+ FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].RxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].ByteCount = DUMMY_CLOCKS;
+ FlashMsg[FlashMsgCnt].Flags = 0;
+
+ FlashMsgCnt++;
+
+ FlashMsg[FlashMsgCnt].TxBfrPtr = NULL;
+ FlashMsg[FlashMsgCnt].RxBfrPtr = ReadBuffer;
+ FlashMsg[FlashMsgCnt].ByteCount = data_len;
+ FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
+ FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX;
+
+ if (QspiPsuPtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_PARALLEL)
+ FlashMsg[FlashMsgCnt].Flags |=
+ XQSPIPSU_MSG_FLAG_STRIPE;
+
+ TransferInProgress = TRUE;
+ Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg,
+ FlashMsgCnt + 1);
+ if (Status != XST_SUCCESS)
+ return XST_FAILURE;
+
+ while (TransferInProgress);
+
+ ReadBuffer += data_len;
+ Address += data_len;
+ remain_len -= data_len;
+ }
+ return 0;
+}
+
+u32 QspiPsu_NOR_Get_Sector_Size(XQspiPsu *QspiPsuPtr)
+{
+ if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ return Flash_Config_Table[FCTIndex].SectSize * 2;
+ }
+ return Flash_Config_Table[FCTIndex].SectSize;
+}
+
+u32 QspiPsu_NOR_Get_Device_Size(XQspiPsu *QspiPsuPtr)
+{
+ if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED
+ || QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) {
+ return Flash_Config_Table[FCTIndex].FlashDeviceSize * 2;
+ }
+ return Flash_Config_Table[FCTIndex].FlashDeviceSize;
+}
diff --git a/bsps/shared/dev/spi/xqspipsu.c b/bsps/shared/dev/spi/xqspipsu.c
new file mode 100644
index 0000000000..93d3fa4c98
--- /dev/null
+++ b/bsps/shared/dev/spi/xqspipsu.c
@@ -0,0 +1,1086 @@
+/******************************************************************************
+* Copyright (C) 2014 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+
+/*****************************************************************************/
+/**
+ *
+ * @file xqspipsu.c
+ * @addtogroup Overview
+ * @{
+ *
+ * This file implements the functions required to use the QSPIPSU hardware to
+ * perform a transfer. These are accessible to the user via xqspipsu.h.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- --- -------- -----------------------------------------------
+ * 1.0 hk 08/21/14 First release
+ * sk 03/13/15 Added IO mode support.
+ * hk 03/18/15 Switch to I/O mode before clearing RX FIFO.
+ * Clear and disable DMA interrupts/status in abort.
+ * Use DMA DONE bit instead of BUSY as recommended.
+ * sk 04/24/15 Modified the code according to MISRAC-2012.
+ * sk 06/17/15 Removed NULL checks for Rx/Tx buffers. As
+ * writing/reading from 0x0 location is permitted.
+ * 1.1 sk 04/12/16 Added debug message prints.
+ * 1.2 nsk 07/01/16 Changed XQspiPsu_Select to support GQSPI and LQSPI
+ * selection.
+ * rk 07/15/16 Added support for TapDelays at different frequencies.
+ * nsk 08/05/16 Added example support PollData and PollTimeout
+ * 1.3 nsk 09/16/16 Update PollData and PollTimeout support for dual
+ * parallel configurations, modified XQspiPsu_PollData()
+ * and XQspiPsu_Create_PollConfigData()
+ * 1,5 nsk 08/14/17 Added CCI support
+ * 1.7 tjs 01/16/18 Removed the check for DMA MSB to be written. (CR#992560)
+ * 1.7 tjs 01/17/18 Added a support to toggle WP pin of the flash.
+ * 1.7 tjs 03/14/18 Added support in EL1 NS mode (CR#974882)
+ * 1.8 tjs 06/26/18 Added an example for accessing 64bit dma within
+ * 32 bit application. CR#1004701
+ * 1.8 tjs 06/26/18 Removed checkpatch warnings.
+ * 1.8 tjs 07/09/18 Fixed cppcheck and doxygen warnings. (CR#1006336)
+ * 1.8 tjs 07/18/18 Setup64BRxDma() should be called only if the RxAddress is
+ * greater than 32 bit address space. (CR#1006862)
+ * 1.8 tjs 09/06/18 Fixed the code in XQspiPsu_GenFifoEntryData() for data
+ * transfer length up to 255 for reducing the extra loop.
+ * 1.8 mus 11/05/18 Support 64 bit DMA addresses for Microblaze-X platform.
+ * 1.9 tjs 11/22/17 Added the check for A72 and R5 processors (CR-987075)
+ * 1.9 tjs 04/17/18 Updated register addresses as per the latest revision
+ * of versal (CR#999610)
+ * 1.9 aru 01/17/19 Fixes violations according to MISRAC-2012
+ * in safety mode and modified the code such as
+ * Added UNITPTR inplace of INTPTR,Declared the pointer param
+ * as Pointer to const .
+ * 1.9 nsk 02/01/19 Clear DMA_DST_ADDR_MSB register on 32bit machine, if the
+ * address is of only 32bit (CR#1020031)
+ * 1.9 nsk 02/01/19 Added QSPI idling support.
+ * 1.9 rama 03/13/19 Fixed MISRA violations related to UR data anamoly,
+ * expression is not a boolean
+ * 1.9 nsk 03/27/19 Update 64bit dma support
+ * 1.10 sk 08/20/19 Fixed issues in poll timeout feature.
+ * 1.11 akm 02/19/20 Added XQspiPsu_StartDmaTransfer() and XQspiPsu_CheckDmaDone()
+ * APIs for non-blocking transfer.
+ * 1.11 sd 01/02/20 Added clocking support
+ * 1.11 akm 03/09/20 Reorganize the source code, enable qspi controller and
+ * interrupts in XQspiPsu_CfgInitialize() API.
+ * 1.11 akm 03/26/20 Fixed issue by updating XQspiPsu_CfgInitialize to return
+ * XST_DEVICE_IS_STARTED instead of asserting, when the
+ * instance is already configured.
+ * 1.13 akm 01/04/21 Fix MISRA-C violations.
+ * 1.14 akm 06/24/21 Allow enough time for the controller to reset the FIFOs.
+ * 1.14 akm 08/12/21 Perform Dcache invalidate at the end of the DMA transfer.
+ * 1.15 akm 10/21/21 Fix MISRA-C violations.
+ *
+ * </pre>
+ *
+ ******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xqspipsu.h"
+#include "xqspipsu_control.h"
+#include "sleep.h"
+#ifdef __rtems__
+#include <rtems/rtems/cache.h>
+#endif
+
+/************************** Constant Definitions *****************************/
+#define MAX_DELAY_CNT 10000000U /**< Max delay count */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+/**
+ *
+ * Initializes a specific XQspiPsu instance as such the driver is ready to use.
+ *
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param ConfigPtr is a reference to a structure containing information
+ * about a specific QSPIPSU device. This function initializes an
+ * InstancePtr object for a specific device specified by the
+ * contents of Config.
+ * @param EffectiveAddr is the device base address in the virtual memory
+ * address space. The caller is responsible for keeping the address
+ * mapping from EffectiveAddr to the device physical base address
+ * unchanged once this function is invoked. Unexpected errors may
+ * occur if the address mapping changes after this function is
+ * called. If address translation is not used, use
+ * ConfigPtr->Config.BaseAddress for this device.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_DEVICE_IS_STARTED if the device is already started.
+ * It must be stopped to re-initialize.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+s32 XQspiPsu_CfgInitialize(XQspiPsu *InstancePtr,
+ const XQspiPsu_Config *ConfigPtr,
+ UINTPTR EffectiveAddr)
+{
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(ConfigPtr != NULL);
+ s32 Status;
+
+ /*
+ * If the device is busy, disallow the initialize and return a status
+ * indicating it is already started. This allows the user to stop the
+ * device and re-initialize, but prevents a user from inadvertently
+ * initializing. This assumes the busy flag is cleared at startup.
+ */
+ if ((InstancePtr->IsBusy == (u32)TRUE) ||
+ (InstancePtr->IsReady == XIL_COMPONENT_IS_READY)) {
+ Status = (s32)XST_DEVICE_IS_STARTED;
+ } else {
+ /* Set some default values. */
+ InstancePtr->IsBusy = (u32)FALSE;
+ InstancePtr->Config.BaseAddress =
+ EffectiveAddr + XQSPIPSU_OFFSET;
+ InstancePtr->Config.ConnectionMode = ConfigPtr->ConnectionMode;
+ InstancePtr->StatusHandler = StubStatusHandler;
+ InstancePtr->Config.BusWidth = ConfigPtr->BusWidth;
+ InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz;
+#if defined (XCLOCKING)
+ InstancePtr->Config.RefClk = ConfigPtr->RefClk;
+#endif
+ InstancePtr->Config.IsCacheCoherent =
+ ConfigPtr->IsCacheCoherent;
+ /* Other instance variable initializations */
+ InstancePtr->SendBufferPtr = NULL;
+ InstancePtr->RecvBufferPtr = NULL;
+ InstancePtr->GenFifoBufferPtr = NULL;
+ InstancePtr->TxBytes = 0;
+ InstancePtr->RxBytes = 0;
+ InstancePtr->GenFifoEntries = 0;
+ InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
+ InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER;
+ InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER;
+ InstancePtr->IsUnaligned = 0;
+ InstancePtr->IsManualstart = (u8)TRUE;
+
+ /* Select QSPIPSU */
+ XQspiPsu_Select(InstancePtr, XQSPIPSU_SEL_GQSPI_MASK);
+ /*
+ * Reset the QSPIPSU device to get it into its initial state.
+ * It is expected that device configuration will take place
+ * after this initialization is done, but before the device
+ * is started.
+ */
+ XQspiPsu_Reset(InstancePtr);
+ /* Enable */
+ XQspiPsu_Enable(InstancePtr);
+
+ InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
+
+ Status = (s32)XST_SUCCESS;
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Stops the transfer of data to internal DST FIFO from stream interface and
+ * also stops the issuing of new write commands to memory.
+ *
+ * By calling this API, any ongoing Dma transfers will be paused and DMA will
+ * not issue AXI write commands to memory
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_Idle(const XQspiPsu *InstancePtr)
+{
+ u32 RegEn;
+ u32 DmaStatus;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ /* Check for QSPI enable */
+ RegEn = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_EN_OFFSET);
+ if ((RegEn & XQSPIPSU_EN_MASK) != 0U) {
+ DmaStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET);
+ DmaStatus |= XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_STRM_MASK;
+ DmaStatus |= XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_MEM_MASK;
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET, DmaStatus);
+ }
+#if defined (XCLOCKING)
+ Xil_ClockDisable(InstancePtr->Config.RefClk);
+#endif
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Resets the QSPIPSU device. Reset must only be called after the driver has
+ * been initialized. Any data transfer that is in progress is aborted.
+ *
+ * The upper layer software is responsible for re-configuring (if necessary)
+ * and restarting the QSPIPSU device after the reset.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_Reset(XQspiPsu *InstancePtr)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_Reset\r\n");
+#endif
+
+ /* Abort any transfer that is in progress */
+ XQspiPsu_Abort(InstancePtr);
+
+ /* Default value to config register */
+ XQspiPsu_SetDefaultConfig(InstancePtr);
+
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Aborts a transfer in progress.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_Abort(XQspiPsu *InstancePtr)
+{
+ u32 IntrStatus, ConfigReg, FifoStatus;
+ u32 DelayCount = 0U;
+
+#ifdef __rtems__
+ u32 FifoStatusMask = XQSPIPSU_ISR_RXEMPTY_MASK;
+ FifoStatusMask |= XQSPIPSU_ISR_TXEMPTY_MASK;
+ FifoStatusMask |= XQSPIPSU_ISR_GENFIFOEMPTY_MASK;
+#endif
+
+ Xil_AssertVoid(InstancePtr != NULL);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_Abort\r\n");
+#endif
+ IntrStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_ISR_OFFSET);
+
+ /* Clear and disable interrupts */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_ISR_OFFSET, IntrStatus | XQSPIPSU_ISR_WR_TO_CLR_MASK);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET,
+ XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET));
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_STS_OFFSET,
+ XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_STS_OFFSET) |
+ XQSPIPSU_QSPIDMA_DST_STS_WTC);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_IDR_OFFSET, XQSPIPSU_IDR_ALL_MASK);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET,
+ XQSPIPSU_QSPIDMA_DST_INTR_ALL_MASK);
+
+ /*
+ * Clear GEN FIFO, TX FIFO & RX FIFO. Switch to IO mode to Clear
+ * RX FIFO. This is because of DMA behaviour where it waits on
+ * RX empty and goes busy assuming there is data to be transferred
+ * even if there is no request.
+ */
+ ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+ ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET, ConfigReg);
+
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_FIFO_CTRL_OFFSET,
+ XQSPIPSU_FIFO_CTRL_RST_TX_FIFO_MASK |
+ XQSPIPSU_FIFO_CTRL_RST_GEN_FIFO_MASK |
+ XQSPIPSU_FIFO_CTRL_RST_RX_FIFO_MASK);
+ /*
+ * QSPI Controller takes few clock cycles to update the RX_FIFO_Empty,
+ * TX_FIFO_Empty and GEN_FIFO_Empty status bit. Checking the GQSPI FIFO
+ * Control register bits gives enough time for the QSPI controller to
+ * update the status bit. The opeartion timesout, if the status bit are
+ * not updated after 10secs.
+ */
+
+ FifoStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+#ifdef __rtems__
+ XQSPIPSU_ISR_OFFSET) & FifoStatusMask;
+ while(FifoStatus != FifoStatusMask) {
+#else
+ XQSPIPSU_FIFO_CTRL_OFFSET);
+ while(FifoStatus != 0U) {
+#endif
+ if (DelayCount == MAX_DELAY_CNT) {
+#ifdef DEBUG
+ xil_printf("Timeout error, FIFO reset failed.\r\n");
+#endif
+ } else {
+ /* Wait for 1 usec */
+ usleep(1);
+ DelayCount++;
+ FifoStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+#ifdef __rtems__
+ XQSPIPSU_ISR_OFFSET) & FifoStatusMask;
+#else
+ XQSPIPSU_FIFO_CTRL_OFFSET);
+#endif
+ }
+ }
+
+ if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
+ ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK;
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET, ConfigReg);
+ }
+
+
+ InstancePtr->TxBytes = 0;
+ InstancePtr->RxBytes = 0;
+ InstancePtr->GenFifoEntries = 0;
+ InstancePtr->IsBusy = (u32)FALSE;
+}
+
+/*****************************************************************************/
+/**
+ * This is the handler for polling functionality of controller. It reads data
+ * from RXFIFO, since when data from the flash device (status data) matched
+ * with configured value in poll_cfg, then controller writes the matched data
+ * into RXFIFO.
+ *
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param StatusReg is the Interrupt status Register value.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_PollDataHandler(XQspiPsu *InstancePtr, u32 StatusReg)
+{
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_PollDataHandler\r\n");
+#endif
+
+ if ((StatusReg & XQSPIPSU_ISR_RXNEMPTY_MASK) != (u32)FALSE) {
+ /*
+ * Read data from RXFIFO, since when data from the
+ * flash device (status data) matched with configured
+ * value in poll_cfg, then controller writes the
+ * matched data into RXFIFO.
+ */
+ (void)XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_RXD_OFFSET);
+
+ InstancePtr->StatusHandler(InstancePtr->StatusRef,
+ XST_SPI_POLL_DONE, 0);
+ }
+ if ((StatusReg & XQSPIPSU_ISR_POLL_TIME_EXPIRE_MASK) != (u32)FALSE) {
+ InstancePtr->StatusHandler(InstancePtr->StatusRef,
+ XST_FLASH_TIMEOUT_ERROR, 0);
+ }
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IDR_OFFSET,
+ (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
+ (u32)XQSPIPSU_IER_POLL_TIME_EXPIRE_MASK);
+ InstancePtr->IsBusy = (u32)FALSE;
+ if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
+ XQspiPsu_SetReadMode(InstancePtr, XQSPIPSU_READMODE_DMA);
+ }
+ /* De-select slave */
+ XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
+ XQspiPsu_ManualStartEnable(InstancePtr);
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function performs a transfer on the bus in polled mode. The messages
+ * passed are all transferred on the bus between one CS assert and de-assert.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ * @param NumMsg is the number of messages to be transferred.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if transfer fails.
+ * - XST_DEVICE_BUSY if a transfer is already in progress.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+s32 XQspiPsu_PolledTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
+ u32 NumMsg)
+{
+ s32 Index;
+ u32 QspiPsuStatusReg;
+ u32 IOPending = (u32)FALSE;
+ u32 DmaIntrSts;
+ s32 Status;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(Msg != NULL);
+ Xil_AssertNonvoid(NumMsg > 0U);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ for (Index = 0; Index < (s32)NumMsg; Index++) {
+ Xil_AssertNonvoid(Msg[Index].ByteCount > 0U);
+#ifdef __rtems__
+ if (Msg[Index].TxBfrPtr != NULL) {
+ rtems_cache_flush_multiple_data_lines(Msg[Index].TxBfrPtr, Msg[Index].ByteCount);
+ }
+#endif
+ }
+#ifdef __rtems__
+ rtems_cache_flush_multiple_data_lines(Msg, NumMsg * sizeof(*Msg));
+#endif
+
+ /*
+ * Check whether there is another transfer in progress.
+ * Not thread-safe
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ Status = (s32)XST_DEVICE_BUSY;
+ goto END;
+ }
+ /* Check for ByteCount upper limit - 2^28 for DMA */
+ for (Index = 0; Index < (s32)NumMsg; Index++) {
+ if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) &&
+ ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
+ Status = (s32)XST_FAILURE;
+ goto END;
+ }
+ }
+ /*
+ * Set the busy flag, which will be cleared when the transfer is
+ * entirely done.
+ */
+ InstancePtr->IsBusy = (u32)TRUE;
+
+#if defined (XCLOCKING)
+ Xil_ClockEnable(InstancePtr->Config.RefClk);
+#endif
+ /* Select slave */
+ XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
+
+ /* list */
+ Index = 0;
+ while (Index < (s32)NumMsg) {
+ XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[Index]);
+ XQspiPsu_ManualStartEnable(InstancePtr);
+ /* Use thresholds here */
+ /* If there is more data to be transmitted */
+ do {
+ QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_ISR_OFFSET);
+ /* Transmit more data if left */
+ if (((QspiPsuStatusReg & XQSPIPSU_ISR_TXNOT_FULL_MASK) != (u32)FALSE) &&
+ ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) &&
+ (InstancePtr->TxBytes > 0)) {
+ XQspiPsu_FillTxFifo(InstancePtr, &Msg[Index],
+ (u32)XQSPIPSU_TXD_DEPTH);
+ }
+
+ if ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE) {
+ if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
+ /* Check if DMA RX is complete and update RxBytes */
+ DmaIntrSts = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET);
+ if ((DmaIntrSts &
+ XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) {
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, DmaIntrSts);
+ /* DMA transfer done, Invalidate Data Cache */
+ if (!((Msg[Index].RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) ||
+ (Msg[Index].Xfer64bit != (u8)0U)) &&
+ (InstancePtr->Config.IsCacheCoherent == 0U)) {
+ Xil_DCacheInvalidateRange((INTPTR)Msg[Index].RxBfrPtr,
+ (INTPTR)Msg[Index].ByteCount);
+ }
+ IOPending = XQspiPsu_SetIOMode(InstancePtr, &Msg[Index]);
+ InstancePtr->RxBytes = 0;
+ if (IOPending == (u32)TRUE) {
+ break;
+ }
+ }
+ } else {
+ XQspiPsu_IORead(InstancePtr, &Msg[Index], QspiPsuStatusReg);
+ }
+ }
+ } while (((QspiPsuStatusReg &
+ XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE) ||
+ (InstancePtr->TxBytes != 0) ||
+ ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) == (u32)FALSE) ||
+ (InstancePtr->RxBytes != 0));
+
+ if ((InstancePtr->IsUnaligned != 0) && (IOPending == (u32)FALSE)) {
+ InstancePtr->IsUnaligned = 0;
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ (XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) |
+ XQSPIPSU_CFG_MODE_EN_DMA_MASK));
+ InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
+ }
+ if (IOPending == (u32)TRUE) {
+ IOPending = (u32)FALSE;
+ } else {
+ Index++;
+ }
+ }
+ /* De-select slave */
+ XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
+ XQspiPsu_ManualStartEnable(InstancePtr);
+ do {
+ QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET);
+ } while ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE);
+
+ /* Clear the busy flag. */
+ InstancePtr->IsBusy = (u32)FALSE;
+
+ Status = (s32)XST_SUCCESS;
+
+#if defined (XCLOCKING)
+ Xil_ClockDisable(InstancePtr->Config.RefClk);
+#endif
+ END:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function initiates a transfer on the bus and enables interrupts.
+ * The transfer is completed by the interrupt handler. The messages passed are
+ * all transferred on the bus between one CS assert and de-assert.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ * @param NumMsg is the number of messages to be transferred.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if transfer fails.
+ * - XST_DEVICE_BUSY if a transfer is already in progress.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+s32 XQspiPsu_InterruptTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
+ u32 NumMsg)
+{
+ s32 Index;
+ s32 Status;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ for (Index = 0; Index < (s32)NumMsg; Index++)
+#ifdef __rtems__
+ {
+#endif
+ Xil_AssertNonvoid(Msg[Index].ByteCount > 0U);
+#ifdef __rtems__
+ if (Msg[Index].TxBfrPtr != NULL) {
+ rtems_cache_flush_multiple_data_lines(Msg[Index].TxBfrPtr, Msg[Index].ByteCount);
+ }
+ }
+ rtems_cache_flush_multiple_data_lines(Msg, NumMsg * sizeof(*Msg));
+#endif
+
+ /*
+ * Check whether there is another transfer in progress.
+ * Not thread-safe
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ Status = (s32)XST_DEVICE_BUSY;
+ goto END;
+ }
+#if defined (XCLOCKING)
+ Xil_ClockEnable(InstancePtr->Config.RefClk);
+#endif
+
+ if ((Msg[0].Flags & XQSPIPSU_MSG_FLAG_POLL) != (u32)FALSE) {
+ InstancePtr->IsBusy = (u32)TRUE;
+ XQspiPsu_PollDataConfig(InstancePtr, Msg);
+ } else {
+ /* Check for ByteCount upper limit - 2^28 for DMA */
+ for (Index = 0; Index < (s32)NumMsg; Index++) {
+ if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) &&
+ ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
+ Status = (s32)XST_FAILURE;
+ goto END;
+ }
+ }
+ /*
+ * Set the busy flag, which will be cleared when the transfer is
+ * entirely done.
+ */
+ InstancePtr->IsBusy = (u32)TRUE;
+
+ InstancePtr->Msg = Msg;
+ InstancePtr->NumMsg = (s32)NumMsg;
+ InstancePtr->MsgCnt = 0;
+
+ /* Select slave */
+ XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
+ /* This might not work if not manual start */
+ /* Put first message in FIFO along with the above slave select */
+ XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[0]);
+ XQspiPsu_ManualStartEnable(InstancePtr);
+
+ /* Enable interrupts */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IER_OFFSET,
+ (u32)XQSPIPSU_IER_TXNOT_FULL_MASK |
+ (u32)XQSPIPSU_IER_TXEMPTY_MASK |
+ (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
+ (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK |
+ (u32)XQSPIPSU_IER_RXEMPTY_MASK);
+
+ if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_EN_OFFSET,
+ XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK);
+ }
+ }
+ Status = (s32)XST_SUCCESS;
+
+ END:
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Handles interrupt based transfers by acting on GENFIFO and DMA interurpts.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if transfer fails.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+s32 XQspiPsu_InterruptHandler(XQspiPsu *InstancePtr)
+{
+ u32 QspiPsuStatusReg, DmaIntrStatusReg = 0;
+ XQspiPsu_Msg *Msg;
+ s32 NumMsg;
+ s32 MsgCnt;
+ u8 DeltaMsgCnt = 0;
+ u32 TxRxFlag;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(InstancePtr->NumMsg > 0);
+ Xil_AssertNonvoid(InstancePtr->Msg != NULL);
+
+ Msg = InstancePtr->Msg;
+ NumMsg = InstancePtr->NumMsg;
+ MsgCnt = InstancePtr->MsgCnt;
+ TxRxFlag = Msg[MsgCnt].Flags;
+
+ /* QSPIPSU Intr cleared on read */
+ QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET);
+ if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
+ /* DMA Intr write to clear */
+ DmaIntrStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET,
+ DmaIntrStatusReg);
+ }
+ if (((DmaIntrStatusReg & XQSPIPSU_QSPIDMA_DST_INTR_ERR_MASK) != (u32)FALSE)) {
+ /* Call status handler to indicate error */
+ InstancePtr->StatusHandler(InstancePtr->StatusRef,
+ XST_SPI_COMMAND_ERROR, 0);
+ }
+ /* Fill more data to be txed if required */
+ if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) &&
+ ((QspiPsuStatusReg & XQSPIPSU_ISR_TXNOT_FULL_MASK) != (u32)FALSE) &&
+ (InstancePtr->TxBytes > 0)) {
+ XQspiPsu_FillTxFifo(InstancePtr, &Msg[MsgCnt], (u32)XQSPIPSU_TXD_DEPTH);
+ }
+ /*
+ * Check if the entry is ONLY TX and increase MsgCnt.
+ * This is to allow TX and RX together in one entry - corner case.
+ */
+ if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) &&
+ ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) != (u32)FALSE) &&
+ ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE) &&
+ (InstancePtr->TxBytes == 0) &&
+ ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE)) {
+ MsgCnt += 1;
+ DeltaMsgCnt = 1U;
+ }
+
+ if ((MsgCnt < NumMsg) &&
+ ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
+ if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
+ if ((DmaIntrStatusReg &
+ XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) {
+ /* DMA transfer done, Invalidate Data Cache */
+ if (!((Msg[MsgCnt].RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) ||
+ (Msg[MsgCnt].Xfer64bit != (u8)0U)) &&
+ (InstancePtr->Config.IsCacheCoherent == 0U)) {
+ Xil_DCacheInvalidateRange((INTPTR)Msg[MsgCnt].RxBfrPtr, (INTPTR)Msg[MsgCnt].ByteCount);
+ }
+ if (XQspiPsu_SetIOMode(InstancePtr, &Msg[MsgCnt]) == (u32)TRUE) {
+ XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[MsgCnt]);
+ XQspiPsu_ManualStartEnable(InstancePtr);
+ } else {
+ InstancePtr->RxBytes = 0;
+ MsgCnt += 1;
+ DeltaMsgCnt = 1U;
+ }
+ }
+ } else {
+ if (InstancePtr->RxBytes != 0) {
+ XQspiPsu_IORead(InstancePtr, &Msg[MsgCnt], QspiPsuStatusReg);
+ if (InstancePtr->RxBytes == 0) {
+ MsgCnt += 1;
+ DeltaMsgCnt = 1U;
+ }
+ }
+ }
+ }
+
+ /*
+ * Dummy byte transfer
+ * MsgCnt < NumMsg check is to ensure is it a valid dummy cycle message
+ * If one of the above conditions increased MsgCnt, then
+ * the new message is yet to be placed in the FIFO; hence !DeltaMsgCnt.
+ */
+ if ((MsgCnt < NumMsg) && (DeltaMsgCnt == (u8)FALSE) &&
+ ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE) &&
+ ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) == (u32)FALSE) &&
+ ((TxRxFlag & XQSPIPSU_MSG_FLAG_POLL) == (u32)FALSE) &&
+ ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE)) {
+ MsgCnt += 1;
+ DeltaMsgCnt = 1U;
+ }
+ InstancePtr->MsgCnt = MsgCnt;
+ /*
+ * DeltaMsgCnt is to handle conditions where genfifo empty can be set
+ * while tx is still not empty or rx dma is not yet done.
+ * MsgCnt > NumMsg indicates CS de-assert entry was also executed.
+ */
+ if (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE) &&
+ ((DeltaMsgCnt != (u8)FALSE) || (MsgCnt > NumMsg))) {
+ if (MsgCnt < NumMsg) {
+ if (InstancePtr->IsUnaligned != 0) {
+ InstancePtr->IsUnaligned = 0;
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET, (XQspiPsu_ReadReg(
+ InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) |
+ XQSPIPSU_CFG_MODE_EN_DMA_MASK));
+ InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
+ }
+ /* This might not work if not manual start */
+ XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[MsgCnt]);
+ XQspiPsu_ManualStartEnable(InstancePtr);
+ } else if (MsgCnt == NumMsg) {
+ /* This is just to keep track of the de-assert entry */
+ MsgCnt += 1;
+ InstancePtr->MsgCnt = MsgCnt;
+ /* De-select slave */
+ XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
+ XQspiPsu_ManualStartEnable(InstancePtr);
+ } else {
+ /* Disable interrupts */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IDR_OFFSET,
+ (u32)XQSPIPSU_IER_TXNOT_FULL_MASK |
+ (u32)XQSPIPSU_IER_TXEMPTY_MASK |
+ (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
+ (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK |
+ (u32)XQSPIPSU_IER_RXEMPTY_MASK);
+ if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET,
+ XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK);
+ }
+ /* Clear the busy flag. */
+ InstancePtr->IsBusy = (u32)FALSE;
+#if defined (XCLOCKING)
+ Xil_ClockDisable(InstancePtr->Config.RefClk);
+#endif
+ /* Call status handler to indicate completion */
+ InstancePtr->StatusHandler(InstancePtr->StatusRef,
+ XST_SPI_TRANSFER_DONE, 0);
+ }
+ }
+ if ((TxRxFlag & XQSPIPSU_MSG_FLAG_POLL) != (u32)FALSE) {
+ XQspiPsu_PollDataHandler(InstancePtr, QspiPsuStatusReg);
+ }
+ return (s32)XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Sets the status callback function, the status handler, which the driver
+ * calls when it encounters conditions that should be reported to upper
+ * layer software. The handler executes in an interrupt context, so it must
+ * minimize the amount of processing performed. One of the following status
+ * events is passed to the status handler.
+ *
+ * <pre>
+ *
+ * XST_SPI_TRANSFER_DONE The requested data transfer is done
+ *
+ * XST_SPI_TRANSMIT_UNDERRUN As a slave device, the master clocked data
+ * but there were none available in the transmit
+ * register/FIFO. This typically means the slave
+ * application did not issue a transfer request
+ * fast enough, or the processor/driver could not
+ * fill the transmit register/FIFO fast enough.
+ *
+ * XST_SPI_RECEIVE_OVERRUN The QSPIPSU device lost data. Data was received
+ * but the receive data register/FIFO was full.
+ *
+ * </pre>
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param CallBackRef is the upper layer callback reference passed back
+ * when the callback function is invoked.
+ * @param FuncPointer is the pointer to the callback function.
+ *
+ * @return None.
+ *
+ * @note
+ *
+ * The handler is called within interrupt context, so it should do its work
+ * quickly and queue potentially time-consuming work to a task-level thread.
+ *
+ ******************************************************************************/
+void XQspiPsu_SetStatusHandler(XQspiPsu *InstancePtr, void *CallBackRef,
+ XQspiPsu_StatusHandler FuncPointer)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(FuncPointer != NULL);
+ Xil_AssertVoid(CallBackRef != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ InstancePtr->StatusHandler = FuncPointer;
+ InstancePtr->StatusRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/**
+ * @brief
+ * This API enables/ disables Write Protect pin on the flash parts.
+ *
+ * @param InstancePtr is a pointer to the QSPIPSU driver component to use.
+ *
+ * @param Toggle is a value of the GPIO pin
+ *
+ * @return None
+ *
+ * @note By default WP pin as per the QSPI controller is driven High
+ * which means no write protection. Calling this function once
+ * will enable the protection.
+ *
+ ******************************************************************************/
+void XQspiPsu_WriteProtectToggle(const XQspiPsu *InstancePtr, u32 Toggle)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ /* For Single and Stacked flash configuration with x1 or x2 mode*/
+ if (InstancePtr->Config.ConnectionMode ==
+ XQSPIPSU_CONNECTION_MODE_SINGLE) {
+ /* Select slave */
+ XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
+
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_GPIO_OFFSET, Toggle);
+
+ } else {
+#ifdef DEBUG
+ xil_printf("Dual Parallel/Stacked configuration ");
+ xil_printf("is not supported by this API\r\n");
+#endif
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function start a DMA transfer.
+*
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ * @param NumMsg is the number of messages to be transferred.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if ByteCount is greater than
+ * XQSPIPSU_DMA_BYTES_MAX.
+ * - XST_DEVICE_BUSY if a transfer is already in progress.
+ *
+ * @note None.
+ *
+*
+******************************************************************************/
+s32 XQspiPsu_StartDmaTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
+ u32 NumMsg)
+{
+ s32 Index;
+ u32 QspiPsuStatusReg = 0;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(Msg != NULL);
+ Xil_AssertNonvoid(NumMsg > 0U);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ for (Index = 0; Index < (s32)NumMsg; Index++) {
+ Xil_AssertNonvoid(Msg[Index].ByteCount > 0U);
+ }
+
+ /*
+ * Check whether there is another transfer in progress.
+ * Not thread-safe
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ return (s32)XST_DEVICE_BUSY;
+ }
+
+ /* Check for ByteCount upper limit - 2^28 for DMA */
+ for (Index = 0; Index < (s32)NumMsg; Index++) {
+ if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) &&
+ ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
+ return (s32)XST_FAILURE;
+ }
+ }
+
+ /*
+ * Set the busy flag, which will be cleared when the transfer is
+ * entirely done.
+ */
+ InstancePtr->IsBusy = (u32)TRUE;
+
+ /* Select slave */
+ XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
+ /* list */
+ Index = 0;
+ while (Index < (s32)NumMsg) {
+ InstancePtr->Msg = &Msg[Index];
+ XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[Index]);
+ if (InstancePtr->IsManualstart == (u32)TRUE) {
+#ifdef DEBUG
+ xil_printf("\nManual Start\r\n");
+#endif
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET) |
+ XQSPIPSU_CFG_START_GEN_FIFO_MASK);
+ }
+ do {
+ if((InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) &&
+ ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
+ break;
+ }
+ QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET);
+
+ } while (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE) ||
+ (InstancePtr->TxBytes != 0) ||
+ ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) == (u32)FALSE));
+
+ if(InstancePtr->ReadMode == XQSPIPSU_READMODE_IO) {
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET, (XQspiPsu_ReadReg(
+ InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) |
+ XQSPIPSU_CFG_MODE_EN_DMA_MASK));
+ InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
+ }
+ Index++;
+ }
+ return (s32)XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function check for DMA transfer complete.
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+*
+* @return
+* - XST_SUCCESS if DMA transfer complete.
+* - XST_FAILURE if DMA transfer is not completed.
+*
+* @note None.
+*
+******************************************************************************/
+s32 XQspiPsu_CheckDmaDone(XQspiPsu *InstancePtr)
+{
+ u32 QspiPsuStatusReg;
+ u32 DmaIntrSts;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ DmaIntrSts = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET);
+ if ((DmaIntrSts & XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) {
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, DmaIntrSts);
+ /* DMA transfer done, Invalidate Data Cache */
+ if (!((InstancePtr->Msg->RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) ||
+ (InstancePtr->Msg->Xfer64bit != (u8)0U)) &&
+ (InstancePtr->Config.IsCacheCoherent == 0U)) {
+ Xil_DCacheInvalidateRange((INTPTR)InstancePtr->Msg->RxBfrPtr, (INTPTR)InstancePtr->RxBytes);
+ }
+ /* De-select slave */
+ XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
+ if (InstancePtr->IsManualstart == (u8)TRUE) {
+#ifdef DEBUG
+ xil_printf("\nManual Start\r\n");
+#endif
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) |
+ XQSPIPSU_CFG_START_GEN_FIFO_MASK);
+ }
+ do {
+ QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET);
+ } while ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE);
+
+ /* Clear the busy flag. */
+ InstancePtr->IsBusy = (u32)FALSE;
+
+ return (s32)XST_SUCCESS;
+ }
+ else {
+ return (s32)XST_FAILURE;
+ }
+
+}
+/** @} */
diff --git a/bsps/shared/dev/spi/xqspipsu_control.c b/bsps/shared/dev/spi/xqspipsu_control.c
new file mode 100644
index 0000000000..af2400bf4c
--- /dev/null
+++ b/bsps/shared/dev/spi/xqspipsu_control.c
@@ -0,0 +1,282 @@
+/******************************************************************************
+* Copyright (C) 2020 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+
+/*****************************************************************************/
+/**
+ *
+ * @file xqspipsu_control.c
+ * @addtogroup Overview
+ * @{
+ *
+ * This file contains intermediate control functions used by functions
+ * in xqspipsu.c and xqspipsu_options.c files.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- --- -------- -----------------------------------------------
+ * 1.11 akm 03/09/20 First release
+ * 1.13 akm 01/04/21 Fix MISRA-C violations.
+ * 1.15 akm 10/21/21 Fix MISRA-C violations.
+ * 1.15 akm 03/03/22 Enable tapdelay settings for applications on
+ * Microblaze platform.
+ * </pre>
+ *
+ ******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xqspipsu_control.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+
+/*****************************************************************************/
+/**
+ *
+ * This function writes the GENFIFO entries to transmit the messages requested.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if transfer fails.
+ * - XST_DEVICE_BUSY if a transfer is already in progress.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_GenFifoEntryData(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg)
+{
+ u32 GenFifoEntry;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_GenFifoEntryData\r\n");
+#endif
+
+ GenFifoEntry = 0x0U;
+ /* Bus width */
+ GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_MODE_MASK;
+ GenFifoEntry |= XQspiPsu_SelectSpiMode((u8)Msg->BusWidth);
+
+ GenFifoEntry |= InstancePtr->GenFifoCS;
+ GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_BUS_MASK;
+ GenFifoEntry |= InstancePtr->GenFifoBus;
+
+ /* Data */
+ if (((Msg->Flags) & XQSPIPSU_MSG_FLAG_STRIPE) != (u32)FALSE) {
+ GenFifoEntry |= XQSPIPSU_GENFIFO_STRIPE;
+ } else {
+ GenFifoEntry &= ~XQSPIPSU_GENFIFO_STRIPE;
+ }
+ /* If Byte Count is less than 8 bytes do the transfer in IO mode */
+ if ((Msg->ByteCount < 8U) &&
+ (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA)) {
+ InstancePtr->ReadMode = XQSPIPSU_READMODE_IO;
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ (XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) &
+ ~XQSPIPSU_CFG_MODE_EN_MASK));
+ InstancePtr->IsUnaligned = 1;
+ }
+
+ XQspiPsu_TXRXSetup(InstancePtr, Msg, &GenFifoEntry);
+
+ XQspiPsu_GenFifoEntryDataLen(InstancePtr, Msg, &GenFifoEntry);
+
+ /* One dummy GenFifo entry in case of IO mode */
+ if ((InstancePtr->ReadMode == XQSPIPSU_READMODE_IO) &&
+ ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
+ GenFifoEntry = 0x0U;
+#ifdef DEBUG
+ xil_printf("\nDummy FifoEntry=%08x\r\n", GenFifoEntry);
+#endif
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry);
+ }
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function enables the polling functionality of controller
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ *
+ *
+ * @param FlashMsg is a pointer to the structure containing transfer data
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_PollDataConfig(XQspiPsu *InstancePtr, XQspiPsu_Msg *FlashMsg)
+{
+
+ u32 GenFifoEntry;
+ u32 Value;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(FlashMsg != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_PollDataConfig\r\n");
+#endif
+
+ Value = XQspiPsu_CreatePollDataConfig(InstancePtr, FlashMsg);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_POLL_CFG_OFFSET, Value);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_P_TO_OFFSET, FlashMsg->PollTimeout);
+
+ XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
+
+ GenFifoEntry = (u32)0;
+ GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_TX;
+ GenFifoEntry |= InstancePtr->GenFifoBus;
+ GenFifoEntry |= InstancePtr->GenFifoCS;
+ GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_MODE_SPI;
+ GenFifoEntry |= (u32)FlashMsg->PollStatusCmd;
+
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry);
+
+ GenFifoEntry = (u32)0;
+ GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_POLL;
+ GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_RX;
+ GenFifoEntry |= InstancePtr->GenFifoBus;
+ GenFifoEntry |= InstancePtr->GenFifoCS;
+ GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_MODE_SPI;
+ if (((FlashMsg->Flags) & XQSPIPSU_MSG_FLAG_STRIPE) != (u32)FALSE) {
+ GenFifoEntry |= XQSPIPSU_GENFIFO_STRIPE;
+ } else {
+ GenFifoEntry &= ~XQSPIPSU_GENFIFO_STRIPE;
+ }
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET,
+ GenFifoEntry);
+
+ /* One Dummy entry required for IO mode */
+ GenFifoEntry = 0x0U;
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET,
+ GenFifoEntry);
+
+ InstancePtr->Msg = FlashMsg;
+ InstancePtr->NumMsg = (s32)1;
+ InstancePtr->MsgCnt = 0;
+
+ Value = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+ Value &= ~XQSPIPSU_CFG_MODE_EN_MASK;
+ Value |= (XQSPIPSU_CFG_START_GEN_FIFO_MASK |
+ XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK |
+ XQSPIPSU_CFG_EN_POLL_TO_MASK);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ Value);
+
+ /* Enable interrupts */
+ Value = ((u32)XQSPIPSU_IER_RXNEMPTY_MASK |
+ (u32)XQSPIPSU_IER_POLL_TIME_EXPIRE_MASK);
+
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IER_OFFSET,
+ Value);
+
+}
+
+#if defined (ARMR5) || defined (__aarch64__) || defined (__MICROBLAZE__)
+/*****************************************************************************/
+/**
+*
+* Configures the clock according to the prescaler passed.
+*
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+* @param Prescaler - clock prescaler.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_DEVICE_BUSY if the device is currently transferring data.
+* The transfer must complete or be aborted before setting Tapdelay.
+*
+* @note None.
+*
+******************************************************************************/
+s32 XQspipsu_Calculate_Tapdelay(const XQspiPsu *InstancePtr, u8 Prescaler)
+{
+ u32 FreqDiv, Divider;
+ u32 Tapdelay = 0;
+ u32 LBkModeReg = 0;
+ u32 delayReg = 0;
+ s32 Status;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(Prescaler <= XQSPIPSU_CR_PRESC_MAXIMUM);
+
+ /*
+ * Do not allow the slave select to change while a transfer is in
+ * progress. Not thread-safe.
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ Status = (s32)XST_DEVICE_BUSY;
+ goto END;
+ } else {
+
+ Divider = (u32)1U << (Prescaler+1U);
+
+ FreqDiv = (InstancePtr->Config.InputClockHz)/Divider;
+
+#if defined (versal)
+ if (FreqDiv <= XQSPIPSU_FREQ_37_5MHZ) {
+#else
+ if (FreqDiv <= XQSPIPSU_FREQ_40MHZ) {
+#endif
+ Tapdelay |= (TAPDLY_BYPASS_VALVE_40MHZ <<
+ IOU_TAPDLY_BYPASS_LQSPI_RX_SHIFT);
+ } else if (FreqDiv <= XQSPIPSU_FREQ_100MHZ) {
+ Tapdelay |= (TAPDLY_BYPASS_VALVE_100MHZ <<
+ IOU_TAPDLY_BYPASS_LQSPI_RX_SHIFT);
+ LBkModeReg |= (USE_DLY_LPBK << XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_SHIFT);
+#if defined (versal)
+ delayReg |= (u32)USE_DATA_DLY_ADJ <<
+ XQSPIPSU_DATA_DLY_ADJ_USE_DATA_DLY_SHIFT;
+#else
+ delayReg |= ((u32)USE_DATA_DLY_ADJ <<
+ XQSPIPSU_DATA_DLY_ADJ_USE_DATA_DLY_SHIFT) |
+ ((u32)DATA_DLY_ADJ_DLY << XQSPIPSU_DATA_DLY_ADJ_DLY_SHIFT);
+#endif
+ } else if (FreqDiv <= XQSPIPSU_FREQ_150MHZ) {
+#if defined (versal)
+ LBkModeReg |= (USE_DLY_LPBK << XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_SHIFT) |
+ (LPBK_DLY_ADJ_DLY1 << XQSPIPSU_LPBK_DLY_ADJ_DLY1_SHIFT);
+#else
+ LBkModeReg |= USE_DLY_LPBK << XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_SHIFT;
+#endif
+ } else {
+ Status = (s32)XST_FAILURE;
+ goto END;
+ }
+
+ Status = XQspipsu_Set_TapDelay(InstancePtr, Tapdelay, LBkModeReg, delayReg);
+ }
+
+ END:
+ return Status;
+}
+#endif
+/** @} */
diff --git a/bsps/shared/dev/spi/xqspipsu_hw.c b/bsps/shared/dev/spi/xqspipsu_hw.c
new file mode 100644
index 0000000000..6f7708893f
--- /dev/null
+++ b/bsps/shared/dev/spi/xqspipsu_hw.c
@@ -0,0 +1,768 @@
+/******************************************************************************
+* Copyright (C) 2020 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+
+/*****************************************************************************/
+/**
+ *
+ * @file xqspipsu_hw.c
+ * @addtogroup Overview
+ * @{
+ *
+ * This file contains functions to reads RXFifo, writes TXFifo and setup
+ * RX DMA operation, used by xqspipsu_control.c and xqspipsu_lowlevel.c files.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- --- -------- -----------------------------------------------
+ * 1.11 akm 03/09/20 First release
+ * mn 03/30/20 Add xil_smc.h include for Xil_Smc calls
+ * 1.13 akm 01/04/21 Fix MISRA-C violations.
+ * 1.15 akm 10/21/21 Fix MISRA-C violations.
+ * 1.15 akm 11/16/21 Typecast function parameter with appropriate
+ * data type.
+ * 1.15 akm 11/30/21 Fix compilation warnings reported with -Wundef flag
+ * 1.15 akm 03/03/22 Enable tapdelay settings for applications on
+ * Microblaze platform.
+ *
+ * </pre>
+ ******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xqspipsu.h"
+#include "xqspipsu_control.h"
+#if defined (__aarch64__)
+#include "xil_smc.h"
+#endif
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+
+/*****************************************************************************/
+/**
+ *
+ * Fills the TX FIFO as long as there is room in the FIFO or the bytes required
+ * to be transmitted.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ * @param Size is the number of bytes to be transmitted.
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_FillTxFifo(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, u32 Size)
+{
+ u32 Count = 0;
+ u32 Data = 0U;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(Size != 0U);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_FillTxFifo\r\n");
+#endif
+ while ((InstancePtr->TxBytes > 0) && (Count < Size)) {
+ if (InstancePtr->TxBytes >= 4) {
+ (void)Xil_MemCpy((u8 *)&Data, Msg->TxBfrPtr, 4);
+ Msg->TxBfrPtr += 4;
+ InstancePtr->TxBytes -= 4;
+ Count += 4U;
+ } else {
+ (void)Xil_MemCpy((u8 *)&Data, Msg->TxBfrPtr,
+ (u32)InstancePtr->TxBytes);
+ Msg->TxBfrPtr += InstancePtr->TxBytes;
+ Count += (u32)InstancePtr->TxBytes;
+ InstancePtr->TxBytes = 0;
+ }
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_TXD_OFFSET, Data);
+#ifdef DEBUG
+ xil_printf("\nData is %08x\r\n", Data);
+#endif
+
+ }
+ if (InstancePtr->TxBytes < 0) {
+ InstancePtr->TxBytes = 0;
+ }
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function checks the TX buffer in the message and setup the
+ * TX FIFO as required.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_TXSetup(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_TXSetup\r\n");
+#endif
+ InstancePtr->TxBytes = (s32)Msg->ByteCount;
+ InstancePtr->SendBufferPtr = Msg->TxBfrPtr;
+
+ XQspiPsu_FillTxFifo(InstancePtr, Msg, (u32)XQSPIPSU_TXD_DEPTH);
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function sets up the RX DMA operation.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_SetupRxDma(const XQspiPsu *InstancePtr,
+ XQspiPsu_Msg *Msg)
+{
+ s32 Remainder;
+ s32 DmaRxBytes;
+ UINTPTR AddrTemp;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_SetupRxDma\r\n");
+#endif
+
+ AddrTemp = ((UINTPTR)(Msg->RxBfrPtr) & XQSPIPSU_QSPIDMA_DST_ADDR_MASK);
+ /* Check for RXBfrPtr to be word aligned */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_ADDR_OFFSET, (u32)AddrTemp);
+
+#if defined(__aarch64__) || defined(__arch64__)
+ AddrTemp = ((UINTPTR)(Msg->RxBfrPtr) >> 32U);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_ADDR_MSB_OFFSET, (u32)AddrTemp &
+ XQSPIPSU_QSPIDMA_DST_ADDR_MSB_MASK);
+#else
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_ADDR_MSB_OFFSET, 0U);
+#endif
+
+ Remainder = InstancePtr->RxBytes % 4;
+ DmaRxBytes = InstancePtr->RxBytes;
+ if (Remainder != 0) {
+ /* This is done to make Dma bytes aligned */
+ DmaRxBytes = InstancePtr->RxBytes - Remainder;
+ Msg->ByteCount = (u32)DmaRxBytes;
+ }
+ if (InstancePtr->Config.IsCacheCoherent == 0U) {
+ Xil_DCacheInvalidateRange((INTPTR)Msg->RxBfrPtr, (INTPTR)Msg->ByteCount);
+ }
+ /* Write no. of words to DMA DST SIZE */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_SIZE_OFFSET, (u32)DmaRxBytes);
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function sets up the RX DMA operation on a 32bit Machine
+ * For 64bit Dma transfers.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_Setup64BRxDma(const XQspiPsu *InstancePtr,
+ XQspiPsu_Msg *Msg)
+{
+ s32 Remainder;
+ s32 DmaRxBytes;
+ u64 AddrTemp;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_Setup64BRxDma\r\n");
+#endif
+ AddrTemp = Msg->RxAddr64bit & XQSPIPSU_QSPIDMA_DST_ADDR_MASK;
+
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_ADDR_OFFSET, (u32)AddrTemp);
+
+ AddrTemp = (Msg->RxAddr64bit >> 32);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_ADDR_MSB_OFFSET, (u32)AddrTemp &
+ XQSPIPSU_QSPIDMA_DST_ADDR_MSB_MASK);
+
+ Remainder = InstancePtr->RxBytes % 4;
+ DmaRxBytes = InstancePtr->RxBytes;
+ if (Remainder != 0) {
+ /* This is done to make Dma bytes aligned */
+ DmaRxBytes = InstancePtr->RxBytes - Remainder;
+ Msg->ByteCount = (u32)DmaRxBytes;
+ }
+
+ /* Write no. of words to DMA DST SIZE */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_SIZE_OFFSET, (u32)DmaRxBytes);
+
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function reads remaining bytes, after the completion of a DMA transfer,
+ * using IO mode
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if transfer fails.
+ * - XST_DEVICE_BUSY if a transfer is already in progress.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+u32 XQspiPsu_SetIOMode(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg)
+{
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(Msg != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_DMARXComplete\r\n");
+#endif
+
+ /* Read remaining bytes using IO mode */
+ if ((InstancePtr->RxBytes % 4) != 0) {
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ (XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) &
+ ~XQSPIPSU_CFG_MODE_EN_MASK));
+ InstancePtr->ReadMode = XQSPIPSU_READMODE_IO;
+ Msg->ByteCount = (u32)InstancePtr->RxBytes % 4U;
+ Msg->RxBfrPtr += (InstancePtr->RxBytes - (InstancePtr->RxBytes % 4));
+ InstancePtr->IsUnaligned = 1;
+ return (u32) TRUE;
+ }
+ return (u32) FALSE;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function checks the RX buffers in the message and setup the
+ * RX DMA as required.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_RXSetup(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_RXSetup\r\n");
+#endif
+ InstancePtr->RxBytes = (s32)Msg->ByteCount;
+
+ if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
+ if ((Msg->RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) ||
+ (Msg->Xfer64bit != (u8)0U)) {
+ XQspiPsu_Setup64BRxDma(InstancePtr, Msg);
+ } else {
+ XQspiPsu_SetupRxDma(InstancePtr, Msg);
+ }
+ }
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function checks the TX/RX buffers in the message and setups up the
+ * GENFIFO entries, TX FIFO or RX DMA as required.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ * @param GenFifoEntry is pointer to the variable in which GENFIFO mask
+ * is returned to calling function
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_TXRXSetup(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
+ u32 *GenFifoEntry)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(GenFifoEntry != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_TXRXSetup\r\n");
+#endif
+ /* Transmit */
+ if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) &&
+ ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE)) {
+
+ *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER;
+ *GenFifoEntry |= XQSPIPSU_GENFIFO_TX;
+ /* Discard RX data */
+ *GenFifoEntry &= ~XQSPIPSU_GENFIFO_RX;
+
+ /* Setup data to be TXed */
+ XQspiPsu_TXSetup(InstancePtr, Msg);
+
+ InstancePtr->RecvBufferPtr = NULL;
+ InstancePtr->RxBytes = 0;
+ }
+ /*Receive*/
+ if (((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE) &&
+ ((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) == (u32)FALSE)) {
+
+ /* TX auto fill */
+ *GenFifoEntry &= ~XQSPIPSU_GENFIFO_TX;
+ /* Setup RX */
+ *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER;
+ *GenFifoEntry |= XQSPIPSU_GENFIFO_RX;
+
+ /* Setup DMA for data to be RXed */
+ XQspiPsu_RXSetup(InstancePtr, Msg);
+
+ InstancePtr->SendBufferPtr = NULL;
+ InstancePtr->TxBytes = 0;
+ }
+ /* If only dummy is requested as a separate entry */
+ if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) == (u32)FALSE) &&
+ ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE)) {
+
+ *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER;
+ *GenFifoEntry &= ~(XQSPIPSU_GENFIFO_TX | XQSPIPSU_GENFIFO_RX);
+ InstancePtr->TxBytes = 0;
+ InstancePtr->RxBytes = 0;
+ InstancePtr->SendBufferPtr = NULL;
+ InstancePtr->RecvBufferPtr = NULL;
+ }
+ /* Dummy and cmd sent by upper layer to received data */
+ if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) &&
+ ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
+ *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER;
+ *GenFifoEntry |= (XQSPIPSU_GENFIFO_TX | XQSPIPSU_GENFIFO_RX);
+
+ /* Setup data to be TXed */
+ XQspiPsu_TXSetup(InstancePtr, Msg);
+ /* Setup DMA for data to be RXed */
+ XQspiPsu_RXSetup(InstancePtr, Msg);
+ }
+}
+/*****************************************************************************/
+/**
+ *
+ * This function writes the Data length to GENFIFO entries that need to be
+ * transmitted or received.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ * @param GenFifoEntry is index of the current message to be handled.
+ *
+ * @return
+ * - XST_SUCCESS if successful.
+ * - XST_FAILURE if transfer fails.
+ * - XST_DEVICE_BUSY if a transfer is already in progress.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_GenFifoEntryDataLen(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
+ u32 *GenFifoEntry)
+{
+ u32 TempCount;
+ u32 ImmData;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(GenFifoEntry != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_GenFifoEntryDataLen\r\n");
+#endif
+
+ if (Msg->ByteCount <= XQSPIPSU_GENFIFO_IMM_DATA_MASK) {
+ *GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_IMM_DATA_MASK;
+ *GenFifoEntry |= Msg->ByteCount;
+ #ifdef DEBUG
+ xil_printf("\nFifoEntry=%08x\r\n", *GenFifoEntry);
+ #endif
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET,
+ *GenFifoEntry);
+ } else {
+ TempCount = Msg->ByteCount;
+ u32 Exponent = 8; /* 2^8 = 256 */
+ ImmData = TempCount & 0xFFU;
+ /* Exponent entries */
+ *GenFifoEntry |= XQSPIPSU_GENFIFO_EXP;
+ while (TempCount != 0U) {
+ if ((TempCount & XQSPIPSU_GENFIFO_EXP_START) != (u32)FALSE) {
+ *GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_IMM_DATA_MASK;
+ *GenFifoEntry |= Exponent;
+ #ifdef DEBUG
+ xil_printf("\nFifoEntry=%08x\r\n",
+ *GenFifoEntry);
+ #endif
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET,
+ *GenFifoEntry);
+ }
+ TempCount = TempCount >> 1;
+ Exponent++;
+ }
+ /* Immediate entry */
+ *GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_EXP;
+ if ((ImmData & 0xFFU) != (u32)FALSE) {
+ *GenFifoEntry &= ~(u32)XQSPIPSU_GENFIFO_IMM_DATA_MASK;
+ *GenFifoEntry |= ImmData & 0xFFU;
+ #ifdef DEBUG
+ xil_printf("\nFifoEntry=%08x\r\n", *GenFifoEntry);
+ #endif
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET,
+ *GenFifoEntry);
+ }
+ }
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function creates Poll config register data to write
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ *
+ * @param FlashMsg is a pointer to the structure containing transfer data.
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+u32 XQspiPsu_CreatePollDataConfig(const XQspiPsu *InstancePtr,
+ const XQspiPsu_Msg *FlashMsg)
+{
+ u32 ConfigData = 0;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(FlashMsg != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_CreatePollDataConfig\r\n");
+#endif
+
+ if ((InstancePtr->GenFifoBus & XQSPIPSU_GENFIFO_BUS_UPPER) != (u32)FALSE) {
+ ConfigData = (u32)XQSPIPSU_SELECT_FLASH_BUS_LOWER <<
+ XQSPIPSU_POLL_CFG_EN_MASK_UPPER_SHIFT;
+ }
+ if ((InstancePtr->GenFifoBus & XQSPIPSU_GENFIFO_BUS_LOWER) != (u32)FALSE) {
+ ConfigData |= (u32)XQSPIPSU_SELECT_FLASH_BUS_LOWER <<
+ XQSPIPSU_POLL_CFG_EN_MASK_LOWER_SHIFT;
+ }
+ ConfigData |= (u32)(((u32)FlashMsg->PollBusMask <<
+ XQSPIPSU_POLL_CFG_MASK_EN_SHIFT) & XQSPIPSU_POLL_CFG_MASK_EN_MASK);
+ ConfigData |= (u32)(((u32)FlashMsg->PollData <<
+ XQSPIPSU_POLL_CFG_DATA_VALUE_SHIFT)
+ & XQSPIPSU_POLL_CFG_DATA_VALUE_MASK);
+ return ConfigData;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Selects SPI mode - x1 or x2 or x4.
+ *
+ * @param SpiMode - spi or dual or quad.
+ * @return Mask to set desired SPI mode in GENFIFO entry.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+u32 XQspiPsu_SelectSpiMode(u8 SpiMode)
+{
+ u32 Mask;
+
+ Xil_AssertNonvoid(SpiMode > 0U);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_SelectSpiMode\r\n");
+#endif
+
+ switch (SpiMode) {
+ case XQSPIPSU_SELECT_MODE_DUALSPI:
+ Mask = XQSPIPSU_GENFIFO_MODE_DUALSPI;
+ break;
+ case XQSPIPSU_SELECT_MODE_QUADSPI:
+ Mask = XQSPIPSU_GENFIFO_MODE_QUADSPI;
+ break;
+ case XQSPIPSU_SELECT_MODE_SPI:
+ Mask = XQSPIPSU_GENFIFO_MODE_SPI;
+ break;
+ default:
+ Mask = XQSPIPSU_GENFIFO_MODE_SPI;
+ break;
+ }
+#ifdef DEBUG
+ xil_printf("\nSPIMode is %08x\r\n", SpiMode);
+#endif
+ return Mask;
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Enable and initialize DMA Mode, set little endain, disable poll timeout,
+ * clear prescalar bits and reset thresholds
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_SetDefaultConfig(XQspiPsu *InstancePtr)
+{
+ u32 ConfigReg;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_SetDefaultConfig\r\n");
+#endif
+
+ /* Default value to config register */
+ ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+
+ /* DMA mode */
+ ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
+ ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK;
+ /* Manual start */
+ ConfigReg |= XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK;
+ /* Little endain by default */
+ ConfigReg &= ~XQSPIPSU_CFG_ENDIAN_MASK;
+ /* Disable poll timeout */
+ ConfigReg &= ~XQSPIPSU_CFG_EN_POLL_TO_MASK;
+ /* Set hold bit */
+ ConfigReg |= XQSPIPSU_CFG_WP_HOLD_MASK;
+ /* Clear prescalar by default */
+ ConfigReg &= ~(u32)XQSPIPSU_CFG_BAUD_RATE_DIV_MASK;
+ /* CPOL CPHA 00 */
+ ConfigReg &= ~(u32)XQSPIPSU_CFG_CLK_PHA_MASK;
+ ConfigReg &= ~(u32)XQSPIPSU_CFG_CLK_POL_MASK;
+
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET, ConfigReg);
+
+ /* Set by default to allow for high frequencies */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_LPBK_DLY_ADJ_OFFSET,
+ XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_LPBK_DLY_ADJ_OFFSET) |
+ XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_MASK);
+
+ /* Reset thresholds */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_TX_THRESHOLD_OFFSET, XQSPIPSU_TX_FIFO_THRESHOLD_RESET_VAL);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_RX_THRESHOLD_OFFSET, XQSPIPSU_RX_FIFO_THRESHOLD_RESET_VAL);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_GF_THRESHOLD_OFFSET, XQSPIPSU_GEN_FIFO_THRESHOLD_RESET_VAL);
+
+ /* DMA init */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET,
+ XQSPIPSU_QSPIDMA_DST_CTRL_RESET_VAL);
+}
+
+/*****************************************************************************/
+/**
+ *
+ * Read the specified number of bytes from RX FIFO
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ * @param Size is the number of bytes to be read.
+ *
+ * @return None
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_ReadRxFifo(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, s32 Size)
+{
+ s32 Count = 0;
+ u32 Data;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(Size > 0);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_ReadRxFifo\r\n");
+#endif
+ while ((InstancePtr->RxBytes != 0) && (Count < Size)) {
+ Data = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_RXD_OFFSET);
+#ifdef DEBUG
+ xil_printf("\nData is %08x\r\n", Data);
+#endif
+ if (InstancePtr->RxBytes >= 4) {
+ (void)Xil_MemCpy(Msg->RxBfrPtr, (u8 *)&Data, 4);
+ InstancePtr->RxBytes -= 4;
+ Msg->RxBfrPtr += 4;
+ Count += 4;
+ } else {
+ /* Read unaligned bytes (< 4 bytes) */
+ (void)Xil_MemCpy(Msg->RxBfrPtr, (u8 *)&Data,
+ (u32)InstancePtr->RxBytes);
+ Msg->RxBfrPtr += InstancePtr->RxBytes;
+ Count += InstancePtr->RxBytes;
+ InstancePtr->RxBytes = 0;
+ }
+ }
+}
+
+/*****************************************************************************/
+/**
+ *
+ * This function reads data from RXFifo in IO mode.
+ *
+ * @param InstancePtr is a pointer to the XQspiPsu instance.
+ * @param Msg is a pointer to the structure containing transfer data.
+ * @param StatusReg is the Interrupt status Register value.
+ *
+ * @return None.
+ *
+ * @note None.
+ *
+ ******************************************************************************/
+void XQspiPsu_IORead(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
+ u32 StatusReg)
+{
+ s32 RxThr;
+
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(Msg != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_IORXComplete\r\n");
+#endif
+
+ if ((StatusReg & XQSPIPSU_ISR_RXNEMPTY_MASK) != 0U) {
+ /*
+ * Check if PIO RX is complete and
+ * update RxBytes
+ */
+ RxThr = (s32)XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_RX_THRESHOLD_OFFSET);
+ RxThr = RxThr*4;
+ XQspiPsu_ReadRxFifo(InstancePtr, Msg, RxThr);
+
+ return;
+ }
+
+ if ((StatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != 0U) {
+ XQspiPsu_ReadRxFifo(InstancePtr, Msg, InstancePtr->RxBytes);
+ }
+}
+
+#if defined (ARMR5) || defined (__aarch64__) || defined (__MICROBLAZE__)
+/*****************************************************************************/
+/**
+*
+* This function sets the Tapdelay values for the QSPIPSU device driver.The device
+* must be idle rather than busy transferring data before setting Tapdelay.
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+* @param TapdelayBypss contains the IOU_TAPDLY_BYPASS register value.
+* @param LPBKDelay contains the GQSPI_LPBK_DLY_ADJ register value.
+* @param Datadelay contains the QSPI_DATA_DLY_ADJ register value.
+*
+* @return
+* - XST_SUCCESS if options are successfully set.
+* - XST_DEVICE_BUSY if the device is currently transferring data.
+* The transfer must complete or be aborted before setting TapDelay.
+*
+* @note
+* This function is not thread-safe.
+*
+******************************************************************************/
+s32 XQspipsu_Set_TapDelay(const XQspiPsu *InstancePtr, u32 TapdelayBypass,
+ u32 LPBKDelay, u32 Datadelay)
+{
+ s32 Status;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ /*
+ * Do not allow to modify the Control Register while a transfer is in
+ * progress. Not thread-safe.
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ Status = (s32)XST_DEVICE_BUSY;
+ } else {
+#if defined (__aarch64__) && (EL1_NONSECURE == 1) && !defined (versal)
+ Xil_Smc(MMIO_WRITE_SMC_FID, (u64)(XPS_SYS_CTRL_BASEADDR +
+ IOU_TAPDLY_BYPASS_OFFSET) | ((u64)(0x4) << 32),
+ (u64)TapdelayBypass, 0, 0, 0, 0, 0);
+#elif defined (versal)
+ XQspiPsu_WriteReg(XQSPIPS_BASEADDR, IOU_TAPDLY_BYPASS_OFFSET,
+ TapdelayBypass);
+#else
+ XQspiPsu_WriteReg(XPS_SYS_CTRL_BASEADDR, IOU_TAPDLY_BYPASS_OFFSET,
+ TapdelayBypass);
+#endif
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_LPBK_DLY_ADJ_OFFSET, LPBKDelay);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_DATA_DLY_ADJ_OFFSET, Datadelay);
+
+ Status = (s32)XST_SUCCESS;
+ }
+ return Status;
+}
+#endif
+/** @} */
diff --git a/bsps/shared/dev/spi/xqspipsu_options.c b/bsps/shared/dev/spi/xqspipsu_options.c
new file mode 100644
index 0000000000..c889d64abb
--- /dev/null
+++ b/bsps/shared/dev/spi/xqspipsu_options.c
@@ -0,0 +1,532 @@
+/******************************************************************************
+* Copyright (C) 2014 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xqspipsu_options.c
+* @addtogroup Overview
+* @{
+*
+* This file implements functions to configure the QSPIPSU component,
+* specifically some optional settings, clock and flash related information.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- -----------------------------------------------
+* 1.0 hk 08/21/14 First release
+* sk 03/13/15 Added IO mode support.
+* sk 04/24/15 Modified the code according to MISRAC-2012.
+* 1.1 sk 04/12/16 Added debug message prints.
+* 1.2 nsk 07/01/16 Modified XQspiPsu_SetOptions() to support
+* LQSPI options and updated OptionsTable
+* rk 07/15/16 Added support for TapDelays at different frequencies.
+* 1.7 tjs 01/17/18 Added support to toggle the WP pin of flash. (PR#2448)
+* 1.7 tjs 03/14/18 Added support in EL1 NS mode. (CR#974882)
+* 1.8 tjs 05/02/18 Added support for IS25LP064 and IS25WP064.
+* 1.8 tjs 07/26/18 Resolved cppcheck errors. (CR#1006336)
+* 1.9 tjs 04/17/18 Updated register addresses as per the latest revision
+* of versal (CR#999610)
+* 1.9 aru 01/17/19 Fixes violations according to MISRAC-2012
+* in safety mode and modified the code such as
+* Added Xil_MemCpy inplace of memcpy,Declared the pointer param
+* as Pointer to const, declared XQspi_Set_TapDelay() as static.
+* 1.9 akm 03/08/19 Set recommended clock and data tap delay values for 40MHZ,
+* 100MHZ and 150MHZ frequencies(CR#1023187)
+* 1.10 akm 08/22/19 Set recommended tap delay values for 37.5MHZ, 100MHZ and
+* 150MHZ frequencies in Versal.
+* 1.11 akm 11/07/19 Removed LQSPI register access in Versal.
+* 1.11 akm 11/15/19 Fixed Coverity deadcode warning in
+* XQspipsu_Calculate_Tapdelay().
+* 1.11 akm 03/09/20 Reorganize the source code, enable qspi controller and
+* interrupts in XQspiPsu_CfgInitialize() API.
+* 1.13 akm 01/04/21 Fix MISRA-C violations.
+* 1.15 akm 03/03/22 Enable tapdelay settings for applications on Microblaze
+* platform.
+*
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xqspipsu_control.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+/**
+ * Create the table of options which are processed to get/set the device
+ * options. These options are table driven to allow easy maintenance and
+ * expansion of the options.
+ */
+typedef struct {
+ u32 Option; /**< Get/Set the device option */
+ u32 Mask; /**< Mask */
+} OptionsMap;
+
+static OptionsMap OptionsTable[] = {
+ {XQSPIPSU_CLK_ACTIVE_LOW_OPTION, XQSPIPSU_CFG_CLK_POL_MASK},
+ {XQSPIPSU_CLK_PHASE_1_OPTION, XQSPIPSU_CFG_CLK_PHA_MASK},
+ {XQSPIPSU_MANUAL_START_OPTION, XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK},
+#if !defined (versal)
+ {XQSPIPSU_LQSPI_MODE_OPTION, XQSPIPSU_CFG_WP_HOLD_MASK},
+#endif
+};
+
+/**
+ * Number of options in option table
+ */
+#define XQSPIPSU_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap))
+
+/*****************************************************************************/
+/**
+*
+* This function sets the options for the QSPIPSU device driver.The options
+* control how the device behaves relative to the QSPIPSU bus. The device must be
+* idle rather than busy transferring data before setting these device options.
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+* @param Options contains the specified options to be set. This is a bit
+* mask where a 1 indicates the option should be turned ON and
+* a 0 indicates no action. One or more bit values may be
+* contained in the mask. See the bit definitions named
+* XQSPIPSU_*_OPTIONS in the file xqspipsu.h.
+*
+* @return
+* - XST_SUCCESS if options are successfully set.
+* - XST_DEVICE_BUSY if the device is currently transferring data.
+* The transfer must complete or be aborted before setting options.
+*
+* @note
+* This function is not thread-safe.
+*
+******************************************************************************/
+s32 XQspiPsu_SetOptions(XQspiPsu *InstancePtr, u32 Options)
+{
+ u32 ConfigReg;
+ u32 Index;
+#if !defined (versal)
+ u32 QspiPsuOptions;
+#endif
+ s32 Status;
+ u32 OptionsVal;
+ OptionsVal = Options;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ /*
+ * Do not allow to modify the Control Register while a transfer is in
+ * progress. Not thread-safe.
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ Status = (s32)XST_DEVICE_BUSY;
+ } else {
+ ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+#if !defined (versal)
+ QspiPsuOptions = OptionsVal & XQSPIPSU_LQSPI_MODE_OPTION;
+ OptionsVal &= (~XQSPIPSU_LQSPI_MODE_OPTION);
+#endif
+ /*
+ * Loop through the options table, turning the option on
+ * depending on whether the bit is set in the incoming options flag.
+ */
+ for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
+ if ((OptionsVal & OptionsTable[Index].Option) ==
+ OptionsTable[Index].Option) {
+ /* Turn it on */
+ ConfigReg |= OptionsTable[Index].Mask;
+ } else {
+ /* Turn it off */
+ ConfigReg &= ~(OptionsTable[Index].Mask);
+ }
+ }
+ /*
+ * Now write the control register. Leave it to the upper layers
+ * to restart the device.
+ */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ ConfigReg);
+
+ if ((OptionsVal & XQSPIPSU_MANUAL_START_OPTION) != (u32)FALSE) {
+ InstancePtr->IsManualstart = (u8)TRUE;
+ }
+#if !defined (versal)
+ if ((QspiPsuOptions & XQSPIPSU_LQSPI_MODE_OPTION) != (u32)FALSE) {
+ if ((Options & XQSPIPSU_LQSPI_LESS_THEN_SIXTEENMB) != (u32)FALSE) {
+ XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_LQSPI_CR_OFFSET,XQSPIPS_LQSPI_CR_RST_STATE);
+ } else {
+ XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_LQSPI_CR_OFFSET,XQSPIPS_LQSPI_CR_4_BYTE_STATE);
+ }
+ XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_CFG_OFFSET,XQSPIPS_LQSPI_CFG_RST_STATE);
+ /* Enable the QSPI controller */
+ XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_EN_OFFSET,XQSPIPSU_EN_MASK);
+ } else {
+ /*
+ * Check for the LQSPI configuration options.
+ */
+ ConfigReg = XQspiPsu_ReadReg(XQSPIPS_BASEADDR,XQSPIPSU_LQSPI_CR_OFFSET);
+ ConfigReg &= ~(XQSPIPSU_LQSPI_CR_LINEAR_MASK);
+ XQspiPsu_WriteReg(XQSPIPS_BASEADDR,XQSPIPSU_LQSPI_CR_OFFSET, ConfigReg);
+ }
+#endif
+ Status = (s32)XST_SUCCESS;
+ }
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function resets the options for the QSPIPSU device driver.The options
+* control how the device behaves relative to the QSPIPSU bus. The device must be
+* idle rather than busy transferring data before setting these device options.
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+* @param Options contains the specified options to be set. This is a bit
+* mask where a 1 indicates the option should be turned OFF and
+* a 0 indicates no action. One or more bit values may be
+* contained in the mask. See the bit definitions named
+* XQSPIPSU_*_OPTIONS in the file xqspipsu.h.
+*
+* @return
+* - XST_SUCCESS if options are successfully set.
+* - XST_DEVICE_BUSY if the device is currently transferring data.
+* The transfer must complete or be aborted before setting options.
+*
+* @note
+* This function is not thread-safe.
+*
+******************************************************************************/
+s32 XQspiPsu_ClearOptions(XQspiPsu *InstancePtr, u32 Options)
+{
+ u32 ConfigReg;
+ u32 Index;
+ s32 Status;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ /*
+ * Do not allow to modify the Control Register while a transfer is in
+ * progress. Not thread-safe.
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ Status = (s32)XST_DEVICE_BUSY;
+ } else {
+
+ ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+
+ /*
+ * Loop through the options table, turning the option on
+ * depending on whether the bit is set in the incoming options flag.
+ */
+ for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
+ if ((Options & OptionsTable[Index].Option) != (u32)FALSE) {
+ /* Turn it off */
+ ConfigReg &= ~OptionsTable[Index].Mask;
+ }
+ }
+ /*
+ * Now write the control register. Leave it to the upper layers
+ * to restart the device.
+ */
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ ConfigReg);
+
+ if ((Options & XQSPIPSU_MANUAL_START_OPTION) != (u32)FALSE) {
+ InstancePtr->IsManualstart = (u8)FALSE;
+ }
+
+ Status = (s32)XST_SUCCESS;
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function gets the options for the QSPIPSU device. The options control how
+* the device behaves relative to the QSPIPSU bus.
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+*
+* @return
+*
+* Options contains the specified options currently set. This is a bit value
+* where a 1 means the option is on, and a 0 means the option is off.
+* See the bit definitions named XQSPIPSU_*_OPTIONS in file xqspipsu.h.
+*
+* @note None.
+*
+******************************************************************************/
+u32 XQspiPsu_GetOptions(const XQspiPsu *InstancePtr)
+{
+ u32 OptionsFlag = 0;
+ u32 ConfigReg;
+ u32 Index;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+ /* Loop through the options table to grab options */
+ for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
+ /*
+ * Get the current options from QSPIPSU configuration register.
+ */
+ ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+ if ((ConfigReg & OptionsTable[Index].Mask) != (u32)FALSE) {
+ OptionsFlag |= OptionsTable[Index].Option;
+ }
+ }
+ return OptionsFlag;
+}
+
+/*****************************************************************************/
+/**
+*
+* Configures the clock according to the prescaler passed.
+*
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+* @param Prescaler - clock prescaler to be set.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_DEVICE_IS_STARTED if the device is already started.
+* - XST_DEVICE_BUSY if the device is currently transferring data.
+* It must be stopped to re-initialize.
+*
+* @note None.
+*
+******************************************************************************/
+s32 XQspiPsu_SetClkPrescaler(const XQspiPsu *InstancePtr, u8 Prescaler)
+{
+ u32 ConfigReg;
+ s32 Status;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid(Prescaler <= XQSPIPSU_CR_PRESC_MAXIMUM);
+
+ /*
+ * Do not allow the slave select to change while a transfer is in
+ * progress. Not thread-safe.
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ Status = (s32)XST_DEVICE_BUSY;
+ } else {
+ /*
+ * Read the configuration register, mask out the relevant bits, and set
+ * them with the shifted value passed into the function. Write the
+ * results back to the configuration register.
+ */
+ ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+
+ ConfigReg &= ~(u32)XQSPIPSU_CFG_BAUD_RATE_DIV_MASK;
+ ConfigReg |= (u32) ((u32)Prescaler & (u32)XQSPIPSU_CR_PRESC_MAXIMUM) <<
+ XQSPIPSU_CFG_BAUD_RATE_DIV_SHIFT;
+
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ ConfigReg);
+
+#if defined (ARMR5) || defined (__aarch64__) || defined (__MICROBLAZE__)
+ Status = XQspipsu_Calculate_Tapdelay(InstancePtr,Prescaler);
+#else
+ Status = (s32)XST_SUCCESS;
+#endif
+ }
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function should be used to tell the QSPIPSU driver the HW flash
+* configuration being used. This API should be called at least once in the
+* application. If desired, it can be called multiple times when switching
+* between communicating to different flahs devices/using different configs.
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+* @param FlashCS - Flash Chip Select.
+* @param FlashBus - Flash Bus (Upper, Lower or Both).
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_DEVICE_IS_STARTED if the device is already started.
+* It must be stopped to re-initialize.
+*
+* @note If this function is not called at least once in the application,
+* the driver assumes there is a single flash connected to the
+* lower bus and CS line.
+*
+******************************************************************************/
+void XQspiPsu_SelectFlash(XQspiPsu *InstancePtr, u8 FlashCS, u8 FlashBus)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(FlashCS > 0U);
+ Xil_AssertVoid(FlashBus > 0U);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_SelectFlash\r\n");
+#endif
+
+ /*
+ * Bus and CS lines selected here will be updated in the instance and
+ * used for subsequent GENFIFO entries during transfer.
+ */
+
+ /* Choose slave select line */
+ switch (FlashCS) {
+ case XQSPIPSU_SELECT_FLASH_CS_BOTH:
+ InstancePtr->GenFifoCS = (u32)XQSPIPSU_GENFIFO_CS_LOWER |
+ (u32)XQSPIPSU_GENFIFO_CS_UPPER;
+ break;
+ case XQSPIPSU_SELECT_FLASH_CS_UPPER:
+ InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_UPPER;
+ break;
+ case XQSPIPSU_SELECT_FLASH_CS_LOWER:
+ InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER;
+ break;
+ default:
+ InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER;
+ break;
+ }
+
+ /* Choose bus */
+ switch (FlashBus) {
+ case XQSPIPSU_SELECT_FLASH_BUS_BOTH:
+ InstancePtr->GenFifoBus = (u32)XQSPIPSU_GENFIFO_BUS_LOWER |
+ (u32)XQSPIPSU_GENFIFO_BUS_UPPER;
+ break;
+ case XQSPIPSU_SELECT_FLASH_BUS_UPPER:
+ InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_UPPER;
+ break;
+ case XQSPIPSU_SELECT_FLASH_BUS_LOWER:
+ InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER;
+ break;
+ default:
+ InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER;
+ break;
+ }
+#ifdef DEBUG
+ xil_printf("\nGenFifoCS is %08x and GenFifoBus is %08x\r\n",
+ InstancePtr->GenFifoCS, InstancePtr->GenFifoBus);
+#endif
+
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets the Read mode for the QSPIPSU device driver.The device
+* must be idle rather than busy transferring data before setting Read mode
+* options.
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+* @param Mode contains the specified Mode to be set. See the
+* bit definitions named XQSPIPSU_READMODE_* in the file xqspipsu.h.
+*
+* @return
+* - XST_SUCCESS if options are successfully set.
+* - XST_DEVICE_BUSY if the device is currently transferring data.
+* The transfer must complete or be aborted before setting Mode.
+*
+* @note
+* This function is not thread-safe.
+*
+******************************************************************************/
+s32 XQspiPsu_SetReadMode(XQspiPsu *InstancePtr, u32 Mode)
+{
+ u32 ConfigReg;
+ s32 Status;
+
+#ifdef DEBUG
+ xil_printf("\nXQspiPsu_SetReadMode\r\n");
+#endif
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertNonvoid((Mode == XQSPIPSU_READMODE_DMA) || (Mode == XQSPIPSU_READMODE_IO));
+
+ /*
+ * Do not allow to modify the Control Register while a transfer is in
+ * progress. Not thread-safe.
+ */
+ if (InstancePtr->IsBusy == (u32)TRUE) {
+ Status = (s32)XST_DEVICE_BUSY;
+ } else {
+
+ InstancePtr->ReadMode = Mode;
+
+ ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+
+ if (Mode == XQSPIPSU_READMODE_DMA) {
+ ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
+ ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK;
+ } else {
+ ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
+ }
+
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ ConfigReg);
+
+ Status = (s32)XST_SUCCESS;
+ }
+#ifdef DEBUG
+ xil_printf("\nRead Mode is %08x\r\n", InstancePtr->ReadMode);
+#endif
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function sets the Write Protect and Hold options for the QSPIPSU device
+* driver.The device must be idle rather than busy transferring data before
+* setting Write Protect and Hold options.
+*
+* @param InstancePtr is a pointer to the XQspiPsu instance.
+* @param Value of the WP_HOLD bit in configuration register
+*
+* @return None
+*
+* @note
+* This function is not thread-safe. This function can only be used with single
+* flash configuration and x1/x2 data mode. This function cannot be used with
+* x4 data mode and dual parallel and stacked flash configuration.
+*
+******************************************************************************/
+void XQspiPsu_SetWP(const XQspiPsu *InstancePtr, u8 Value)
+{
+ u32 ConfigReg;
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+ Xil_AssertVoid(InstancePtr->IsBusy != TRUE);
+
+ ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
+ XQSPIPSU_CFG_OFFSET);
+ ConfigReg |= (u32)((u32)Value << XQSPIPSU_CFG_WP_HOLD_SHIFT);
+ XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
+ ConfigReg);
+}
+/** @} */
diff --git a/bsps/shared/doxygen.h b/bsps/shared/doxygen.h
index d3679c2f3d..be681673d0 100644
--- a/bsps/shared/doxygen.h
+++ b/bsps/shared/doxygen.h
@@ -1,4 +1,12 @@
/**
+ * @file
+ *
+ * @ingroup RTEMSImplDoxygen
+ *
+ * @brief This header file defines BSP-specific groups.
+ */
+
+/**
* @defgroup RTEMSBSPs Board Support Packages
*
* @brief This group contains the Board Support Packages (BSPs).
diff --git a/bsps/shared/freebsd/stand/efi/include/README b/bsps/shared/freebsd/stand/efi/include/README
new file mode 100644
index 0000000000..bf821fae7e
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/README
@@ -0,0 +1,36 @@
+/* $FreeBSD$ */
+/*-
+
+Files in this directory and subdirectories are subject to the following
+copyright unless superceded or supplemented by additional specific license
+terms found in the file headers of individual files.
+
+Copyright (c) 1998-2000 Intel Corporation
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+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 ``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 INTEL 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. THE EFI SPECIFICATION AND ALL
+OTHER INFORMATION ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO
+WARRANTIES, AND ARE SUBJECT TO CHANGE WITHOUT NOTICE.
+
+*/
diff --git a/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h b/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h
new file mode 100644
index 0000000000..97b4a04865
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h
@@ -0,0 +1,275 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efefind.h
+
+Abstract:
+
+ EFI to compile bindings
+
+
+
+
+Revision History
+
+--*/
+
+#pragma pack()
+
+
+#ifdef __FreeBSD__
+#include <sys/stdint.h>
+#elif __rtems__
+#include <stdint.h>
+#else
+//
+// Basic int types of various widths
+//
+
+#if (__STDC_VERSION__ < 199901L )
+
+ // No ANSI C 1999/2000 stdint.h integer width declarations
+
+ #ifdef _MSC_EXTENSIONS
+
+ // Use Microsoft C compiler integer width declarations
+
+ typedef unsigned __int64 uint64_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef __int32 int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+ #ifdef UNIX_LP64
+
+ // Use LP64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long uint64_t;
+ typedef long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+
+ // Assume P64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #endif
+ #endif
+#endif
+#endif /* __FreeBSD__ */
+
+//
+// Basic EFI types of various widths
+//
+
+#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */
+#define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */
+
+typedef uint64_t UINT64;
+typedef int64_t INT64;
+
+#ifndef _BASETSD_H_
+ typedef uint32_t UINT32;
+ typedef int32_t INT32;
+#endif
+
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+
+#endif
+
+#undef VOID
+#define VOID void
+
+
+typedef int64_t INTN;
+typedef uint64_t UINTN;
+
+#ifdef EFI_NT_EMULATOR
+ #define POST_CODE(_Data)
+#else
+ #ifdef EFI_DEBUG
+#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al
+ #else
+ #define POST_CODE(_Data)
+ #endif
+#endif
+
+#define EFIERR(a) (0x8000000000000000 | a)
+#define EFI_ERROR_MASK 0x8000000000000000
+#define EFIERR_OEM(a) (0xc000000000000000 | a)
+
+
+#define BAD_POINTER 0xFBFBFBFBFBFBFBFB
+#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF
+
+#define BREAKPOINT() __asm { int 3 }
+
+//
+// Pointers must be aligned to these address to function
+//
+
+#define MIN_ALIGNMENT_SIZE 4
+
+#define ALIGN_VARIABLE(Value ,Adjustment) \
+ (UINTN)Adjustment = 0; \
+ if((UINTN)Value % MIN_ALIGNMENT_SIZE) \
+ (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
+ Value = (UINTN)Value + (UINTN)Adjustment
+
+
+//
+// Define macros to build data structure signatures from characters.
+//
+
+#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
+#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
+#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
+
+//
+// EFIAPI - prototype calling convention for EFI function pointers
+// BOOTSERVICE - prototype for implementation of a boot service interface
+// RUNTIMESERVICE - prototype for implementation of a runtime service interface
+// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service
+// RUNTIME_CODE - pragma macro for declaring runtime code
+//
+
+#ifdef __amd64__
+#define EFIAPI __attribute__((ms_abi))
+#endif
+
+#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options
+ #ifdef _MSC_EXTENSIONS
+ #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler
+ #else
+ #define EFIAPI // Substitute expresion to force C calling convention
+ #endif
+#endif
+
+#define BOOTSERVICE
+//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a
+//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a
+#define RUNTIMESERVICE
+#define RUNTIMEFUNCTION
+
+
+#define RUNTIME_CODE(a) alloc_text("rtcode", a)
+#define BEGIN_RUNTIME_DATA() data_seg("rtdata")
+#define END_RUNTIME_DATA() data_seg("")
+
+#define VOLATILE volatile
+
+#define MEMORY_FENCE()
+
+#ifdef EFI_NO_INTERFACE_DECL
+ #define EFI_FORWARD_DECLARATION(x)
+ #define EFI_INTERFACE_DECL(x)
+#else
+ #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+ #define EFI_INTERFACE_DECL(x) typedef struct x
+#endif
+
+#ifdef EFI_NT_EMULATOR
+
+//
+// To help ensure proper coding of integrated drivers, they are
+// compiled as DLLs. In NT they require a dll init entry pointer.
+// The macro puts a stub entry point into the DLL so it will load.
+//
+
+#define EFI_DRIVER_ENTRY_POINT(InitFunction) \
+ EFI_STATUS \
+ InitFunction ( \
+ EFI_HANDLE ImageHandle, \
+ EFI_SYSTEM_TABLE *SystemTable \
+ ); \
+ \
+ UINTN \
+ __stdcall \
+ _DllMainCRTStartup ( \
+ UINTN Inst, \
+ UINTN reason_for_call, \
+ VOID *rserved \
+ ) \
+ { \
+ return 1; \
+ } \
+ \
+ int \
+ __declspec( dllexport ) \
+ __cdecl \
+ InitializeDriver ( \
+ void *ImageHandle, \
+ void *SystemTable \
+ ) \
+ { \
+ return InitFunction(ImageHandle, SystemTable); \
+ }
+
+
+ #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, NULL)
+
+#else // EFI_NT_EMULATOR
+
+//
+// When building similar to FW, link everything together as
+// one big module.
+//
+
+ #define EFI_DRIVER_ENTRY_POINT(InitFunction)
+
+ #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, entry)
+
+#endif // EFI_FW_NT
+
+#ifdef __FreeBSD__
+#define INTERFACE_DECL(x) struct x
+#elif __rtems__
+#define INTERFACE_DECL(x) struct x
+#else
+//
+// Some compilers don't support the forward reference construct:
+// typedef struct XXXXX
+//
+// The following macro provide a workaround for such cases.
+//
+#ifdef NO_INTERFACE_DECL
+#define INTERFACE_DECL(x)
+#else
+#define INTERFACE_DECL(x) typedef struct x
+#endif
+#endif /* __FreeBSD__ */
+
+#ifdef _MSC_EXTENSIONS
+#pragma warning ( disable : 4731 ) // Suppress warnings about modification of EBP
+#endif
+
diff --git a/bsps/shared/freebsd/stand/efi/include/efi.h b/bsps/shared/freebsd/stand/efi/include/efi.h
new file mode 100644
index 0000000000..5b4743d44b
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/efi.h
@@ -0,0 +1,87 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efi.h
+
+Abstract:
+
+ Public EFI header files
+
+
+
+Revision History
+
+--*/
+
+//
+// Build flags on input
+// EFI32
+// EFI_DEBUG - Enable debugging code
+// EFI_NT_EMULATOR - Building for running under NT
+//
+
+
+#ifndef _EFI_INCLUDE_
+#define _EFI_INCLUDE_
+
+#define EFI_FIRMWARE_VENDOR L"INTEL"
+#define EFI_FIRMWARE_MAJOR_REVISION 14
+#define EFI_FIRMWARE_MINOR_REVISION 62
+#define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION))
+
+#include "efibind.h"
+#include "efidef.h"
+#include "efidevp.h"
+#ifndef __rtems__
+#include "efipciio.h"
+#include "efiprot.h"
+#endif /* __rtems__ */
+#include "eficon.h"
+#include "eficonsctl.h"
+#ifndef __rtems__
+#include "efiser.h"
+#include "efi_nii.h"
+#include "efipxebc.h"
+#include "efinet.h"
+#endif /* __rtems__ */
+#include "efiapi.h"
+#ifndef __rtems__
+#include "efifs.h"
+#endif /* __rtems__ */
+#include "efierr.h"
+#include "efigop.h"
+#ifndef __rtems__
+#include "efiip.h"
+#include "efiudp.h"
+#include "efitcp.h"
+#include "efipoint.h"
+#include "efiuga.h"
+#endif /* __rtems__ */
+#include <sys/types.h>
+#ifdef __rtems__
+#include <stdbool.h>
+#endif
+/*
+ * Global variables
+ */
+extern EFI_LOADED_IMAGE *boot_img;
+extern bool boot_services_active;
+
+/*
+ * FreeBSD UUID
+ */
+#define FREEBSD_BOOT_VAR_GUID \
+ { 0xCFEE69AD, 0xA0DE, 0x47A9, {0x93, 0xA8, 0xF6, 0x31, 0x06, 0xF8, 0xAE, 0x99} }
+
+#endif
diff --git a/bsps/shared/freebsd/stand/efi/include/efiapi.h b/bsps/shared/freebsd/stand/efi/include/efiapi.h
new file mode 100644
index 0000000000..fb5c861b38
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/efiapi.h
@@ -0,0 +1,1204 @@
+/* $FreeBSD$ */
+#ifndef _EFI_API_H
+#define _EFI_API_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efiapi.h
+
+Abstract:
+
+ Global EFI runtime & boot service interfaces
+
+
+
+
+Revision History
+
+--*/
+
+//
+// EFI Specification Revision
+//
+
+#define EFI_SPECIFICATION_MAJOR_REVISION 1
+#define EFI_SPECIFICATION_MINOR_REVISION 10
+
+//
+// Declare forward referenced data structures
+//
+
+INTERFACE_DECL(_EFI_SYSTEM_TABLE);
+
+//
+// EFI Memory
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ALLOCATE_PAGES) (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NoPages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FREE_PAGES) (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NoPages
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_MEMORY_MAP) (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ );
+
+#define NextMemoryDescriptor(Ptr,Size) ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) Ptr) + Size))
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ALLOCATE_POOL) (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FREE_POOL) (
+ IN VOID *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) (
+ IN UINTN MemoryMapSize,
+ IN UINTN DescriptorSize,
+ IN UINT32 DescriptorVersion,
+ IN EFI_MEMORY_DESCRIPTOR *VirtualMap
+ );
+
+
+#define EFI_OPTIONAL_PTR 0x00000001
+#define EFI_INTERNAL_FNC 0x00000002 // Pointer to internal runtime fnc
+#define EFI_INTERNAL_PTR 0x00000004 // Pointer to internal runtime data
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONVERT_POINTER) (
+ IN UINTN DebugDisposition,
+ IN OUT VOID **Address
+ );
+
+
+//
+// EFI Events
+//
+
+
+
+#define EVT_TIMER 0x80000000
+#define EVT_RUNTIME 0x40000000
+#define EVT_RUNTIME_CONTEXT 0x20000000
+
+#define EVT_NOTIFY_WAIT 0x00000100
+#define EVT_NOTIFY_SIGNAL 0x00000200
+
+#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201
+#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
+
+#define EVT_EFI_SIGNAL_MASK 0x000000FF
+#define EVT_EFI_SIGNAL_MAX 2
+
+typedef
+VOID
+(EFIAPI *EFI_EVENT_NOTIFY) (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CREATE_EVENT) (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ OUT EFI_EVENT *Event
+ );
+
+typedef enum {
+ TimerCancel,
+ TimerPeriodic,
+ TimerRelative,
+ TimerTypeMax
+} EFI_TIMER_DELAY;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIMER) (
+ IN EFI_EVENT Event,
+ IN EFI_TIMER_DELAY Type,
+ IN UINT64 TriggerTime
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIGNAL_EVENT) (
+ IN EFI_EVENT Event
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WAIT_FOR_EVENT) (
+ IN UINTN NumberOfEvents,
+ IN EFI_EVENT *Event,
+ OUT UINTN *Index
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_EVENT) (
+ IN EFI_EVENT Event
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CHECK_EVENT) (
+ IN EFI_EVENT Event
+ );
+
+//
+// Task priority level
+//
+
+#define TPL_APPLICATION 4
+#define TPL_CALLBACK 8
+#define TPL_NOTIFY 16
+#define TPL_HIGH_LEVEL 31
+
+typedef
+EFI_TPL
+(EFIAPI *EFI_RAISE_TPL) (
+ IN EFI_TPL NewTpl
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_RESTORE_TPL) (
+ IN EFI_TPL OldTpl
+ );
+
+
+//
+// EFI platform varibles
+//
+
+#define EFI_GLOBAL_VARIABLE \
+ { 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} }
+
+// Variable attributes
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
+
+// Variable size limitation
+#define EFI_MAXIMUM_VARIABLE_SIZE 1024
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_VARIABLE) (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) (
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName,
+ IN OUT EFI_GUID *VendorGuid
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_VARIABLE) (
+ IN const CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+
+//
+// EFI Time
+//
+
+typedef struct {
+ UINT32 Resolution; // 1e-6 parts per million
+ UINT32 Accuracy; // hertz
+ BOOLEAN SetsToZero; // Set clears sub-second time
+} EFI_TIME_CAPABILITIES;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_TIME) (
+ OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIME) (
+ IN EFI_TIME *Time
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_WAKEUP_TIME) (
+ OUT BOOLEAN *Enabled,
+ OUT BOOLEAN *Pending,
+ OUT EFI_TIME *Time
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_WAKEUP_TIME) (
+ IN BOOLEAN Enable,
+ IN EFI_TIME *Time OPTIONAL
+ );
+
+
+//
+// Image functions
+//
+
+
+// PE32+ Subsystem type for EFI images
+
+#if !defined(IMAGE_SUBSYSTEM_EFI_APPLICATION)
+#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+#endif
+
+// PE32+ Machine type for EFI images
+
+#if !defined(EFI_IMAGE_MACHINE_IA32)
+#define EFI_IMAGE_MACHINE_IA32 0x014c
+#endif
+
+#if !defined(EFI_IMAGE_MACHINE_EBC)
+#define EFI_IMAGE_MACHINE_EBC 0x0EBC
+#endif
+
+// Image Entry prototype
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_ENTRY_POINT) (
+ IN EFI_HANDLE ImageHandle,
+ IN struct _EFI_SYSTEM_TABLE *SystemTable
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_LOAD) (
+ IN BOOLEAN BootPolicy,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_START) (
+ IN EFI_HANDLE ImageHandle,
+ OUT UINTN *ExitDataSize,
+ OUT CHAR16 **ExitData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXIT) (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_STATUS ExitStatus,
+ IN UINTN ExitDataSize,
+ IN CHAR16 *ExitData OPTIONAL
+ )
+#ifndef __rtems__
+ __dead2
+#endif
+ ;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_UNLOAD) (
+ IN EFI_HANDLE ImageHandle
+ );
+
+
+// Image handle
+#define LOADED_IMAGE_PROTOCOL \
+ { 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} }
+
+#define EFI_LOADED_IMAGE_INFORMATION_REVISION 0x1000
+typedef struct {
+ UINT32 Revision;
+ EFI_HANDLE ParentHandle;
+ struct _EFI_SYSTEM_TABLE *SystemTable;
+
+ // Source location of image
+ EFI_HANDLE DeviceHandle;
+ EFI_DEVICE_PATH *FilePath;
+ VOID *Reserved;
+
+ // Images load options
+ UINT32 LoadOptionsSize;
+ VOID *LoadOptions;
+
+ // Location of where image was loaded
+ VOID *ImageBase;
+ UINT64 ImageSize;
+ EFI_MEMORY_TYPE ImageCodeType;
+ EFI_MEMORY_TYPE ImageDataType;
+
+ // If the driver image supports a dynamic unload request
+ EFI_IMAGE_UNLOAD Unload;
+
+} EFI_LOADED_IMAGE;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXIT_BOOT_SERVICES) (
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN MapKey
+ );
+
+//
+// Misc
+//
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_STALL) (
+ IN UINTN Microseconds
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_WATCHDOG_TIMER) (
+ IN UINTN Timeout,
+ IN UINT64 WatchdogCode,
+ IN UINTN DataSize,
+ IN CHAR16 *WatchdogData OPTIONAL
+ );
+
+
+typedef enum {
+ EfiResetCold,
+ EfiResetWarm,
+ EfiResetShutdown
+} EFI_RESET_TYPE;
+
+typedef
+VOID
+(EFIAPI *EFI_RESET_SYSTEM) (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData OPTIONAL
+ )
+#ifndef __rtems__
+ __dead2
+#endif
+ ;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT) (
+ OUT UINT64 *Count
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) (
+ OUT UINT32 *HighCount
+ );
+
+//
+// Protocol handler functions
+//
+
+typedef enum {
+ EFI_NATIVE_INTERFACE
+} EFI_INTERFACE_TYPE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE) (
+ IN OUT EFI_HANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *OldInterface,
+ IN VOID *NewInterface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HANDLE_PROTOCOL) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) (
+ IN EFI_GUID *Protocol,
+ IN EFI_EVENT Event,
+ OUT VOID **Registration
+ );
+
+typedef enum {
+ AllHandles,
+ ByRegisterNotify,
+ ByProtocol
+} EFI_LOCATE_SEARCH_TYPE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE) (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HANDLE *Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_DEVICE_PATH) (
+ IN EFI_GUID *Protocol,
+ IN OUT EFI_DEVICE_PATH **DevicePath,
+ OUT EFI_HANDLE *Device
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE) (
+ IN EFI_GUID *Guid,
+ IN VOID *Table
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RESERVED_SERVICE) (
+ VOID
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONNECT_CONTROLLER) (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL,
+ IN BOOLEAN Recursive
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DISCONNECT_CONTROLLER)(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle, OPTIONAL
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ );
+
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE ControllerHandle, OPTIONAL
+ IN UINT32 Attributes
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_PROTOCOL) (
+ IN EFI_HANDLE Handle,
+ IN EFI_GUID *Protocol,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle
+ );
+
+typedef struct {
+ EFI_HANDLE AgentHandle;
+ EFI_HANDLE ControllerHandle;
+ UINT32 Attributes;
+ UINT32 OpenCount;
+} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION) (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+ OUT UINTN *EntryCount
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PROTOCOLS_PER_HANDLE) (
+ IN EFI_HANDLE UserHandle,
+ OUT EFI_GUID ***ProtocolBuffer,
+ OUT UINTN *ProtocolBufferCount
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE_BUFFER) (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_PROTOCOL) (
+ EFI_GUID *Protocol,
+ VOID *Registration, OPTIONAL
+ VOID **Interface
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) (
+ IN OUT EFI_HANDLE *Handle,
+ ...
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) (
+ IN EFI_HANDLE Handle,
+ ...
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CALCULATE_CRC32) (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT32 *Crc32
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_COPY_MEM) (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ );
+
+typedef
+VOID
+(EFIAPI *EFI_SET_MEM) (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ );
+
+//
+// Standard EFI table header
+//
+
+typedef struct _EFI_TABLE_HEARDER {
+ UINT64 Signature;
+ UINT32 Revision;
+ UINT32 HeaderSize;
+ UINT32 CRC32;
+ UINT32 Reserved;
+} EFI_TABLE_HEADER;
+
+
+//
+// EFI Runtime Serivces Table
+//
+
+#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552
+#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION))
+
+typedef struct {
+ EFI_TABLE_HEADER Hdr;
+
+ //
+ // Time services
+ //
+
+ EFI_GET_TIME GetTime;
+ EFI_SET_TIME SetTime;
+ EFI_GET_WAKEUP_TIME GetWakeupTime;
+ EFI_SET_WAKEUP_TIME SetWakeupTime;
+
+ //
+ // Virtual memory services
+ //
+
+ EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;
+ EFI_CONVERT_POINTER ConvertPointer;
+
+ //
+ // Variable serviers
+ //
+
+ EFI_GET_VARIABLE GetVariable;
+ EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;
+ EFI_SET_VARIABLE SetVariable;
+
+ //
+ // Misc
+ //
+
+ EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount;
+ EFI_RESET_SYSTEM ResetSystem;
+
+} EFI_RUNTIME_SERVICES;
+
+
+//
+// EFI Boot Services Table
+//
+
+#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42
+#define EFI_BOOT_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION))
+
+typedef struct {
+
+ EFI_TABLE_HEADER Hdr;
+
+ //
+ // Task priority functions
+ //
+
+ EFI_RAISE_TPL RaiseTPL;
+ EFI_RESTORE_TPL RestoreTPL;
+
+ //
+ // Memory functions
+ //
+
+ EFI_ALLOCATE_PAGES AllocatePages;
+ EFI_FREE_PAGES FreePages;
+ EFI_GET_MEMORY_MAP GetMemoryMap;
+ EFI_ALLOCATE_POOL AllocatePool;
+ EFI_FREE_POOL FreePool;
+
+ //
+ // Event & timer functions
+ //
+
+ EFI_CREATE_EVENT CreateEvent;
+ EFI_SET_TIMER SetTimer;
+ EFI_WAIT_FOR_EVENT WaitForEvent;
+ EFI_SIGNAL_EVENT SignalEvent;
+ EFI_CLOSE_EVENT CloseEvent;
+ EFI_CHECK_EVENT CheckEvent;
+
+ //
+ // Protocol handler functions
+ //
+
+ EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;
+ EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
+ EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
+ EFI_HANDLE_PROTOCOL HandleProtocol;
+ VOID *Reserved;
+ EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
+ EFI_LOCATE_HANDLE LocateHandle;
+ EFI_LOCATE_DEVICE_PATH LocateDevicePath;
+ EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;
+
+ //
+ // Image functions
+ //
+
+ EFI_IMAGE_LOAD LoadImage;
+ EFI_IMAGE_START StartImage;
+ EFI_EXIT Exit;
+ EFI_IMAGE_UNLOAD UnloadImage;
+ EFI_EXIT_BOOT_SERVICES ExitBootServices;
+
+ //
+ // Misc functions
+ //
+
+ EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
+ EFI_STALL Stall;
+ EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;
+
+ //
+ // DriverSupport Services
+ //
+ EFI_CONNECT_CONTROLLER ConnectController;
+ EFI_DISCONNECT_CONTROLLER DisconnectController;
+
+ //
+ // Open and Close Protocol Services
+ //
+ EFI_OPEN_PROTOCOL OpenProtocol;
+ EFI_CLOSE_PROTOCOL CloseProtocol;
+ EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation;
+
+ //
+ // Library Services to reduce size of drivers
+ //
+ EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle;
+ EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
+ EFI_LOCATE_PROTOCOL LocateProtocol;
+
+ EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces;
+ EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces;
+
+ //
+ // CRC32 services
+ //
+ EFI_CALCULATE_CRC32 CalculateCrc32;
+
+ //
+ // Memory Utility Services
+ //
+ EFI_COPY_MEM CopyMem;
+ EFI_SET_MEM SetMem;
+
+} EFI_BOOT_SERVICES;
+
+
+//
+// EFI Configuration Table and GUID definitions
+//
+
+#define MPS_TABLE_GUID \
+ { 0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define ACPI_TABLE_GUID \
+ { 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define ACPI_20_TABLE_GUID \
+ { 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} }
+
+#define SMBIOS_TABLE_GUID \
+ { 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define SMBIOS3_TABLE_GUID \
+ { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94} }
+
+#define SAL_SYSTEM_TABLE_GUID \
+ { 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define FDT_TABLE_GUID \
+ { 0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0} }
+
+#define DXE_SERVICES_TABLE_GUID \
+ { 0x5ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9} }
+
+#define HOB_LIST_TABLE_GUID \
+ { 0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define LZMA_DECOMPRESSION_GUID \
+ { 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x3, 0xcf} }
+
+#define ARM_MP_CORE_INFO_TABLE_GUID \
+ { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
+
+#define ESRT_TABLE_GUID \
+ { 0xb122a263, 0x3661, 0x4f68, {0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80} }
+
+#define MEMORY_TYPE_INFORMATION_TABLE_GUID \
+ { 0x4c19049f, 0x4137, 0x4dd3, {0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa} }
+
+#define DEBUG_IMAGE_INFO_TABLE_GUID \
+ { 0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b} }
+
+typedef struct _EFI_CONFIGURATION_TABLE {
+ EFI_GUID VendorGuid;
+ VOID *VendorTable;
+} EFI_CONFIGURATION_TABLE;
+
+
+//
+// EFI System Table
+//
+
+
+
+
+#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
+#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION))
+#define EFI_1_10_SYSTEM_TABLE_REVISION ((1<<16) | 10)
+#define EFI_1_02_SYSTEM_TABLE_REVISION ((1<<16) | 02)
+
+typedef struct _EFI_SYSTEM_TABLE {
+ EFI_TABLE_HEADER Hdr;
+
+ CHAR16 *FirmwareVendor;
+ UINT32 FirmwareRevision;
+
+ EFI_HANDLE ConsoleInHandle;
+ SIMPLE_INPUT_INTERFACE *ConIn;
+
+ EFI_HANDLE ConsoleOutHandle;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut;
+
+ EFI_HANDLE StandardErrorHandle;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
+
+ EFI_RUNTIME_SERVICES *RuntimeServices;
+ EFI_BOOT_SERVICES *BootServices;
+
+ UINTN NumberOfTableEntries;
+ EFI_CONFIGURATION_TABLE *ConfigurationTable;
+
+} EFI_SYSTEM_TABLE;
+
+/*
+ * unlisted GUID's..
+ */
+#define EFI_EBC_INTERPRETER_PROTOCOL_GUID \
+{ 0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7} }
+
+#define EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID \
+{ 0xbfd7dc1d, 0x24f1, 0x40d9, {0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe} }
+
+#define EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID \
+{ 0x107a772b, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
+ { 0x18A031AB, 0xB443, 0x4D1A, \
+ { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \
+ }
+
+#define EFI_TAPE_IO_PROTOCOL_GUID \
+ { 0x1e93e633, 0xd65a, 0x459e, \
+ { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \
+ }
+
+#define EFI_SCSI_IO_PROTOCOL_GUID \
+ { 0x932f47e6, 0x2362, 0x4002, \
+ { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \
+ }
+
+#define EFI_USB2_HC_PROTOCOL_GUID \
+ { 0x3e745226, 0x9818, 0x45b6, \
+ { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \
+ }
+
+#define EFI_DEBUG_SUPPORT_PROTOCOL_GUID \
+ { 0x2755590C, 0x6F3C, 0x42FA, \
+ { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \
+ }
+
+#define EFI_DEBUGPORT_PROTOCOL_GUID \
+ { 0xEBA4E8D2, 0x3858, 0x41EC, \
+ { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \
+ }
+
+#define EFI_DECOMPRESS_PROTOCOL_GUID \
+ { 0xd8117cfe, 0x94a6, 0x11d4, \
+ { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define EFI_ACPI_TABLE_PROTOCOL_GUID \
+ { 0xffe06bdd, 0x6107, 0x46a6, \
+ { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \
+ }
+
+#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \
+ { 0x587e72d7, 0xcc50, 0x4f79, \
+ { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \
+ }
+
+#define EFI_HII_DATABASE_PROTOCOL_GUID \
+ { 0xef9fc172, 0xa1b2, 0x4693, \
+ { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \
+ }
+
+#define EFI_HII_STRING_PROTOCOL_GUID \
+ { 0xfd96974, 0x23aa, 0x4cdc, \
+ { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \
+ }
+
+#define EFI_HII_IMAGE_PROTOCOL_GUID \
+ { 0x31a6406a, 0x6bdf, 0x4e46, \
+ { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \
+ }
+
+#define EFI_HII_FONT_PROTOCOL_GUID \
+ { 0xe9ca4775, 0x8657, 0x47fc, \
+ { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \
+ }
+#define EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \
+ { 0x330d4706, 0xf2a0, 0x4e4f, \
+ { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \
+ }
+
+#define EFI_COMPONENT_NAME_PROTOCOL_GUID \
+{ 0x107a772c, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_COMPONENT_NAME2_PROTOCOL_GUID \
+ { 0x6a7a5cff, 0xe8d9, 0x4f70, \
+ { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \
+ }
+
+#define EFI_USB_IO_PROTOCOL_GUID \
+ { 0x2B2F68D6, 0x0CD2, 0x44cf, \
+ { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \
+ }
+#define EFI_HCDP_TABLE_GUID \
+ { 0xf951938d, 0x620b, 0x42ef, \
+ { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \
+ }
+
+#define EFI_DEVICE_TREE_GUID \
+ { 0xb1b621d5, 0xf19c, 0x41a5, \
+ { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
+ }
+
+#define EFI_VENDOR_APPLE_GUID \
+ { 0x2B0585EB, 0xD8B8, 0x49A9, \
+ { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
+ }
+
+#define EFI_CONSOLE_IN_DEVICE_GUID \
+{ 0xd3b36f2b, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_CONSOLE_OUT_DEVICE_GUID \
+{ 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_STANDARD_ERROR_DEVICE_GUID \
+{ 0xd3b36f2d, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_UNICODE_COLLATION2_PROTOCOL_GUID \
+{ 0xa4c751fc, 0x23ae, 0x4c3e, {0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49} }
+
+#define EFI_FORM_BROWSER2_PROTOCOL_GUID \
+{ 0xb9d4c360, 0xbcfb, 0x4f9b, {0x92, 0x98, 0x53, 0xc1, 0x36, 0x98, 0x22, 0x58} }
+
+#define EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0xf44c00ee, 0x1f2c, 0x4a00, {0xaa, 0x9, 0x1c, 0x9f, 0x3e, 0x8, 0x0, 0xa3} }
+
+#define EFI_ARP_PROTOCOL_GUID \
+{ 0xf4b427bb, 0xba21, 0x4f16, {0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c} }
+
+#define EFI_IP4_CONFIG_PROTOCOL_GUID \
+{ 0x3b95aa31, 0x3793, 0x434b, {0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e} }
+
+#define EFI_IP6_CONFIG_PROTOCOL_GUID \
+{ 0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a} }
+
+#define EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0xf36ff770, 0xa7e1, 0x42cf, {0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c} }
+
+#define EFI_MANAGED_NETWORK_PROTOCOL_GUID \
+{ 0x7ab33a91, 0xace5, 0x4326, {0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16} }
+
+#define EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0x2FE800BE, 0x8F01, 0x4aa6, {0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F} }
+
+#define EFI_MTFTP4_PROTOCOL_GUID \
+{ 0x78247c57, 0x63db, 0x4708, {0x99, 0xc2, 0xa8, 0xb4, 0xa9, 0xa6, 0x1f, 0x6b} }
+
+#define EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0xd9760ff3, 0x3cca, 0x4267, {0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23} }
+
+#define EFI_MTFTP6_PROTOCOL_GUID \
+{ 0xbf0a78ba, 0xec29, 0x49cf, {0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51} }
+
+#define EFI_DHCP4_PROTOCOL_GUID \
+{ 0x8a219718, 0x4ef5, 0x4761, {0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56} }
+
+#define EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0x9d9a39d8, 0xbd42, 0x4a73, {0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80} }
+
+#define EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID \
+{ 0x9fb9a8a1, 0x2f4a, 0x43a6, {0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5} }
+
+#define EFI_DHCP6_PROTOCOL_GUID \
+{ 0x87c8bad7, 0x595, 0x4053, {0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b} }
+
+#define EFI_SCSI_PASS_THRU_PROTOCOL_GUID \
+{ 0xa59e8fcf, 0xbda0, 0x43bb, {0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77} }
+
+#define EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID \
+{ 0x143b7632, 0xb81b, 0x4cb7, {0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe} }
+
+#define EFI_DISK_INFO_PROTOCOL_GUID \
+{ 0xd432a67f, 0x14dc, 0x484b, {0xb3, 0xbb, 0x3f, 0x2, 0x91, 0x84, 0x93, 0x27} }
+
+#define EFI_ISA_IO_PROTOCOL_GUID \
+{ 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_VLAN_CONFIG_PROTOCOL_GUID \
+{ 0x9e23d768, 0xd2f3, 0x4366, {0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74} }
+
+#define EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID \
+{ 0xa1e37052, 0x80d9, 0x4e65, {0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9} }
+
+#define EFI_ISA_ACPI_PROTOCOL_GUID \
+{ 0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55} }
+
+#define EFI_PCI_ENUMERATION_COMPLETE_GUID \
+{ 0x30cfe3e7, 0x3de1, 0x4586, {0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93} }
+
+#define EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID \
+{ 0x0784924f, 0xe296, 0x11d4, {0x9a, 0x49, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+#define EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID \
+{ 0x4d330321, 0x025f, 0x4aac, {0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63} }
+
+#define EFI_CAPSULE_ARCH_PROTOCOL_GUID \
+{ 0x5053697e, 0x2cbc, 0x4819, {0x90, 0xd9, 0x05, 0x80, 0xde, 0xee, 0x57, 0x54} }
+
+#define EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID \
+{0x1da97072, 0xbddc, 0x4b30, {0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a} }
+
+#define EFI_REALTIME_CLOCK_ARCH_PROTOCOL_GUID \
+{0x27cfac87, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_MP_SERVICES_PROTOCOL_GUID \
+{ 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} }
+
+#define EFI_VARIABLE_ARCH_PROTOCOL_GUID \
+{ 0x1e5668e2, 0x8481, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID \
+{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} }
+
+#define EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID \
+{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} }
+
+#define EFI_ACPI_SUPPORT_PROTOCOL_GUID \
+{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} }
+
+#define EFI_BDS_ARCH_PROTOCOL_GUID \
+{ 0x665e3ff6, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_METRONOME_ARCH_PROTOCOL_GUID \
+{ 0x26baccb2, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define EFI_TIMER_ARCH_PROTOCOL_GUID \
+{ 0x26baccb3, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define EFI_DPC_PROTOCOL_GUID \
+{ 0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6} }
+
+#define EFI_PRINT2_PROTOCOL_GUID \
+{ 0xf05976ef, 0x83f1, 0x4f3d, {0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38} }
+
+#define EFI_RESET_ARCH_PROTOCOL_GUID \
+{ 0x27cfac88, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define EFI_CPU_ARCH_PROTOCOL_GUID \
+{ 0x26baccb1, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define EFI_CPU_IO2_PROTOCOL_GUID \
+{ 0xad61f191, 0xae5f, 0x4c0e, {0xb9, 0xfa, 0xe8, 0x69, 0xd2, 0x88, 0xc6, 0x4f} }
+
+#define EFI_LEGACY_8259_PROTOCOL_GUID \
+{ 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1} }
+
+#define EFI_SECURITY_ARCH_PROTOCOL_GUID \
+{ 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39} }
+
+#define EFI_SECURITY2_ARCH_PROTOCOL_GUID \
+{ 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68} }
+
+#define EFI_RUNTIME_ARCH_PROTOCOL_GUID \
+{ 0xb7dfb4e1, 0x52f, 0x449f, {0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33} }
+
+#define EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID \
+{ 0xd2b2b828, 0x826, 0x48a7, {0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0} }
+
+#define EFI_DATA_HUB_PROTOCOL_GUID \
+{ 0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} }
+
+#define PCD_PROTOCOL_GUID \
+{ 0x11b34006, 0xd85b, 0x4d0a, { 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0xe, 0xf7} }
+
+#define EFI_PCD_PROTOCOL_GUID \
+{ 0x13a3f0f6, 0x264a, 0x3ef0, {0xf2, 0xe0, 0xde, 0xc5, 0x12, 0x34, 0x2f, 0x34} }
+
+#define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \
+{ 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } }
+
+#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID \
+{ 0x220e73b6, 0x6bdb, 0x4413, { 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a } }
+
+#define EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID \
+{ 0x7aa35a69, 0x506c, 0x444f, {0xa7, 0xaf, 0x69, 0x4b, 0xf5, 0x6f, 0x71, 0xc8} }
+
+#define LZMA_COMPRESS_GUID \
+{ 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf} }
+#endif
diff --git a/bsps/shared/freebsd/stand/efi/include/eficon.h b/bsps/shared/freebsd/stand/efi/include/eficon.h
new file mode 100644
index 0000000000..ba80114eb9
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/eficon.h
@@ -0,0 +1,527 @@
+/* $FreeBSD$ */
+#ifndef _EFI_CON_H
+#define _EFI_CON_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ eficon.h
+
+Abstract:
+
+ EFI console protocols
+
+
+
+Revision History
+
+--*/
+
+//
+// Text output protocol
+//
+
+#define SIMPLE_TEXT_OUTPUT_PROTOCOL \
+ { 0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+INTERFACE_DECL(_SIMPLE_TEXT_OUTPUT_INTERFACE);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_RESET) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_OUTPUT_STRING) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN CHAR16 *String
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_TEST_STRING) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN CHAR16 *String
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_QUERY_MODE) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN UINTN ModeNumber,
+ OUT UINTN *Columns,
+ OUT UINTN *Rows
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_MODE) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN UINTN ModeNumber
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_ATTRIBUTE) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN UINTN Attribute
+ );
+
+#define EFI_BLACK 0x00
+#define EFI_BLUE 0x01
+#define EFI_GREEN 0x02
+#define EFI_CYAN (EFI_BLUE | EFI_GREEN)
+#define EFI_RED 0x04
+#define EFI_MAGENTA (EFI_BLUE | EFI_RED)
+#define EFI_BROWN (EFI_GREEN | EFI_RED)
+#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED)
+#define EFI_BRIGHT 0x08
+#define EFI_DARKGRAY (EFI_BRIGHT)
+#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT)
+#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT)
+#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT)
+#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT)
+#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT)
+#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT)
+#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT)
+
+#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4))
+
+#define EFI_BACKGROUND_BLACK 0x00
+#define EFI_BACKGROUND_BLUE 0x10
+#define EFI_BACKGROUND_GREEN 0x20
+#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN)
+#define EFI_BACKGROUND_RED 0x40
+#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED)
+#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_CLEAR_SCREEN) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN UINTN Column,
+ IN UINTN Row
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_ENABLE_CURSOR) (
+ IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This,
+ IN BOOLEAN Enable
+ );
+
+typedef struct {
+ INT32 MaxMode;
+ // current settings
+ INT32 Mode;
+ INT32 Attribute;
+ INT32 CursorColumn;
+ INT32 CursorRow;
+ BOOLEAN CursorVisible;
+} SIMPLE_TEXT_OUTPUT_MODE;
+
+typedef struct _SIMPLE_TEXT_OUTPUT_INTERFACE {
+ EFI_TEXT_RESET Reset;
+
+ EFI_TEXT_OUTPUT_STRING OutputString;
+ EFI_TEXT_TEST_STRING TestString;
+
+ EFI_TEXT_QUERY_MODE QueryMode;
+ EFI_TEXT_SET_MODE SetMode;
+ EFI_TEXT_SET_ATTRIBUTE SetAttribute;
+
+ EFI_TEXT_CLEAR_SCREEN ClearScreen;
+ EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition;
+ EFI_TEXT_ENABLE_CURSOR EnableCursor;
+
+ // Current mode
+ SIMPLE_TEXT_OUTPUT_MODE *Mode;
+} SIMPLE_TEXT_OUTPUT_INTERFACE;
+
+//
+// Define's for required EFI Unicode Box Draw character
+//
+
+#define BOXDRAW_HORIZONTAL 0x2500
+#define BOXDRAW_VERTICAL 0x2502
+#define BOXDRAW_DOWN_RIGHT 0x250c
+#define BOXDRAW_DOWN_LEFT 0x2510
+#define BOXDRAW_UP_RIGHT 0x2514
+#define BOXDRAW_UP_LEFT 0x2518
+#define BOXDRAW_VERTICAL_RIGHT 0x251c
+#define BOXDRAW_VERTICAL_LEFT 0x2524
+#define BOXDRAW_DOWN_HORIZONTAL 0x252c
+#define BOXDRAW_UP_HORIZONTAL 0x2534
+#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c
+
+#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550
+#define BOXDRAW_DOUBLE_VERTICAL 0x2551
+#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552
+#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553
+#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554
+
+#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555
+#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556
+#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557
+
+#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558
+#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559
+#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a
+
+#define BOXDRAW_UP_LEFT_DOUBLE 0x255b
+#define BOXDRAW_UP_DOUBLE_LEFT 0x255c
+#define BOXDRAW_DOUBLE_UP_LEFT 0x255d
+
+#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e
+#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f
+#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560
+
+#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561
+#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562
+#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563
+
+#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564
+#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565
+#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566
+
+#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567
+#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568
+#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569
+
+#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a
+#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b
+#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c
+
+//
+// EFI Required Block Elements Code Chart
+//
+
+#define BLOCKELEMENT_FULL_BLOCK 0x2588
+#define BLOCKELEMENT_LIGHT_SHADE 0x2591
+//
+// EFI Required Geometric Shapes Code Chart
+//
+
+#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2
+#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba
+#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc
+#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4
+
+//
+// EFI Required Arrow shapes
+//
+
+#define ARROW_UP 0x2191
+#define ARROW_DOWN 0x2193
+
+//
+// Text input protocol
+//
+
+#define SIMPLE_TEXT_INPUT_PROTOCOL \
+ { 0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+INTERFACE_DECL(_SIMPLE_INPUT_INTERFACE);
+
+typedef struct {
+ UINT16 ScanCode;
+ CHAR16 UnicodeChar;
+} EFI_INPUT_KEY;
+
+//
+// Baseline unicode control chars
+//
+
+#define CHAR_NULL 0x0000
+#define CHAR_BACKSPACE 0x0008
+#define CHAR_TAB 0x0009
+#define CHAR_LINEFEED 0x000A
+#define CHAR_CARRIAGE_RETURN 0x000D
+
+//
+// Scan codes for base line keys
+//
+
+#define SCAN_NULL 0x0000
+#define SCAN_UP 0x0001
+#define SCAN_DOWN 0x0002
+#define SCAN_RIGHT 0x0003
+#define SCAN_LEFT 0x0004
+#define SCAN_HOME 0x0005
+#define SCAN_END 0x0006
+#define SCAN_INSERT 0x0007
+#define SCAN_DELETE 0x0008
+#define SCAN_PAGE_UP 0x0009
+#define SCAN_PAGE_DOWN 0x000A
+#define SCAN_F1 0x000B
+#define SCAN_F2 0x000C
+#define SCAN_F3 0x000D
+#define SCAN_F4 0x000E
+#define SCAN_F5 0x000F
+#define SCAN_F6 0x0010
+#define SCAN_F7 0x0011
+#define SCAN_F8 0x0012
+#define SCAN_F9 0x0013
+#define SCAN_F10 0x0014
+#define SCAN_ESC 0x0017
+
+//
+// EFI Scan code Ex
+//
+#define SCAN_F11 0x0015
+#define SCAN_F12 0x0016
+#define SCAN_F13 0x0068
+#define SCAN_F14 0x0069
+#define SCAN_F15 0x006A
+#define SCAN_F16 0x006B
+#define SCAN_F17 0x006C
+#define SCAN_F18 0x006D
+#define SCAN_F19 0x006E
+#define SCAN_F20 0x006F
+#define SCAN_F21 0x0070
+#define SCAN_F22 0x0071
+#define SCAN_F23 0x0072
+#define SCAN_F24 0x0073
+#define SCAN_MUTE 0x007F
+#define SCAN_VOLUME_UP 0x0080
+#define SCAN_VOLUME_DOWN 0x0081
+#define SCAN_BRIGHTNESS_UP 0x0100
+#define SCAN_BRIGHTNESS_DOWN 0x0101
+#define SCAN_SUSPEND 0x0102
+#define SCAN_HIBERNATE 0x0103
+#define SCAN_TOGGLE_DISPLAY 0x0104
+#define SCAN_RECOVERY 0x0105
+#define SCAN_EJECT 0x0106
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_RESET) (
+ IN struct _SIMPLE_INPUT_INTERFACE *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_READ_KEY) (
+ IN struct _SIMPLE_INPUT_INTERFACE *This,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+typedef struct _SIMPLE_INPUT_INTERFACE {
+ EFI_INPUT_RESET Reset;
+ EFI_INPUT_READ_KEY ReadKeyStroke;
+ EFI_EVENT WaitForKey;
+} SIMPLE_INPUT_INTERFACE;
+
+#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
+ {0xdd9e7534, 0x7762, 0x4698, {0x8c, 0x14, 0xf5, 0x85, \
+ 0x17, 0xa6, 0x25, 0xaa} }
+
+INTERFACE_DECL(_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL);
+
+typedef UINT8 EFI_KEY_TOGGLE_STATE;
+//
+// Any Shift or Toggle State that is valid should have
+// high order bit set.
+//
+typedef struct EFI_KEY_STATE {
+ UINT32 KeyShiftState;
+ EFI_KEY_TOGGLE_STATE KeyToggleState;
+} EFI_KEY_STATE;
+
+typedef struct {
+ EFI_INPUT_KEY Key;
+ EFI_KEY_STATE KeyState;
+} EFI_KEY_DATA;
+
+//
+// Shift state
+//
+#define EFI_SHIFT_STATE_VALID 0x80000000
+#define EFI_RIGHT_SHIFT_PRESSED 0x00000001
+#define EFI_LEFT_SHIFT_PRESSED 0x00000002
+#define EFI_RIGHT_CONTROL_PRESSED 0x00000004
+#define EFI_LEFT_CONTROL_PRESSED 0x00000008
+#define EFI_RIGHT_ALT_PRESSED 0x00000010
+#define EFI_LEFT_ALT_PRESSED 0x00000020
+#define EFI_RIGHT_LOGO_PRESSED 0x00000040
+#define EFI_LEFT_LOGO_PRESSED 0x00000080
+#define EFI_MENU_KEY_PRESSED 0x00000100
+#define EFI_SYS_REQ_PRESSED 0x00000200
+
+//
+// Toggle state
+//
+#define EFI_TOGGLE_STATE_VALID 0x80
+#define EFI_KEY_STATE_EXPOSED 0x40
+#define EFI_SCROLL_LOCK_ACTIVE 0x01
+#define EFI_NUM_LOCK_ACTIVE 0x02
+#define EFI_CAPS_LOCK_ACTIVE 0x04
+
+//
+// EFI Key Notfication Function
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KEY_NOTIFY_FUNCTION) (
+ IN EFI_KEY_DATA *KeyData
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_RESET_EX) (
+ IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+ Routine Description:
+ Reset the input device and optionaly run diagnostics
+
+ Arguments:
+ This - Protocol instance pointer.
+ ExtendedVerification - Driver may perform diagnostics on reset.
+
+ Returns:
+ EFI_SUCCESS - The device was reset.
+ EFI_DEVICE_ERROR - The device is not functioning properly and could
+ not be reset.
+
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_READ_KEY_EX) (
+ IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ )
+/*++
+
+ Routine Description:
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+ Arguments:
+ This - Protocol instance pointer.
+ KeyData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ Returns:
+ EFI_SUCCESS - The keystroke information was returned.
+ EFI_NOT_READY - There was no keystroke data availiable.
+ EFI_DEVICE_ERROR - The keystroke information was not returned due to
+ hardware errors.
+ EFI_INVALID_PARAMETER - KeyData is NULL.
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_STATE) (
+ IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ )
+/*++
+
+ Routine Description:
+ Set certain state for the input device.
+
+ Arguments:
+ This - Protocol instance pointer.
+ KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
+ state for the input device.
+
+ Returns:
+ EFI_SUCCESS - The device state was set successfully.
+ EFI_DEVICE_ERROR - The device is not functioning correctly and could
+ not have the setting adjusted.
+ EFI_UNSUPPORTED - The device does not have the ability to set its state.
+ EFI_INVALID_PARAMETER - KeyToggleState is NULL.
+
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY) (
+ IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+ )
+/*++
+
+ Routine Description:
+ Register a notification function for a particular keystroke for the input device.
+
+ Arguments:
+ This - Protocol instance pointer.
+ KeyData - A pointer to a buffer that is filled in with the keystroke
+ information data for the key that was pressed.
+ KeyNotificationFunction - Points to the function to be called when the key
+ sequence is typed specified by KeyData.
+ NotifyHandle - Points to the unique handle assigned to the registered notification.
+
+ Returns:
+ EFI_SUCCESS - The notification function was registered successfully.
+ EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
+ EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
+
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY) (
+ IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+ )
+/*++
+
+ Routine Description:
+ Remove a registered notification function from a particular keystroke.
+
+ Arguments:
+ This - Protocol instance pointer.
+ NotificationHandle - The handle of the notification function being unregistered.
+
+ Returns:
+ EFI_SUCCESS - The notification function was unregistered successfully.
+ EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
+ EFI_NOT_FOUND - Can not find the matching entry in database.
+
+--*/
+;
+
+typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL {
+ EFI_INPUT_RESET_EX Reset;
+ EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx;
+ EFI_EVENT WaitForKeyEx;
+ EFI_SET_STATE SetState;
+ EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify;
+ EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify;
+} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
+
+#endif
diff --git a/bsps/shared/freebsd/stand/efi/include/eficonsctl.h b/bsps/shared/freebsd/stand/efi/include/eficonsctl.h
new file mode 100644
index 0000000000..68be3d69f4
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/eficonsctl.h
@@ -0,0 +1,134 @@
+/*-
+ * Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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 HOLDER 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.
+ */
+
+/*
+ * Original Module Name: ConsoleControl.h
+ * Abstract: Abstraction of a Text mode or GOP/UGA screen
+ */
+
+/* $FreeBSD$ */
+
+#ifndef _EFI_CONS_CTL_H
+#define _EFI_CONS_CTL_H
+
+#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \
+ { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} }
+
+typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL;
+
+
+typedef enum {
+ EfiConsoleControlScreenText,
+ EfiConsoleControlScreenGraphics,
+ EfiConsoleControlScreenMaxValue
+} EFI_CONSOLE_CONTROL_SCREEN_MODE;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
+ OUT BOOLEAN *GopUgaExists, OPTIONAL
+ OUT BOOLEAN *StdInLocked OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Return the current video mode information. Also returns info about existence
+ of Graphics Output devices or UGA Draw devices in system, and if the Std In
+ device is locked. All the arguments are optional and only returned if a non
+ NULL pointer is passed in.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Mode - Are we in text of grahics mode.
+ GopUgaExists - TRUE if Console Spliter has found a GOP or UGA device
+ StdInLocked - TRUE if StdIn device is keyboard locked
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+
+--*/
+;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
+ )
+/*++
+
+ Routine Description:
+ Set the current mode to either text or graphics. Graphics is
+ for Quiet Boot.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Mode - Mode to set the
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+
+--*/
+;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) (
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN CHAR16 *Password
+ )
+/*++
+
+ Routine Description:
+ Lock Std In devices until Password is typed.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Password - Password needed to unlock screen. NULL means unlock keyboard
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_DEVICE_ERROR - Std In not locked
+
+--*/
+;
+
+
+
+struct _EFI_CONSOLE_CONTROL_PROTOCOL {
+ EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode;
+ EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode;
+ EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn;
+};
+
+extern EFI_GUID gEfiConsoleControlProtocolGuid;
+
+#endif
diff --git a/bsps/shared/freebsd/stand/efi/include/efidef.h b/bsps/shared/freebsd/stand/efi/include/efidef.h
new file mode 100644
index 0000000000..a8f88d41df
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/efidef.h
@@ -0,0 +1,224 @@
+/* $FreeBSD$ */
+#ifndef _EFI_DEF_H
+#define _EFI_DEF_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efidef.h
+
+Abstract:
+
+ EFI definitions
+
+
+
+
+Revision History
+
+--*/
+
+typedef UINT16 CHAR16;
+typedef UINT8 CHAR8;
+#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */
+typedef UINT8 BOOLEAN;
+#endif
+
+#ifndef TRUE
+ #define TRUE ((BOOLEAN) 1)
+ #define FALSE ((BOOLEAN) 0)
+#endif
+
+#ifndef NULL
+ #define NULL ((VOID *) 0)
+#endif
+
+typedef UINTN EFI_STATUS;
+typedef UINT64 EFI_LBA;
+typedef UINTN EFI_TPL;
+typedef VOID *EFI_HANDLE;
+typedef VOID *EFI_EVENT;
+
+
+//
+// Prototype argument decoration for EFI parameters to indicate
+// their direction
+//
+// IN - argument is passed into the function
+// OUT - argument (pointer) is returned from the function
+// OPTIONAL - argument is optional
+//
+
+#ifndef IN
+ #define IN
+ #define OUT
+ #define OPTIONAL
+ #define CONST const
+#endif
+
+
+//
+// A GUID
+//
+
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} EFI_GUID;
+
+
+//
+// Time
+//
+
+typedef struct {
+ UINT16 Year; // 1998 - 20XX
+ UINT8 Month; // 1 - 12
+ UINT8 Day; // 1 - 31
+ UINT8 Hour; // 0 - 23
+ UINT8 Minute; // 0 - 59
+ UINT8 Second; // 0 - 59
+ UINT8 Pad1;
+ UINT32 Nanosecond; // 0 - 999,999,999
+ INT16 TimeZone; // -1440 to 1440 or 2047
+ UINT8 Daylight;
+ UINT8 Pad2;
+} EFI_TIME;
+
+// Bit definitions for EFI_TIME.Daylight
+#define EFI_TIME_ADJUST_DAYLIGHT 0x01
+#define EFI_TIME_IN_DAYLIGHT 0x02
+
+// Value definition for EFI_TIME.TimeZone
+#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
+
+
+
+//
+// Networking
+//
+
+typedef struct {
+ UINT8 Addr[4];
+} EFI_IPv4_ADDRESS;
+
+typedef struct {
+ UINT8 Addr[16];
+} EFI_IPv6_ADDRESS;
+
+typedef struct {
+ UINT8 Addr[32];
+} EFI_MAC_ADDRESS;
+
+typedef struct {
+ UINT32 ReceivedQueueTimeoutValue;
+ UINT32 TransmitQueueTimeoutValue;
+ UINT16 ProtocolTypeFilter;
+ BOOLEAN EnableUnicastReceive;
+ BOOLEAN EnableMulticastReceive;
+ BOOLEAN EnableBroadcastReceive;
+ BOOLEAN EnablePromiscuousReceive;
+ BOOLEAN FlushQueuesOnReset;
+ BOOLEAN EnableReceiveTimestamps;
+ BOOLEAN DisableBackgroundPolling;
+} EFI_MANAGED_NETWORK_CONFIG_DATA;
+
+//
+// Memory
+//
+
+typedef UINT64 EFI_PHYSICAL_ADDRESS;
+typedef UINT64 EFI_VIRTUAL_ADDRESS;
+
+typedef enum {
+ AllocateAnyPages,
+ AllocateMaxAddress,
+ AllocateAddress,
+ MaxAllocateType
+} EFI_ALLOCATE_TYPE;
+
+//Preseve the attr on any range supplied.
+//ConventialMemory must have WB,SR,SW when supplied.
+//When allocating from ConventialMemory always make it WB,SR,SW
+//When returning to ConventialMemory always make it WB,SR,SW
+//When getting the memory map, or on RT for runtime types
+
+
+typedef enum {
+ EfiReservedMemoryType,
+ EfiLoaderCode,
+ EfiLoaderData,
+ EfiBootServicesCode,
+ EfiBootServicesData,
+ EfiRuntimeServicesCode,
+ EfiRuntimeServicesData,
+ EfiConventionalMemory,
+ EfiUnusableMemory,
+ EfiACPIReclaimMemory,
+ EfiACPIMemoryNVS,
+ EfiMemoryMappedIO,
+ EfiMemoryMappedIOPortSpace,
+ EfiPalCode,
+ EfiPersistentMemory,
+ EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+// possible caching types for the memory range
+#define EFI_MEMORY_UC 0x0000000000000001
+#define EFI_MEMORY_WC 0x0000000000000002
+#define EFI_MEMORY_WT 0x0000000000000004
+#define EFI_MEMORY_WB 0x0000000000000008
+#define EFI_MEMORY_UCE 0x0000000000000010
+
+// physical memory protection on range
+#define EFI_MEMORY_WP 0x0000000000001000
+#define EFI_MEMORY_RP 0x0000000000002000
+#define EFI_MEMORY_XP 0x0000000000004000
+#define EFI_MEMORY_NV 0x0000000000008000
+#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000
+#define EFI_MEMORY_RO 0x0000000000020000
+
+// range requires a runtime mapping
+#define EFI_MEMORY_RUNTIME 0x8000000000000000
+
+#define EFI_MEMORY_DESCRIPTOR_VERSION 1
+typedef struct {
+ UINT32 Type; // Field size is 32 bits followed by 32 bit pad
+ UINT32 Pad;
+ EFI_PHYSICAL_ADDRESS PhysicalStart; // Field size is 64 bits
+ EFI_VIRTUAL_ADDRESS VirtualStart; // Field size is 64 bits
+ UINT64 NumberOfPages; // Field size is 64 bits
+ UINT64 Attribute; // Field size is 64 bits
+} EFI_MEMORY_DESCRIPTOR;
+
+//
+// International Language
+//
+
+typedef UINT8 ISO_639_2;
+#define ISO_639_2_ENTRY_SIZE 3
+
+//
+//
+//
+
+#define EFI_PAGE_SIZE 4096
+#define EFI_PAGE_MASK 0xFFF
+#define EFI_PAGE_SHIFT 12
+
+#define EFI_SIZE_TO_PAGES(a) \
+ ( ((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0) )
+
+#endif
diff --git a/bsps/shared/freebsd/stand/efi/include/efidevp.h b/bsps/shared/freebsd/stand/efi/include/efidevp.h
new file mode 100644
index 0000000000..b00b78f02c
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/efidevp.h
@@ -0,0 +1,511 @@
+/* $FreeBSD$ */
+#ifndef _DEVPATH_H
+#define _DEVPATH_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ devpath.h
+
+Abstract:
+
+ Defines for parsing the EFI Device Path structures
+
+
+
+Revision History
+
+--*/
+
+//
+// Device Path structures - Section C
+//
+
+#pragma pack(1)
+
+typedef struct _EFI_DEVICE_PATH {
+ UINT8 Type;
+ UINT8 SubType;
+ UINT8 Length[2];
+} EFI_DEVICE_PATH;
+
+#define EFI_DP_TYPE_MASK 0x7F
+#define EFI_DP_TYPE_UNPACKED 0x80
+
+#define END_DEVICE_PATH_TYPE 0x7f
+
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH))
+
+
+#define DP_IS_END_TYPE(a)
+#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+
+#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK )
+#define DevicePathSubType(a) ( (a)->SubType )
+#define DevicePathNodeLength(a) ((size_t)(((a)->Length[0]) | ((a)->Length[1] << 8)))
+#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a)))
+#define IsDevicePathType(a, t) ( DevicePathType(a) == t )
+#define IsDevicePathEndType(a) IsDevicePathType(a, END_DEVICE_PATH_TYPE)
+#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
+#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED )
+
+
+#define SetDevicePathNodeLength(a,l) { \
+ (a)->Length[0] = (UINT8) (l); \
+ (a)->Length[1] = (UINT8) ((l) >> 8); \
+ }
+
+#define SetDevicePathEndNode(a) { \
+ (a)->Type = END_DEVICE_PATH_TYPE; \
+ (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \
+ (a)->Length[0] = sizeof(EFI_DEVICE_PATH); \
+ (a)->Length[1] = 0; \
+ }
+
+/*
+ *
+ */
+#define HARDWARE_DEVICE_PATH 0x01
+
+#define HW_PCI_DP 0x01
+typedef struct _PCI_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT8 Function;
+ UINT8 Device;
+} PCI_DEVICE_PATH;
+
+#define HW_PCCARD_DP 0x02
+typedef struct _PCCARD_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT8 FunctionNumber;
+} PCCARD_DEVICE_PATH;
+
+#define HW_MEMMAP_DP 0x03
+typedef struct _MEMMAP_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 MemoryType;
+ EFI_PHYSICAL_ADDRESS StartingAddress;
+ EFI_PHYSICAL_ADDRESS EndingAddress;
+} MEMMAP_DEVICE_PATH;
+
+#define HW_VENDOR_DP 0x04
+typedef struct _VENDOR_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_GUID Guid;
+} VENDOR_DEVICE_PATH;
+
+#define UNKNOWN_DEVICE_GUID \
+ { 0xcf31fac5, 0xc24e, 0x11d2, {0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} }
+
+typedef struct _UKNOWN_DEVICE_VENDOR_DP {
+ VENDOR_DEVICE_PATH DevicePath;
+ UINT8 LegacyDriveLetter;
+} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH;
+
+#define HW_CONTROLLER_DP 0x05
+typedef struct _CONTROLLER_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Controller;
+} CONTROLLER_DEVICE_PATH;
+
+/*
+ *
+ */
+#define ACPI_DEVICE_PATH 0x02
+
+#define ACPI_DP 0x01
+typedef struct _ACPI_HID_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 HID;
+ UINT32 UID;
+} ACPI_HID_DEVICE_PATH;
+
+#define ACPI_EXTENDED_DP 0x02
+typedef struct _ACPI_EXTENDED_HID_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 HID;
+ UINT32 UID;
+ UINT32 CID;
+} ACPI_EXTENDED_HID_DEVICE_PATH;
+
+#define ACPI_ADR_DP 0x03
+/* ACPI_ADR_DEVICE_PATH not defined */
+
+//
+// EISA ID Macro
+// EISA ID Definition 32-bits
+// bits[15:0] - three character compressed ASCII EISA ID.
+// bits[31:16] - binary number
+// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
+//
+#define PNP_EISA_ID_CONST 0x41d0
+#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16))
+#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+
+#define PNP_EISA_ID_MASK 0xffff
+#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16)
+/*
+ *
+ */
+#define MESSAGING_DEVICE_PATH 0x03
+
+#define MSG_ATAPI_DP 0x01
+typedef struct _ATAPI_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT8 PrimarySecondary;
+ UINT8 SlaveMaster;
+ UINT16 Lun;
+} ATAPI_DEVICE_PATH;
+
+#define MSG_SCSI_DP 0x02
+typedef struct _SCSI_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 Pun;
+ UINT16 Lun;
+} SCSI_DEVICE_PATH;
+
+#define MSG_FIBRECHANNEL_DP 0x03
+typedef struct _FIBRECHANNEL_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Reserved;
+ UINT64 WWN;
+ UINT64 Lun;
+} FIBRECHANNEL_DEVICE_PATH;
+
+#define MSG_1394_DP 0x04
+typedef struct _F1394_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Reserved;
+ UINT64 Guid;
+} F1394_DEVICE_PATH;
+
+#define MSG_USB_DP 0x05
+typedef struct _USB_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT8 ParentPortNumber;
+ UINT8 InterfaceNumber;
+} USB_DEVICE_PATH;
+
+#define MSG_USB_CLASS_DP 0x0F
+typedef struct _USB_CLASS_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 VendorId;
+ UINT16 ProductId;
+ UINT8 DeviceClass;
+ UINT8 DeviceSubClass;
+ UINT8 DeviceProtocol;
+} USB_CLASS_DEVICE_PATH;
+
+#define MSG_I2O_DP 0x06
+typedef struct _I2O_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Tid;
+} I2O_DEVICE_PATH;
+
+#define MSG_MAC_ADDR_DP 0x0b
+typedef struct _MAC_ADDR_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_MAC_ADDRESS MacAddress;
+ UINT8 IfType;
+} MAC_ADDR_DEVICE_PATH;
+
+#define MSG_IPv4_DP 0x0c
+typedef struct _IPv4_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_IPv4_ADDRESS LocalIpAddress;
+ EFI_IPv4_ADDRESS RemoteIpAddress;
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ UINT16 Protocol;
+ BOOLEAN StaticIpAddress;
+ EFI_IPv4_ADDRESS GatewayIpAddress;
+ EFI_IPv4_ADDRESS SubnetMask;
+} IPv4_DEVICE_PATH;
+
+#define MSG_IPv6_DP 0x0d
+typedef struct _IPv6_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_IPv6_ADDRESS LocalIpAddress;
+ EFI_IPv6_ADDRESS RemoteIpAddress;
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ UINT16 Protocol;
+ BOOLEAN StaticIpAddress;
+} IPv6_DEVICE_PATH;
+
+#define MSG_INFINIBAND_DP 0x09
+typedef struct _INFINIBAND_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 ResourceFlags;
+ UINT8 PortGid[16];
+ UINT64 ServiceId;
+ UINT64 TargetPortId;
+ UINT64 DeviceId;
+} INFINIBAND_DEVICE_PATH;
+
+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01
+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02
+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04
+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08
+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10
+
+#define MSG_UART_DP 0x0e
+typedef struct _UART_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 Reserved;
+ UINT64 BaudRate;
+ UINT8 DataBits;
+ UINT8 Parity;
+ UINT8 StopBits;
+} UART_DEVICE_PATH;
+
+#define MSG_VENDOR_DP 0x0A
+/* Use VENDOR_DEVICE_PATH struct */
+
+#define DEVICE_PATH_MESSAGING_PC_ANSI \
+ { 0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define DEVICE_PATH_MESSAGING_VT_100 \
+ { 0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
+
+#define DEVICE_PATH_MESSAGING_VT_100_PLUS \
+ { 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43} }
+
+#define DEVICE_PATH_MESSAGING_VT_UTF8 \
+ { 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88} }
+
+/* Device Logical Unit SubType. */
+#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11
+typedef struct {
+ EFI_DEVICE_PATH Header;
+ /* Logical Unit Number for the interface. */
+ UINT8 Lun;
+} DEVICE_LOGICAL_UNIT_DEVICE_PATH;
+
+#define MSG_SATA_DP 0x12
+typedef struct _SATA_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 HBAPortNumber;
+ UINT16 PortMultiplierPortNumber;
+ UINT16 Lun;
+} SATA_DEVICE_PATH;
+
+
+/* DNS Device Path SubType */
+#define MSG_DNS_DP 0x1F
+typedef struct {
+ EFI_DEVICE_PATH Header;
+ /* Indicates the DNS server address is IPv4 or IPv6 address. */
+ UINT8 IsIPv6;
+ /* Instance of the DNS server address. */
+ /* XXX: actually EFI_IP_ADDRESS */
+ EFI_IPv4_ADDRESS DnsServerIp[];
+} DNS_DEVICE_PATH;
+
+/* Uniform Resource Identifiers (URI) Device Path SubType */
+#define MSG_URI_DP 0x18
+typedef struct {
+ EFI_DEVICE_PATH Header;
+ /* Instance of the URI pursuant to RFC 3986. */
+ CHAR8 Uri[];
+} URI_DEVICE_PATH;
+
+#define MEDIA_DEVICE_PATH 0x04
+
+#define MEDIA_HARDDRIVE_DP 0x01
+typedef struct _HARDDRIVE_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 PartitionNumber;
+ UINT64 PartitionStart;
+ UINT64 PartitionSize;
+ UINT8 Signature[16];
+ UINT8 MBRType;
+ UINT8 SignatureType;
+} HARDDRIVE_DEVICE_PATH;
+
+#define MBR_TYPE_PCAT 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define SIGNATURE_TYPE_MBR 0x01
+#define SIGNATURE_TYPE_GUID 0x02
+
+#define MEDIA_CDROM_DP 0x02
+typedef struct _CDROM_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT32 BootEntry;
+ UINT64 PartitionStart;
+ UINT64 PartitionSize;
+} CDROM_DEVICE_PATH;
+
+#define MEDIA_VENDOR_DP 0x03
+/* Use VENDOR_DEVICE_PATH struct */
+
+#define MEDIA_FILEPATH_DP 0x04
+typedef struct _FILEPATH_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ CHAR16 PathName[1];
+} FILEPATH_DEVICE_PATH;
+
+#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName)
+
+#define MEDIA_PROTOCOL_DP 0x05
+typedef struct _MEDIA_PROTOCOL_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ EFI_GUID Protocol;
+} MEDIA_PROTOCOL_DEVICE_PATH;
+
+
+#define BBS_DEVICE_PATH 0x05
+#define BBS_BBS_DP 0x01
+typedef struct _BBS_BBS_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 DeviceType;
+ UINT16 StatusFlag;
+ CHAR8 String[1];
+} BBS_BBS_DEVICE_PATH;
+
+/* DeviceType definitions - from BBS specification */
+#define BBS_TYPE_FLOPPY 0x01
+#define BBS_TYPE_HARDDRIVE 0x02
+#define BBS_TYPE_CDROM 0x03
+#define BBS_TYPE_PCMCIA 0x04
+#define BBS_TYPE_USB 0x05
+#define BBS_TYPE_EMBEDDED_NETWORK 0x06
+#define BBS_TYPE_DEV 0x80
+#define BBS_TYPE_UNKNOWN 0xFF
+
+typedef union {
+ EFI_DEVICE_PATH DevPath;
+ PCI_DEVICE_PATH Pci;
+ PCCARD_DEVICE_PATH PcCard;
+ MEMMAP_DEVICE_PATH MemMap;
+ VENDOR_DEVICE_PATH Vendor;
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor;
+ CONTROLLER_DEVICE_PATH Controller;
+ ACPI_HID_DEVICE_PATH Acpi;
+
+ ATAPI_DEVICE_PATH Atapi;
+ SCSI_DEVICE_PATH Scsi;
+ FIBRECHANNEL_DEVICE_PATH FibreChannel;
+
+ F1394_DEVICE_PATH F1394;
+ USB_DEVICE_PATH Usb;
+ USB_CLASS_DEVICE_PATH UsbClass;
+ I2O_DEVICE_PATH I2O;
+ MAC_ADDR_DEVICE_PATH MacAddr;
+ IPv4_DEVICE_PATH Ipv4;
+ IPv6_DEVICE_PATH Ipv6;
+ INFINIBAND_DEVICE_PATH InfiniBand;
+ UART_DEVICE_PATH Uart;
+
+ HARDDRIVE_DEVICE_PATH HardDrive;
+ CDROM_DEVICE_PATH CD;
+
+ FILEPATH_DEVICE_PATH FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;
+
+ BBS_BBS_DEVICE_PATH Bbs;
+
+} EFI_DEV_PATH;
+
+typedef union {
+ EFI_DEVICE_PATH *DevPath;
+ PCI_DEVICE_PATH *Pci;
+ PCCARD_DEVICE_PATH *PcCard;
+ MEMMAP_DEVICE_PATH *MemMap;
+ VENDOR_DEVICE_PATH *Vendor;
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor;
+ CONTROLLER_DEVICE_PATH *Controller;
+ ACPI_HID_DEVICE_PATH *Acpi;
+ ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
+
+ ATAPI_DEVICE_PATH *Atapi;
+ SCSI_DEVICE_PATH *Scsi;
+ FIBRECHANNEL_DEVICE_PATH *FibreChannel;
+
+ F1394_DEVICE_PATH *F1394;
+ USB_DEVICE_PATH *Usb;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+ I2O_DEVICE_PATH *I2O;
+ MAC_ADDR_DEVICE_PATH *MacAddr;
+ IPv4_DEVICE_PATH *Ipv4;
+ IPv6_DEVICE_PATH *Ipv6;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+ UART_DEVICE_PATH *Uart;
+
+ HARDDRIVE_DEVICE_PATH *HardDrive;
+
+ FILEPATH_DEVICE_PATH *FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol;
+
+ CDROM_DEVICE_PATH *CD;
+ BBS_BBS_DEVICE_PATH *Bbs;
+
+} EFI_DEV_PATH_PTR;
+
+#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \
+ { 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } }
+
+#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \
+ { 0x8b843e20, 0x8132, 0x4852, { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } }
+
+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
+ { 0x05c99a21, 0xc70f, 0x4ad2, { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } }
+
+INTERFACE_DECL(_EFI_DEVICE_PATH_PROTOCOL);
+
+typedef
+CHAR16*
+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE) (
+ IN struct _EFI_DEVICE_PATH *This,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortCuts
+ );
+
+typedef
+CHAR16*
+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH) (
+ IN struct _EFI_DEVICE_PATH *This,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortCuts
+ );
+
+typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL {
+ EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText;
+ EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText;
+} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;
+
+typedef
+struct _EFI_DEVICE_PATH*
+(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_NODE) (
+ IN CONST CHAR16* TextDeviceNode
+ );
+typedef
+struct _EFI_DEVICE_PATH*
+(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_PATH) (
+ IN CONST CHAR16* TextDevicePath
+ );
+
+
+typedef struct _EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL {
+ EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode;
+ EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath;
+} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;
+
+#pragma pack()
+
+#endif
diff --git a/bsps/shared/freebsd/stand/efi/include/efierr.h b/bsps/shared/freebsd/stand/efi/include/efierr.h
new file mode 100644
index 0000000000..a8b6557185
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/efierr.h
@@ -0,0 +1,68 @@
+/* $FreeBSD$ */
+#ifndef _EFI_ERR_H
+#define _EFI_ERR_H
+
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efierr.h
+
+Abstract:
+
+ EFI error codes
+
+
+
+
+Revision History
+
+--*/
+
+
+#define EFIWARN(a) (a)
+#define EFI_ERROR(a) (((INTN) a) < 0)
+#define EFI_ERROR_CODE(a) (unsigned long)(a & ~EFI_ERROR_MASK)
+
+
+#define EFI_SUCCESS 0
+#define EFI_LOAD_ERROR EFIERR(1)
+#define EFI_INVALID_PARAMETER EFIERR(2)
+#define EFI_UNSUPPORTED EFIERR(3)
+#define EFI_BAD_BUFFER_SIZE EFIERR(4)
+#define EFI_BUFFER_TOO_SMALL EFIERR(5)
+#define EFI_NOT_READY EFIERR(6)
+#define EFI_DEVICE_ERROR EFIERR(7)
+#define EFI_WRITE_PROTECTED EFIERR(8)
+#define EFI_OUT_OF_RESOURCES EFIERR(9)
+#define EFI_VOLUME_CORRUPTED EFIERR(10)
+#define EFI_VOLUME_FULL EFIERR(11)
+#define EFI_NO_MEDIA EFIERR(12)
+#define EFI_MEDIA_CHANGED EFIERR(13)
+#define EFI_NOT_FOUND EFIERR(14)
+#define EFI_ACCESS_DENIED EFIERR(15)
+#define EFI_NO_RESPONSE EFIERR(16)
+#define EFI_NO_MAPPING EFIERR(17)
+#define EFI_TIMEOUT EFIERR(18)
+#define EFI_NOT_STARTED EFIERR(19)
+#define EFI_ALREADY_STARTED EFIERR(20)
+#define EFI_ABORTED EFIERR(21)
+#define EFI_ICMP_ERROR EFIERR(22)
+#define EFI_TFTP_ERROR EFIERR(23)
+#define EFI_PROTOCOL_ERROR EFIERR(24)
+
+#define EFI_WARN_UNKNOWN_GLYPH EFIWARN(1)
+#define EFI_WARN_DELETE_FAILURE EFIWARN(2)
+#define EFI_WARN_WRITE_FAILURE EFIWARN(3)
+#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4)
+
+#endif
diff --git a/bsps/shared/freebsd/stand/efi/include/efigop.h b/bsps/shared/freebsd/stand/efi/include/efigop.h
new file mode 100644
index 0000000000..104fa6e44b
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/efigop.h
@@ -0,0 +1,121 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efigop.h
+
+Abstract:
+ Info about framebuffers
+
+
+
+
+Revision History
+
+--*/
+
+#ifndef _EFIGOP_H
+#define _EFIGOP_H
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ { 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a} }
+
+INTERFACE_DECL(_EFI_GRAPHICS_OUTPUT);
+
+typedef struct {
+ UINT32 RedMask;
+ UINT32 GreenMask;
+ UINT32 BlueMask;
+ UINT32 ReservedMask;
+} EFI_PIXEL_BITMASK;
+
+typedef enum {
+ PixelRedGreenBlueReserved8BitPerColor,
+ PixelBlueGreenRedReserved8BitPerColor,
+ PixelBitMask,
+ PixelBltOnly,
+ PixelFormatMax,
+} EFI_GRAPHICS_PIXEL_FORMAT;
+
+typedef struct {
+ UINT32 Version;
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+ EFI_PIXEL_BITMASK PixelInformation;
+ UINT32 PixelsPerScanLine;
+} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
+
+typedef struct {
+ UINT32 MaxMode;
+ UINT32 Mode;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINTN SizeOfInfo;
+ EFI_PHYSICAL_ADDRESS FrameBufferBase;
+ UINTN FrameBufferSize;
+} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN UINT32 ModeNumber
+ );
+
+typedef struct {
+ UINT8 Blue;
+ UINT8 Green;
+ UINT8 Red;
+ UINT8 Reserved;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
+
+typedef enum {
+ EfiBltVideoFill,
+ EfiBltVideoToBltBuffer,
+ EfiBltBufferToVideo,
+ EfiBltVideoToVideo,
+ EfiGraphcisOutputBltOperationMax,
+} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ );
+
+typedef struct _EFI_GRAPHICS_OUTPUT {
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
+} EFI_GRAPHICS_OUTPUT;
+
+#endif /* _EFIGOP_H */
diff --git a/bsps/shared/freebsd/stand/efi/include/efilib.h b/bsps/shared/freebsd/stand/efi/include/efilib.h
new file mode 100644
index 0000000000..d31212ff9a
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/include/efilib.h
@@ -0,0 +1,172 @@
+/*-
+ * Copyright (c) 2000 Doug Rabson
+ * Copyright (c) 2006 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LOADER_EFILIB_H
+#define _LOADER_EFILIB_H
+
+#ifndef __rtems__
+#include <stand.h>
+#endif /* __rtems__ */
+#include <stdbool.h>
+#include <sys/queue.h>
+#ifdef __rtems__
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#endif /* __rtems__ */
+
+extern EFI_HANDLE IH;
+extern EFI_SYSTEM_TABLE *ST;
+extern EFI_BOOT_SERVICES *BS;
+extern EFI_RUNTIME_SERVICES *RS;
+
+#ifndef __rtems__
+
+extern struct devsw efipart_fddev;
+extern struct devsw efipart_cddev;
+extern struct devsw efipart_hddev;
+extern struct devsw efihttp_dev;
+extern struct devsw efinet_dev;
+extern struct netif_driver efinetif;
+
+/* EFI block device data, included here to help efi_zfs_probe() */
+typedef STAILQ_HEAD(pdinfo_list, pdinfo) pdinfo_list_t;
+
+typedef struct pdinfo
+{
+ STAILQ_ENTRY(pdinfo) pd_link; /* link in device list */
+ pdinfo_list_t pd_part; /* list of partitions */
+ EFI_HANDLE pd_handle;
+ EFI_HANDLE pd_alias;
+ EFI_DEVICE_PATH *pd_devpath;
+ EFI_BLOCK_IO *pd_blkio;
+ uint32_t pd_unit; /* unit number */
+ uint32_t pd_open; /* reference counter */
+ void *pd_bcache; /* buffer cache data */
+ struct pdinfo *pd_parent; /* Linked items (eg partitions) */
+ struct devsw *pd_devsw; /* Back pointer to devsw */
+} pdinfo_t;
+
+pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev);
+pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev);
+pdinfo_t *efiblk_get_pdinfo_by_handle(EFI_HANDLE h);
+pdinfo_t *efiblk_get_pdinfo_by_device_path(EFI_DEVICE_PATH *path);
+
+/* libefi.c */
+void *efi_get_table(EFI_GUID *tbl);
+EFI_STATUS OpenProtocolByHandle(EFI_HANDLE, EFI_GUID *, void **);
+
+static inline EFI_STATUS
+efi_exit_boot_services(UINTN key)
+{
+ EFI_STATUS status;
+
+ status = BS->ExitBootServices(IH, key);
+ if (!EFI_ERROR(status))
+ boot_services_active = false;
+ return (status);
+}
+
+int efi_getdev(void **vdev, const char *devspec, const char **path);
+
+int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int);
+EFI_HANDLE efi_find_handle(struct devsw *, int);
+int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *, uint64_t *);
+int efi_handle_update_dev(EFI_HANDLE, struct devsw *, int, uint64_t);
+
+EFI_DEVICE_PATH *efi_lookup_image_devpath(EFI_HANDLE);
+EFI_DEVICE_PATH *efi_lookup_devpath(EFI_HANDLE);
+void efi_close_devpath(EFI_HANDLE);
+EFI_HANDLE efi_devpath_handle(EFI_DEVICE_PATH *);
+EFI_DEVICE_PATH *efi_devpath_last_node(EFI_DEVICE_PATH *);
+EFI_DEVICE_PATH *efi_devpath_trim(EFI_DEVICE_PATH *);
+bool efi_devpath_match(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *);
+bool efi_devpath_match_node(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *);
+bool efi_devpath_is_prefix(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *);
+CHAR16 *efi_devpath_name(EFI_DEVICE_PATH *);
+void efi_free_devpath_name(CHAR16 *);
+bool efi_devpath_same_disk(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *);
+EFI_DEVICE_PATH *efi_devpath_to_media_path(EFI_DEVICE_PATH *);
+UINTN efi_devpath_length(EFI_DEVICE_PATH *);
+EFI_DEVICE_PATH *efi_name_to_devpath(const char *path);
+EFI_DEVICE_PATH *efi_name_to_devpath16(CHAR16 *path);
+void efi_devpath_free(EFI_DEVICE_PATH *dp);
+EFI_HANDLE efi_devpath_to_handle(EFI_DEVICE_PATH *path, EFI_HANDLE *handles, unsigned nhandles);
+
+int efi_status_to_errno(EFI_STATUS);
+EFI_STATUS errno_to_efi_status(int errno);
+
+void efi_time_init(void);
+void efi_time_fini(void);
+
+int parse_uefi_con_out(void);
+EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
+
+EFI_STATUS main(int argc, CHAR16 *argv[]);
+void efi_exit(EFI_STATUS status) __dead2;
+
+/* EFI environment initialization. */
+void efi_init_environment(void);
+
+/* EFI Memory type strings. */
+const char *efi_memory_type(EFI_MEMORY_TYPE);
+#endif /* __rtems__ */
+
+/* CHAR16 utility functions. */
+int wcscmp(CHAR16 *, CHAR16 *);
+void cpy8to16(const char *, CHAR16 *, size_t);
+void cpy16to8(const CHAR16 *, char *, size_t);
+
+#ifndef __rtems__
+/*
+ * Routines for interacting with EFI's env vars in a more unix-like
+ * way than the standard APIs. In addition, convenience routines for
+ * the loader setting / getting FreeBSD specific variables.
+ */
+
+EFI_STATUS efi_delenv(EFI_GUID *guid, const char *varname);
+EFI_STATUS efi_freebsd_delenv(const char *varname);
+EFI_STATUS efi_freebsd_getenv(const char *v, void *data, __size_t *len);
+EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, __size_t *len);
+EFI_STATUS efi_global_getenv(const char *v, void *data, __size_t *len);
+EFI_STATUS efi_setenv(EFI_GUID *guid, const char *varname, UINT32 attr, void *data, __size_t len);
+EFI_STATUS efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr);
+
+/* guids and names */
+bool efi_guid_to_str(const EFI_GUID *, char **);
+bool efi_str_to_guid(const char *, EFI_GUID *);
+bool efi_name_to_guid(const char *, EFI_GUID *);
+bool efi_guid_to_name(EFI_GUID *, char **);
+
+/* efipart.c */
+int efipart_inithandles(void);
+
+#endif /* __rtems__ */
+
+#endif /* _LOADER_EFILIB_H */
diff --git a/bsps/shared/freebsd/stand/efi/libefi/libefi.c b/bsps/shared/freebsd/stand/efi/libefi/libefi.c
new file mode 100644
index 0000000000..f63e146f2e
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/libefi/libefi.c
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2000 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efi.h>
+#ifndef __rtems__
+#include <eficonsctl.h>
+#include <efilib.h>
+#include <stand.h>
+#endif /* __rtems__ */
+
+EFI_HANDLE IH;
+EFI_SYSTEM_TABLE *ST;
+EFI_BOOT_SERVICES *BS;
+EFI_RUNTIME_SERVICES *RS;
+
+#ifndef __rtems__
+void *
+efi_get_table(EFI_GUID *tbl)
+{
+ EFI_GUID *id;
+ int i;
+
+ for (i = 0; i < ST->NumberOfTableEntries; i++) {
+ id = &ST->ConfigurationTable[i].VendorGuid;
+ if (!memcmp(id, tbl, sizeof(EFI_GUID)))
+ return (ST->ConfigurationTable[i].VendorTable);
+ }
+ return (NULL);
+}
+
+EFI_STATUS
+OpenProtocolByHandle(EFI_HANDLE handle, EFI_GUID *protocol, void **interface)
+{
+ return (BS->OpenProtocol(handle, protocol, interface, IH, NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
+}
+#endif
diff --git a/bsps/shared/freebsd/stand/efi/libefi/wchar.c b/bsps/shared/freebsd/stand/efi/libefi/wchar.c
new file mode 100644
index 0000000000..d0c6535143
--- /dev/null
+++ b/bsps/shared/freebsd/stand/efi/libefi/wchar.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright 2016 Netflix, Inc.
+ *
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efi.h>
+#include <efilib.h>
+
+/*
+ * CHAR16 related functions moved from loader.
+ * Perhaps we should move those to libsa afterall, but they are
+ * needed only by UEFI.
+ */
+
+int
+wcscmp(CHAR16 *a, CHAR16 *b)
+{
+
+ while (*a && *b && *a == *b) {
+ a++;
+ b++;
+ }
+ return *a - *b;
+}
+
+/*
+ * cpy8to16 copies a traditional C string into a CHAR16 string and
+ * 0 terminates it. len is the size of *dst in bytes.
+ */
+void
+cpy8to16(const char *src, CHAR16 *dst, size_t len)
+{
+ len <<= 1; /* Assume CHAR16 is 2 bytes */
+ while (len > 0 && *src) {
+ *dst++ = *src++;
+ len--;
+ }
+ *dst++ = (CHAR16)0;
+}
+
+void
+cpy16to8(const CHAR16 *src, char *dst, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len && src[i]; i++)
+ dst[i] = (char)src[i];
+ if (i < len)
+ dst[i] = '\0';
+}
diff --git a/bsps/shared/grlib/1553/b1553brm.c b/bsps/shared/grlib/1553/b1553brm.c
index 484ee6d0df..7e0b9924e6 100644
--- a/bsps/shared/grlib/1553/b1553brm.c
+++ b/bsps/shared/grlib/1553/b1553brm.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* BRM driver
*
* COPYRIGHT (c) 2006.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*/
/********** Set defaults **********/
@@ -100,7 +119,7 @@ struct irq_log_list {
typedef struct {
struct drvmgr_dev *dev; /* Driver manager device */
- char devName[32]; /* Device Name */
+ char devName[52]; /* Device Name */
struct brm_reg *regs;
unsigned int memarea_base;
diff --git a/bsps/shared/grlib/1553/b1553rt.c b/bsps/shared/grlib/1553/b1553rt.c
index df72ada285..7a4e2535bd 100644
--- a/bsps/shared/grlib/1553/b1553rt.c
+++ b/bsps/shared/grlib/1553/b1553rt.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* B1553RT driver implmenetation
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
@@ -68,7 +87,7 @@ static rtems_driver_address_table b1553rt_driver = RT_DRIVER_TABLE_ENTRY;
typedef struct {
struct drvmgr_dev *dev; /* Driver manager device */
- char devName[32]; /* Device Name */
+ char devName[52]; /* Device Name */
struct rt_reg *regs;
unsigned int ctrl_copy; /* Local copy of config register */
diff --git a/bsps/shared/grlib/1553/gr1553b.c b/bsps/shared/grlib/1553/gr1553b.c
index 179f5e3786..debabf0d4c 100644
--- a/bsps/shared/grlib/1553/gr1553b.c
+++ b/bsps/shared/grlib/1553/gr1553b.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR1553B driver, used by BC, RT and/or BM driver
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/1553/gr1553bc.c b/bsps/shared/grlib/1553/gr1553bc.c
index f37364e0ea..b992e2e87f 100644
--- a/bsps/shared/grlib/1553/gr1553bc.c
+++ b/bsps/shared/grlib/1553/gr1553bc.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR1553B BC driver
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/1553/gr1553bm.c b/bsps/shared/grlib/1553/gr1553bm.c
index 0672c468a4..26736d6cd0 100644
--- a/bsps/shared/grlib/1553/gr1553bm.c
+++ b/bsps/shared/grlib/1553/gr1553bm.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR1553B BM driver
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/1553/gr1553rt.c b/bsps/shared/grlib/1553/gr1553rt.c
index 7f35138376..d6eaf11a4b 100644
--- a/bsps/shared/grlib/1553/gr1553rt.c
+++ b/bsps/shared/grlib/1553/gr1553rt.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR1553B RT driver
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
diff --git a/bsps/shared/grlib/amba/ahbstat.c b/bsps/shared/grlib/amba/ahbstat.c
index 3ab0262e1e..ab3807d1d5 100644
--- a/bsps/shared/grlib/amba/ahbstat.c
+++ b/bsps/shared/grlib/amba/ahbstat.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* AHB Status register driver
*
* COPYRIGHT (c) 2009 - 2017.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <inttypes.h>
diff --git a/bsps/shared/grlib/amba/ambapp.c b/bsps/shared/grlib/amba/ambapp.c
index a94718610b..a63452133d 100644
--- a/bsps/shared/grlib/amba/ambapp.c
+++ b/bsps/shared/grlib/amba/ambapp.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play routines
*
* COPYRIGHT (c) 2011.
* Aeroflex Gaisler.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <string.h>
diff --git a/bsps/shared/grlib/amba/ambapp_alloc.c b/bsps/shared/grlib/amba/ambapp_alloc.c
index 96fcb7961b..c8cd5dc2e9 100644
--- a/bsps/shared/grlib/amba/ambapp_alloc.c
+++ b/bsps/shared/grlib/amba/ambapp_alloc.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play routines
*
* COPYRIGHT (c) 2011
* Aeroflex Gaisler
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/ambapp.h>
diff --git a/bsps/shared/grlib/amba/ambapp_count.c b/bsps/shared/grlib/amba/ambapp_count.c
index 9da4d93a19..190b5a77e4 100644
--- a/bsps/shared/grlib/amba/ambapp_count.c
+++ b/bsps/shared/grlib/amba/ambapp_count.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play routines
*
* COPYRIGHT (c) 2011
* Aeroflex Gaisler
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/ambapp.h>
diff --git a/bsps/shared/grlib/amba/ambapp_depth.c b/bsps/shared/grlib/amba/ambapp_depth.c
index 2fe0b142e9..b58f43f5b2 100644
--- a/bsps/shared/grlib/amba/ambapp_depth.c
+++ b/bsps/shared/grlib/amba/ambapp_depth.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play routines
*
* COPYRIGHT (c) 2011
* Aeroflex Gaisler
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/ambapp.h>
diff --git a/bsps/shared/grlib/amba/ambapp_find_by_idx.c b/bsps/shared/grlib/amba/ambapp_find_by_idx.c
index 55d9022881..5adbf4f0f0 100644
--- a/bsps/shared/grlib/amba/ambapp_find_by_idx.c
+++ b/bsps/shared/grlib/amba/ambapp_find_by_idx.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play routines
*
* COPYRIGHT (c) 2011
* Aeroflex Gaisler
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/ambapp.h>
diff --git a/bsps/shared/grlib/amba/ambapp_freq.c b/bsps/shared/grlib/amba/ambapp_freq.c
index 07d8be5b39..b5cd5d6de4 100644
--- a/bsps/shared/grlib/amba/ambapp_freq.c
+++ b/bsps/shared/grlib/amba/ambapp_freq.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play routines
*
* COPYRIGHT (c) 2011
* Aeroflex Gaisler
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/ambapp.h>
diff --git a/bsps/shared/grlib/amba/ambapp_names.c b/bsps/shared/grlib/amba/ambapp_names.c
index 4ccb0621e6..f001e58d34 100644
--- a/bsps/shared/grlib/amba/ambapp_names.c
+++ b/bsps/shared/grlib/amba/ambapp_names.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play Device and Vendor name database: Created from GRLIB 3386.
*
@@ -7,9 +9,26 @@
* The device and vendor definitions are extracted with a script from
* GRLIB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/ambapp.h>
diff --git a/bsps/shared/grlib/amba/ambapp_old.c b/bsps/shared/grlib/amba/ambapp_old.c
index a51e692fbf..823a2ae773 100644
--- a/bsps/shared/grlib/amba/ambapp_old.c
+++ b/bsps/shared/grlib/amba/ambapp_old.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* Old AMBA scanning Interface provided for backwards compability
*
* COPYRIGHT (c) 2011
* Aeroflex Gaisler
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/ambapp.h>
diff --git a/bsps/shared/grlib/amba/ambapp_parent.c b/bsps/shared/grlib/amba/ambapp_parent.c
index b77b6eec68..bcb4c0424f 100644
--- a/bsps/shared/grlib/amba/ambapp_parent.c
+++ b/bsps/shared/grlib/amba/ambapp_parent.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play routines
*
* COPYRIGHT (c) 2011
* Aeroflex Gaisler
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/amba/ambapp_show.c b/bsps/shared/grlib/amba/ambapp_show.c
index 12cefa2c0f..cad978539b 100644
--- a/bsps/shared/grlib/amba/ambapp_show.c
+++ b/bsps/shared/grlib/amba/ambapp_show.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* AMBA Plug & Play routines: device information printing.
*
* COPYRIGHT (c) 2009.
* Aeroflex Gaisler.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <stdio.h>
diff --git a/bsps/shared/grlib/analog/gradcdac.c b/bsps/shared/grlib/analog/gradcdac.c
index 02939e58f0..09f8760bcd 100644
--- a/bsps/shared/grlib/analog/gradcdac.c
+++ b/bsps/shared/grlib/analog/gradcdac.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* ADC / DAC (GRADCDAC) interface implementation
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
@@ -34,7 +53,7 @@
struct gradcdac_priv {
struct gradcdac_regs *regs; /* Must be first */
struct drvmgr_dev *dev;
- char devName[48];
+ char devName[54]; /* Must be at least 48 per names */
unsigned int freq;
int irqno;
diff --git a/bsps/shared/grlib/ascs/grascs.c b/bsps/shared/grlib/ascs/grascs.c
index 0e4a2ba868..016fb207e4 100644
--- a/bsps/shared/grlib/ascs/grascs.c
+++ b/bsps/shared/grlib/ascs/grascs.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* This file contains the GRASCS RTEMS driver
*
* COPYRIGHT (c) 2008.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/btimer/gptimer.c b/bsps/shared/grlib/btimer/gptimer.c
index 4b3ec8c4b8..cbf058ccef 100644
--- a/bsps/shared/grlib/btimer/gptimer.c
+++ b/bsps/shared/grlib/btimer/gptimer.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* This file contains the driver for the GRLIB GPTIMER timers port. The driver
* is implemented by using the tlib.c simple timer layer and the Driver
* Manager.
@@ -26,23 +28,37 @@
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
-#include <bsp.h>
-#include <stdlib.h>
-#include <string.h>
#include <drvmgr/drvmgr.h>
#include <grlib/ambapp_bus.h>
-#include <grlib/grlib.h>
#include <grlib/gptimer.h>
+#include <grlib/gptimer-regs.h>
+#include <grlib/io.h>
#include <grlib/tlib.h>
#if defined(LEON3)
-#include <leon.h>
+#include <bsp/leon3.h>
#endif
#ifdef GPTIMER_INFO_AVAIL
@@ -56,49 +72,21 @@
#include <grlib/grlib_impl.h>
-/* GPTIMER Core Configuration Register (READ-ONLY) */
-#define GPTIMER_CFG_TIMERS_BIT 0
-#define GPTIMER_CFG_IRQ_BIT 3
-#define GPTIMER_CFG_SI_BIT 8
-#define GPTIMER_CFG_DF_BIT 9
-
-#define GPTIMER_CFG_TIMERS (0x7<<GPTIMER_CFG_TIMERS_BIT)
-#define GPTIMER_CFG_IRQ (0x1f<<GPTIMER_CFG_IRQ_BIT)
-#define GPTIMER_CFG_SI (1<<GPTIMER_CFG_SI_BIT)
-#define GPTIMER_CFG_DF (1<<GPTIMER_CFG_DF_BIT)
-
-/* GPTIMER Timer Control Register */
-#define GPTIMER_CTRL_EN_BIT 0
-#define GPTIMER_CTRL_RS_BIT 1
-#define GPTIMER_CTRL_LD_BIT 2
-#define GPTIMER_CTRL_IE_BIT 3
-#define GPTIMER_CTRL_IP_BIT 4
-#define GPTIMER_CTRL_CH_BIT 5
-#define GPTIMER_CTRL_DH_BIT 6
-
-#define GPTIMER_CTRL_EN (1<<GPTIMER_CTRL_EN_BIT)
-#define GPTIMER_CTRL_RS (1<<GPTIMER_CTRL_RS_BIT)
-#define GPTIMER_CTRL_LD (1<<GPTIMER_CTRL_LD_BIT)
-#define GPTIMER_CTRL_IE (1<<GPTIMER_CTRL_IE_BIT)
-#define GPTIMER_CTRL_IP (1<<GPTIMER_CTRL_IP_BIT)
-#define GPTIMER_CTRL_CH (1<<GPTIMER_CTRL_CH_BIT)
-#define GPTIMER_CTRL_DH (1<<GPTIMER_CTRL_DH_BIT)
-
#define DBG(x...)
/* GPTIMER timer private */
-struct gptimer_timer {
+struct gptimer_timer_priv {
struct tlib_dev tdev; /* Must be first in struct */
- struct gptimer_timer_regs *tregs;
+ gptimer_timer *tregs;
char index; /* Timer Index in this driver */
char tindex; /* Timer Index In Hardware */
- unsigned char irq_ack_mask;
+ uint32_t irq_ack_mask;
};
/* GPTIMER Core private */
struct gptimer_priv {
struct drvmgr_dev *dev;
- struct gptimer_regs *regs;
+ gptimer *regs;
unsigned int base_clk;
unsigned int base_freq;
unsigned int widthmask;
@@ -107,7 +95,7 @@ struct gptimer_priv {
/* Structure per Timer unit, the core supports up to 8 timers */
int timer_cnt;
- struct gptimer_timer timers[0];
+ struct gptimer_timer_priv timers[0];
};
void gptimer_isr(void *data);
@@ -181,14 +169,14 @@ void gptimer_register_drv (void)
int gptimer_init1(struct drvmgr_dev *dev)
{
struct gptimer_priv *priv;
- struct gptimer_regs *regs;
+ gptimer *regs;
struct amba_dev_info *ambadev;
struct ambapp_core *pnpinfo;
int timer_hw_cnt, timer_cnt, timer_start;
int i, size;
- struct gptimer_timer *timer;
+ struct gptimer_timer_priv *timer;
union drvmgr_key_value *value;
- unsigned char irq_ack_mask;
+ uint32_t irq_ack_mask;
/* Get device information from AMBA PnP information */
ambadev = (struct amba_dev_info *)dev->businfo;
@@ -196,12 +184,12 @@ int gptimer_init1(struct drvmgr_dev *dev)
return -1;
}
pnpinfo = &ambadev->info;
- regs = (struct gptimer_regs *)pnpinfo->apb_slv->start;
+ regs = (gptimer *)pnpinfo->apb_slv->start;
DBG("GPTIMER[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
/* Get number of Timers */
- timer_hw_cnt = regs->cfg & GPTIMER_CFG_TIMERS;
+ timer_hw_cnt = GPTIMER_CONFIG_TIMERS_GET(grlib_load_32(&regs->config));
/* Let user spelect a range of timers to be used. In AMP systems
* it is sometimes neccessary to leave timers for other CPU instances.
@@ -232,7 +220,7 @@ int gptimer_init1(struct drvmgr_dev *dev)
* are present.
*/
size = sizeof(struct gptimer_priv) +
- timer_cnt*sizeof(struct gptimer_timer);
+ timer_cnt*sizeof(struct gptimer_timer_priv);
priv = dev->priv = grlib_calloc(1, size);
if ( !priv )
return DRVMGR_NOMEM;
@@ -258,24 +246,24 @@ int gptimer_init1(struct drvmgr_dev *dev)
*/
value = drvmgr_dev_key_get(priv->dev, "prescaler", DRVMGR_KT_INT);
if ( value )
- regs->scaler_reload = value->i;
+ grlib_store_32(&regs->sreload, value->i);
/* Get Frequency that the timers are operating in (after prescaler) */
- priv->base_freq = priv->base_clk / (priv->regs->scaler_reload + 1);
+ priv->base_freq = priv->base_clk / (grlib_load_32(&regs->sreload) + 1);
/* Stop Timer and probe Pending bit. In newer hardware the
* timer has pending bit is cleared by writing a one to it,
* whereas older versions it is cleared with a zero.
*/
- priv->regs->timer[timer_start].ctrl = GPTIMER_CTRL_IP;
- if ((priv->regs->timer[timer_start].ctrl & GPTIMER_CTRL_IP) != 0)
- irq_ack_mask = ~GPTIMER_CTRL_IP;
+ grlib_store_32(&regs->timer[timer_start].tctrl, GPTIMER_TCTRL_IP);
+ if ((grlib_load_32(&regs->timer[timer_start].tctrl) & GPTIMER_TCTRL_IP) != 0)
+ irq_ack_mask = ~GPTIMER_TCTRL_IP;
else
- irq_ack_mask = ~0;
+ irq_ack_mask = ~0U;
/* Probe timer register width mask */
- priv->regs->timer[timer_start].value = 0xffffffff;
- priv->widthmask = priv->regs->timer[timer_start].value;
+ grlib_store_32(&regs->timer[timer_start].tcntval, 0xffffffff);
+ priv->widthmask = grlib_load_32(&regs->timer[timer_start].tcntval);
priv->timer_cnt = timer_cnt;
for (i=0; i<timer_cnt; i++) {
@@ -295,7 +283,7 @@ int gptimer_init1(struct drvmgr_dev *dev)
* B. Each Timer have an individual IRQ. The number is:
* BASE_IRQ + timer_index
*/
- priv->separate_interrupt = (regs->cfg & GPTIMER_CFG_SI) != 0;
+ priv->separate_interrupt = (grlib_load_32(&regs->config) & GPTIMER_CONFIG_SI) != 0;
return DRVMGR_OK;
}
@@ -307,7 +295,7 @@ static int gptimer_info(
void *p, int argc, char *argv[])
{
struct gptimer_priv *priv = dev->priv;
- struct gptimer_timer *timer;
+ struct gptimer_timer_priv *timer;
char buf[64];
int i;
@@ -318,7 +306,7 @@ static int gptimer_info(
print_line(p, buf);
sprintf(buf, "REGS: 0x%08x", (unsigned int)priv->regs);
print_line(p, buf);
- sprintf(buf, "BASE SCALER: %d", priv->regs->scaler_reload);
+ sprintf(buf, "BASE SCALER: %d", grlib_load_32(&priv->regs->sreload));
print_line(p, buf);
sprintf(buf, "BASE FREQ: %dkHz", priv->base_freq / 1000);
print_line(p, buf);
@@ -331,9 +319,9 @@ static int gptimer_info(
print_line(p, buf);
sprintf(buf, " TLIB Index: %d", timer->index);
print_line(p, buf);
- sprintf(buf, " RELOAD REG: %d", timer->tregs->reload);
+ sprintf(buf, " RELOAD REG: %d", grlib_load_32(&timer->tregs->trldval));
print_line(p, buf);
- sprintf(buf, " CTRL REG: %d", timer->tregs->ctrl);
+ sprintf(buf, " CTRL REG: %d", grlib_load_32(&timer->tregs->tctrl));
print_line(p, buf);
}
@@ -341,24 +329,28 @@ static int gptimer_info(
}
#endif
-static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer *t)
+static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer_priv *t)
{
return (struct gptimer_priv *)
((unsigned int)t -
sizeof(struct gptimer_priv) -
- t->index * sizeof(struct gptimer_timer));
+ t->index * sizeof(struct gptimer_timer_priv));
}
static int gptimer_tlib_int_pend(struct tlib_dev *hand, int ack)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
- unsigned int ctrl = timer->tregs->ctrl;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
+ uint32_t tctrl;
- if ((ctrl & (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) ==
- (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) {
+ tctrl = grlib_load_32(&timer->tregs->tctrl);
+
+ if ((tctrl & (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) ==
+ (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) {
/* clear Pending IRQ ? */
- if (ack)
- timer->tregs->ctrl = ctrl & timer->irq_ack_mask;
+ if (ack) {
+ tctrl &= timer->irq_ack_mask;
+ grlib_store_32(&timer->tregs->tctrl, tctrl);
+ }
return 1; /* timer generated IRQ */
} else
return 0; /* was not timer causing IRQ */
@@ -387,12 +379,15 @@ void gptimer_isr(void *data)
static void gptimer_tlib_reset(struct tlib_dev *hand)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
-
- timer->tregs->ctrl = (timer->tregs->ctrl & timer->irq_ack_mask) &
- GPTIMER_CTRL_IP;
- timer->tregs->reload = 0xffffffff;
- timer->tregs->ctrl = GPTIMER_CTRL_LD;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
+ uint32_t tctrl;
+
+ tctrl = grlib_load_32(&timer->tregs->tctrl);
+ tctrl &= timer->irq_ack_mask;
+ tctrl &= GPTIMER_TCTRL_IP;
+ grlib_store_32(&timer->tregs->tctrl, tctrl);
+ grlib_store_32(&timer->tregs->trldval, 0xffffffff);
+ grlib_store_32(&timer->tregs->tctrl, GPTIMER_TCTRL_LD);
}
static void gptimer_tlib_get_freq(
@@ -400,24 +395,24 @@ static void gptimer_tlib_get_freq(
unsigned int *basefreq,
unsigned int *tickrate)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
struct gptimer_priv *priv = priv_from_timer(timer);
/* Calculate base frequency from Timer Clock and Prescaler */
if ( basefreq )
*basefreq = priv->base_freq;
if ( tickrate )
- *tickrate = timer->tregs->reload + 1;
+ *tickrate = grlib_load_32(&timer->tregs->trldval) + 1;
}
static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
- timer->tregs->reload = tickrate - 1;
+ grlib_store_32(&timer->tregs->trldval, tickrate - 1);
/*Check that value was allowed (Timer may not be as wide as expected)*/
- if ( timer->tregs->reload != (tickrate - 1) )
+ if (grlib_load_32(&timer->tregs->trldval) != (tickrate - 1))
return -1;
else
return 0;
@@ -425,8 +420,9 @@ static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate)
static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
struct gptimer_priv *priv = priv_from_timer(timer);
+ uint32_t tctrl;
if ( priv->separate_interrupt ) {
drvmgr_interrupt_register(priv->dev, timer->tindex,
@@ -457,16 +453,21 @@ static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *d
}
#endif
- timer->tregs->ctrl |= GPTIMER_CTRL_IE;
+ tctrl = grlib_load_32(&timer->tregs->tctrl);
+ tctrl |= GPTIMER_TCTRL_IE;
+ grlib_store_32(&timer->tregs->tctrl, tctrl);
}
static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void *data)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
struct gptimer_priv *priv = priv_from_timer(timer);
+ uint32_t tctrl;
/* Turn off IRQ at source, unregister IRQ handler */
- timer->tregs->ctrl &= ~GPTIMER_CTRL_IE;
+ tctrl = grlib_load_32(&timer->tregs->tctrl);
+ tctrl &= ~GPTIMER_TCTRL_IE;
+ grlib_store_32(&timer->tregs->tctrl, tctrl);
if ( priv->separate_interrupt ) {
drvmgr_interrupt_unregister(priv->dev, timer->tindex,
@@ -483,46 +484,54 @@ static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void
static void gptimer_tlib_start(struct tlib_dev *hand, int once)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
- unsigned int ctrl;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
+ uint32_t tctrl;
/* Load the selected frequency before starting Frequency */
- ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_EN;
+ tctrl = grlib_load_32(&timer->tregs->tctrl);
+ tctrl &= timer->irq_ack_mask;
+ tctrl &= ~GPTIMER_TCTRL_RS;
+ tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN;
if ( once == 0 )
- ctrl |= GPTIMER_CTRL_RS; /* Restart Timer */
- timer->tregs->ctrl = ctrl | (timer->tregs->ctrl & timer->irq_ack_mask &
- ~GPTIMER_CTRL_RS);
+ tctrl |= GPTIMER_TCTRL_RS; /* Restart Timer */
+ grlib_store_32(&timer->tregs->tctrl, tctrl);
}
static void gptimer_tlib_stop(struct tlib_dev *hand)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
+ uint32_t tctrl;
/* Load the selected Frequency */
- timer->tregs->ctrl &= ~(GPTIMER_CTRL_EN|GPTIMER_CTRL_IP);
+ tctrl = grlib_load_32(&timer->tregs->tctrl);
+ tctrl &= ~(GPTIMER_TCTRL_EN|GPTIMER_TCTRL_IP);
+ grlib_store_32(&timer->tregs->tctrl, tctrl);
}
static void gptimer_tlib_restart(struct tlib_dev *hand)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
+ uint32_t tctrl;
- timer->tregs->ctrl |= GPTIMER_CTRL_LD | GPTIMER_CTRL_EN;
+ tctrl = grlib_load_32(&timer->tregs->tctrl);
+ tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN;
+ grlib_store_32(&timer->tregs->tctrl, tctrl);
}
static void gptimer_tlib_get_counter(
struct tlib_dev *hand,
unsigned int *counter)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
- *counter = timer->tregs->value;
+ *counter = grlib_load_32(&timer->tregs->tcntval);
}
static void gptimer_tlib_get_widthmask(
struct tlib_dev *hand,
unsigned int *widthmask)
{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+ struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
struct gptimer_priv *priv = priv_from_timer(timer);
*widthmask = priv->widthmask;
diff --git a/bsps/shared/grlib/btimer/tlib.c b/bsps/shared/grlib/btimer/tlib.c
index d66a472fe9..ee5dbd7730 100644
--- a/bsps/shared/grlib/btimer/tlib.c
+++ b/bsps/shared/grlib/btimer/tlib.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* Timer Library (TLIB)
*
* COPYRIGHT (c) 2011.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
diff --git a/bsps/shared/grlib/btimer/tlib_ckinit.c b/bsps/shared/grlib/btimer/tlib_ckinit.c
index bc52ff4fe9..e2179090fa 100644
--- a/bsps/shared/grlib/btimer/tlib_ckinit.c
+++ b/bsps/shared/grlib/btimer/tlib_ckinit.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* Clock Tick Device Driver using Timer Library implemented
* by the GRLIB GPTIMER / LEON2 Timer drivers.
@@ -5,9 +7,26 @@
* COPYRIGHT (c) 2010 - 2017.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*
*/
@@ -414,10 +433,10 @@ static const struct ops ops_irqamp = {
} \
} while (0)
-#define Clock_driver_timecounter_tick() \
+#define Clock_driver_timecounter_tick(arg) \
tlib_clock_timecounter_tick()
-#define Clock_driver_support_at_tick() \
+#define Clock_driver_support_at_tick(arg) \
do { \
rtems_device_driver ret; \
ret = tlib_clock_at_tick(); \
diff --git a/bsps/shared/grlib/can/canbtrs.c b/bsps/shared/grlib/can/canbtrs.c
index 307547475c..289f13a2f0 100644
--- a/bsps/shared/grlib/can/canbtrs.c
+++ b/bsps/shared/grlib/can/canbtrs.c
@@ -12,7 +12,7 @@
*/
/*
- * Copyright (C) 2019, 2020 Cobham Gailer AB
+ * Copyright (C) 2019, 2020 Cobham Gaisler AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/grlib/can/canmux.c b/bsps/shared/grlib/can/canmux.c
index 631b9d941a..a6c64ea0d9 100644
--- a/bsps/shared/grlib/can/canmux.c
+++ b/bsps/shared/grlib/can/canmux.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* CAN_MUX driver. Present in GR712RC.
*
* COPYRIGHT (c) 2008.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems/libio.h>
diff --git a/bsps/shared/grlib/can/grcan.c b/bsps/shared/grlib/can/grcan.c
index 162b2e1a79..47d86b053b 100644
--- a/bsps/shared/grlib/can/grcan.c
+++ b/bsps/shared/grlib/can/grcan.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* GRCAN driver
*
* COPYRIGHT (c) 2007-2019.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/can/grcan_internal.h b/bsps/shared/grlib/can/grcan_internal.h
index 86ccda1997..d27476a985 100644
--- a/bsps/shared/grlib/can/grcan_internal.h
+++ b/bsps/shared/grlib/can/grcan_internal.h
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* GRCAN driver
*
* COPYRIGHT (c) 2007-2019.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*/
#ifndef GRCAN_DEFAULT_BAUD
@@ -37,7 +56,7 @@ struct grcan_config {
struct grcan_priv {
struct drvmgr_dev *dev; /* Driver manager device */
- char devName[32]; /* Device Name */
+ char devName[52]; /* Device Name */
unsigned int baseaddr, ram_base;
struct grcan_regs *regs;
int irq;
diff --git a/bsps/shared/grlib/can/grcanfd.c b/bsps/shared/grlib/can/grcanfd.c
index 00eb4b6432..e50280c41c 100644
--- a/bsps/shared/grlib/can/grcanfd.c
+++ b/bsps/shared/grlib/can/grcanfd.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* FD extenstions to the GRCAN driver
*
* COPYRIGHT (c) 2007-2019.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/can/grcanstd.c b/bsps/shared/grlib/can/grcanstd.c
index b92c15a32b..a9da013aca 100644
--- a/bsps/shared/grlib/can/grcanstd.c
+++ b/bsps/shared/grlib/can/grcanstd.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* non-FD specific function for GRCAN driver
*
* COPYRIGHT (c) 2007-2019.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/can/occan.c b/bsps/shared/grlib/can/occan.c
index 3df5c147de..a6b37ec74c 100644
--- a/bsps/shared/grlib/can/occan.c
+++ b/bsps/shared/grlib/can/occan.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* OC_CAN driver
*
* COPYRIGHT (c) 2007.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
@@ -207,7 +226,7 @@ typedef struct {
typedef struct {
struct drvmgr_dev *dev;
- char devName[32];
+ char devName[52];
SPIN_DECLARE(devlock);
/* hardware shortcuts */
diff --git a/bsps/shared/grlib/can/satcan.c b/bsps/shared/grlib/can/satcan.c
index a94d570955..5487de49ac 100644
--- a/bsps/shared/grlib/can/satcan.c
+++ b/bsps/shared/grlib/can/satcan.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* SatCAN FPGA driver
*
* COPYRIGHT (c) 2008.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems/libio.h>
diff --git a/bsps/shared/grlib/drvmgr/ambapp_bus.c b/bsps/shared/grlib/drvmgr/ambapp_bus.c
index 3c38fc16e0..54960233d9 100644
--- a/bsps/shared/grlib/drvmgr/ambapp_bus.c
+++ b/bsps/shared/grlib/drvmgr/ambapp_bus.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* General part of a AMBA Plug & Play bus driver.
*
* COPYRIGHT (c) 2008.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*
* This is the general part of the different AMBA Plug & Play
* drivers. The drivers are wrappers around this driver, making
diff --git a/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c b/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c
index fbbe5fa9bb..35d23c1858 100644
--- a/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c
+++ b/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* LEON3 GRLIB AMBA Plug & Play bus driver.
*
* COPYRIGHT (c) 2008.
@@ -6,9 +8,26 @@
* This is driver is a wrapper for the general AMBA Plug & Play bus
* driver. This is the root bus driver for GRLIB systems.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
@@ -22,7 +41,7 @@
#include <grlib/genirq.h>
#include <bsp.h>
-#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
#include <grlib/grlib_impl.h>
@@ -208,7 +227,10 @@ static int ambapp_grlib_int_clear
struct drvmgr_dev *dev,
int irq)
{
- BSP_shared_interrupt_clear(irq);
+ if (rtems_interrupt_clear(irq) != RTEMS_SUCCESSFUL) {
+ return DRVMGR_FAIL;
+ }
+
return DRVMGR_OK;
}
@@ -218,7 +240,10 @@ static int ambapp_grlib_int_mask
int irq
)
{
- BSP_shared_interrupt_mask(irq);
+ if (rtems_interrupt_vector_disable(irq) != RTEMS_SUCCESSFUL) {
+ return DRVMGR_FAIL;
+ }
+
return DRVMGR_OK;
}
@@ -228,7 +253,10 @@ static int ambapp_grlib_int_unmask
int irq
)
{
- BSP_shared_interrupt_unmask(irq);
+ if (rtems_interrupt_vector_enable(irq) != RTEMS_SUCCESSFUL) {
+ return DRVMGR_FAIL;
+ }
+
return DRVMGR_OK;
}
diff --git a/bsps/shared/grlib/drvmgr/get_resarray_count.c b/bsps/shared/grlib/drvmgr/get_resarray_count.c
index 7b5850d982..40eaacb48e 100644
--- a/bsps/shared/grlib/drvmgr/get_resarray_count.c
+++ b/bsps/shared/grlib/drvmgr/get_resarray_count.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* Common driver configuration routines.
*
* COPYRIGHT (c) 2015.
* Cobham Gaisler.
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/gpio/gpiolib.c b/bsps/shared/grlib/gpio/gpiolib.c
index cf0038c5bb..16e3a79ac2 100644
--- a/bsps/shared/grlib/gpio/gpiolib.c
+++ b/bsps/shared/grlib/gpio/gpiolib.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GPIOLIB interface implementation
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/gpio/grgpio.c b/bsps/shared/grlib/gpio/grgpio.c
index 05504ef020..711293dd15 100644
--- a/bsps/shared/grlib/gpio/grgpio.c
+++ b/bsps/shared/grlib/gpio/grgpio.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GRGPIO GPIO Driver interface.
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
@@ -360,12 +379,12 @@ static int grgpio_gpiolib_get_info(void *handle, struct gpiolib_info *pinfo)
/* Failed to get prefix, make sure of a unique FS name
* by using the driver minor.
*/
- snprintf(pinfo->devName, 64, "/dev/grgpio%d/%d", dev->minor_drv, portnr);
+ snprintf(pinfo->devName, 80, "/dev/grgpio%d/%d", dev->minor_drv, portnr);
} else {
/* Got special prefix, this means we have a bus prefix
* And we should use our "bus minor"
*/
- snprintf(pinfo->devName, 64, "/dev/%sgrgpio%d/%d", prefix, dev->minor_bus, portnr);
+ snprintf(pinfo->devName, 80, "/dev/%sgrgpio%d/%d", prefix, dev->minor_bus, portnr);
}
return 0;
diff --git a/bsps/shared/grlib/i2c/i2cmst.c b/bsps/shared/grlib/i2c/i2cmst.c
index fad0937df2..70c796bbce 100644
--- a/bsps/shared/grlib/i2c/i2cmst.c
+++ b/bsps/shared/grlib/i2c/i2cmst.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* Driver for GRLIB port of OpenCores I2C-master
*
* COPYRIGHT (c) 2007 Cobham Gaisler AB
* based on the RTEMS MPC83xx I2C driver (c) 2007 Embedded Brains GmbH.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*
* This file contains the driver and initialization code
*/
@@ -356,7 +375,7 @@ int i2cmst_init3(struct drvmgr_dev *dev)
{
gr_i2cmst_prv_t *priv;
char prefix[32];
- char devName[32];
+ char devName[50];
int rc;
priv = (gr_i2cmst_prv_t *)dev->priv;
diff --git a/bsps/shared/grlib/iommu/griommu.c b/bsps/shared/grlib/iommu/griommu.c
index d0d22723ca..7e0a1eb263 100644
--- a/bsps/shared/grlib/iommu/griommu.c
+++ b/bsps/shared/grlib/iommu/griommu.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* GRIOMMU Driver Interface
*
* COPYRIGHT (c) 2017
* Cobham Gaisler AB
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/irq/genirq.c b/bsps/shared/grlib/irq/genirq.c
index ca80445c70..8c35e80474 100644
--- a/bsps/shared/grlib/irq/genirq.c
+++ b/bsps/shared/grlib/irq/genirq.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* Generic interrupt helpers mainly for GRLIB PCI peripherals
*
* COPYRIGHT (c) 2008.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
diff --git a/bsps/shared/grlib/l2c/l2c.c b/bsps/shared/grlib/l2c/l2c.c
index 4a443ed7cf..17d96874ae 100644
--- a/bsps/shared/grlib/l2c/l2c.c
+++ b/bsps/shared/grlib/l2c/l2c.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* GRLIB L2CACHE Driver
*
* COPYRIGHT (c) 2017
* Cobham Gaisler AB
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/mem/mctrl.c b/bsps/shared/grlib/mem/mctrl.c
index a384547de8..f98b1713e6 100644
--- a/bsps/shared/grlib/mem/mctrl.c
+++ b/bsps/shared/grlib/mem/mctrl.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* Memory Controller driver (FTMTRL, MCTRL)
*
* COPYRIGHT (c) 2008.
@@ -7,9 +9,26 @@
* The driver sets the memory configuration registers (MCFG1, MCFG2, MCFG3)
* during driver initialization
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*/
/******************* Driver manager interface ***********************/
diff --git a/bsps/shared/grlib/pci/gr_701.c b/bsps/shared/grlib/pci/gr_701.c
index 25dc6801a9..85e9fd54c5 100644
--- a/bsps/shared/grlib/pci/gr_701.c
+++ b/bsps/shared/grlib/pci/gr_701.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR-701 PCI Target driver.
*
* COPYRIGHT (c) 2008.
@@ -10,9 +12,26 @@
* Driver resources for the AMBA PnP bus provided can be set using
* gr701_set_resources().
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <inttypes.h>
diff --git a/bsps/shared/grlib/pci/gr_rasta_adcdac.c b/bsps/shared/grlib/pci/gr_rasta_adcdac.c
index 9054967d6c..cafb1d14b9 100644
--- a/bsps/shared/grlib/pci/gr_rasta_adcdac.c
+++ b/bsps/shared/grlib/pci/gr_rasta_adcdac.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR-RASTA-ADCDAC PCI Target driver.
*
* COPYRIGHT (c) 2008.
@@ -10,9 +12,26 @@
* Driver resources for the AMBA PnP bus provided can be set using
* gr_rasta_adcdac_set_resources().
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <inttypes.h>
diff --git a/bsps/shared/grlib/pci/gr_rasta_io.c b/bsps/shared/grlib/pci/gr_rasta_io.c
index f93f73c5a0..25153c1b2e 100644
--- a/bsps/shared/grlib/pci/gr_rasta_io.c
+++ b/bsps/shared/grlib/pci/gr_rasta_io.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR-RASTA-IO PCI Target driver.
*
* COPYRIGHT (c) 2008.
@@ -10,9 +12,26 @@
* Driver resources for the AMBA PnP bus provided can be set using
* gr_rasta_io_set_resources().
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <inttypes.h>
diff --git a/bsps/shared/grlib/pci/gr_rasta_spw_router.c b/bsps/shared/grlib/pci/gr_rasta_spw_router.c
index 33168cf156..facd554195 100644
--- a/bsps/shared/grlib/pci/gr_rasta_spw_router.c
+++ b/bsps/shared/grlib/pci/gr_rasta_spw_router.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR-RASTA-SPW-ROUTER PCI Target driver.
*
* COPYRIGHT (c) 2011.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*
* Configures the GR-RASTA-SPW-ROUTER interface PCI board.
* This driver provides a AMBA PnP bus by using the general part
diff --git a/bsps/shared/grlib/pci/gr_rasta_tmtc.c b/bsps/shared/grlib/pci/gr_rasta_tmtc.c
index ccd1df40a6..60db715802 100644
--- a/bsps/shared/grlib/pci/gr_rasta_tmtc.c
+++ b/bsps/shared/grlib/pci/gr_rasta_tmtc.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR-RASTA-TMTC PCI Target driver.
*
* COPYRIGHT (c) 2008.
@@ -10,9 +12,26 @@
* Driver resources for the AMBA PnP bus provided can be set by overriding
* the defaults by declaring gr_rasta_tmtc_resources[].
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <inttypes.h>
diff --git a/bsps/shared/grlib/pci/gr_tmtc_1553.c b/bsps/shared/grlib/pci/gr_tmtc_1553.c
index 55a6358035..f87ea3c8ed 100644
--- a/bsps/shared/grlib/pci/gr_tmtc_1553.c
+++ b/bsps/shared/grlib/pci/gr_tmtc_1553.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GR-TMTC-1553 PCI Target driver.
*
* COPYRIGHT (c) 2008.
@@ -10,9 +12,26 @@
* Driver resources for the AMBA PnP bus provided can be set using
* gr_tmtc_1553_set_resources().
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <inttypes.h>
diff --git a/bsps/shared/grlib/pci/grpci.c b/bsps/shared/grlib/pci/grpci.c
index 75eacbf272..eef995304d 100644
--- a/bsps/shared/grlib/pci/grpci.c
+++ b/bsps/shared/grlib/pci/grpci.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GRLIB GRPCI PCI HOST driver.
*
* COPYRIGHT (c) 2008.
@@ -11,9 +13,26 @@
* default taken from Plug and Play, but may be overridden by the
* driver resources INTA#..INTD#.
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/pci/grpci2.c b/bsps/shared/grlib/pci/grpci2.c
index 7e3a414839..d8b521459f 100644
--- a/bsps/shared/grlib/pci/grpci2.c
+++ b/bsps/shared/grlib/pci/grpci2.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GRLIB GRPCI2 PCI HOST driver.
*
* COPYRIGHT (c) 2011
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*/
/* Configures the GRPCI2 core and initialize,
diff --git a/bsps/shared/grlib/pci/grpci2dma.c b/bsps/shared/grlib/pci/grpci2dma.c
index cb41d48966..3d90c811b1 100644
--- a/bsps/shared/grlib/pci/grpci2dma.c
+++ b/bsps/shared/grlib/pci/grpci2dma.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* GRPCI2 DMA Driver
*
* COPYRIGHT (c) 2017
* Cobham Gaisler AB
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/pci/pcif.c b/bsps/shared/grlib/pci/pcif.c
index 9be45ba189..602c74dc44 100644
--- a/bsps/shared/grlib/pci/pcif.c
+++ b/bsps/shared/grlib/pci/pcif.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GRLIB PCIF PCI HOST driver.
*
* COPYRIGHT (c) 2008.
@@ -11,9 +13,26 @@
* default taken from Plug and Play, but may be overridden by the
* driver resources INTA#..INTD#.
*
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <stdio.h>
diff --git a/bsps/shared/grlib/pwm/grpwm.c b/bsps/shared/grlib/pwm/grpwm.c
index a824201795..32d16a2da8 100644
--- a/bsps/shared/grlib/pwm/grpwm.c
+++ b/bsps/shared/grlib/pwm/grpwm.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* GRPWM PWM Driver interface.
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB,
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
@@ -150,7 +169,7 @@ struct grpwm_regs {
struct grpwm_priv {
struct drvmgr_dev *dev;
struct grpwm_regs *regs;
- char devName[32];
+ char devName[52];
int irq;
int open;
diff --git a/bsps/shared/grlib/scrub/memscrub.c b/bsps/shared/grlib/scrub/memscrub.c
index 7c6ceb43e0..d4e6c786e5 100644
--- a/bsps/shared/grlib/scrub/memscrub.c
+++ b/bsps/shared/grlib/scrub/memscrub.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* Memory Scrubber register driver
*
* COPYRIGHT (c) 2017.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/grlib/slink/grslink.c b/bsps/shared/grlib/slink/grslink.c
index 7c1eb8e290..d4cdcae868 100644
--- a/bsps/shared/grlib/slink/grslink.c
+++ b/bsps/shared/grlib/slink/grslink.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* This file contains the RTEMS GRSLINK SLINK master driver
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*
* Comments concerning current driver implementation:
*
diff --git a/bsps/shared/grlib/spi/spictrl.c b/bsps/shared/grlib/spi/spictrl.c
index 0c9f88c10f..081d281037 100644
--- a/bsps/shared/grlib/spi/spictrl.c
+++ b/bsps/shared/grlib/spi/spictrl.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* SPICTRL SPI driver implmenetation
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
@@ -232,7 +251,7 @@ int spictrl_init3(struct drvmgr_dev *dev)
{
struct spictrl_priv *priv;
char prefix[32];
- char devName[32];
+ char devName[48];
int rc;
priv = (struct spictrl_priv *)dev->priv;
diff --git a/bsps/shared/grlib/spw/grspw.c b/bsps/shared/grlib/spw/grspw.c
index bf1c823568..80fb26370e 100644
--- a/bsps/shared/grlib/spw/grspw.c
+++ b/bsps/shared/grlib/spw/grspw.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* This file contains the GRSPW SpaceWire Driver for LEON2 and LEON3.
*
* COPYRIGHT (c) 2006
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
@@ -89,7 +108,7 @@ typedef struct {
typedef struct {
/* configuration parameters */
struct drvmgr_dev *dev; /* Driver manager device */
- char devName[32]; /* Device Name */
+ char devName[49]; /* Device Name */
LEON3_SPACEWIRE_Regs_Map *regs;
spw_config config;
diff --git a/bsps/shared/grlib/spw/grspw_pkt.c b/bsps/shared/grlib/spw/grspw_pkt.c
index ca8767eeae..b0707078b7 100644
--- a/bsps/shared/grlib/spw/grspw_pkt.c
+++ b/bsps/shared/grlib/spw/grspw_pkt.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* Cobham Gaisler GRSPW/GRSPW2 SpaceWire Kernel Library Interface for RTEMS.
*
@@ -7,9 +9,26 @@
* COPYRIGHT (c) 2011
* Cobham Gaisler AB
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
diff --git a/bsps/shared/grlib/spw/grspw_router.c b/bsps/shared/grlib/spw/grspw_router.c
index 9a31c3b49a..eeddf85b6d 100644
--- a/bsps/shared/grlib/spw/grspw_router.c
+++ b/bsps/shared/grlib/spw/grspw_router.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GRSPW ROUTER APB-Register Driver.
*
* COPYRIGHT (c) 2010-2017.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
diff --git a/bsps/shared/grlib/spw/spwtdp.c b/bsps/shared/grlib/spw/spwtdp.c
index df74675355..c24ceccddf 100644
--- a/bsps/shared/grlib/spw/spwtdp.c
+++ b/bsps/shared/grlib/spw/spwtdp.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* SPWTDP - SpaceWire Time Distribution Protocol. The driver provides
* device discovery and interrupt management.
*
* COPYRIGHT (c) 2017.
* Cobham Gaisler AB
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
+ * 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.
*
*/
diff --git a/bsps/shared/grlib/stat/l4stat.c b/bsps/shared/grlib/stat/l4stat.c
index d6e5712b00..6261bd7a96 100644
--- a/bsps/shared/grlib/stat/l4stat.c
+++ b/bsps/shared/grlib/stat/l4stat.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* L4STAT APB-Register Driver.
*
* COPYRIGHT (c) 2017.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <rtems.h>
diff --git a/bsps/shared/grlib/time/grctm.c b/bsps/shared/grlib/time/grctm.c
index 038c3ddf34..474d7189c0 100644
--- a/bsps/shared/grlib/time/grctm.c
+++ b/bsps/shared/grlib/time/grctm.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GRCTM - CCSDS Time Manager - register driver interface.
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <drvmgr/drvmgr.h>
diff --git a/bsps/shared/grlib/time/spwcuc.c b/bsps/shared/grlib/time/spwcuc.c
index d742f2d225..3c80653d56 100644
--- a/bsps/shared/grlib/time/spwcuc.c
+++ b/bsps/shared/grlib/time/spwcuc.c
@@ -1,12 +1,31 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* SPWCUC - SpaceWire - CCSDS unsegmented Code Transfer Protocol GRLIB core
* register driver interface.
*
* COPYRIGHT (c) 2009.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <drvmgr/drvmgr.h>
diff --git a/bsps/shared/grlib/tmtc/grtc.c b/bsps/shared/grlib/tmtc/grtc.c
index f734f2ed36..4cb9a06ed0 100644
--- a/bsps/shared/grlib/tmtc/grtc.c
+++ b/bsps/shared/grlib/tmtc/grtc.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GRTC Telecommand decoder driver
*
* COPYRIGHT (c) 2007.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
@@ -222,7 +241,7 @@ struct grtc_frame_pool {
struct grtc_priv {
struct drvmgr_dev *dev; /* Driver manager device */
- char devName[32]; /* Device Name */
+ char devName[52]; /* Device Name */
struct grtc_regs *regs; /* TC Hardware Register MAP */
int irq; /* IRQ number of TC core */
SPIN_DECLARE(devlock); /* spin-lock of registers */
diff --git a/bsps/shared/grlib/tmtc/grtm.c b/bsps/shared/grlib/tmtc/grtm.c
index 43476aaaad..a1b2a546fe 100644
--- a/bsps/shared/grlib/tmtc/grtm.c
+++ b/bsps/shared/grlib/tmtc/grtm.c
@@ -1,11 +1,30 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* GRTM CCSDS Telemetry Encoder driver
*
* COPYRIGHT (c) 2007.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
@@ -348,7 +367,7 @@ struct grtm_ring {
struct grtm_priv {
struct drvmgr_dev *dev; /* Driver manager device */
- char devName[32]; /* Device Name */
+ char devName[52]; /* Device Name */
struct grtm_regs *regs;
int irq;
int minor;
diff --git a/bsps/shared/grlib/uart/apbuart_cons.c b/bsps/shared/grlib/uart/apbuart_cons.c
index c35020e53f..a8b4eaaf88 100644
--- a/bsps/shared/grlib/uart/apbuart_cons.c
+++ b/bsps/shared/grlib/uart/apbuart_cons.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* This file contains the driver for the GRLIB APBUART serial port. The driver
* is implemented by using the cons.c console layer. Interrupt/Polling/Task
* driven mode can be configured using driver resources:
@@ -11,9 +13,26 @@
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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.
*/
/******************* Driver manager interface ***********************/
@@ -28,11 +47,15 @@
#include <grlib/ambapp_bus.h>
#include <grlib/apbuart.h>
#include <grlib/ambapp.h>
-#include <grlib/grlib.h>
+#include <grlib/io.h>
#include <grlib/cons.h>
#include <rtems/termiostypes.h>
#include <grlib/apbuart_cons.h>
+#ifdef LEON3
+#include <bsp/leon3.h>
+#endif
+
/*#define DEBUG 1 */
#ifdef DEBUG
@@ -41,12 +64,6 @@
#define DBG(x...)
#endif
-/* LEON3 Low level transmit/receive functions provided by debug-uart code */
-#ifdef LEON3
-#include <leon.h>
-extern struct apbuart_regs *leon3_debug_uart; /* The debug UART */
-#endif
-
/* Probed hardware capabilities */
enum {
CAP_FIFO = 0x01, /* FIFO available */
@@ -55,9 +72,9 @@ enum {
struct apbuart_priv {
struct console_dev condev;
struct drvmgr_dev *dev;
- struct apbuart_regs *regs;
+ apbuart *regs;
struct rtems_termios_tty *tty;
- char devName[32];
+ char devName[52];
volatile int sending;
int mode;
int cap;
@@ -194,18 +211,23 @@ static const rtems_termios_device_handler handler_polled = {
* can select appropriate routines for the hardware. probecap() return value
* is a CAP_ bitmask.
*/
-static int probecap(struct apbuart_regs *regs)
+static int probecap(apbuart *regs)
{
int cap = 0;
+ uint32_t ctrl;
/* Probe FIFO */
- if (regs->ctrl & APBUART_CTRL_FA) {
+ ctrl = grlib_load_32(&regs->ctrl);
+ if (ctrl & APBUART_CTRL_FA) {
cap |= CAP_FIFO;
/* Probe RX delayed interrupt */
- regs->ctrl |= APBUART_CTRL_DI;
- if (regs->ctrl & APBUART_CTRL_DI) {
- regs->ctrl &= ~APBUART_CTRL_DI;
+ ctrl |= APBUART_CTRL_DI;
+ grlib_store_32(&regs->ctrl, ctrl);
+ ctrl = grlib_load_32(&regs->ctrl);
+ if (ctrl & APBUART_CTRL_DI) {
+ ctrl &= ~APBUART_CTRL_DI;
+ grlib_store_32(&regs->ctrl, ctrl);
cap |= CAP_DI;
}
}
@@ -222,6 +244,7 @@ int apbuart_init1(struct drvmgr_dev *dev)
char prefix[32];
unsigned int db;
static int first_uart = 1;
+ uint32_t ctrl;
/* The default operation in AMP is to use APBUART[0] for CPU[0],
* APBUART[1] for CPU[1] and so on. The remaining UARTs is not used
@@ -250,10 +273,12 @@ int apbuart_init1(struct drvmgr_dev *dev)
if (ambadev == NULL)
return -1;
pnpinfo = &ambadev->info;
- priv->regs = (struct apbuart_regs *)pnpinfo->apb_slv->start;
+ priv->regs = (apbuart *)pnpinfo->apb_slv->start;
/* Clear HW regs, leave baudrate register as it is */
- priv->regs->status = 0;
+ grlib_store_32(&priv->regs->status, 0);
+
+ ctrl = grlib_load_32(&priv->regs->ctrl);
/* leave Transmitter/receiver if this is the RTEMS debug UART (assume
* it has been setup by boot loader).
@@ -261,10 +286,10 @@ int apbuart_init1(struct drvmgr_dev *dev)
db = 0;
#ifdef LEON3
if (priv->regs == leon3_debug_uart) {
- db = priv->regs->ctrl & (APBUART_CTRL_RE |
- APBUART_CTRL_TE |
- APBUART_CTRL_PE |
- APBUART_CTRL_PS);
+ db = ctrl & (APBUART_CTRL_RE |
+ APBUART_CTRL_TE |
+ APBUART_CTRL_PE |
+ APBUART_CTRL_PS);
}
#endif
/* Let UART debug tunnelling be untouched if Flow-control is set.
@@ -274,12 +299,12 @@ int apbuart_init1(struct drvmgr_dev *dev)
* guess that we are debugging if FL is already set, the debugger set
* either LB or DB depending on UART capabilities.
*/
- if (priv->regs->ctrl & APBUART_CTRL_FL) {
- db |= priv->regs->ctrl & (APBUART_CTRL_DB |
+ if (ctrl & APBUART_CTRL_FL) {
+ db |= ctrl & (APBUART_CTRL_DB |
APBUART_CTRL_LB | APBUART_CTRL_FL);
}
- priv->regs->ctrl = db;
+ grlib_store_32(&priv->regs->ctrl, db);
priv->cap = probecap(priv->regs);
@@ -368,12 +393,13 @@ static int apbuart_info(
sprintf(buf, "FS Name: %s", priv->condev.fsname);
print_line(p, buf);
}
- sprintf(buf, "STATUS REG: 0x%x", priv->regs->status);
+ sprintf(buf, "STATUS REG: 0x%x", grlib_load_32(&priv->regs->status));
print_line(p, buf);
- sprintf(buf, "CTRL REG: 0x%x", priv->regs->ctrl);
+ sprintf(buf, "CTRL REG: 0x%x", grlib_load_32(&priv->regs->ctrl));
print_line(p, buf);
sprintf(buf, "SCALER REG: 0x%x baud rate %d",
- priv->regs->scaler, apbuart_get_baud(priv));
+ grlib_load_32(&priv->regs->scaler),
+ apbuart_get_baud(priv));
print_line(p, buf);
return DRVMGR_OK;
@@ -388,6 +414,8 @@ static bool first_open(
)
{
struct apbuart_priv *uart = base_get_priv(base);
+ apbuart *regs = uart->regs;
+ uint32_t ctrl;
uart->tty = tty;
@@ -399,11 +427,11 @@ static bool first_open(
}
/* Enable TX/RX */
- uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
+ ctrl = grlib_load_32(&regs->ctrl);
+ ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
if (uart->mode != TERMIOS_POLLED) {
int ret;
- uint32_t ctrl;
/* Register interrupt and enable it */
ret = drvmgr_interrupt_register(
@@ -416,15 +444,15 @@ static bool first_open(
uart->sending = 0;
/* Turn on RX interrupts */
- ctrl = uart->regs->ctrl;
ctrl |= APBUART_CTRL_RI;
if (uart->cap & CAP_DI) {
/* Use RX FIFO interrupt only if delayed interrupt available. */
ctrl |= (APBUART_CTRL_DI | APBUART_CTRL_RF);
}
- uart->regs->ctrl = ctrl;
}
+ grlib_store_32(&regs->ctrl, ctrl);
+
return true;
}
@@ -435,13 +463,16 @@ static void last_close(
)
{
struct apbuart_priv *uart = base_get_priv(base);
+ apbuart *regs = uart->regs;
rtems_interrupt_lock_context lock_context;
+ uint32_t ctrl;
if (uart->mode != TERMIOS_POLLED) {
/* Turn off RX interrupts */
rtems_termios_device_lock_acquire(base, &lock_context);
- uart->regs->ctrl &=
- ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF);
+ ctrl = grlib_load_32(&regs->ctrl);
+ ctrl &= ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF);
+ grlib_store_32(&regs->ctrl, ctrl);
rtems_termios_device_lock_release(base, &lock_context);
/**** Flush device ****/
@@ -449,8 +480,8 @@ static void last_close(
/* Wait until all data has been sent */
}
while (
- (uart->regs->ctrl & APBUART_CTRL_TE) &&
- !(uart->regs->status & APBUART_STATUS_TS)
+ (grlib_load_32(&regs->ctrl) & APBUART_CTRL_TE) &&
+ !(grlib_load_32(&regs->status) & APBUART_STATUS_TS)
) {
/* Wait until all data has left shift register */
}
@@ -461,8 +492,11 @@ static void last_close(
#ifdef LEON3
/* Disable TX/RX if not used for DEBUG */
- if (uart->regs != leon3_debug_uart)
- uart->regs->ctrl &= ~(APBUART_CTRL_RE | APBUART_CTRL_TE);
+ if (regs != leon3_debug_uart) {
+ ctrl = grlib_load_32(&regs->ctrl);
+ ctrl &= ~(APBUART_CTRL_RE | APBUART_CTRL_TE);
+ grlib_store_32(&regs->ctrl, ctrl);
+ }
#endif
}
@@ -478,10 +512,11 @@ static int read_task(rtems_termios_device_context *base)
{
rtems_interrupt_lock_context lock_context;
struct apbuart_priv *uart = base_get_priv(base);
- struct apbuart_regs *regs = uart->regs;
+ apbuart *regs = uart->regs;
int cnt;
char buf[33];
struct rtems_termios_tty *tty;
+ uint32_t ctrl;
uint32_t ctrl_add;
ctrl_add = APBUART_CTRL_RI;
@@ -492,10 +527,10 @@ static int read_task(rtems_termios_device_context *base)
do {
cnt = 0;
while (
- (regs->status & APBUART_STATUS_DR) &&
+ (grlib_load_32(&regs->status) & APBUART_STATUS_DR) &&
(cnt < sizeof(buf))
) {
- buf[cnt] = regs->data;
+ buf[cnt] = grlib_load_32(&regs->data);
cnt++;
}
if (0 < cnt) {
@@ -509,9 +544,11 @@ static int read_task(rtems_termios_device_context *base)
* afterwards.
*/
rtems_termios_device_lock_acquire(base, &lock_context);
- regs->ctrl |= ctrl_add;
+ ctrl = grlib_load_32(&regs->ctrl);
+ ctrl |= ctrl_add;
+ grlib_store_32(&regs->ctrl, ctrl);
rtems_termios_device_lock_release(base, &lock_context);
- } while (regs->status & APBUART_STATUS_DR);
+ } while (grlib_load_32(&regs->status) & APBUART_STATUS_DR);
return EOF;
}
@@ -522,7 +559,7 @@ int apbuart_get_baud(struct apbuart_priv *uart)
unsigned int scaler;
/* Get current scaler setting */
- scaler = uart->regs->scaler;
+ scaler = grlib_load_32(&uart->regs->scaler);
/* Get APBUART core frequency */
drvmgr_freq_get(uart->dev, DEV_APB_SLV, &core_clk_hz);
@@ -557,7 +594,7 @@ static bool set_attributes(
rtems_termios_device_lock_acquire(base, &lock_context);
/* Read out current value */
- ctrl = uart->regs->ctrl;
+ ctrl = grlib_load_32(&uart->regs->ctrl);
switch(t->c_cflag & (PARENB|PARODD)){
case (PARENB|PARODD):
@@ -584,7 +621,7 @@ static bool set_attributes(
ctrl &= ~APBUART_CTRL_FL;
/* Update new settings */
- uart->regs->ctrl = ctrl;
+ grlib_store_32(&uart->regs->ctrl, ctrl);
rtems_termios_device_lock_release(base, &lock_context);
@@ -598,7 +635,7 @@ static bool set_attributes(
scaler = (((core_clk_hz*10)/(baud*8))-5)/10;
/* Set new baud rate by setting scaler */
- uart->regs->scaler = scaler;
+ grlib_store_32(&uart->regs->scaler, scaler);
}
return true;
@@ -618,7 +655,7 @@ static void get_attributes(
t->c_cflag |= CS8;
/* Read out current parity */
- ctrl = uart->regs->ctrl;
+ ctrl = grlib_load_32(&uart->regs->ctrl);
if (ctrl & APBUART_CTRL_PE) {
if (ctrl & APBUART_CTRL_PS)
t->c_cflag |= PARENB|PARODD; /* Odd parity */
@@ -654,11 +691,11 @@ static void write_interrupt(
)
{
struct apbuart_priv *uart = base_get_priv(base);
- struct apbuart_regs *regs = uart->regs;
+ apbuart *regs = uart->regs;
int sending;
unsigned int ctrl;
- ctrl = regs->ctrl;
+ ctrl = grlib_load_32(&regs->ctrl);
if (len > 0) {
/*
@@ -666,28 +703,30 @@ static void write_interrupt(
* we can tell termios later.
*/
/* Enable TX interrupt (interrupt is edge-triggered) */
- regs->ctrl = ctrl | APBUART_CTRL_TI;
+ ctrl |= APBUART_CTRL_TI;
+ grlib_store_32(&regs->ctrl, ctrl);
if (ctrl & APBUART_CTRL_FA) {
/* APBUART with FIFO.. Fill as many as FIFO allows */
sending = 0;
while (
- ((regs->status & APBUART_STATUS_TF) == 0) &&
+ ((grlib_load_32(&regs->status) & APBUART_STATUS_TF) == 0) &&
(sending < len)
) {
- regs->data = *buf;
+ grlib_store_32(&regs->data, *buf);
buf++;
sending++;
}
} else {
/* start UART TX, this will result in an interrupt when done */
- regs->data = *buf;
+ grlib_store_32(&regs->data, *buf);
sending = 1;
}
} else {
/* No more to send, disable TX interrupts */
- regs->ctrl = ctrl & ~APBUART_CTRL_TI;
+ ctrl &= ~APBUART_CTRL_TI;
+ grlib_store_32(&regs->ctrl, ctrl);
/* Tell close that we sent everything */
sending = 0;
@@ -703,21 +742,24 @@ static void apbuart_cons_isr(void *arg)
rtems_termios_device_context *base;
struct console_dev *condev = rtems_termios_get_device_context(tty);
struct apbuart_priv *uart = condev_get_priv(condev);
- struct apbuart_regs *regs = uart->regs;
+ apbuart *regs = uart->regs;
unsigned int status;
char buf[33];
int cnt;
if (uart->mode == TERMIOS_TASK_DRIVEN) {
- if ((status = regs->status) & APBUART_STATUS_DR) {
+ if ((status = grlib_load_32(&regs->status)) & APBUART_STATUS_DR) {
rtems_interrupt_lock_context lock_context;
+ uint32_t ctrl;
/* Turn off RX interrupts */
base = rtems_termios_get_device_context(tty);
rtems_termios_device_lock_acquire(base, &lock_context);
- regs->ctrl &=
+ ctrl = grlib_load_32(&regs->ctrl);
+ ctrl &=
~(APBUART_CTRL_DI | APBUART_CTRL_RI |
APBUART_CTRL_RF);
+ grlib_store_32(&regs->ctrl, ctrl);
rtems_termios_device_lock_release(base, &lock_context);
/* Activate termios RX daemon task */
rtems_termios_rxirq_occured(tty);
@@ -730,10 +772,10 @@ static void apbuart_cons_isr(void *arg)
*/
cnt = 0;
while (
- ((status=regs->status) & APBUART_STATUS_DR) &&
+ ((status=grlib_load_32(&regs->status)) & APBUART_STATUS_DR) &&
(cnt < sizeof(buf))
) {
- buf[cnt] = regs->data;
+ buf[cnt] = grlib_load_32(&regs->data);
cnt++;
}
if (0 < cnt) {
diff --git a/bsps/shared/grlib/uart/apbuart_polled.c b/bsps/shared/grlib/uart/apbuart_polled.c
index 87325d8951..84c31795df 100644
--- a/bsps/shared/grlib/uart/apbuart_polled.c
+++ b/bsps/shared/grlib/uart/apbuart_polled.c
@@ -1,45 +1,72 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSDeviceGRLIBAPBUART
+ *
+ * @brief This source file contains the implementation of
+ * apbuart_outbyte_wait(), apbuart_outbyte_polled(), and
+ * apbuart_inbyte_nonblocking().
+ */
+
/*
- * COPYRIGHT (c) 2010.
- * Cobham Gaisler AB.
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * 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.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/apbuart.h>
+#include <grlib/io.h>
-#include <rtems/score/cpuimpl.h>
+#include <rtems/dev/io.h>
-void apbuart_outbyte_wait(const struct apbuart_regs *regs)
+void apbuart_outbyte_wait( const apbuart *regs )
{
- while ( (regs->status & APBUART_STATUS_TE) == 0 ) {
- /* Lower bus utilization while waiting for UART */
- _CPU_Instruction_no_operation();
- _CPU_Instruction_no_operation();
- _CPU_Instruction_no_operation();
- _CPU_Instruction_no_operation();
- _CPU_Instruction_no_operation();
- _CPU_Instruction_no_operation();
- _CPU_Instruction_no_operation();
- _CPU_Instruction_no_operation();
+ while ( ( grlib_load_32( &regs->status ) & APBUART_STATUS_TE ) == 0 ) {
+ _IO_Relax();
}
}
-void apbuart_outbyte_polled(struct apbuart_regs *regs, char ch)
+void apbuart_outbyte_polled( apbuart *regs, char ch)
{
- apbuart_outbyte_wait(regs);
- regs->data = (uint8_t) ch;
+ apbuart_outbyte_wait( regs );
+ grlib_store_32( &regs->data, (uint8_t) ch );
}
-int apbuart_inbyte_nonblocking(struct apbuart_regs *regs)
+int apbuart_inbyte_nonblocking( apbuart *regs )
{
- /* Clear errors */
- regs->status = ~APBUART_STATUS_ERR;
+ uint32_t status;
+
+ status = grlib_load_32( &regs->status );
+
+ /* Clear errors, writes to non-error flags are ignored */
+ status &= ~( APBUART_STATUS_FE | APBUART_STATUS_PE | APBUART_STATUS_OV |
+ APBUART_STATUS_BR );
+ grlib_store_32( &regs->status, status );
- if ((regs->status & APBUART_STATUS_DR) == 0) {
+ if ( ( status & APBUART_STATUS_DR ) == 0 ) {
return -1;
}
- return (uint8_t) regs->data;
+ return (int) APBUART_DATA_DATA_GET( grlib_load_32( &regs->data ) );
}
diff --git a/bsps/shared/grlib/uart/apbuart_termios.c b/bsps/shared/grlib/uart/apbuart_termios.c
index 9014a1c735..8b5ccd67f6 100644
--- a/bsps/shared/grlib/uart/apbuart_termios.c
+++ b/bsps/shared/grlib/uart/apbuart_termios.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
@@ -6,13 +8,31 @@
* COPYRIGHT (c) 2004.
* Gaisler Research.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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 <grlib/apbuart_termios.h>
#include <grlib/apbuart.h>
+#include <grlib/io.h>
#include <bsp.h>
static void apbuart_isr(void *arg)
@@ -23,9 +43,9 @@ static void apbuart_isr(void *arg)
char data;
/* Get all received characters */
- while ((status=uart->regs->status) & APBUART_STATUS_DR) {
+ while ((status=grlib_load_32(&uart->regs->status)) & APBUART_STATUS_DR) {
/* Data has arrived, get new data */
- data = uart->regs->data;
+ data = (char)grlib_load_32(&uart->regs->data);
/* Tell termios layer about new character */
rtems_termios_enqueue_raw_characters(tty, &data, 1);
@@ -33,7 +53,7 @@ static void apbuart_isr(void *arg)
if (
(status & APBUART_STATUS_TE)
- && (uart->regs->ctrl & APBUART_CTRL_TI) != 0
+ && (grlib_load_32(&uart->regs->ctrl) & APBUART_CTRL_TI) != 0
) {
/* write_interrupt will get called from this function */
rtems_termios_dequeue_characters(tty, 1);
@@ -48,23 +68,27 @@ static void apbuart_write_support(
{
struct apbuart_context *uart = (struct apbuart_context *) base;
int sending;
+ uint32_t ctrl;
+
+ ctrl = grlib_load_32(&uart->regs->ctrl);
if (len > 0) {
/* Enable TX interrupt (interrupt is edge-triggered) */
- uart->regs->ctrl |= APBUART_CTRL_TI;
+ ctrl |= APBUART_CTRL_TI;
/* start UART TX, this will result in an interrupt when done */
- uart->regs->data = *buf;
+ grlib_store_32(&uart->regs->data, (uint8_t)*buf);
sending = 1;
} else {
/* No more to send, disable TX interrupts */
- uart->regs->ctrl &= ~APBUART_CTRL_TI;
+ ctrl &= ~APBUART_CTRL_TI;
/* Tell close that we sent everything */
sending = 0;
}
+ grlib_store_32(&uart->regs->ctrl, ctrl);
uart->sending = sending;
}
@@ -115,7 +139,7 @@ static bool apbuart_set_attributes(
rtems_termios_device_lock_acquire(base, &lock_context);
/* Read out current value */
- ctrl = uart->regs->ctrl;
+ ctrl = grlib_load_32(&uart->regs->ctrl);
switch (t->c_cflag & (PARENB|PARODD)) {
case (PARENB|PARODD):
@@ -143,7 +167,7 @@ static bool apbuart_set_attributes(
}
/* Update new settings */
- uart->regs->ctrl = ctrl;
+ grlib_store_32(&uart->regs->ctrl, ctrl);
rtems_termios_device_lock_release(base, &lock_context);
@@ -154,7 +178,7 @@ static bool apbuart_set_attributes(
scaler = (((uart->freq_hz * 10) / (baud * 8)) - 5) / 10;
/* Set new baud rate by setting scaler */
- uart->regs->scaler = scaler;
+ grlib_store_32(&uart->regs->scaler, scaler);
}
return true;
@@ -165,7 +189,8 @@ static void apbuart_set_best_baud(
struct termios *term
)
{
- uint32_t baud = (uart->freq_hz * 10) / ((uart->regs->scaler * 10 + 5) * 8);
+ uint32_t baud = (uart->freq_hz * 10) /
+ ((grlib_load_32(&uart->regs->scaler) * 10 + 5) * 8);
rtems_termios_set_best_baud(term, baud);
}
@@ -178,12 +203,15 @@ static bool apbuart_first_open_polled(
)
{
struct apbuart_context *uart = (struct apbuart_context *) base;
+ uint32_t ctrl;
apbuart_set_best_baud(uart, term);
/* Initialize UART on opening */
- uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
- uart->regs->status = 0;
+ ctrl = grlib_load_32(&uart->regs->ctrl);
+ ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
+ grlib_store_32(&uart->regs->ctrl, ctrl);
+ grlib_store_32(&uart->regs->status, 0);
return true;
}
@@ -197,6 +225,7 @@ static bool apbuart_first_open_interrupt(
{
struct apbuart_context *uart = (struct apbuart_context *) base;
rtems_status_code sc;
+ uint32_t ctrl;
apbuart_set_best_baud(uart, term);
@@ -210,11 +239,13 @@ static bool apbuart_first_open_interrupt(
uart->sending = 0;
/* Enable Receiver and transmitter and Turn on RX interrupts */
- uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE |
- APBUART_CTRL_RI;
+ ctrl = grlib_load_32(&uart->regs->ctrl);
+ ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE | APBUART_CTRL_RI;
+ grlib_store_32(&uart->regs->ctrl, ctrl);
/* Initialize UART on opening */
- uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
- uart->regs->status = 0;
+ ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE;
+ grlib_store_32(&uart->regs->ctrl, ctrl);
+ grlib_store_32(&uart->regs->status, 0);
return true;
}
@@ -227,10 +258,13 @@ static void apbuart_last_close_interrupt(
{
struct apbuart_context *uart = (struct apbuart_context *) base;
rtems_interrupt_lock_context lock_context;
+ uint32_t ctrl;
/* Turn off RX interrupts */
rtems_termios_device_lock_acquire(base, &lock_context);
- uart->regs->ctrl &= ~(APBUART_CTRL_RI);
+ ctrl = grlib_load_32(&uart->regs->ctrl);
+ ctrl &= ~APBUART_CTRL_RI;
+ grlib_store_32(&uart->regs->ctrl, ctrl);
rtems_termios_device_lock_release(base, &lock_context);
/**** Flush device ****/
diff --git a/bsps/shared/grlib/uart/cons.c b/bsps/shared/grlib/uart/cons.c
index 9c20193b3c..7db93247a8 100644
--- a/bsps/shared/grlib/uart/cons.c
+++ b/bsps/shared/grlib/uart/cons.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
/* This file contains the TTY driver for the serial ports. The driver
* is layered so that different UART hardware can be used. It is implemented
* using the Driver Manager.
@@ -7,9 +9,26 @@
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * 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>
diff --git a/bsps/shared/irq/irq-affinity.c b/bsps/shared/irq/irq-affinity.c
index c21468077b..7e9250a948 100644
--- a/bsps/shared/irq/irq-affinity.c
+++ b/bsps/shared/irq/irq-affinity.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the implementation of
* rtems_interrupt_get_affinity() and rtems_interrupt_set_affinity().
*/
/*
- * Copyright (C) 2017, 2022 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2017, 2022 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,7 +36,6 @@
#include <bsp/irq-generic.h>
-#include <rtems/score/processormask.h>
#include <rtems/score/smpimpl.h>
rtems_status_code rtems_interrupt_set_affinity(
diff --git a/bsps/shared/irq/irq-default-handler.c b/bsps/shared/irq/irq-default-handler.c
index 666d48aaa8..3f765a2a64 100644
--- a/bsps/shared/irq/irq-default-handler.c
+++ b/bsps/shared/irq/irq-default-handler.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the default implementation of
* bsp_interrupt_handler_default().
*/
/*
- * Copyright (C) 2008, 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2008, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-default.c b/bsps/shared/irq/irq-default.c
index bd93bd72c6..7210235aa6 100644
--- a/bsps/shared/irq/irq-default.c
+++ b/bsps/shared/irq/irq-default.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the default implementation of
* bsp_interrupt_vector_enable(), bsp_interrupt_vector_disable(), and
@@ -11,7 +11,7 @@
*/
/*
- * Copyright (C) 2019 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2019 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-enable-disable.c b/bsps/shared/irq/irq-enable-disable.c
index 75d3d5ec46..2e0a675b85 100644
--- a/bsps/shared/irq/irq-enable-disable.c
+++ b/bsps/shared/irq/irq-enable-disable.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the implementation of
* rtems_interrupt_get_attributes(), rtems_interrupt_vector_is_enabled(),
@@ -11,7 +11,7 @@
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-entry-remove.c b/bsps/shared/irq/irq-entry-remove.c
index 3e5fd33fbe..d2f290d595 100644
--- a/bsps/shared/irq/irq-entry-remove.c
+++ b/bsps/shared/irq/irq-entry-remove.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the implementation of
* rtems_interrupt_entry_remove() and bsp_interrupt_entry_remove().
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,8 +46,8 @@ void bsp_interrupt_entry_remove(
rtems_interrupt_entry *first;
rtems_interrupt_entry *entry_next;
- index = bsp_interrupt_handler_index( vector );
- first = bsp_interrupt_handler_table[ index ];
+ index = bsp_interrupt_dispatch_index( vector );
+ first = *bsp_interrupt_get_dispatch_table_slot( index );
entry_next = entry->next;
if ( entry == first && entry_next == NULL ) {
@@ -60,7 +60,7 @@ void bsp_interrupt_entry_remove(
#endif
bsp_interrupt_set_handler_unique( index, false );
#if defined(BSP_INTERRUPT_USE_INDEX_TABLE)
- bsp_interrupt_handler_index_table[ vector ] = 0;
+ bsp_interrupt_dispatch_index_table[ vector ] = 0;
#endif
}
diff --git a/bsps/shared/irq/irq-generic.c b/bsps/shared/irq/irq-generic.c
index dac1ca4209..b6238025b7 100644
--- a/bsps/shared/irq/irq-generic.c
+++ b/bsps/shared/irq/irq-generic.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the generic interrupt controller support
* implementation.
*/
/*
- * Copyright (C) 2008, 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2008, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,39 +35,41 @@
*/
#include <bsp/irq-generic.h>
-#include <bsp/fatal.h>
-
-#include <stdlib.h>
#include <rtems/malloc.h>
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
- bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table
+ bsp_interrupt_dispatch_index_type bsp_interrupt_dispatch_index_table
[BSP_INTERRUPT_VECTOR_COUNT];
#endif
rtems_interrupt_entry *
-bsp_interrupt_handler_table[ BSP_INTERRUPT_HANDLER_TABLE_SIZE ];
+bsp_interrupt_dispatch_table[ BSP_INTERRUPT_DISPATCH_TABLE_SIZE ];
+
+RTEMS_WEAK rtems_interrupt_entry **bsp_interrupt_get_dispatch_table_slot(
+ rtems_vector_number index
+)
+{
+ return &bsp_interrupt_dispatch_table[ index ];
+}
/* The last entry indicates if everything is initialized */
uint8_t bsp_interrupt_handler_unique_table
- [ ( BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1 ) / 8 ];
+ [ ( BSP_INTERRUPT_DISPATCH_TABLE_SIZE + 7 + 1 ) / 8 ];
static inline void bsp_interrupt_set_initialized(void)
{
- bsp_interrupt_set_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE, true);
+ bsp_interrupt_set_handler_unique(BSP_INTERRUPT_DISPATCH_TABLE_SIZE, true);
}
#if defined(BSP_INTERRUPT_USE_INDEX_TABLE)
-static inline rtems_vector_number bsp_interrupt_allocate_handler_index(
- rtems_vector_number vector
-)
+static inline rtems_vector_number bsp_interrupt_allocate_handler_index( void )
{
rtems_vector_number i;
/* The first entry will remain empty */
- for ( i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i ) {
- if ( bsp_interrupt_handler_table[ i ] == NULL ) {
+ for ( i = 1; i < BSP_INTERRUPT_DISPATCH_TABLE_SIZE; ++i ) {
+ if ( bsp_interrupt_dispatch_table[ i ] == NULL ) {
break;
}
}
@@ -91,9 +93,9 @@ void bsp_interrupt_spurious( rtems_vector_number vector )
* In order to get the last written pointer value to the first entry, we have
* to carry out an atomic read-modify-write operation.
*/
- ptr = (Atomic_Uintptr *) &bsp_interrupt_handler_table[
- bsp_interrupt_handler_index( vector )
- ];
+ ptr = (Atomic_Uintptr *) bsp_interrupt_get_dispatch_table_slot(
+ bsp_interrupt_dispatch_index( vector )
+ );
first = (rtems_interrupt_entry *)
_Atomic_Fetch_add_uintptr( ptr, 0, ATOMIC_ORDER_ACQUIRE );
@@ -142,9 +144,9 @@ rtems_interrupt_entry *bsp_interrupt_entry_find(
rtems_interrupt_entry *entry;
bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) );
- index = bsp_interrupt_handler_index( vector );
- *previous_next = &bsp_interrupt_handler_table[ index ];
- entry = bsp_interrupt_handler_table[ index ];
+ index = bsp_interrupt_dispatch_index( vector );
+ *previous_next = bsp_interrupt_get_dispatch_table_slot( index );
+ entry = **previous_next;
while ( entry != NULL ) {
if ( entry->handler == routine && entry->arg == arg ) {
@@ -173,9 +175,9 @@ static rtems_status_code bsp_interrupt_entry_install_first(
rtems_vector_number index;
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
- index = bsp_interrupt_allocate_handler_index( vector );
+ index = bsp_interrupt_allocate_handler_index();
- if ( index == BSP_INTERRUPT_HANDLER_TABLE_SIZE ) {
+ if ( index == BSP_INTERRUPT_DISPATCH_TABLE_SIZE ) {
/* Handler table is full */
return RTEMS_NO_MEMORY;
}
@@ -184,10 +186,10 @@ static rtems_status_code bsp_interrupt_entry_install_first(
#endif
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
- bsp_interrupt_handler_index_table[ vector ] = index;
+ bsp_interrupt_dispatch_index_table[ vector ] = index;
#endif
bsp_interrupt_entry_store_release(
- &bsp_interrupt_handler_table[ index ],
+ bsp_interrupt_get_dispatch_table_slot( index ),
entry
);
@@ -219,8 +221,8 @@ static rtems_status_code bsp_interrupt_entry_install(
return RTEMS_INVALID_NUMBER;
}
- index = bsp_interrupt_handler_index( vector );
- first = bsp_interrupt_handler_table[ index ];
+ index = bsp_interrupt_dispatch_index( vector );
+ first = *bsp_interrupt_get_dispatch_table_slot( index );
if ( first == NULL ) {
return bsp_interrupt_entry_install_first( vector, options, entry );
diff --git a/bsps/shared/irq/irq-handler-install.c b/bsps/shared/irq/irq-handler-install.c
index 2474d792e6..18c4cbf3a7 100644
--- a/bsps/shared/irq/irq-handler-install.c
+++ b/bsps/shared/irq/irq-handler-install.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the rtems_interrupt_handler_install()
* implementation.
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-handler-iterate.c b/bsps/shared/irq/irq-handler-iterate.c
index 8bb29191fd..770318cc68 100644
--- a/bsps/shared/irq/irq-handler-iterate.c
+++ b/bsps/shared/irq/irq-handler-iterate.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the implementation of
* rtems_interrupt_handler_iterate().
*/
/*
- * Copyright (C) 2017, 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2017, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -56,10 +56,10 @@ rtems_status_code rtems_interrupt_handler_iterate(
return sc;
}
- index = bsp_interrupt_handler_index( vector );
+ index = bsp_interrupt_dispatch_index( vector );
+ entry = *bsp_interrupt_get_dispatch_table_slot( index );
options = bsp_interrupt_is_handler_unique( index ) ?
RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED;
- entry = bsp_interrupt_handler_table[ index ];
while ( entry != NULL ) {
( *routine )( arg, entry->info, options, entry->handler, entry->arg );
diff --git a/bsps/shared/irq/irq-handler-remove.c b/bsps/shared/irq/irq-handler-remove.c
index cb32ba3b7c..a01af46455 100644
--- a/bsps/shared/irq/irq-handler-remove.c
+++ b/bsps/shared/irq/irq-handler-remove.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the implementation of
* rtems_interrupt_handler_remove().
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-info.c b/bsps/shared/irq/irq-info.c
index a52465ef09..c4cbd96acf 100644
--- a/bsps/shared/irq/irq-info.c
+++ b/bsps/shared/irq/irq-info.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the implementation of
* bsp_interrupt_report() and bsp_interrupt_report_with_plugin().
*/
/*
- * Copyright (C) 2008, 2010 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2008, 2010 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-legacy.c b/bsps/shared/irq/irq-legacy.c
index 649b850095..ee4d11cd87 100644
--- a/bsps/shared/irq/irq-legacy.c
+++ b/bsps/shared/irq/irq-legacy.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the legacy interrupt controller support
* implementation.
*/
/*
- * Copyright (C) 2008, 2009 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2008, 2009 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-lock.c b/bsps/shared/irq/irq-lock.c
index 58b7020a3b..8090ade84e 100644
--- a/bsps/shared/irq/irq-lock.c
+++ b/bsps/shared/irq/irq-lock.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the implementation of
* bsp_interrupt_lock() and bsp_interrupt_unlock().
*/
/*
- * Copyright (C) 2008, 2018 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2008, 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-raise-clear.c b/bsps/shared/irq/irq-raise-clear.c
index 93e414b2d1..e06f79658b 100644
--- a/bsps/shared/irq/irq-raise-clear.c
+++ b/bsps/shared/irq/irq-raise-clear.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the implementation of
* rtems_interrupt_clear().
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-record.c b/bsps/shared/irq/irq-record.c
new file mode 100644
index 0000000000..15bb20132d
--- /dev/null
+++ b/bsps/shared/irq/irq-record.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplClassicIntr
+ *
+ * @brief This source file contains the implementation of the interrupt event
+ * recording support.
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * 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/irq-generic.h>
+
+#include <rtems/record.h>
+
+/* The regular interrupt entries are registered in this table */
+static rtems_interrupt_entry *
+_Record_Interrupt_dispatch_table[ BSP_INTERRUPT_DISPATCH_TABLE_SIZE ];
+
+/*
+ * Provide one interrupt entry for the _Record_Interrupt_handler() interrupt
+ * dispatch wrapper for each interrupt vector.
+ */
+static rtems_interrupt_entry
+_Record_Interrupt_entry_table[ BSP_INTERRUPT_DISPATCH_TABLE_SIZE ];
+
+rtems_interrupt_entry **bsp_interrupt_get_dispatch_table_slot(
+ rtems_vector_number index
+)
+{
+ return &_Record_Interrupt_dispatch_table[ index ];
+}
+
+static void _Record_Interrupt_handler( void *arg )
+{
+ uintptr_t vector;
+ rtems_interrupt_entry *entry;
+
+ vector = (uintptr_t) arg;
+ rtems_record_produce( RTEMS_RECORD_INTERRUPT_ENTRY, vector );
+
+ entry = bsp_interrupt_entry_load_acquire(
+ &_Record_Interrupt_dispatch_table[ vector ]
+ );
+
+ if ( RTEMS_PREDICT_TRUE( entry != NULL ) ) {
+ bsp_interrupt_dispatch_entries( entry );
+ } else {
+#if defined(RTEMS_SMP)
+ bsp_interrupt_spurious( vector );
+#else
+ bsp_interrupt_handler_default( vector );
+#endif
+ }
+
+ rtems_record_produce( RTEMS_RECORD_INTERRUPT_EXIT, vector );
+}
+
+void _Record_Interrupt_initialize( void )
+{
+ uintptr_t i;
+
+ /*
+ * Let each interrupt dispatch table slot reference the
+ * _Record_Interrupt_handler() interrupt dispatch wrapper.
+ */
+ for ( i = 0; i < BSP_INTERRUPT_DISPATCH_TABLE_SIZE; ++i ) {
+ _Record_Interrupt_entry_table[ i ].handler = _Record_Interrupt_handler;
+ _Record_Interrupt_entry_table[ i ].arg = (void *) i;
+ bsp_interrupt_dispatch_table[ i ] = &_Record_Interrupt_entry_table[ i ];
+ }
+}
diff --git a/bsps/shared/irq/irq-server.c b/bsps/shared/irq/irq-server.c
index 8b9d82eb29..bac54316d1 100644
--- a/bsps/shared/irq/irq-server.c
+++ b/bsps/shared/irq/irq-server.c
@@ -3,13 +3,13 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the interrupt server implementation.
*/
/*
- * Copyright (C) 2009, 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2009, 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/irq/irq-shell.c b/bsps/shared/irq/irq-shell.c
index cf70f2ce1b..a56fa938cf 100644
--- a/bsps/shared/irq/irq-shell.c
+++ b/bsps/shared/irq/irq-shell.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup bsp_interrupt
+ * @ingroup RTEMSImplClassicIntr
*
* @brief This source file contains the definition of
* ::bsp_interrupt_shell_command.
*/
/*
- * Copyright (C) 2009 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2009 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/rtems-version.c b/bsps/shared/rtems-version.c
index b12504a1c9..aaac5a07f3 100644
--- a/bsps/shared/rtems-version.c
+++ b/bsps/shared/rtems-version.c
@@ -1,3 +1,12 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplClassic
+ *
+ * @brief This source file contains the implementation of
+ * rtems_board_support_package() and the definition of ::_RTEMS_version.
+ */
+
/*
* COPYRIGHT (c) 2003, Ralf Corsepius, Ulm, Germany.
* COPYRIGHT (c) 2003, On-Line Applications Research Corporation (OAR).
diff --git a/bsps/shared/start/bsp-fdt.c b/bsps/shared/start/bsp-fdt.c
index 75a1ea41c9..79f31733e1 100644
--- a/bsps/shared/start/bsp-fdt.c
+++ b/bsps/shared/start/bsp-fdt.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2015, 2017 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,6 +32,10 @@
#include <bsp/fdt.h>
#include <bsp/linker-symbols.h>
+#ifdef BSP_DTB_IS_SUPPORTED
+#include BSP_DTB_HEADER_PATH
+#endif
+
#ifndef BSP_FDT_IS_SUPPORTED
#warning "BSP FDT support indication not defined"
#endif
@@ -76,5 +80,9 @@ void bsp_fdt_copy(const void *src)
const void *bsp_fdt_get(void)
{
+#ifdef BSP_DTB_IS_SUPPORTED
+ return system_dtb;
+#else
return &bsp_fdt_blob[0];
+#endif
}
diff --git a/bsps/shared/start/bsp-uboot-board-info.c b/bsps/shared/start/bsp-uboot-board-info.c
index 29ae573fd7..39828b1a9d 100644
--- a/bsps/shared/start/bsp-uboot-board-info.c
+++ b/bsps/shared/start/bsp-uboot-board-info.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2010, 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2010, 2016 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/start/bspfatal-default.c b/bsps/shared/start/bspfatal-default.c
index 28f492dee1..557a0960fa 100644
--- a/bsps/shared/start/bspfatal-default.c
+++ b/bsps/shared/start/bspfatal-default.c
@@ -1,5 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsShared
+ *
+ * @brief This source file contains the implementation of
+ * bsp_fatal_extension().
+ */
+
/*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
@@ -153,7 +162,7 @@ void bsp_fatal_extension(
_Thread_Get_name( executing, name, sizeof( name ) );
printk(
- "executing thread ID: 0x08%" PRIx32 "\n"
+ "executing thread ID: 0x%08" PRIx32 "\n"
"executing thread name: %s\n",
executing->Object.id,
name
diff --git a/bsps/shared/start/bspgetworkarea-default.c b/bsps/shared/start/bspgetworkarea-default.c
index 5686b013f9..5f956b124f 100644
--- a/bsps/shared/start/bspgetworkarea-default.c
+++ b/bsps/shared/start/bspgetworkarea-default.c
@@ -12,7 +12,7 @@
*/
/*
- * Copyright (C) 2011, 2019 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2011, 2019 embedded brains GmbH & Co. KG
*
* Copyright (C) 1989, 2009 On-Line Applications Research Corporation (OAR)
*
@@ -39,7 +39,6 @@
*/
#include <bsp.h>
-#include <bsp/bootcard.h>
#if defined(HAS_UBOOT) && !defined(BSP_DISABLE_UBOOT_WORK_AREA_CONFIG)
#define USE_UBOOT
diff --git a/bsps/shared/start/gettargethash-default.c b/bsps/shared/start/gettargethash-default.c
index 1647b01a66..28336b9f47 100644
--- a/bsps/shared/start/gettargethash-default.c
+++ b/bsps/shared/start/gettargethash-default.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/start/mallocinitmulti.c b/bsps/shared/start/mallocinitmulti.c
index ad04ea14ed..3d774ab65f 100644
--- a/bsps/shared/start/mallocinitmulti.c
+++ b/bsps/shared/start/mallocinitmulti.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/start/mallocinitone.c b/bsps/shared/start/mallocinitone.c
index 249f0b8e02..f590523ea1 100644
--- a/bsps/shared/start/mallocinitone.c
+++ b/bsps/shared/start/mallocinitone.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/start/stackalloc.c b/bsps/shared/start/stackalloc.c
index 1d2b0e6880..485753fad9 100644
--- a/bsps/shared/start/stackalloc.c
+++ b/bsps/shared/start/stackalloc.c
@@ -9,7 +9,7 @@
*/
/*
- * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2009, 2013 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/start/wkspaceinitmulti.c b/bsps/shared/start/wkspaceinitmulti.c
index 2a0d0b5806..8ca34c1bc5 100644
--- a/bsps/shared/start/wkspaceinitmulti.c
+++ b/bsps/shared/start/wkspaceinitmulti.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/start/wkspaceinitone.c b/bsps/shared/start/wkspaceinitone.c
index 91d007d100..a93edad962 100644
--- a/bsps/shared/start/wkspaceinitone.c
+++ b/bsps/shared/start/wkspaceinitone.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/shared/xil/VERSION b/bsps/shared/xil/VERSION
new file mode 100644
index 0000000000..d94f574255
--- /dev/null
+++ b/bsps/shared/xil/VERSION
@@ -0,0 +1,20 @@
+The information in this file describes the source of files in
+bsps/shared/xil/ and bsps/include/xil/.
+
+Import from:
+
+https://github.com/Xilinx/embeddedsw.git
+
+commit 8a89579489c88ea5acd23d7d439ac928659c26cf
+Author: msreeram <manikanta.sreeram@xilinx.com>
+AuthorDate: Wed Apr 6 23:24:38 2022 -0600
+Commit: Siva Addepalli <sivaprasad.addepalli@xilinx.com>
+CommitDate: Fri Apr 8 16:47:15 2022 +0530
+
+ update license file for EmbeddedSW 2022.1 release
+
+ Update license file for EmbeddedSW 2022.1 release
+
+ Signed-off-by: Manikanta Sreeram <msreeram@xilinx.com>
+
+ Acked-by : Meena Paleti <meena.paleti@xilinx.com>
diff --git a/bsps/shared/xil/arm/ARMv8/xil_cache.c b/bsps/shared/xil/arm/ARMv8/xil_cache.c
new file mode 100644
index 0000000000..aef64b310a
--- /dev/null
+++ b/bsps/shared/xil/arm/ARMv8/xil_cache.c
@@ -0,0 +1,732 @@
+/******************************************************************************
+* Copyright (c) 2014 - 2021 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xil_cache.c
+*
+* Contains required functions for the ARM cache functionality.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 5.0 pkp 05/29/14 First release
+* 5.5 pkp 04/15/16 Updated the Xil_DCacheInvalidate,
+* Xil_DCacheInvalidateLine and Xil_DCacheInvalidateRange
+* functions description for proper explanation
+* 6.2 pkp 01/22/17 Added support for EL1 non-secure
+* 6.2 asa 01/31/17 The existing Xil_DCacheDisable API first flushes the
+* D caches and then disables it. The problem with that is,
+* potentially there will be a small window after the cache
+* flush operation and before the we disable D caches where
+* we might have valid data in cache lines. In such a
+* scenario disabling the D cache can lead to unknown behavior.
+* The ideal solution to this is to use assembly code for
+* the complete API and avoid any memory accesses. But with
+* that we will end up having a huge amount on assembly code
+* which is not maintainable. Changes are done to use a mix
+* of assembly and C code. All local variables are put in
+* registers. Also function calls are avoided in the API to
+* avoid using stack memory.
+* These changes fix CR#966220.
+* 6.2 mus 02/13/17 The new api Xil_ConfigureL1Prefetch is added to disable pre-fetching/configure
+* the maximum number of outstanding data prefetches allowed in
+* L1 cache system.It fixes CR#967864.
+* 6.6 mus 02/27/18 Updated Xil_DCacheInvalidateRange and
+* Xil_ICacheInvalidateRange APIs to change the data type of
+* "cacheline" variable as "INTPTR", This change has been done
+* to avoid the truncation of upper DDR addresses to 32 bit.It
+* fixes CR#995581.
+* 6.6 mus 03/15/18 By default CPUACTLR_EL1 is accessible only from EL3, it
+* results into abort if accessed from EL1 non secure privilege
+* level. Updated Xil_ConfigureL1Prefetch function to access
+* CPUACTLR_EL1 only for EL3.
+* 6.8 mn 08/01/18 Optimize the Xil_DCacheInvalidateRange() function to remove
+* redundant operations
+* 6.8 asa 09/15/18 Fix bug in the Xil_DCacheInvalidateRange API introduced while
+* making optimizations in the previous patch. This change fixes
+* CR-1008926.
+* 7.0 mus 10/12/18 Updated Xil_DCacheInvalidateLine and Xil_DCacheInvalidateRange
+* APIs to replace IVAC instruction with CIVAC. So that, these
+* APIs will always do flush + invalidate in case of Cortexa53 as
+* well as Cortexa72 processor.
+* 7.1 mus 09/17/19 Xil_DCacheFlushRange and Xil_DCacheInvalidateRange are executing
+* same functionality (clean + validate). Removed
+* Xil_DCacheFlushRange function implementation and defined it as
+* macro. Xil_DCacheFlushRange macro points to the
+* Xil_DCacheInvalidateRange API to avoid code duplication.
+*
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xil_cache.h"
+#include "xil_io.h"
+#include "xpseudo_asm.h"
+#include "xparameters.h"
+#include "xreg_cortexa53.h"
+#include "xil_exception.h"
+#include "bspconfig.h"
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+#define IRQ_FIQ_MASK 0xC0U /* Mask IRQ and FIQ interrupts in cpsr */
+
+/****************************************************************************/
+/**
+* @brief Enable the Data cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheEnable(void)
+{
+ u32 CtrlReg;
+
+ if (EL3 == 1) {
+ CtrlReg = mfcp(SCTLR_EL3);
+ } else if (EL1_NONSECURE == 1) {
+ CtrlReg = mfcp(SCTLR_EL1);
+ } else {
+ CtrlReg = 0U;
+ }
+
+ /* enable caches only if they are disabled */
+ if((CtrlReg & XREG_CONTROL_DCACHE_BIT) == 0X00000000U){
+
+ /* invalidate the Data cache */
+ Xil_DCacheInvalidate();
+
+ CtrlReg |= XREG_CONTROL_DCACHE_BIT;
+
+ if (EL3 == 1) {
+ /* enable the Data cache for el3*/
+ mtcp(SCTLR_EL3,CtrlReg);
+ } else if (EL1_NONSECURE == 1) {
+ /* enable the Data cache for el1*/
+ mtcp(SCTLR_EL1,CtrlReg);
+ }
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Disable the Data cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheDisable(void)
+{
+ register u32 CsidReg;
+ register u32 C7Reg;
+ register u32 LineSize;
+ register u32 NumWays;
+ register u32 Way;
+ register u32 WayIndex;
+ register u32 WayAdjust;
+ register u32 Set;
+ register u32 SetIndex;
+ register u32 NumSet;
+ register u32 CacheLevel;
+
+ dsb();
+ asm(
+ "mov x0, #0\n\t"
+#if EL3==1
+ "mrs x0, sctlr_el3 \n\t"
+ "and w0, w0, #0xfffffffb\n\t"
+ "msr sctlr_el3, x0\n\t"
+#elif EL1_NONSECURE==1
+ "mrs x0, sctlr_el1 \n\t"
+ "and w0, w0, #0xfffffffb\n\t"
+ "msr sctlr_el1, x0\n\t"
+#endif
+ "dsb sy\n\t"
+ );
+
+ /* Number of level of cache*/
+ CacheLevel = 0U;
+ /* Select cache level 0 and D cache in CSSR */
+ mtcp(CSSELR_EL1,CacheLevel);
+ isb();
+
+ CsidReg = mfcp(CCSIDR_EL1);
+
+ /* Get the cacheline size, way size, index size from csidr */
+ LineSize = (CsidReg & 0x00000007U) + 0x00000004U;
+
+ /* Number of Ways */
+ NumWays = (CsidReg & 0x00001FFFU) >> 3U;
+ NumWays += 0x00000001U;
+
+ /*Number of Set*/
+ NumSet = (CsidReg >> 13U) & 0x00007FFFU;
+ NumSet += 0x00000001U;
+
+ WayAdjust = clz(NumWays) - (u32)0x0000001FU;
+
+ Way = 0U;
+ Set = 0U;
+
+ /* Flush all the cachelines */
+ for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) {
+ for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) {
+ C7Reg = Way | Set | CacheLevel;
+ mtcpdc(CISW,C7Reg);
+ Set += (0x00000001U << LineSize);
+ }
+ Set = 0U;
+ Way += (0x00000001U << WayAdjust);
+ }
+
+ /* Wait for Flush to complete */
+ dsb();
+
+ /* Select cache level 1 and D cache in CSSR */
+ CacheLevel += (0x00000001U << 1U);
+ mtcp(CSSELR_EL1,CacheLevel);
+ isb();
+
+ CsidReg = mfcp(CCSIDR_EL1);
+
+ /* Get the cacheline size, way size, index size from csidr */
+ LineSize = (CsidReg & 0x00000007U) + 0x00000004U;
+
+ /* Number of Ways */
+ NumWays = (CsidReg & 0x00001FFFU) >> 3U;
+ NumWays += 0x00000001U;
+
+ /* Number of Sets */
+ NumSet = (CsidReg >> 13U) & 0x00007FFFU;
+ NumSet += 0x00000001U;
+
+ WayAdjust=clz(NumWays) - (u32)0x0000001FU;
+
+ Way = 0U;
+ Set = 0U;
+
+ /* Flush all the cachelines */
+ for (WayIndex =0U; WayIndex < NumWays; WayIndex++) {
+ for (SetIndex =0U; SetIndex < NumSet; SetIndex++) {
+ C7Reg = Way | Set | CacheLevel;
+ mtcpdc(CISW,C7Reg);
+ Set += (0x00000001U << LineSize);
+ }
+ Set=0U;
+ Way += (0x00000001U<<WayAdjust);
+ }
+ /* Wait for Flush to complete */
+ dsb();
+
+ asm(
+#if EL3==1
+ "tlbi ALLE3\n\t"
+#elif EL1_NONSECURE==1
+ "tlbi VMALLE1\n\t"
+#endif
+ "dsb sy\r\n"
+ "isb\n\t"
+ );
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate the Data cache. The contents present in the cache are
+* cleaned and invalidated.
+*
+* @return None.
+*
+* @note In Cortex-A53, functionality to simply invalid the cachelines
+* is not present. Such operations are a problem for an environment
+* that supports virtualisation. It would allow one OS to invalidate
+* a line belonging to another OS. This could lead to the other OS
+* crashing because of the loss of essential data. Hence, such
+* operations are promoted to clean and invalidate which avoids such
+* corruption.
+*
+****************************************************************************/
+void Xil_DCacheInvalidate(void)
+{
+ register u32 CsidReg, C7Reg;
+ u32 LineSize, NumWays;
+ u32 Way, WayIndex,WayAdjust, Set, SetIndex, NumSet, CacheLevel;
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+
+ /* Number of level of cache*/
+
+ CacheLevel=0U;
+ /* Select cache level 0 and D cache in CSSR */
+ mtcp(CSSELR_EL1,CacheLevel);
+ isb();
+
+ CsidReg = mfcp(CCSIDR_EL1);
+
+ /* Get the cacheline size, way size, index size from csidr */
+ LineSize = (CsidReg & 0x00000007U) + 0x00000004U;
+
+ /* Number of Ways */
+ NumWays = (CsidReg & 0x00001FFFU) >> 3U;
+ NumWays += 0X00000001U;
+
+ /*Number of Set*/
+ NumSet = (CsidReg >> 13U) & 0x00007FFFU;
+ NumSet += 0X00000001U;
+
+ WayAdjust = clz(NumWays) - (u32)0x0000001FU;
+
+ Way = 0U;
+ Set = 0U;
+
+ /* Invalidate all the cachelines */
+ for (WayIndex =0U; WayIndex < NumWays; WayIndex++) {
+ for (SetIndex =0U; SetIndex < NumSet; SetIndex++) {
+ C7Reg = Way | Set | CacheLevel;
+ mtcpdc(ISW,C7Reg);
+ Set += (0x00000001U << LineSize);
+ }
+ Set = 0U;
+ Way += (0x00000001U << WayAdjust);
+ }
+
+ /* Wait for invalidate to complete */
+ dsb();
+
+ /* Select cache level 1 and D cache in CSSR */
+ CacheLevel += (0x00000001U<<1U) ;
+ mtcp(CSSELR_EL1,CacheLevel);
+ isb();
+
+ CsidReg = mfcp(CCSIDR_EL1);
+
+ /* Get the cacheline size, way size, index size from csidr */
+ LineSize = (CsidReg & 0x00000007U) + 0x00000004U;
+
+ /* Number of Ways */
+ NumWays = (CsidReg & 0x00001FFFU) >> 3U;
+ NumWays += 0x00000001U;
+
+ /* Number of Sets */
+ NumSet = (CsidReg >> 13U) & 0x00007FFFU;
+ NumSet += 0x00000001U;
+
+ WayAdjust = clz(NumWays) - (u32)0x0000001FU;
+
+ Way = 0U;
+ Set = 0U;
+
+ /* Invalidate all the cachelines */
+ for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) {
+ for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) {
+ C7Reg = Way | Set | CacheLevel;
+ mtcpdc(ISW,C7Reg);
+ Set += (0x00000001U << LineSize);
+ }
+ Set = 0U;
+ Way += (0x00000001U << WayAdjust);
+ }
+ /* Wait for invalidate to complete */
+ dsb();
+
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate a Data cache line. The cacheline is cleaned and
+* invalidated.
+*
+* @param adr: 64bit address of the data to be flushed.
+*
+* @return None.
+*
+* @note In Cortex-A53, functionality to simply invalid the cachelines
+* is not present. Such operations are a problem for an environment
+* that supports virtualisation. It would allow one OS to invalidate
+* a line belonging to another OS. This could lead to the other OS
+* crashing because of the loss of essential data. Hence, such
+* operations are promoted to clean and invalidate which avoids such
+* corruption.
+*
+****************************************************************************/
+void Xil_DCacheInvalidateLine(INTPTR adr)
+{
+
+ u32 currmask;
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ /* Select cache level 0 and D cache in CSSR */
+ mtcp(CSSELR_EL1,0x0);
+ mtcpdc(CIVAC,(adr & (~0x3F)));
+ /* Wait for invalidate to complete */
+ dsb();
+ /* Select cache level 1 and D cache in CSSR */
+ mtcp(CSSELR_EL1,0x2);
+ mtcpdc(IVAC,(adr & (~0x3F)));
+ /* Wait for invalidate to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate the Data cache for the given address range.
+* The cachelines present in the adderss range are cleaned and
+* invalidated
+*
+* @param adr: 64bit start address of the range to be invalidated.
+* @param len: Length of the range to be invalidated in bytes.
+*
+* @return None.
+*
+* @note In Cortex-A53, functionality to simply invalid the cachelines
+* is not present. Such operations are a problem for an environment
+* that supports virtualisation. It would allow one OS to invalidate
+* a line belonging to another OS. This could lead to the other OS
+* crashing because of the loss of essential data. Hence, such
+* operations are promoted to clean and invalidate which avoids such
+* corruption.
+*
+****************************************************************************/
+void Xil_DCacheInvalidateRange(INTPTR adr, INTPTR len)
+{
+ const INTPTR cacheline = 64U;
+ INTPTR end = adr + len;
+ adr = adr & (~0x3F);
+ u32 currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+ if (len != 0U) {
+ while (adr < end) {
+ mtcpdc(CIVAC,adr);
+ adr += cacheline;
+ }
+ }
+ /* Wait for invalidate to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Flush the Data cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheFlush(void)
+{
+ register u32 CsidReg, C7Reg;
+ u32 LineSize, NumWays;
+ u32 Way, WayIndex,WayAdjust, Set, SetIndex, NumSet, CacheLevel;
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+
+ /* Number of level of cache*/
+
+ CacheLevel = 0U;
+ /* Select cache level 0 and D cache in CSSR */
+ mtcp(CSSELR_EL1,CacheLevel);
+ isb();
+
+ CsidReg = mfcp(CCSIDR_EL1);
+
+ /* Get the cacheline size, way size, index size from csidr */
+ LineSize = (CsidReg & 0x00000007U) + 0x00000004U;
+
+ /* Number of Ways */
+ NumWays = (CsidReg & 0x00001FFFU) >> 3U;
+ NumWays += 0x00000001U;
+
+ /*Number of Set*/
+ NumSet = (CsidReg >> 13U) & 0x00007FFFU;
+ NumSet += 0x00000001U;
+
+ WayAdjust = clz(NumWays) - (u32)0x0000001FU;
+
+ Way = 0U;
+ Set = 0U;
+
+ /* Flush all the cachelines */
+ for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) {
+ for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) {
+ C7Reg = Way | Set | CacheLevel;
+ mtcpdc(CISW,C7Reg);
+ Set += (0x00000001U << LineSize);
+ }
+ Set = 0U;
+ Way += (0x00000001U << WayAdjust);
+ }
+
+ /* Wait for Flush to complete */
+ dsb();
+
+ /* Select cache level 1 and D cache in CSSR */
+ CacheLevel += (0x00000001U << 1U);
+ mtcp(CSSELR_EL1,CacheLevel);
+ isb();
+
+ CsidReg = mfcp(CCSIDR_EL1);
+
+ /* Get the cacheline size, way size, index size from csidr */
+ LineSize = (CsidReg & 0x00000007U) + 0x00000004U;
+
+ /* Number of Ways */
+ NumWays = (CsidReg & 0x00001FFFU) >> 3U;
+ NumWays += 0x00000001U;
+
+ /* Number of Sets */
+ NumSet = (CsidReg >> 13U) & 0x00007FFFU;
+ NumSet += 0x00000001U;
+
+ WayAdjust=clz(NumWays) - (u32)0x0000001FU;
+
+ Way = 0U;
+ Set = 0U;
+
+ /* Flush all the cachelines */
+ for (WayIndex =0U; WayIndex < NumWays; WayIndex++) {
+ for (SetIndex =0U; SetIndex < NumSet; SetIndex++) {
+ C7Reg = Way | Set | CacheLevel;
+ mtcpdc(CISW,C7Reg);
+ Set += (0x00000001U << LineSize);
+ }
+ Set=0U;
+ Way += (0x00000001U<<WayAdjust);
+ }
+ /* Wait for Flush to complete */
+ dsb();
+
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Flush a Data cache line. If the byte specified by the address (adr)
+* is cached by the Data cache, the cacheline containing that byte is
+* invalidated. If the cacheline is modified (dirty), the entire
+* contents of the cacheline are written to system memory before the
+* line is invalidated.
+*
+* @param adr: 64bit address of the data to be flushed.
+*
+* @return None.
+*
+* @note The bottom 6 bits are set to 0, forced by architecture.
+*
+****************************************************************************/
+void Xil_DCacheFlushLine(INTPTR adr)
+{
+ u32 currmask;
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+ /* Select cache level 0 and D cache in CSSR */
+ mtcp(CSSELR_EL1,0x0);
+ mtcpdc(CIVAC,(adr & (~0x3F)));
+ /* Wait for flush to complete */
+ dsb();
+ /* Select cache level 1 and D cache in CSSR */
+ mtcp(CSSELR_EL1,0x2);
+ mtcpdc(CIVAC,(adr & (~0x3F)));
+ /* Wait for flush to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Enable the instruction cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_ICacheEnable(void)
+{
+ u32 CtrlReg;
+
+ if (EL3 == 1) {
+ CtrlReg = mfcp(SCTLR_EL3);
+ } else if (EL1_NONSECURE == 1) {
+ CtrlReg = mfcp(SCTLR_EL1);
+ } else {
+ CtrlReg = 0U;
+ }
+
+ /* enable caches only if they are disabled */
+ if((CtrlReg & XREG_CONTROL_ICACHE_BIT)==0x00000000U){
+ /* invalidate the instruction cache */
+ Xil_ICacheInvalidate();
+
+ CtrlReg |= XREG_CONTROL_ICACHE_BIT;
+
+ if (EL3 == 1) {
+ /* enable the instruction cache for el3*/
+ mtcp(SCTLR_EL3,CtrlReg);
+ } else if (EL1_NONSECURE == 1) {
+ /* enable the instruction cache for el1*/
+ mtcp(SCTLR_EL1,CtrlReg);
+ }
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Disable the instruction cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_ICacheDisable(void)
+{
+ u32 CtrlReg;
+
+ if (EL3 == 1) {
+ CtrlReg = mfcp(SCTLR_EL3);
+ } else if (EL1_NONSECURE == 1) {
+ CtrlReg = mfcp(SCTLR_EL1);
+ } else {
+ CtrlReg = 0U;
+ }
+ /* invalidate the instruction cache */
+ Xil_ICacheInvalidate();
+ CtrlReg &= ~(XREG_CONTROL_ICACHE_BIT);
+
+ if (EL3 == 1) {
+ /* disable the instruction cache */
+ mtcp(SCTLR_EL3,CtrlReg);
+ } else if (EL1_NONSECURE == 1) {
+ /* disable the instruction cache */
+ mtcp(SCTLR_EL1,CtrlReg);
+ }
+
+
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate the entire instruction cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_ICacheInvalidate(void)
+{
+ unsigned int currmask;
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+ mtcp(CSSELR_EL1,0x1);
+ dsb();
+ /* invalidate the instruction cache */
+ mtcpicall(IALLU);
+ /* Wait for invalidate to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate an instruction cache line. If the instruction specified
+* by the parameter adr is cached by the instruction cache, the
+* cacheline containing that instruction is invalidated.
+*
+* @param adr: 64bit address of the instruction to be invalidated.
+*
+* @return None.
+*
+* @note The bottom 6 bits are set to 0, forced by architecture.
+*
+****************************************************************************/
+void Xil_ICacheInvalidateLine(INTPTR adr)
+{
+ u32 currmask;
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ mtcp(CSSELR_EL1,0x1);
+ /*Invalidate I Cache line*/
+ mtcpic(IVAU,adr & (~0x3F));
+ /* Wait for invalidate to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate the instruction cache for the given address range.
+* If the instructions specified by the address range are cached by
+* the instrunction cache, the cachelines containing those
+* instructions are invalidated.
+*
+* @param adr: 64bit start address of the range to be invalidated.
+* @param len: Length of the range to be invalidated in bytes.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_ICacheInvalidateRange(INTPTR adr, INTPTR len)
+{
+ const INTPTR cacheline = 64U;
+ INTPTR end;
+ INTPTR tempadr = adr;
+ INTPTR tempend;
+ u32 currmask;
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ if (len != 0x00000000U) {
+ end = tempadr + len;
+ tempend = end;
+ tempadr &= ~(cacheline - 0x00000001U);
+
+ /* Select cache Level 0 I-cache in CSSR */
+ mtcp(CSSELR_EL1,0x1);
+ while (tempadr < tempend) {
+ /*Invalidate I Cache line*/
+ mtcpic(IVAU,adr & (~0x3F));
+
+ tempadr += cacheline;
+ }
+ }
+/* Wait for invalidate to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Configure the maximum number of outstanding data prefetches
+* allowed in L1 cache.
+*
+* @param num: maximum number of outstanding data prefetches allowed,
+* valid values are 0-7.
+*
+* @return None.
+*
+* @note This function is implemented only for EL3 privilege level.
+*
+*****************************************************************************/
+void Xil_ConfigureL1Prefetch (u8 num) {
+#if EL3
+ u64 val=0;
+
+ val= mfcp(S3_1_C15_C2_0 );
+ val &= ~(L1_DATA_PREFETCH_CONTROL_MASK);
+ val |= (num << L1_DATA_PREFETCH_CONTROL_SHIFT);
+ mtcp(S3_1_C15_C2_0,val);
+#endif
+}
diff --git a/bsps/shared/xil/arm/cortexr5/xil_cache.c b/bsps/shared/xil/arm/cortexr5/xil_cache.c
new file mode 100644
index 0000000000..631d02f648
--- /dev/null
+++ b/bsps/shared/xil/arm/cortexr5/xil_cache.c
@@ -0,0 +1,561 @@
+/******************************************************************************
+* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xil_cache.c
+*
+* Contains required functions for the ARM cache functionality.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 5.00 pkp 02/20/14 First release
+* 6.2 mus 01/27/17 Updated to support IAR compiler
+* 7.3 dp 06/25/20 Updated to support armclang compiler
+* 7.7 sk 01/10/22 Update IRQ_FIQ_MASK macro from signed to unsigned
+* to fix misra_c_2012_rule_10_4 violation.
+* 7.7 sk 01/10/22 Typecast to fix wider essential type misra_c_2012_rule_10_7
+* violation.
+* 7.7 mus 02/21/22 Existing note in cache API's says, "bottom 4 bits of input
+* address are forced to 0 as per architecture". As cache line
+* length is of 32 byte, bottom 5 bits of input address would
+* be forced to 0. Updated note to have correct details.
+* It fixes CR#1122561.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xil_cache.h"
+#include "xil_io.h"
+#include "xpseudo_asm.h"
+#include "xparameters.h"
+#include "xreg_cortexr5.h"
+#include "xil_exception.h"
+
+
+/************************** Variable Definitions *****************************/
+
+#define IRQ_FIQ_MASK 0xC0U /* Mask IRQ and FIQ interrupts in cpsr */
+
+#if defined (__clang__)
+extern s32 Image$$ARM_LIB_STACK$$Limit;
+extern s32 Image$$ARM_UNDEF_STACK$$Base;
+#elif defined (__GNUC__)
+extern s32 _stack_end;
+extern s32 __undef_stack;
+#endif
+
+/****************************************************************************/
+/************************** Function Prototypes ******************************/
+
+/****************************************************************************/
+/**
+* @brief Enable the Data cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheEnable(void)
+{
+ register u32 CtrlReg;
+
+ /* enable caches only if they are disabled */
+#if defined (__GNUC__)
+ CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
+#endif
+ if ((CtrlReg & XREG_CP15_CONTROL_C_BIT)==0x00000000U) {
+ /* invalidate the Data cache */
+ Xil_DCacheInvalidate();
+
+ /* enable the Data cache */
+ CtrlReg |= (XREG_CP15_CONTROL_C_BIT);
+
+ mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Disable the Data cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheDisable(void)
+{
+ register u32 CtrlReg;
+
+ /* clean and invalidate the Data cache */
+ Xil_DCacheFlush();
+
+ /* disable the Data cache */
+#if defined (__GNUC__)
+ CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
+#endif
+
+ CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT);
+
+ mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate the entire Data cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheInvalidate(void)
+{
+ u32 currmask;
+ u32 stack_start,stack_end,stack_size;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+#if defined (__clang__)
+ stack_end = (u32 )&Image$$ARM_LIB_STACK$$Limit;
+ stack_start = (u32 )&Image$$ARM_UNDEF_STACK$$Base;
+#elif defined (__GNUC__)
+ stack_end = (u32 )&_stack_end;
+ stack_start = (u32 )&__undef_stack;
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+ stack_size = stack_start-stack_end;
+
+ /* Flush stack memory to save return address */
+ Xil_DCacheFlushRange(stack_end, stack_size);
+#endif
+
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
+
+ /*invalidate all D cache*/
+ mtcp(XREG_CP15_INVAL_DC_ALL, 0);
+
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate a Data cache line. If the byte specified by the
+* address (adr) is cached by the data cache, the cacheline
+* containing that byte is invalidated.If the cacheline is modified
+* (dirty), the modified contents are lost and are NOT written
+* to system memory before the line is invalidated.
+*
+*
+* @param adr: 32bit address of the data to be flushed.
+*
+* @return None.
+*
+* @note The bottom 5 bits are set to 0, forced by architecture.
+*
+****************************************************************************/
+void Xil_DCacheInvalidateLine(INTPTR adr)
+{
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
+ mtcp(XREG_CP15_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F)));
+
+ /* Wait for invalidate to complete */
+ dsb();
+
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate the Data cache for the given address range.
+* If the bytes specified by the address (adr) are cached by the
+* Data cache,the cacheline containing that byte is invalidated.
+* If the cacheline is modified (dirty), the modified contents are
+* lost and are NOT written to system memory before the line is
+* invalidated.
+*
+* @param adr: 32bit start address of the range to be invalidated.
+* @param len: Length of range to be invalidated in bytes.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheInvalidateRange(INTPTR adr, u32 len)
+{
+ const u32 cacheline = 32U;
+ u32 end;
+ u32 tempadr = adr;
+ u32 tempend;
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ if (len != 0U) {
+ end = tempadr + len;
+ tempend = end;
+ /* Select L1 Data cache in CSSR */
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U);
+
+ if ((tempadr & (cacheline-1U)) != 0U) {
+ tempadr &= (~(cacheline - 1U));
+
+ Xil_DCacheFlushLine(tempadr);
+ }
+ if ((tempend & (cacheline-1U)) != 0U) {
+ tempend &= (~(cacheline - 1U));
+
+ Xil_DCacheFlushLine(tempend);
+ }
+
+ while (tempadr < tempend) {
+
+ /* Invalidate Data cache line */
+ asm_inval_dc_line_mva_poc(tempadr);
+
+ tempadr += cacheline;
+ }
+ }
+
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Flush the entire Data cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheFlush(void)
+{
+ register u32 CsidReg, C7Reg;
+ u32 CacheSize, LineSize, NumWays;
+ u32 Way, WayIndex, Set, SetIndex, NumSet;
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ /* Select cache level 0 and D cache in CSSR */
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
+
+#if defined (__GNUC__)
+ CsidReg = mfcp(XREG_CP15_CACHE_SIZE_ID);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_CACHE_SIZE_ID,CsidReg);
+#endif
+ /* Determine Cache Size */
+
+ CacheSize = (CsidReg >> 13U) & 0x000001FFU;
+ CacheSize += 0x00000001U;
+ CacheSize *= (u32)128; /* to get number of bytes */
+
+ /* Number of Ways */
+ NumWays = (CsidReg & 0x000003ffU) >> 3U;
+ NumWays += 0x00000001U;
+
+ /* Get the cacheline size, way size, index size from csidr */
+ LineSize = (CsidReg & 0x00000007U) + 0x00000004U;
+
+ NumSet = CacheSize/NumWays;
+ NumSet /= (((u32)0x00000001U) << LineSize);
+
+ Way = 0U;
+ Set = 0U;
+
+ /* Invalidate all the cachelines */
+ for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) {
+ for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) {
+ C7Reg = Way | Set;
+ /* Flush by Set/Way */
+ asm_clean_inval_dc_line_sw(C7Reg);
+
+ Set += (((u32)0x00000001U) << LineSize);
+ }
+ Set = 0U;
+ Way += 0x40000000U;
+ }
+
+ /* Wait for flush to complete */
+ dsb();
+ mtcpsr(currmask);
+
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Flush a Data cache line. If the byte specified by the address (adr)
+* is cached by the Data cache, the cacheline containing that byte is
+* invalidated. If the cacheline is modified (dirty), the entire
+* contents of the cacheline are written to system memory before the
+* line is invalidated.
+*
+* @param adr: 32bit address of the data to be flushed.
+*
+* @return None.
+*
+* @note The bottom 5 bits are set to 0, forced by architecture.
+*
+****************************************************************************/
+void Xil_DCacheFlushLine(INTPTR adr)
+{
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
+
+ mtcp(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F)));
+
+ /* Wait for flush to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Flush the Data cache for the given address range.
+* If the bytes specified by the address (adr) are cached by the
+* Data cache, the cacheline containing those bytes is invalidated.If
+* the cacheline is modified (dirty), the written to system memory
+* before the lines are invalidated.
+*
+* @param adr: 32bit start address of the range to be flushed.
+* @param len: Length of the range to be flushed in bytes
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_DCacheFlushRange(INTPTR adr, u32 len)
+{
+ u32 LocalAddr = adr;
+ const u32 cacheline = 32U;
+ u32 end;
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ if (len != 0x00000000U) {
+ /* Back the starting address up to the start of a cache line
+ * perform cache operations until adr+len
+ */
+ end = LocalAddr + len;
+ LocalAddr &= ~(cacheline - 1U);
+
+ while (LocalAddr < end) {
+ /* Flush Data cache line */
+ asm_clean_inval_dc_line_mva_poc(LocalAddr);
+
+ LocalAddr += cacheline;
+ }
+ }
+ dsb();
+ mtcpsr(currmask);
+}
+/****************************************************************************/
+/**
+* @brief Store a Data cache line. If the byte specified by the address
+* (adr) is cached by the Data cache and the cacheline is modified
+* (dirty), the entire contents of the cacheline are written to
+* system memory.After the store completes, the cacheline is marked
+* as unmodified (not dirty).
+*
+* @param adr: 32bit address of the data to be stored
+*
+* @return None.
+*
+* @note The bottom 5 bits are set to 0, forced by architecture.
+*
+****************************************************************************/
+void Xil_DCacheStoreLine(INTPTR adr)
+{
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
+ mtcp(XREG_CP15_CLEAN_DC_LINE_MVA_POC, (adr & (~0x1F)));
+
+ /* Wait for store to complete */
+ dsb();
+ isb();
+
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Enable the instruction cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_ICacheEnable(void)
+{
+ register u32 CtrlReg;
+
+ /* enable caches only if they are disabled */
+#if defined (__GNUC__)
+ CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_SYS_CONTROL, CtrlReg);
+#endif
+ if ((CtrlReg & XREG_CP15_CONTROL_I_BIT)==0x00000000U) {
+ /* invalidate the instruction cache */
+ mtcp(XREG_CP15_INVAL_IC_POU, 0);
+
+ /* enable the instruction cache */
+ CtrlReg |= (XREG_CP15_CONTROL_I_BIT);
+
+ mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Disable the instruction cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_ICacheDisable(void)
+{
+ register u32 CtrlReg;
+
+ dsb();
+
+ /* invalidate the instruction cache */
+ mtcp(XREG_CP15_INVAL_IC_POU, 0);
+
+ /* disable the instruction cache */
+#if defined (__GNUC__)
+ CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
+#endif
+
+ CtrlReg &= ~(XREG_CP15_CONTROL_I_BIT);
+
+ mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate the entire instruction cache.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_ICacheInvalidate(void)
+{
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 1);
+
+ /* invalidate the instruction cache */
+ mtcp(XREG_CP15_INVAL_IC_POU, 0);
+
+ /* Wait for invalidate to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate an instruction cache line.If the instruction specified
+* by the address is cached by the instruction cache, the
+* cacheline containing that instruction is invalidated.
+*
+* @param adr: 32bit address of the instruction to be invalidated.
+*
+* @return None.
+*
+* @note The bottom 5 bits are set to 0, forced by architecture.
+*
+****************************************************************************/
+void Xil_ICacheInvalidateLine(INTPTR adr)
+{
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 1);
+ mtcp(XREG_CP15_INVAL_IC_LINE_MVA_POU, (adr & (~0x1F)));
+
+ /* Wait for invalidate to complete */
+ dsb();
+ mtcpsr(currmask);
+}
+
+/****************************************************************************/
+/**
+* @brief Invalidate the instruction cache for the given address range.
+* If the bytes specified by the address (adr) are cached by the
+* Data cache, the cacheline containing that byte is invalidated.
+* If the cachelineis modified (dirty), the modified contents are
+* lost and are NOT written to system memory before the line is
+* invalidated.
+*
+* @param adr: 32bit start address of the range to be invalidated.
+* @param len: Length of the range to be invalidated in bytes.
+*
+* @return None.
+*
+****************************************************************************/
+void Xil_ICacheInvalidateRange(INTPTR adr, u32 len)
+{
+ u32 LocalAddr = adr;
+ const u32 cacheline = 32U;
+ u32 end;
+ u32 currmask;
+
+ currmask = mfcpsr();
+ mtcpsr(currmask | IRQ_FIQ_MASK);
+ if (len != 0x00000000U) {
+ /* Back the starting address up to the start of a cache line
+ * perform cache operations until adr+len
+ */
+ end = LocalAddr + len;
+ LocalAddr = LocalAddr & ~(cacheline - 1U);
+
+ /* Select cache L0 I-cache in CSSR */
+ mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U);
+
+ while (LocalAddr < end) {
+
+ /* Invalidate L1 I-cache line */
+ asm_inval_ic_line_mva_pou(LocalAddr);
+
+ LocalAddr += cacheline;
+ }
+ }
+
+ /* Wait for invalidate to complete */
+ dsb();
+ mtcpsr(currmask);
+}
diff --git a/bsps/shared/xil/arm/cortexr5/xil_mpu.c b/bsps/shared/xil/arm/cortexr5/xil_mpu.c
new file mode 100644
index 0000000000..85f8f7f8da
--- /dev/null
+++ b/bsps/shared/xil/arm/cortexr5/xil_mpu.c
@@ -0,0 +1,645 @@
+/******************************************************************************
+* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+* @file xil_mpu.c
+*
+* This file provides APIs for enabling/disabling MPU and setting the memory
+* attributes for sections, in the MPU translation table.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- ---------------------------------------------------
+* 5.00 pkp 02/10/14 Initial version
+* 6.2 mus 01/27/17 Updated to support IAR compiler
+* 6.4 asa 08/16/17 Added many APIs for MPU access to make MPU usage
+* user-friendly. The APIs added are: Xil_UpdateMPUConfig,
+* Xil_GetMPUConfig, Xil_GetNumOfFreeRegions,
+* Xil_GetNextMPURegion, Xil_DisableMPURegionByRegNum,
+* Xil_GetMPUFreeRegMask, Xil_SetMPURegionByRegNum, and
+* Xil_InitializeExistingMPURegConfig.
+* Added a new array of structure of type XMpuConfig to
+* represent the MPU configuration table.
+* 6.8 aru 07/02/18 Returned the pointer instead of address
+* of that pointer in Xil_MemMap().
+* 7.5 asa 03/01/21 Ensure that Mpu_Config does not stay in .boot/.vector
+* sections which generally should be executable code
+* which can be allocated and not written.
+* Mpu_Config array is populated during boot time, hence
+* cannot be placed in .bss or .data section. Putting
+* Mpu_Config in a new .bootdata section.
+* 7.7 sk 01/10/22 Update int to u32 to fix misrac misra_c_2012_directive_4_6
+* violations.
+* 7.7 sk 01/10/22 Typecast variables from signed to unsigned to fix
+* misra_c_2012_rule_10_4 violation.
+* 7.7 sk 01/10/22 Add explicit parentheses for region_size and region_size[0]
+* to fix misra_c_2012_rule_12_1 violation.
+* 7.7 sk 01/10/22 Remove unsigned sign to fix misra_c_2012_rule_10_3 violation.
+* 7.7 sk 01/10/22 Modify if condition to fix misra_c_2012_rule_10_1 violation.
+* 7.7 sk 01/10/22 Typecast to fix wider essential type misra_c_2012_rule_10_7
+* violation.
+* 7.7 sk 01/10/22 Update conditional expression to fix misra_c_2012_rule_14_4
+* violation.
+* 7.7 sk 01/10/22 Add braces for the if statement to make it a compound
+* statement to fix misra_c_2012_rule_15_6 violation.
+* </pre>
+*
+*
+******************************************************************************/
+
+/*
+ * Origin: https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/arm/cortexr5/xil_mpu.c
+ * __rtems__ changes:
+ * - un-include xdebug.h and add macro for xdbg_printf
+ * - relocate XMpu_Config
+ * - form Xilinx link script section(".bootdata")
+ * - to RTEMS link script section(".bsp_start_data")
+ */
+
+/***************************** Include Files *********************************/
+
+#include "xil_cache.h"
+#include "xpseudo_asm.h"
+#include "xil_types.h"
+#include "xil_mpu.h"
+#ifndef __rtems__
+#include "xdebug.h"
+#else
+#define xdbg_printf(...)
+#endif
+#include "xstatus.h"
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/**************************** Type Definitions *******************************/
+
+/************************** Constant Definitions *****************************/
+#define MPU_REGION_SIZE_MIN 0x20
+/************************** Variable Definitions *****************************/
+
+static const struct {
+ u64 size;
+ u32 encoding;
+}region_size[] = {
+ { 0x20, REGION_32B },
+ { 0x40, REGION_64B },
+ { 0x80, REGION_128B },
+ { 0x100, REGION_256B },
+ { 0x200, REGION_512B },
+ { 0x400, REGION_1K },
+ { 0x800, REGION_2K },
+ { 0x1000, REGION_4K },
+ { 0x2000, REGION_8K },
+ { 0x4000, REGION_16K },
+ { 0x8000, REGION_32K },
+ { 0x10000, REGION_64K },
+ { 0x20000, REGION_128K },
+ { 0x40000, REGION_256K },
+ { 0x80000, REGION_512K },
+ { 0x100000, REGION_1M },
+ { 0x200000, REGION_2M },
+ { 0x400000, REGION_4M },
+ { 0x800000, REGION_8M },
+ { 0x1000000, REGION_16M },
+ { 0x2000000, REGION_32M },
+ { 0x4000000, REGION_64M },
+ { 0x8000000, REGION_128M },
+ { 0x10000000, REGION_256M },
+ { 0x20000000, REGION_512M },
+ { 0x40000000, REGION_1G },
+ { 0x80000000, REGION_2G },
+ { 0x100000000, REGION_4G },
+};
+
+#ifndef __rtems__
+#if defined (__GNUC__)
+XMpu_Config Mpu_Config __attribute__((section(".bootdata")));
+#elif defined (__ICCARM__)
+#pragma default_function_attributes = @ ".bootdata"
+XMpu_Config Mpu_Config;
+#endif
+#else
+XMpu_Config Mpu_Config __attribute__((section(".bsp_start_data")));
+#endif
+
+/************************** Function Prototypes ******************************/
+void Xil_InitializeExistingMPURegConfig(void);
+/*****************************************************************************/
+/**
+* @brief This function sets the memory attributes for a section covering
+* 1MB, of memory in the translation table.
+*
+* @param addr: 32-bit address for which memory attributes need to be set.
+* @param attrib: Attribute for the given memory region.
+* @return None.
+*
+*
+******************************************************************************/
+void Xil_SetTlbAttributes(INTPTR addr, u32 attrib)
+{
+ INTPTR Localaddr = addr;
+ Localaddr &= (INTPTR)(~(0xFFFFFU));
+ /* Setting the MPU region with given attribute with 1MB size */
+ Xil_SetMPURegion(Localaddr, 0x100000, attrib);
+}
+
+/*****************************************************************************/
+/**
+* @brief Set the memory attributes for a section of memory in the
+* translation table.
+*
+* @param addr: 32-bit address for which memory attributes need to be set..
+* @param size: size is the size of the region.
+* @param attrib: Attribute for the given memory region.
+* @return None.
+*
+*
+******************************************************************************/
+u32 Xil_SetMPURegion(INTPTR addr, u64 size, u32 attrib)
+{
+ u32 Regionsize = 0;
+ INTPTR Localaddr = addr;
+ u32 NextAvailableMemRegion;
+ u32 i;
+
+ NextAvailableMemRegion = Xil_GetNextMPURegion();
+ if (NextAvailableMemRegion == 0xFFU) {
+ xdbg_printf(DEBUG, "No regions available\r\n");
+ return XST_FAILURE;
+ }
+
+ Xil_DCacheFlush();
+ Xil_ICacheInvalidate();
+
+ mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,NextAvailableMemRegion);
+ isb();
+
+ /* Lookup the size. */
+ for (i = 0; i < (sizeof (region_size) / sizeof (region_size[0])); i++) {
+ if (size <= region_size[i].size) {
+ Regionsize = region_size[i].encoding;
+ break;
+ }
+ }
+
+ Localaddr &= (INTPTR)(~(region_size[i].size - 1U));
+
+ Regionsize <<= 1;
+ Regionsize |= REGION_EN;
+ dsb();
+ mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr); /* Set base address of a region */
+ mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib); /* Set the control attribute */
+ mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize); /* set the region size and enable it*/
+ dsb();
+ isb();
+ Xil_UpdateMPUConfig(NextAvailableMemRegion, Localaddr, Regionsize, attrib);
+ return XST_SUCCESS;
+}
+/*****************************************************************************/
+/**
+* @brief Enable MPU for Cortex R5 processor. This function invalidates I
+* cache and flush the D Caches, and then enables the MPU.
+*
+* @return None.
+*
+******************************************************************************/
+void Xil_EnableMPU(void)
+{
+ u32 CtrlReg, Reg;
+ s32 DCacheStatus=0, ICacheStatus=0;
+ /* enable caches only if they are disabled */
+#if defined (__GNUC__)
+ CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
+#endif
+ if ((CtrlReg & XREG_CP15_CONTROL_C_BIT) != 0x00000000U) {
+ DCacheStatus=1;
+ }
+ if ((CtrlReg & XREG_CP15_CONTROL_I_BIT) != 0x00000000U) {
+ ICacheStatus=1;
+ }
+
+ if(DCacheStatus != 0) {
+ Xil_DCacheDisable();
+ }
+ if(ICacheStatus != 0){
+ Xil_ICacheDisable();
+ }
+#if defined (__GNUC__)
+ Reg = mfcp(XREG_CP15_SYS_CONTROL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_SYS_CONTROL,Reg);
+#endif
+ Reg |= 0x00000001U;
+ dsb();
+ mtcp(XREG_CP15_SYS_CONTROL, Reg);
+ isb();
+ /* enable caches only if they are disabled in routine*/
+ if(DCacheStatus != 0) {
+ Xil_DCacheEnable();
+ }
+ if(ICacheStatus != 0) {
+ Xil_ICacheEnable();
+ }
+}
+
+/*****************************************************************************/
+/**
+* @brief Disable MPU for Cortex R5 processors. This function invalidates I
+* cache and flush the D Caches, and then disabes the MPU.
+*
+* @return None.
+*
+******************************************************************************/
+void Xil_DisableMPU(void)
+{
+ u32 CtrlReg, Reg;
+ s32 DCacheStatus=0, ICacheStatus=0;
+ /* enable caches only if they are disabled */
+
+#if defined (__GNUC__)
+ CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
+#endif
+ if ((CtrlReg & XREG_CP15_CONTROL_C_BIT) != 0x00000000U) {
+ DCacheStatus=1;
+ }
+ if ((CtrlReg & XREG_CP15_CONTROL_I_BIT) != 0x00000000U) {
+ ICacheStatus=1;
+ }
+
+ if(DCacheStatus != 0) {
+ Xil_DCacheDisable();
+ }
+ if(ICacheStatus != 0){
+ Xil_ICacheDisable();
+ }
+
+ mtcp(XREG_CP15_INVAL_BRANCH_ARRAY, 0);
+#if defined (__GNUC__)
+ Reg = mfcp(XREG_CP15_SYS_CONTROL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_SYS_CONTROL,Reg);
+#endif
+ Reg &= ~(0x00000001U);
+ dsb();
+ mtcp(XREG_CP15_SYS_CONTROL, Reg);
+ isb();
+ /* enable caches only if they are disabled in routine*/
+ if(DCacheStatus != 0) {
+ Xil_DCacheEnable();
+ }
+ if(ICacheStatus != 0) {
+ Xil_ICacheEnable();
+ }
+}
+
+/*****************************************************************************/
+/**
+* @brief Update the MPU configuration for the requested region number in
+* the global MPU configuration table.
+*
+* @param reg_num: The requested region number to be updated information for.
+* @param address: 32 bit address for start of the region.
+* @param size: Requested size of the region.
+* @param attrib: Attribute for the corresponding region.
+* @return XST_FAILURE: When the requested region number if 16 or more.
+* XST_SUCCESS: When the MPU configuration table is updated.
+*
+*
+******************************************************************************/
+u32 Xil_UpdateMPUConfig(u32 reg_num, INTPTR address, u32 size, u32 attrib)
+{
+ u32 ReturnVal = XST_SUCCESS;
+ u32 Tempsize = size;
+ u32 Index;
+
+ if (reg_num >= MAX_POSSIBLE_MPU_REGS) {
+ xdbg_printf(DEBUG, "Invalid region number\r\n");
+ ReturnVal = XST_FAILURE;
+ goto exit;
+ }
+
+ if ((size & REGION_EN) != 0) {
+ Mpu_Config[reg_num].RegionStatus = MPU_REG_ENABLED;
+ Mpu_Config[reg_num].BaseAddress = address;
+ Tempsize &= (~REGION_EN);
+ Tempsize >>= 1;
+ /* Lookup the size. */
+ for (Index = 0; Index <
+ (sizeof (region_size) / sizeof (region_size[0])); Index++) {
+ if (Tempsize <= region_size[Index].encoding) {
+ Mpu_Config[reg_num].Size = region_size[Index].size;
+ break;
+ }
+ }
+ Mpu_Config[reg_num].Attribute = attrib;
+ } else {
+ Mpu_Config[reg_num].RegionStatus = 0U;
+ Mpu_Config[reg_num].BaseAddress = 0;
+ Mpu_Config[reg_num].Size = 0U;
+ Mpu_Config[reg_num].Attribute = 0U;
+ }
+
+exit:
+ return ReturnVal;
+}
+
+/*****************************************************************************/
+/**
+* @brief The MPU configuration table is passed to the caller.
+*
+* @param mpuconfig: This is of type XMpu_Config which is an array of
+* 16 entries of type structure representing the MPU config table
+* @return none
+*
+*
+******************************************************************************/
+void Xil_GetMPUConfig (XMpu_Config mpuconfig) {
+ u32 Index = 0U;
+
+ while (Index < MAX_POSSIBLE_MPU_REGS) {
+ mpuconfig[Index].RegionStatus = Mpu_Config[Index].RegionStatus;
+ mpuconfig[Index].BaseAddress = Mpu_Config[Index].BaseAddress;
+ mpuconfig[Index].Attribute = Mpu_Config[Index].Attribute;
+ mpuconfig[Index].Size = Mpu_Config[Index].Size;
+ Index++;
+ }
+}
+
+/*****************************************************************************/
+/**
+* @brief Returns the total number of free MPU regions available.
+*
+* @return Number of free regions available to users
+*
+*
+******************************************************************************/
+u32 Xil_GetNumOfFreeRegions (void) {
+ u32 Index = 0U;
+ u32 NumofFreeRegs = 0U;
+
+ while (Index < MAX_POSSIBLE_MPU_REGS) {
+ if (MPU_REG_DISABLED == Mpu_Config[Index].RegionStatus) {
+ NumofFreeRegs++;
+ }
+ Index++;
+ }
+ return NumofFreeRegs;
+}
+
+/*****************************************************************************/
+/**
+* @brief Returns the total number of free MPU regions available in the form
+* of a mask. A bit of 1 in the returned 16 bit value represents the
+* corresponding region number to be available.
+* For example, if this function returns 0xC0000, this would mean, the
+* regions 14 and 15 are available to users.
+*
+* @return The free region mask as a 16 bit value
+*
+*
+******************************************************************************/
+u16 Xil_GetMPUFreeRegMask (void) {
+ u32 Index = 0U;
+ u16 FreeRegMask = 0U;
+
+ while (Index < MAX_POSSIBLE_MPU_REGS) {
+ if (MPU_REG_DISABLED == Mpu_Config[Index].RegionStatus) {
+ FreeRegMask |= ((u16)1U << Index);
+ }
+ Index++;
+ }
+ return FreeRegMask;
+}
+
+/*****************************************************************************/
+/**
+* @brief Disables the corresponding region number as passed by the user.
+*
+* @param reg_num: The region number to be disabled
+* @return XST_SUCCESS: If the region could be disabled successfully
+* XST_FAILURE: If the requested region number is 16 or more.
+*
+*
+******************************************************************************/
+u32 Xil_DisableMPURegionByRegNum (u32 reg_num) {
+ u32 Temp = 0U;
+ u32 ReturnVal = XST_FAILURE;
+
+ if (reg_num >= 16U) {
+ xdbg_printf(DEBUG, "Invalid region number\r\n");
+ goto exit1;
+ }
+ Xil_DCacheFlush();
+ Xil_ICacheInvalidate();
+
+ mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num);
+#if defined (__GNUC__)
+ Temp = mfcp(XREG_CP15_MPU_REG_SIZE_EN);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_MPU_REG_SIZE_EN,Temp);
+#endif
+ Temp &= (~REGION_EN);
+ dsb();
+ mtcp(XREG_CP15_MPU_REG_SIZE_EN,Temp);
+ dsb();
+ isb();
+ Xil_UpdateMPUConfig(reg_num, 0, 0U, 0U);
+ ReturnVal = XST_SUCCESS;
+
+exit1:
+ return ReturnVal;
+}
+
+/*****************************************************************************/
+/**
+* @brief Enables the corresponding region number as passed by the user.
+*
+* @param reg_num: The region number to be enabled
+* @param addr: 32 bit address for start of the region.
+* @param size: Requested size of the region.
+* @param attrib: Attribute for the corresponding region.
+* @return XST_SUCCESS: If the region could be created successfully
+* XST_FAILURE: If the requested region number is 16 or more.
+*
+*
+******************************************************************************/
+u32 Xil_SetMPURegionByRegNum (u32 reg_num, INTPTR addr, u64 size, u32 attrib)
+{
+ u32 ReturnVal = XST_SUCCESS;
+ INTPTR Localaddr = addr;
+ u32 Regionsize = 0;
+ u32 Index;
+
+ if (reg_num >= 16U) {
+ xdbg_printf(DEBUG, "Invalid region number\r\n");
+ ReturnVal = XST_FAILURE;
+ goto exit2;
+ }
+
+ if (Mpu_Config[reg_num].RegionStatus == MPU_REG_ENABLED) {
+ xdbg_printf(DEBUG, "Region already enabled\r\n");
+ ReturnVal = XST_FAILURE;
+ goto exit2;
+ }
+
+ Xil_DCacheFlush();
+ Xil_ICacheInvalidate();
+ mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num);
+ isb();
+
+ /* Lookup the size. */
+ for (Index = 0; Index <
+ (sizeof (region_size) / sizeof (region_size[0])); Index++) {
+ if (size <= region_size[Index].size) {
+ Regionsize = region_size[Index].encoding;
+ break;
+ }
+ }
+
+ Localaddr &= (INTPTR)(~(region_size[Index].size - 1U));
+ Regionsize <<= 1;
+ Regionsize |= REGION_EN;
+ dsb();
+ mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr);
+ mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib);
+ mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize);
+ dsb();
+ isb();
+ Xil_UpdateMPUConfig(reg_num, Localaddr, Regionsize, attrib);
+exit2:
+ return ReturnVal;
+
+}
+
+/*****************************************************************************/
+/**
+* @brief Initializes the MPU configuration table that are setup in the
+* R5 boot code in the Init_Mpu function called before C main.
+*
+* @return none
+*
+*
+******************************************************************************/
+void Xil_InitializeExistingMPURegConfig(void)
+{
+ u32 Index = 0U;
+ u32 Index1 = 0U;
+ u32 MPURegSize;
+ INTPTR MPURegBA;
+ u32 MPURegAttrib;
+ u32 Tempsize;
+
+ while (Index < MAX_POSSIBLE_MPU_REGS) {
+ mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,Index);
+#if defined (__GNUC__)
+ MPURegSize = mfcp(XREG_CP15_MPU_REG_SIZE_EN);
+ MPURegBA = mfcp(XREG_CP15_MPU_REG_BASEADDR);
+ MPURegAttrib = mfcp(XREG_CP15_MPU_REG_ACCESS_CTRL);
+#elif defined (__ICCARM__)
+ mfcp(XREG_CP15_MPU_REG_SIZE_EN,MPURegSize);
+ mfcp(XREG_CP15_MPU_REG_BASEADDR, MPURegBA);
+ mfcp(XREG_CP15_MPU_REG_ACCESS_CTRL, MPURegAttrib);
+#endif
+ if ((MPURegSize & REGION_EN) != 0) {
+ Mpu_Config[Index].RegionStatus = MPU_REG_ENABLED;
+ Mpu_Config[Index].BaseAddress = MPURegBA;
+ Mpu_Config[Index].Attribute = MPURegAttrib;
+ Tempsize = MPURegSize & (~REGION_EN);
+ Tempsize >>= 1;
+ for (Index1 = 0; Index1 <
+ (sizeof (region_size) / sizeof (region_size[0])); Index1++) {
+ if (Tempsize <= region_size[Index1].encoding) {
+ Mpu_Config[Index].Size = region_size[Index1].size;
+ break;
+ }
+ }
+ }
+ Index++;
+ }
+}
+
+/*****************************************************************************/
+/**
+* @brief Returns the next available free MPU region
+*
+* @return The free MPU region available
+*
+*
+******************************************************************************/
+u32 Xil_GetNextMPURegion(void)
+{
+ u32 Index = 0U;
+ u32 NextAvailableReg = 0xFF;
+ while (Index < MAX_POSSIBLE_MPU_REGS) {
+ if (Mpu_Config[Index].RegionStatus != MPU_REG_ENABLED) {
+ NextAvailableReg = Index;
+ break;
+ }
+ Index++;
+ }
+ return NextAvailableReg;
+}
+
+#ifdef __GNUC__
+#define u32overflow(a, b) ({typeof(a) s; __builtin_uadd_overflow(a, b, &s); })
+#else
+#define u32overflow(a, b) ((a) > ((a) + (b)))
+#endif /* __GNUC__ */
+
+/*****************************************************************************/
+/**
+* @brief Memory mapping for Cortex-R5F. If successful, the mapped
+* region will include all of the memory requested, but may
+* include more. Specifically, it will be a power of 2 in
+* size, aligned on a boundary of that size.
+*
+* @param Physaddr is base physical address at which to start mapping.
+* NULL in Physaddr masks possible mapping errors.
+* @param size of region to be mapped.
+* @param flags used to set translation table.
+*
+* @return Physaddr on success, NULL on error. Ambiguous if Physaddr==NULL
+*
+* @cond Xil_MemMap_internal
+* @note: u32overflow() is defined for readability and (for __GNUC__) to
+* - force the type of the check to be the same as the first argument
+* - hide the otherwise unused third argument of the builtin
+* - improve safety by choosing the explicit _uadd_ version.
+* Consider __builtin_add_overflow_p() when available.
+* Use an alternative (less optimal?) for compilers w/o the builtin.
+* @endcond
+******************************************************************************/
+void *Xil_MemMap(UINTPTR Physaddr, size_t size, u32 flags)
+{
+ size_t Regionsize = MPU_REGION_SIZE_MIN;
+ UINTPTR Basephysaddr = 0, end = Physaddr + size;
+
+ if (flags == 0U) {
+ return (void *)Physaddr;
+ }
+ if (u32overflow(Physaddr, size)) {
+ return NULL;
+ }
+ for ( ; Regionsize != 0U; Regionsize <<= 1) {
+ if (Regionsize >= size) {
+ Basephysaddr = Physaddr & ~(Regionsize - 1U);
+ if (u32overflow(Basephysaddr, Regionsize)) {
+ break;
+ }
+ if ((Basephysaddr + Regionsize) >= end) {
+ return ((Xil_SetMPURegion(Basephysaddr,
+ Regionsize, flags) == XST_SUCCESS) ?
+ (void *)Physaddr : NULL);
+ }
+ }
+ }
+ return NULL;
+}
diff --git a/bsps/shared/xil/xil_assert.c b/bsps/shared/xil/xil_assert.c
new file mode 100644
index 0000000000..b3dd7e9718
--- /dev/null
+++ b/bsps/shared/xil/xil_assert.c
@@ -0,0 +1,126 @@
+/******************************************************************************
+* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xil_assert.c
+* @addtogroup common_assert_apis Assert APIs and Macros
+* @{
+*
+* This file contains basic assert related functions for Xilinx software IP.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm 07/14/09 Initial release
+* 6.0 kvn 05/31/16 Make Xil_AsserWait a global variable
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xil_types.h"
+#include "xil_assert.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/**
+ * @brief This variable allows testing to be done easier with asserts. An assert
+ * sets this variable such that a driver can evaluate this variable
+ * to determine if an assert occurred.
+ */
+u32 Xil_AssertStatus;
+
+/**
+ * @brief This variable allows the assert functionality to be changed for testing
+ * such that it does not wait infinitely. Use the debugger to disable the
+ * waiting during testing of asserts.
+ */
+s32 Xil_AssertWait = 1;
+
+/* The callback function to be invoked when an assert is taken */
+static Xil_AssertCallback Xil_AssertCallbackRoutine = NULL;
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* @brief Implement assert. Currently, it calls a user-defined callback
+* function if one has been set. Then, it potentially enters an
+* infinite loop depending on the value of the Xil_AssertWait
+* variable.
+*
+* @param File: filename of the source
+* @param Line: linenumber within File
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void Xil_Assert(const char8 *File, s32 Line)
+{
+ /* if the callback has been set then invoke it */
+ if (Xil_AssertCallbackRoutine != 0) {
+ (*Xil_AssertCallbackRoutine)(File, Line);
+ }
+
+ /* if specified, wait indefinitely such that the assert will show up
+ * in testing
+ */
+ while (Xil_AssertWait != 0) {
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* @brief Set up a callback function to be invoked when an assert occurs.
+* If a callback is already installed, then it will be replaced.
+*
+* @param Routine: callback to be invoked when an assert is taken
+*
+* @return None.
+*
+* @note This function has no effect if NDEBUG is set
+*
+******************************************************************************/
+void Xil_AssertSetCallback(Xil_AssertCallback Routine)
+{
+ Xil_AssertCallbackRoutine = Routine;
+}
+
+/*****************************************************************************/
+/**
+*
+* @brief Null handler function. This follows the XInterruptHandler
+* signature for interrupt handlers. It can be used to assign a null
+* handler (a stub) to an interrupt controller vector table.
+*
+* @param NullParameter: arbitrary void pointer and not used.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XNullHandler(void *NullParameter)
+{
+ (void) NullParameter;
+}
+/**
+* @} End of "addtogroup common_assert_apis".
+*/
diff --git a/bsps/shared/xil/xil_mem.c b/bsps/shared/xil/xil_mem.c
new file mode 100644
index 0000000000..44e7d9a0c4
--- /dev/null
+++ b/bsps/shared/xil/xil_mem.c
@@ -0,0 +1,70 @@
+/******************************************************************************/
+/**
+* Copyright (c) 2015 - 2022 Xilinx, Inc. All rights reserved.
+* SPDX-License-Identifier: MIT
+******************************************************************************/
+
+/****************************************************************************/
+/**
+* @file xil_mem.c
+*
+* This file contains xil mem copy function to use in case of word aligned
+* data copies.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.1 nsk 11/07/16 First release.
+* 7.7 sk 01/10/22 Update Xil_MemCpy functions variables typecast
+* from int to s32 to fix misra_c_2012_directive_4_6
+* violations.
+* 7.7 sk 01/10/22 Include xil_mem.h header file to fix Xil_MemCpy
+* prototype misra_c_2012_rule_8_4 violation.
+*
+* </pre>
+*
+*****************************************************************************/
+
+/***************************** Include Files ********************************/
+
+#include "xil_types.h"
+#include "xil_mem.h"
+
+/***************** Inline Functions Definitions ********************/
+/*****************************************************************************/
+/**
+* @brief This function copies memory from once location to other.
+*
+* @param dst: pointer pointing to destination memory
+*
+* @param src: pointer pointing to source memory
+*
+* @param cnt: 32 bit length of bytes to be copied
+*
+*****************************************************************************/
+void Xil_MemCpy(void* dst, const void* src, u32 cnt)
+{
+ char *d = (char*)(void *)dst;
+ const char *s = src;
+
+ while (cnt >= sizeof (s32)) {
+ *(s32*)d = *(s32*)s;
+ d += sizeof (s32);
+ s += sizeof (s32);
+ cnt -= sizeof (s32);
+ }
+ while (cnt >= sizeof (u16)) {
+ *(u16*)d = *(u16*)s;
+ d += sizeof (u16);
+ s += sizeof (u16);
+ cnt -= sizeof (u16);
+ }
+ while ((cnt) > 0U){
+ *d = *s;
+ d += 1U;
+ s += 1U;
+ cnt -= 1U;
+ }
+}