2 * FreeRTOS V202002.00
\r
3 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\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
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\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
22 * http://aws.amazon.com/freertos
\r
23 * http://www.FreeRTOS.org
\r
29 * This module will declare 1 MB of memory and switch off the caching for it.
\r
31 * pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length
\r
32 * rounded up to a multiple of 4 KB.
\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
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
45 /* Standard includes. */
\r
50 /* FreeRTOS includes. */
\r
51 #include "FreeRTOS.h"
\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
60 #include "Zynq/x_emacpsif.h"
\r
61 #include "Zynq/x_topology.h"
\r
62 #include "xstatus.h"
\r
64 #include "xparameters.h"
\r
65 #include "xparameters_ps.h"
\r
66 #include "xil_exception.h"
\r
67 #include "xil_mmu.h"
\r
69 #include "uncached_memory.h"
\r
71 /* Reserve 1 MB of memory. */
\r
72 #define uncMEMORY_SIZE 0x100000uL
\r
74 /* Make sure that each pointer has an alignment of 4 KB. */
\r
75 #define uncALIGNMENT_SIZE 0x1000uL
\r
77 #define DDR_MEMORY_END (XPAR_PS7_DDR_0_S_AXI_HIGHADDR+1)
\r
79 #define uncMEMORY_ATTRIBUTE 0x1C02
\r
81 static void vInitialiseUncachedMemory( void );
\r
83 static uint8_t *pucHeadOfMemory;
\r
84 static uint32_t ulMemorySize;
\r
85 static uint8_t *pucStartOfMemory = NULL;
\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
91 /*-----------------------------------------------------------*/
\r
93 uint8_t ucIsCachedMemory( const uint8_t *pucBuffer )
\r
97 if( ( pucStartOfMemory != NULL ) &&
\r
98 ( pucBuffer >= pucStartOfMemory ) &&
\r
99 ( pucBuffer < ( pucStartOfMemory + uncMEMORY_SIZE ) ) )
\r
101 ucReturn = pdFALSE;
\r
110 /*-----------------------------------------------------------*/
\r
112 uint8_t *pucGetUncachedMemory( uint32_t ulSize )
\r
114 uint8_t *pucReturn;
\r
115 uint32_t ulSkipSize;
\r
117 if( pucStartOfMemory == NULL )
\r
119 vInitialiseUncachedMemory( );
\r
121 if( ( pucStartOfMemory == NULL ) || ( ulSize > ulMemorySize ) )
\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
136 /*-----------------------------------------------------------*/
\r
138 static void vInitialiseUncachedMemory( )
\r
140 /* At the end of program's space... */
\r
141 pucStartOfMemory = ( uint8_t * ) &( _end );
\r
143 /* Align the start address to 1 MB boundary. */
\r
144 pucStartOfMemory = ( uint8_t * )( ( ( uint32_t )pucStartOfMemory + uncMEMORY_SIZE ) & ( ~( uncMEMORY_SIZE - 1 ) ) );
\r
146 if( ( ( u32 )pucStartOfMemory ) + uncMEMORY_SIZE > DDR_MEMORY_END )
\r
148 FreeRTOS_printf( ( "vInitialiseUncachedMemory: Can not allocate uncached memory\n" ) );
\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
157 /* For experiments in the SDIO driver, make the remaining uncached memory
\r
159 pucHeadOfMemory = pucStartOfMemory;
\r
160 ulMemorySize = uncMEMORY_SIZE;
\r
161 memset( pucStartOfMemory, '\0', uncMEMORY_SIZE );
\r