summaryrefslogtreecommitdiff
path: root/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c')
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
new file mode 100644
index 000000000..b43e50ec2
--- /dev/null
+++ b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
@@ -0,0 +1,132 @@
+/*
+ * uncached_memory.c
+ *
+ * This module will declare 1 MB of memory and switch off the caching for it.
+ *
+ * pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length
+ * rounded up to a multiple of 4 KB
+ *
+ * ucIsCachedMemory( pucBuffer ) returns non-zero if a given pointer is NOT
+ * within the range of the 1 MB non-cached memory.
+ *
+ */
+
+/*
+ * After "_end", 1 MB of uncached memory will be allocated for DMA transfers.
+ * Both the DMA descriptors as well as all EMAC TX-buffers will be allocated in
+ * uncached memory.
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+
+#include "Zynq/x_emacpsif.h"
+#include "Zynq/x_topology.h"
+#include "xstatus.h"
+
+#include "xparameters.h"
+#include "xparameters_ps.h"
+#include "xil_exception.h"
+#include "xil_mmu.h"
+
+#include "uncached_memory.h"
+
+#define UNCACHED_MEMORY_SIZE 0x100000ul
+
+#define DDR_MEMORY_END (XPAR_PS7_DDR_0_S_AXI_HIGHADDR+1)
+
+static void vInitialiseUncachedMemory( void );
+
+static uint8_t *pucHeadOfMemory;
+static uint32_t ulMemorySize;
+static uint8_t *pucStartOfMemory = NULL;
+
+uint8_t ucIsCachedMemory( const uint8_t *pucBuffer )
+{
+uint8_t ucReturn;
+
+ if( ( pucStartOfMemory != NULL ) &&
+ ( pucBuffer >= pucStartOfMemory ) &&
+ ( pucBuffer < ( pucStartOfMemory + UNCACHED_MEMORY_SIZE ) ) )
+ {
+ ucReturn = pdFALSE;
+ }
+ else
+ {
+ ucReturn = pdTRUE;
+ }
+
+ return ucReturn;
+}
+
+uint8_t *pucGetUncachedMemory( uint32_t ulSize )
+{
+uint8_t *pucReturn;
+
+ if( pucStartOfMemory == NULL )
+ {
+ vInitialiseUncachedMemory( );
+ }
+ if( ( pucStartOfMemory == NULL ) || ( ulSize > ulMemorySize ) )
+ {
+ pucReturn = NULL;
+ }
+ else
+ {
+ uint32_t ulSkipSize;
+
+ pucReturn = pucHeadOfMemory;
+ ulSkipSize = ( ulSize + 0x1000ul ) & ~0xffful;
+ pucHeadOfMemory += ulSkipSize;
+ ulMemorySize -= ulSkipSize;
+ }
+
+ return pucReturn;
+}
+
+extern u8 _end;
+
+static void vInitialiseUncachedMemory( )
+{
+ /* At the end of program's space... */
+ pucStartOfMemory = (uint8_t *) &_end;
+ /*
+ * Align the start address to 1 MB boundary.
+ */
+ pucStartOfMemory = (uint8_t *)( ( ( uint32_t )pucStartOfMemory + UNCACHED_MEMORY_SIZE ) & ( ~( UNCACHED_MEMORY_SIZE - 1 ) ) );
+
+ if( ( ( u32 )pucStartOfMemory ) + UNCACHED_MEMORY_SIZE > DDR_MEMORY_END )
+ {
+// vLoggingPrintf("vInitialiseUncachedMemory: Can not allocate uncached memory\n" );
+ }
+ else
+ {
+ /*
+ * Some objects want to be stored in uncached memory. Hence the 1 MB
+ * address range that starts after "_end" is made uncached
+ * by setting appropriate attributes in the translation table.
+ */
+ /* FIXME claudio rossi. Modified to prevent data abort exception (misaligned access)
+ * when application is compiled with -O1 or more optimization flag.
+ */
+/* Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0xc02 ); // addr, attr */
+ Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0x1c02 ); // addr, attr
+
+ /* For experiments in the SDIO driver, make the remaining uncached memory public */
+ pucHeadOfMemory = pucStartOfMemory;
+ ulMemorySize = UNCACHED_MEMORY_SIZE;
+ memset( pucStartOfMemory, '\0', UNCACHED_MEMORY_SIZE );
+ }
+}