]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / Zynq / uncached_memory.c
1 /*\r
2  * FreeRTOS V202002.00\r
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://aws.amazon.com/freertos\r
23  * http://www.FreeRTOS.org\r
24  */\r
25 \r
26 /*\r
27  * uncached_memory.c\r
28  *\r
29  * This module will declare 1 MB of memory and switch off the caching for it.\r
30  *\r
31  * pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length\r
32  * rounded up to a multiple of 4 KB.\r
33  *\r
34  * ucIsCachedMemory( pucBuffer ) returns non-zero if a given pointer is NOT\r
35  * within the range of the 1 MB non-cached memory.\r
36  *\r
37  */\r
38 \r
39 /*\r
40  * After "_end", 1 MB of uncached memory will be allocated for DMA transfers.\r
41  * Both the DMA descriptors as well as all EMAC TX-buffers will be allocated in\r
42  * uncached memory.\r
43  */\r
44 \r
45 /* Standard includes. */\r
46 #include <stdint.h>\r
47 #include <stdio.h>\r
48 #include <stdlib.h>\r
49 \r
50 /* FreeRTOS includes. */\r
51 #include "FreeRTOS.h"\r
52 #include "task.h"\r
53 #include "queue.h"\r
54 \r
55 /* FreeRTOS+TCP includes. */\r
56 #include "FreeRTOS_IP.h"\r
57 #include "FreeRTOS_Sockets.h"\r
58 #include "FreeRTOS_IP_Private.h"\r
59 \r
60 #include "Zynq/x_emacpsif.h"\r
61 #include "Zynq/x_topology.h"\r
62 #include "xstatus.h"\r
63 \r
64 #include "xparameters.h"\r
65 #include "xparameters_ps.h"\r
66 #include "xil_exception.h"\r
67 #include "xil_mmu.h"\r
68 \r
69 #include "uncached_memory.h"\r
70 \r
71 /* Reserve 1 MB of memory. */\r
72 #define uncMEMORY_SIZE                          0x100000uL\r
73 \r
74 /* Make sure that each pointer has an alignment of 4 KB. */\r
75 #define uncALIGNMENT_SIZE                       0x1000uL\r
76 \r
77 #define DDR_MEMORY_END  (XPAR_PS7_DDR_0_S_AXI_HIGHADDR+1)\r
78 \r
79 #define uncMEMORY_ATTRIBUTE                     0x1C02\r
80 \r
81 static void vInitialiseUncachedMemory( void );\r
82 \r
83 static uint8_t *pucHeadOfMemory;\r
84 static uint32_t ulMemorySize;\r
85 static uint8_t *pucStartOfMemory = NULL;\r
86 \r
87 /* The linker file defines some pseudo variables. '_end' is one of them.\r
88 It is located at the first free byte in RAM. */\r
89 extern u8 _end;\r
90 \r
91 /*-----------------------------------------------------------*/\r
92 \r
93 uint8_t ucIsCachedMemory( const uint8_t *pucBuffer )\r
94 {\r
95 uint8_t ucReturn;\r
96 \r
97         if( ( pucStartOfMemory != NULL ) &&\r
98                 ( pucBuffer >= pucStartOfMemory ) &&\r
99                 ( pucBuffer < ( pucStartOfMemory + uncMEMORY_SIZE ) ) )\r
100         {\r
101                 ucReturn = pdFALSE;\r
102         }\r
103         else\r
104         {\r
105                 ucReturn = pdTRUE;\r
106         }\r
107 \r
108         return ucReturn;\r
109 }\r
110 /*-----------------------------------------------------------*/\r
111 \r
112 uint8_t *pucGetUncachedMemory( uint32_t ulSize )\r
113 {\r
114 uint8_t *pucReturn;\r
115 uint32_t ulSkipSize;\r
116 \r
117         if( pucStartOfMemory == NULL )\r
118         {\r
119                 vInitialiseUncachedMemory( );\r
120         }\r
121         if( ( pucStartOfMemory == NULL ) || ( ulSize > ulMemorySize ) )\r
122         {\r
123                 pucReturn = NULL;\r
124         }\r
125         else\r
126         {\r
127                 pucReturn = pucHeadOfMemory;\r
128                 /* Make sure that the next pointer return will have a good alignment. */\r
129                 ulSkipSize = ( ulSize + uncALIGNMENT_SIZE ) & ~( uncALIGNMENT_SIZE - 1uL );\r
130                 pucHeadOfMemory += ulSkipSize;\r
131                 ulMemorySize -= ulSkipSize;\r
132         }\r
133 \r
134         return pucReturn;\r
135 }\r
136 /*-----------------------------------------------------------*/\r
137 \r
138 static void vInitialiseUncachedMemory( )\r
139 {\r
140         /* At the end of program's space... */\r
141         pucStartOfMemory = ( uint8_t * ) &( _end );\r
142 \r
143         /* Align the start address to 1 MB boundary. */\r
144         pucStartOfMemory = ( uint8_t * )( ( ( uint32_t )pucStartOfMemory + uncMEMORY_SIZE ) & ( ~( uncMEMORY_SIZE - 1 ) ) );\r
145 \r
146         if( ( ( u32 )pucStartOfMemory ) + uncMEMORY_SIZE > DDR_MEMORY_END )\r
147         {\r
148                 FreeRTOS_printf( ( "vInitialiseUncachedMemory: Can not allocate uncached memory\n" ) );\r
149         }\r
150         else\r
151         {\r
152                 /* Some objects want to be stored in uncached memory. Hence the 1 MB\r
153                 address range that starts after "_end" is made uncached by setting\r
154                 appropriate attributes in the translation table. */\r
155                 Xil_SetTlbAttributes( ( uint32_t ) pucStartOfMemory, uncMEMORY_ATTRIBUTE );\r
156 \r
157                 /* For experiments in the SDIO driver, make the remaining uncached memory\r
158                 public */\r
159                 pucHeadOfMemory = pucStartOfMemory;\r
160                 ulMemorySize = uncMEMORY_SIZE;\r
161                 memset( pucStartOfMemory, '\0', uncMEMORY_SIZE );\r
162         }\r
163 }\r