]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
b43e50ec20f4bc5f410b39d1653cc6d0767b3982
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / Zynq / uncached_memory.c
1 /*\r
2  * uncached_memory.c\r
3  *\r
4  * This module will declare 1 MB of memory and switch off the caching for it.\r
5  *\r
6  * pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length\r
7  * rounded up to a multiple of 4 KB\r
8  *\r
9  * ucIsCachedMemory( pucBuffer ) returns non-zero if a given pointer is NOT\r
10  * within the range of the 1 MB non-cached memory.\r
11  *\r
12  */\r
13 \r
14 /*\r
15  * After "_end", 1 MB of uncached memory will be allocated for DMA transfers.\r
16  * Both the DMA descriptors as well as all EMAC TX-buffers will be allocated in\r
17  * uncached memory.\r
18  */\r
19 \r
20 /* Standard includes. */\r
21 #include <stdint.h>\r
22 #include <stdio.h>\r
23 #include <stdlib.h>\r
24 \r
25 /* FreeRTOS includes. */\r
26 #include "FreeRTOS.h"\r
27 #include "task.h"\r
28 #include "queue.h"\r
29 \r
30 /* FreeRTOS+TCP includes. */\r
31 #include "FreeRTOS_IP.h"\r
32 #include "FreeRTOS_Sockets.h"\r
33 #include "FreeRTOS_IP_Private.h"\r
34 \r
35 #include "Zynq/x_emacpsif.h"\r
36 #include "Zynq/x_topology.h"\r
37 #include "xstatus.h"\r
38 \r
39 #include "xparameters.h"\r
40 #include "xparameters_ps.h"\r
41 #include "xil_exception.h"\r
42 #include "xil_mmu.h"\r
43 \r
44 #include "uncached_memory.h"\r
45 \r
46 #define UNCACHED_MEMORY_SIZE    0x100000ul\r
47 \r
48 #define DDR_MEMORY_END  (XPAR_PS7_DDR_0_S_AXI_HIGHADDR+1)\r
49 \r
50 static void vInitialiseUncachedMemory( void );\r
51 \r
52 static uint8_t *pucHeadOfMemory;\r
53 static uint32_t ulMemorySize;\r
54 static uint8_t *pucStartOfMemory = NULL;\r
55 \r
56 uint8_t ucIsCachedMemory( const uint8_t *pucBuffer )\r
57 {\r
58 uint8_t ucReturn;\r
59 \r
60         if( ( pucStartOfMemory != NULL ) &&\r
61                 ( pucBuffer >= pucStartOfMemory ) &&\r
62                 ( pucBuffer < ( pucStartOfMemory + UNCACHED_MEMORY_SIZE ) ) )\r
63         {\r
64                 ucReturn = pdFALSE;\r
65         }\r
66         else\r
67         {\r
68                 ucReturn = pdTRUE;\r
69         }\r
70 \r
71         return ucReturn;\r
72 }\r
73 \r
74 uint8_t *pucGetUncachedMemory( uint32_t ulSize )\r
75 {\r
76 uint8_t *pucReturn;\r
77 \r
78         if( pucStartOfMemory == NULL )\r
79         {\r
80                 vInitialiseUncachedMemory( );\r
81         }\r
82         if( ( pucStartOfMemory == NULL ) || ( ulSize > ulMemorySize ) )\r
83         {\r
84                 pucReturn = NULL;\r
85         }\r
86         else\r
87         {\r
88         uint32_t ulSkipSize;\r
89 \r
90                 pucReturn = pucHeadOfMemory;\r
91                 ulSkipSize = ( ulSize + 0x1000ul ) & ~0xffful;\r
92                 pucHeadOfMemory += ulSkipSize;\r
93                 ulMemorySize -= ulSkipSize;\r
94         }\r
95 \r
96         return pucReturn;\r
97 }\r
98 \r
99 extern u8 _end;\r
100 \r
101 static void vInitialiseUncachedMemory( )\r
102 {\r
103         /* At the end of program's space... */\r
104         pucStartOfMemory = (uint8_t *) &_end;\r
105         /*\r
106          * Align the start address to 1 MB boundary.\r
107          */\r
108         pucStartOfMemory = (uint8_t *)( ( ( uint32_t )pucStartOfMemory + UNCACHED_MEMORY_SIZE ) & ( ~( UNCACHED_MEMORY_SIZE - 1 ) ) );\r
109 \r
110         if( ( ( u32 )pucStartOfMemory ) + UNCACHED_MEMORY_SIZE > DDR_MEMORY_END )\r
111         {\r
112 //              vLoggingPrintf("vInitialiseUncachedMemory: Can not allocate uncached memory\n" );\r
113         }\r
114         else\r
115         {\r
116                 /*\r
117                  * Some objects want to be stored in uncached memory. Hence the 1 MB\r
118                  * address range that starts after "_end" is made uncached\r
119                  * by setting appropriate attributes in the translation table.\r
120                  */\r
121                 /* FIXME claudio rossi. Modified to prevent data abort exception (misaligned access)\r
122                  * when application is compiled with -O1 or more optimization flag.\r
123                  */\r
124 /*              Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0xc02 ); // addr, attr */\r
125                 Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0x1c02 ); // addr, attr\r
126 \r
127                 /* For experiments in the SDIO driver, make the remaining uncached memory public */\r
128                 pucHeadOfMemory = pucStartOfMemory;\r
129                 ulMemorySize = UNCACHED_MEMORY_SIZE;\r
130                 memset( pucStartOfMemory, '\0', UNCACHED_MEMORY_SIZE );\r
131         }\r
132 }\r