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