[PATCH rtems 2/3] bsps/atsam: Add NULL pointer protection

2022-12-09 Thread Christian Mauderer
---
 bsps/arm/atsam/README   |  6 +-
 .../libraries/libboard/source/board_lowlevel.c  | 17 +
 bsps/arm/atsam/include/bsp.h|  4 
 bsps/arm/atsam/include/libchip/include/mpu.h|  1 +
 bsps/arm/atsam/start/bspstarthooks.c|  2 +-
 spec/build/bsps/arm/atsam/bspatsam.yml  |  2 ++
 spec/build/bsps/arm/atsam/linkcmds.yml  |  7 ++-
 spec/build/bsps/arm/atsam/optnullsz.yml | 17 +
 spec/build/bsps/arm/atsam/opttcmsz.yml  |  3 ++-
 9 files changed, 55 insertions(+), 4 deletions(-)
 create mode 100644 spec/build/bsps/arm/atsam/optnullsz.yml

diff --git a/bsps/arm/atsam/README b/bsps/arm/atsam/README
index 2ebaa726c8..47aa11d2c0 100644
--- a/bsps/arm/atsam/README
+++ b/bsps/arm/atsam/README
@@ -59,9 +59,13 @@ Use ATSAM_CONSOLE_DEVICE_INDEX=XYZ to set the device index 
for /dev/console
 Use ATSAM_CONSOLE_USE_INTERRUPTS=XYZ to set the use interrupt driven mode for
 console devices (used by default).
 
-Use ATSAM_MEMORY_TCM_SIZE=XYZ to set the size of tightly coupled memories (TCM)
+Use ATSAM_MEMORY_NULL_SIZE=XYZ to set the size of NULL pointer protection area
 in bytes (default 0x).
 
+Use ATSAM_MEMORY_TCM_SIZE=XYZ to set the size of tightly coupled memories (TCM)
+in bytes (default 0x). Note: ITCM is reduced by the
+ATSAM_MEMORY_NULL_SIZE.
+
 Use ATSAM_MEMORY_INTFLASH_SIZE=XYZ to set the size of internal flash in bytes
 (default is derived from chip variant).
 
diff --git a/bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c 
b/bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c
index cbdf41ba73..a2dd595fb5 100644
--- a/bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c
+++ b/bsps/arm/atsam/contrib/libraries/libboard/source/board_lowlevel.c
@@ -347,6 +347,23 @@ void _SetupMemoryRegion(void)
SCB->SHCSR |= (SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk
   | SCB_SHCSR_USGFAULTENA_Msk);
 
+#ifdef __rtems__
+   dwRegionBaseAddr =
+   ((uintptr_t)atsam_memory_null_begin) |
+   MPU_REGION_VALID |
+   MPU_NULL_REGION;
+   if (atsam_memory_null_begin != atsam_memory_itcm_end) {
+   dwRegionAttr =
+   MPU_AP_NO_ACCESS |
+   MPU_REGION_EXECUTE_NEVER |
+   MPU_CalMPURegionSize((uintptr_t)atsam_memory_null_size) 
|
+   MPU_REGION_ENABLE;
+   } else {
+   dwRegionAttr = MPU_REGION_DISABLE;
+   }
+   MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
+#endif /* __rtems__ */
+
/* Enable the MPU region */
 #ifndef __rtems__
MPU_Enable(MPU_ENABLE | MPU_PRIVDEFENA);
diff --git a/bsps/arm/atsam/include/bsp.h b/bsps/arm/atsam/include/bsp.h
index 8fe98be364..0bca3d2c22 100644
--- a/bsps/arm/atsam/include/bsp.h
+++ b/bsps/arm/atsam/include/bsp.h
@@ -89,6 +89,10 @@ typedef struct {
   uint8_t phy_addr;
 } if_atsam_config;
 
+extern char atsam_memory_null_begin[];
+extern char atsam_memory_null_end[];
+extern char atsam_memory_null_size[];
+
 extern char atsam_memory_dtcm_begin[];
 extern char atsam_memory_dtcm_end[];
 extern char atsam_memory_dtcm_size[];
diff --git a/bsps/arm/atsam/include/libchip/include/mpu.h 
b/bsps/arm/atsam/include/libchip/include/mpu.h
index a5d00a681b..034ba58474 100644
--- a/bsps/arm/atsam/include/libchip/include/mpu.h
+++ b/bsps/arm/atsam/include/libchip/include/mpu.h
@@ -56,6 +56,7 @@
 #endif
 #define MPU_SYSTEM_REGION   (12)
 #ifdef __rtems__
