1 /*
2 ** Two Level Segregated Fit memory allocator, version 3.1.
3 ** Written by Matthew Conte
4 **	http://tlsf.baisoku.org
5 **
6 ** Based on the original documentation by Miguel Masmano:
7 **	http://www.gii.upv.es/tlsf/main/docs
8 **
9 ** This implementation was written to the specification
10 ** of the document, therefore no GPL restrictions apply.
11 **
12 ** Copyright (c) 2006-2016, Matthew Conte
13 ** All rights reserved.
14 **
15 ** Redistribution and use in source and binary forms, with or without
16 ** modification, are permitted provided that the following conditions are met:
17 **     * Redistributions of source code must retain the above copyright
18 **       notice, this list of conditions and the following disclaimer.
19 **     * Redistributions in binary form must reproduce the above copyright
20 **       notice, this list of conditions and the following disclaimer in the
21 **       documentation and/or other materials provided with the distribution.
22 **     * Neither the name of the copyright holder nor the
23 **       names of its contributors may be used to endorse or promote products
24 **       derived from this software without specific prior written permission.
25 **
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 ** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY
30 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37 
38 #pragma once
39 
40 #ifdef ESP_PLATFORM
41 
42 #include "soc/soc.h"
43 
44 #if !CONFIG_SPIRAM
45 #define TLSF_MAX_POOL_SIZE (SOC_DIRAM_DRAM_HIGH - SOC_DIRAM_DRAM_LOW)
46 #else
47 #define TLSF_MAX_POOL_SIZE SOC_EXTRAM_DATA_SIZE
48 #endif
49 
50 enum tlsf_config
51 {
52 	/* log2 of number of linear subdivisions of block sizes. Larger
53 	** values require more memory in the control structure. Values of
54 	** 4 or 5 are typical.
55 	*/
56 	SL_INDEX_COUNT_LOG2  = 5,
57 
58 	/* All allocation sizes and addresses are aligned to 4 bytes. */
59 	ALIGN_SIZE_LOG2 = 2,
60 	ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2),
61 
62 	/*
63 	** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits.
64 	** However, because we linearly subdivide the second-level lists, and
65 	** our minimum size granularity is 4 bytes, it doesn't make sense to
66 	** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4,
67 	** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be
68 	** trying to split size ranges into more slots than we have available.
69 	** Instead, we calculate the minimum threshold size, and place all
70 	** blocks below that size into the 0th first-level list.
71 	*/
72 
73 	/* Tunning the first level, we can reduce TLSF pool overhead
74 	 * in exchange of manage a pool smaller than 4GB
75 	 */
76 	#if (TLSF_MAX_POOL_SIZE <= (256 * 1024))
77 	FL_INDEX_MAX = 18, //Each pool can have up 256KB
78 	#elif (TLSF_MAX_POOL_SIZE <= (512 * 1024))
79 	FL_INDEX_MAX = 19, //Each pool can have up 512KB
80 	#elif (TLSF_MAX_POOL_SIZE <= (1 * 1024 * 1024))
81 	FL_INDEX_MAX = 20, //Each pool can have up 1MB
82 	#elif (TLSF_MAX_POOL_SIZE <= (2 * 1024 * 1024))
83 	FL_INDEX_MAX = 21, //Each pool can have up 2MB
84 	#elif (TLSF_MAX_POOL_SIZE <= (4 * 1024 * 1024))
85 	FL_INDEX_MAX = 22, //Each pool can have up 4MB
86 	#elif (TLSF_MAX_POOL_SIZE <= (8 * 1024 * 1024))
87 	FL_INDEX_MAX = 23, //Each pool can have up 8MB
88 	#elif (TLSF_MAX_POOL_SIZE <= (16 * 1024 * 1024))
89 	FL_INDEX_MAX = 24, //Each pool can have up 16MB
90 	#else
91 	#error "Higher TLSF pool sizes should be added for this new config"
92 	#endif
93 
94 	SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2),
95 	FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2),
96 	FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1),
97 
98 	SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT),
99 };
100 #else
101 enum tlsf_config
102 {
103 	//Specific configuration for host test.
104 
105 	/* log2 of number of linear subdivisions of block sizes. Larger
106 	** values require more memory in the control structure. Values of
107 	** 4 or 5 are typical.
108 	*/
109 	SL_INDEX_COUNT_LOG2  = 5,
110 
111 	/* All allocation sizes and addresses are aligned to 4 bytes. */
112 	ALIGN_SIZE_LOG2 = 2,
113 	ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2),
114 
115 	/* Tunning the first level, we can reduce TLSF pool overhead
116 	 * in exchange of manage a pool smaller than 4GB
117 	 */
118 	FL_INDEX_MAX = 30,
119 
120 	SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2),
121 	FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2),
122 	FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1),
123 
124 	SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT),
125 };
126 #endif
127