1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include "cvmx-config.h"
37#include "cvmx.h"
38#include "cvmx-fpa.h"
39#include "cvmx-ipd.h"
40
41
42
43
44
45CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
64 uint64_t block_size, uint64_t num_blocks)
65{
66 char *ptr;
67 if (!buffer) {
68 cvmx_dprintf
69 ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
70 return -1;
71 }
72 if (pool >= CVMX_FPA_NUM_POOLS) {
73 cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
74 return -1;
75 }
76
77 if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
78 cvmx_dprintf
79 ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
80 return -1;
81 }
82
83 if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
84 cvmx_dprintf
85 ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
86 return -1;
87 }
88
89 cvmx_fpa_pool_info[pool].name = name;
90 cvmx_fpa_pool_info[pool].size = block_size;
91 cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
92 cvmx_fpa_pool_info[pool].base = buffer;
93
94 ptr = (char *)buffer;
95 while (num_blocks--) {
96 cvmx_fpa_free(ptr, pool, 0);
97 ptr += block_size;
98 }
99 return 0;
100}
101
102
103
104
105
106
107
108
109
110
111uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
112{
113 uint64_t errors = 0;
114 uint64_t count = 0;
115 uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
116 uint64_t finish =
117 base +
118 cvmx_fpa_pool_info[pool].size *
119 cvmx_fpa_pool_info[pool].starting_element_count;
120 void *ptr;
121 uint64_t address;
122
123 count = 0;
124 do {
125 ptr = cvmx_fpa_alloc(pool);
126 if (ptr)
127 address = cvmx_ptr_to_phys(ptr);
128 else
129 address = 0;
130 if (address) {
131 if ((address >= base) && (address < finish) &&
132 (((address -
133 base) % cvmx_fpa_pool_info[pool].size) == 0)) {
134 count++;
135 } else {
136 cvmx_dprintf
137 ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
138 (unsigned long long)address,
139 cvmx_fpa_pool_info[pool].name, (int)pool);
140 errors++;
141 }
142 }
143 } while (address);
144
145#ifdef CVMX_ENABLE_PKO_FUNCTIONS
146 if (pool == 0)
147 cvmx_ipd_free_ptr();
148#endif
149
150 if (errors) {
151 cvmx_dprintf
152 ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n",
153 cvmx_fpa_pool_info[pool].name, (int)pool,
154 (unsigned long long)base, (unsigned long long)finish,
155 (unsigned long long)cvmx_fpa_pool_info[pool].size);
156 return -errors;
157 } else
158 return 0;
159}
160
161uint64_t cvmx_fpa_get_block_size(uint64_t pool)
162{
163 switch (pool) {
164 case 0:
165 return CVMX_FPA_POOL_0_SIZE;
166 case 1:
167 return CVMX_FPA_POOL_1_SIZE;
168 case 2:
169 return CVMX_FPA_POOL_2_SIZE;
170 case 3:
171 return CVMX_FPA_POOL_3_SIZE;
172 case 4:
173 return CVMX_FPA_POOL_4_SIZE;
174 case 5:
175 return CVMX_FPA_POOL_5_SIZE;
176 case 6:
177 return CVMX_FPA_POOL_6_SIZE;
178 case 7:
179 return CVMX_FPA_POOL_7_SIZE;
180 default:
181 return 0;
182 }
183}
184