+#define MPU_NULL_REGION (13)
 /* Reserve the region with highest priority for user applications */
 #define MPU_USER_DEFINED_REGION (15)
 #endif /* __rtems__ */
diff --git a/bsps/arm/atsam/start/bspstarthooks.c 
b/bsps/arm/atsam/start/bspstarthooks.c
index 516b86228d..2be2fc050b 100644
--- a/bsps/arm/atsam/start/bspstarthooks.c
+++ b/bsps/arm/atsam/start/bspstarthooks.c
@@ -106,7 +106,7 @@ static void configure_tcm(void)
   uintptr_t tcm_size;
   uint32_t itcmcr_sz;
 
-  tcm_size = (uintptr_t) atsam_memory_itcm_size;
+  tcm_size = (uintptr_t) atsam_memory_dtcm_size;
   itcmcr_sz = (SCB->ITCMCR & SCB_ITCMCR_SZ_Msk) >> SCB_ITCMCR_SZ_Pos;
 
   if (tcm_setup_and_check_if_do_efc_config(tcm_size, itcmcr_sz)) {
diff --git a/spec/build/bsps/arm/atsam/bspatsam.yml 
b/spec/build/bsps/arm/atsam/bspatsam.yml
index 6716bea248..679889d253 100644
--- a/spec/build/bsps/arm/atsam/bspatsam.yml
+++ b/spec/build/bsps/arm/atsam/bspatsam.yml
@@ -296,6 +296,8 @@ links:
   uid: optmck
 - role: build-dependency
   uid: optnocachesz
+- role: build-dependency
+  uid: optnullsz
 - role: build-dependency
   uid: optoscmain
 - role: build-dependency
diff --git a/spec/build/bsps/arm/atsam/linkcmds.yml 
b/spec/build/bsps/arm/atsam/linkcmds.yml
index fe6211f82f..d475b6a245 100644
--- a/spec/build/bsps/arm/atsam/linkcmds.yml
+++ 

[PATCH rtems 1/3] bsps/atsam: Fix unidirectional SPI transfers

2022-12-09 Thread Christian Mauderer
A SPI transfer where the Rx or Tx buffer is set to NULL currently
transfers or overwrites data starting from address 0x via DMA.

This patch changes the DMA setup so that dummy transfers are done.
Just reading / writing to a single location is simpler than changing the
whole logic of the transfer depending on the passed buffers.
---
 bsps/arm/atsam/spi/atsam_spi_bus.c | 188 -
 1 file changed, 131 insertions(+), 57 deletions(-)

diff --git a/bsps/arm/atsam/spi/atsam_spi_bus.c 
b/bsps/arm/atsam/spi/atsam_spi_bus.c
index 53c1fe4827..dcf1397043 100644
--- a/bsps/arm/atsam/spi/atsam_spi_bus.c
+++ b/bsps/arm/atsam/spi/atsam_spi_bus.c
@@ -41,8 +41,8 @@
 #define MAX_SPI_FREQUENCY 5000
 
 typedef struct {
-  volatile LinkedListDescriporView0 tx_desc;
-  volatile LinkedListDescriporView0 rx_desc[3];
+  volatile LinkedListDescriporView2 tx_desc;
+  volatile LinkedListDescriporView2 rx_desc[3];
   uint8_t rx_bounce_head_buf[CPU_CACHE_LINE_BYTES];
   uint8_t rx_bounce_tail_buf[CPU_CACHE_LINE_BYTES];
 } atsam_spi_dma;
@@ -67,6 +67,8 @@ typedef struct {
   uint32_t spi_csr[4];
 } atsam_spi_bus;
 
+static const uint32_t atsam_spi_dummy_write_data = 0x;
+
 static void atsam_spi_wakeup_task(atsam_spi_bus *bus)
 {
   rtems_binary_semaphore_post(>sem);
@@ -181,14 +183,14 @@ static void atsam_spi_copy_rx_bounce_bufs(
   }
 }
 
-static void atsam_spi_setup_rx_dma_desc(
+static void atsam_spi_setup_real_rx_dma_desc(
   atsam_spi_bus *bus,
   atsam_spi_dma *dma,
   const uint8_t *buf,
   size_t n
 )
 {
-  volatile LinkedListDescriporView0 *desc;
+  volatile LinkedListDescriporView2 *desc;
   uintptr_t m;
   uintptr_t b;
   uintptr_t a;
@@ -202,53 +204,56 @@ static void atsam_spi_setup_rx_dma_desc(
   a = (b + m) & ~m;
   ae = e & ~m;
 
+  /* An earlier dummy read maybe has set the DAM to FIXED_AM. Reset it. */
+  desc[0].mbr_cfg =
+  (desc[0].mbr_cfg & ~XDMAC_CC_DAM_Msk) | XDMAC_CC_DAM_INCREMENTED_AM;
   if (n <= m) {
 bus->rx_bounce_head_len = n;
 bus->rx_bounce_tail_len = 0;
 
-desc[0].mbr_ta = (uint32_t) dma->rx_bounce_head_buf;
-desc[0].mbr_ubc = n;
+desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf;
+desc[0].mbr_ubc = n | XDMA_UBC_NVIEW_NDV2;
   } else {
 bus->rx_bounce_head_len = a - b;
 bus->rx_bounce_tail_len = e & m;
 
 if ((b & m) == 0) {
   if ((n & m) == 0) {
-desc[0].mbr_ta = a;
-desc[0].mbr_ubc = n;
+desc[0].mbr_da = a;
+desc[0].mbr_ubc = n | XDMA_UBC_NVIEW_NDV2;
   } else {
-desc[0].mbr_ta = a;
+desc[0].mbr_da = a;
 desc[0].mbr_ubc = (ae - a) | XDMA_UBC_NDEN_UPDATED
-  | XDMA_UBC_NVIEW_NDV0
+  | XDMA_UBC_NVIEW_NDV2
   | XDMA_UBC_NDE_FETCH_EN;
-desc[1].mbr_ta = (uint32_t) dma->rx_bounce_tail_buf;
-desc[1].mbr_ubc = n & m;
+desc[1].mbr_da = (uint32_t) dma->rx_bounce_tail_buf;
+desc[1].mbr_ubc = n & m | XDMA_UBC_NVIEW_NDV2;
   }
 } else {
   if ((e & m) == 0) {
-desc[0].mbr_ta = (uint32_t) dma->rx_bounce_head_buf;
+desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf;
 desc[0].mbr_ubc = (a - b) | XDMA_UBC_NDEN_UPDATED
-  | XDMA_UBC_NVIEW_NDV0
+  | XDMA_UBC_NVIEW_NDV2
   | XDMA_UBC_NDE_FETCH_EN;
-desc[1].mbr_ta = a;
-desc[1].mbr_ubc = ae - a;
+desc[1].mbr_da = a;
+desc[1].mbr_ubc = ae - a | XDMA_UBC_NVIEW_NDV2;
   } else if ((ae - a) == 0) {
 bus->rx_bounce_head_len = n;
 bus->rx_bounce_tail_len = 0;
 
-desc[0].mbr_ta = (uint32_t) dma->rx_bounce_head_buf;
-desc[0].mbr_ubc = n;
+desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf;
+desc[0].mbr_ubc = n | XDMA_UBC_NVIEW_NDV2;
   } else {
-desc[0].mbr_ta = (uint32_t) dma->rx_bounce_head_buf;
+desc[0].mbr_da = (uint32_t) dma->rx_bounce_head_buf;
 desc[0].mbr_ubc = (a - b) | XDMA_UBC_NDEN_UPDATED
-  | XDMA_UBC_NVIEW_NDV0
+  | XDMA_UBC_NVIEW_NDV2
   | XDMA_UBC_NDE_FETCH_EN;
-desc[1].mbr_ta = a;
+desc[1].mbr_da = a;
 desc[1].mbr_ubc = (ae - a) | XDMA_UBC_NDEN_UPDATED
-  | XDMA_UBC_NVIEW_NDV0
+  | XDMA_UBC_NVIEW_NDV2
   | XDMA_UBC_NDE_FETCH_EN;
-desc[2].mbr_ta = (uint32_t) dma->rx_bounce_tail_buf;
-desc[2].mbr_ubc = e - ae;
+desc[2].mbr_da = (uint32_t) dma->rx_bounce_tail_buf;
+desc[2].mbr_ubc = e - ae | XDMA_UBC_NVIEW_NDV2;
   }
 }
 
@@ -256,19 +261,61 @@ static void atsam_spi_setup_rx_dma_desc(
   }
 }
 
+static void atsam_spi_setup_dummy_rx_dma_desc(
+  atsam_spi_bus *bus,
+  atsam_spi_dma *dma,
+  size_t n
+)
+{
+  volatile LinkedListDescriporView2 *desc;
+
+  desc = >rx_desc[0];
+
+  /* Avoid copying bounce buffers after receive. */
+  bus->rx_bounce_head_len = 0;
+  bus->rx_bounce_tail_len = 0;
+
+  /* But use one of the bounce buffers to write dummy data to. */
+  desc[0].mbr_da = 

[PATCH rtems 3/3] bsp/atsam: Allow to use custom SDRAM

2022-12-09 Thread Christian Mauderer
With the old build system in RTEMS 5 that was possible by just
overwriting BOARD_Sdram_Config and setting a custom
ATSAM_MEMORY_SDRAM_SIZE during building the BSP. In the new build system
that ATSAM_MEMORY_SDRAM_SIZE is set exclusively by the selected SDRAM
chip.

This patch adds the possibility to specify a "custom-0x10" or
similar as SDRAM type where the number gives the SDRAM size.
---
 bsps/arm/atsam/start/sdram-config.c|  7 +++
 spec/build/bsps/arm/atsam/optsdram.yml | 21 -
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/bsps/arm/atsam/start/sdram-config.c 
b/bsps/arm/atsam/start/sdram-config.c
index 87e52ebed0..85b009a9d5 100644
--- a/bsps/arm/atsam/start/sdram-config.c
+++ b/bsps/arm/atsam/start/sdram-config.c
@@ -148,6 +148,13 @@ const struct BOARD_Sdram_Config BOARD_Sdram_Config = {
 #error Please check SDRAM settings for this frequency.
 #endif
 
+#elif defined ATSAM_SDRAM_CUSTOM
+/*
+ * Custom SDRAM defined. Provide only a dummy BOARD_Sdram_Config. This config
+ * won't work and is only there so that test applications can link. The
+ * application has to overwrite this BOARD_Sdram_Config!
+ */
+const struct BOARD_Sdram_Config BOARD_Sdram_Config = {};
 #else
   #error SDRAM not supported.
 #endif
diff --git a/spec/build/bsps/arm/atsam/optsdram.yml 
b/spec/build/bsps/arm/atsam/optsdram.yml
index c07edd9ba5..0c3808ab2b 100644
--- a/spec/build/bsps/arm/atsam/optsdram.yml
+++ b/spec/build/bsps/arm/atsam/optsdram.yml
@@ -9,10 +9,18 @@ actions:
  "mt48lc16m16a2p-6a": ("ATSAM_SDRAM_MT48LC16M16A2P_6A", 0x0200),
 }
 if value:
-try:
-s = sdram[value]
-except:
-conf.fatal("Unkown SDRAM variant '{}'".format(value))
+if value.startswith("custom-"):
+name = "ATSAM_SDRAM_CUSTOM"
+try:
+size = int(value[len("custom-"):], base=0)
+s = (name, size)
+except Exception as e:
+conf.fatal("Invalid SDRAM size '{}': {}".format(value, e))
+else:
+try:
+s = sdram[value]
+except:
+conf.fatal("Unkown SDRAM variant '{}'".format(value))
 conf.define_cond(s[0], True)
 conf.env["ATSAM_MEMORY_SDRAM_SIZE"] = s[1]
 build-type: option
@@ -21,7 +29,10 @@ copyrights:
 default: is42s16100e-7bli
 default-by-variant: []
 description: |
-  SDRAM variant
+  SDRAM variant. Known chips are "is42s16100e-7bli", "is42s16320f-7bl",
+  "mt48lc16m16a2p-6a". You can also set this to "custom-" (for 
example
+  "custom-0x100" for a 16MiB RAM). In that case the BOARD_Sdram_Config has
+  to be overwritten by the application to get working applications.
 enabled-by: true
 format: '{}'
 links: []
-- 
2.35.3

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


[PATCH rtems 0/3] bsps/atsam: Various small improvements

2022-12-09 Thread Christian Mauderer
Hello,

this patch set adds a number of improvements to the ATSAM BSP. The
patches accumulated over the last few month on a branch.

The first one fixes a problem with unidirectional SPI transfers. The
current driver would overwrite or send data at / from 0x00.

The second one adds a small protection for the NULL pointer.

The last one adds the ability to use a custom SDRAM configuration and
size. That was possible on RTEMS 5 by overwriting some of the configure
variables during build and the RAM configuration structure in the
application. With the new build system, the variables now depend purely
on the RAM chip and can't be overwritten any more. This adds a
possibility for a custom RAM size again.

Best regards

Christian


___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel