1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020 Marvell International Ltd.
4  */
5 
6 /**
7  * @file
8  * Simple allocate only memory allocator. Used to allocate memory at application
9  * start time.
10  */
11 
12 #ifndef __CVMX_BOOTMEM_H__
13 #define __CVMX_BOOTMEM_H__
14 
15 /* Must be multiple of 8, changing breaks ABI */
16 #define CVMX_BOOTMEM_NAME_LEN		128
17 /* Can change without breaking ABI */
18 #define CVMX_BOOTMEM_NUM_NAMED_BLOCKS	64
19 /* minimum alignment of bootmem alloced blocks */
20 #define CVMX_BOOTMEM_ALIGNMENT_SIZE	(16ull)
21 
22 /* Flags for cvmx_bootmem_phy_mem* functions */
23 /* Allocate from end of block instead of beginning */
24 #define CVMX_BOOTMEM_FLAG_END_ALLOC	(1 << 0)
25 #define CVMX_BOOTMEM_FLAG_NO_LOCKING	(1 << 1) /* Don't do any locking. */
26 
27 /* Real physical addresses of memory regions */
28 #define OCTEON_DDR0_BASE    (0x0ULL)
29 /* Use 16MiB here, as 256 leads to overwriting U-Boot reloc space */
30 #define OCTEON_DDR0_SIZE    (0x001000000ULL)
31 #define OCTEON_DDR1_BASE    ((OCTEON_IS_OCTEON2() || OCTEON_IS_OCTEON3()) \
32 			     ? 0x20000000ULL : 0x410000000ULL)
33 #define OCTEON_DDR1_SIZE    (0x010000000ULL)
34 #define OCTEON_DDR2_BASE    ((OCTEON_IS_OCTEON2() || OCTEON_IS_OCTEON3()) \
35 			     ? 0x30000000ULL : 0x20000000ULL)
36 #define OCTEON_DDR2_SIZE    ((OCTEON_IS_OCTEON2() || OCTEON_IS_OCTEON3()) \
37 			     ? 0x7d0000000ULL : 0x3e0000000ULL)
38 #define OCTEON_MAX_PHY_MEM_SIZE ((OCTEON_IS_MODEL(OCTEON_CN68XX))	\
39 				 ? 128 * 1024 * 1024 * 1024ULL		\
40 				 : (OCTEON_IS_OCTEON2())		\
41 				 ? 32 * 1024 * 1024 * 1024ull		\
42 				 : (OCTEON_IS_OCTEON3())		\
43 				 ? 512 * 1024 * 1024 * 1024ULL		\
44 				 : 16 * 1024 * 1024 * 1024ULL)
45 
46 /*
47  * First bytes of each free physical block of memory contain this structure,
48  * which is used to maintain the free memory list.  Since the bootloader is
49  * only 32 bits, there is a union providing 64 and 32 bit versions.  The
50  * application init code converts addresses to 64 bit addresses before the
51  * application starts.
52  */
53 struct cvmx_bootmem_block_header {
54 	/* Note: these are referenced from assembly routines in the bootloader,
55 	 * so this structure should not be changed without changing those
56 	 * routines as well.
57 	 */
58 	u64 next_block_addr;
59 	u64 size;
60 
61 };
62 
63 /*
64  * Structure for named memory blocks
65  * Number of descriptors
66  * available can be changed without affecting compatibility,
67  * but name length changes require a bump in the bootmem
68  * descriptor version
69  * Note: This structure must be naturally 64 bit aligned, as a single
70  * memory image will be used by both 32 and 64 bit programs.
71  */
72 struct cvmx_bootmem_named_block_desc {
73 	u64 base_addr;	/* Base address of named block */
74 	/*
75 	 * Size actually allocated for named block (may differ from requested)
76 	 */
77 	u64 size;
78 	char name[CVMX_BOOTMEM_NAME_LEN]; /* name of named block */
79 };
80 
81 /* Current descriptor versions */
82 /* CVMX bootmem descriptor major version */
83 #define CVMX_BOOTMEM_DESC_MAJ_VER	3
84 /* CVMX bootmem descriptor minor version */
85 #define CVMX_BOOTMEM_DESC_MIN_VER	0
86 
87 /*
88  * First three members of cvmx_bootmem_desc_t are left in original
89  * positions for backwards compatibility.
90  */
91 struct cvmx_bootmem_desc {
92 	/* Linux compatible proxy for __BIG_ENDIAN */
93 	u32 lock;	/* spinlock to control access to list */
94 	u32 flags;	/* flags for indicating various conditions */
95 	u64 head_addr;
96 
97 	/* incremented changed when incompatible changes made */
98 	u32 major_version;
99 	/*
100 	 * incremented changed when compatible changes made, reset to
101 	 * zero when major incremented
102 	 */
103 	u32 minor_version;
104 	u64 app_data_addr;
105 	u64 app_data_size;
106 
107 	/* number of elements in named blocks array */
108 	u32 named_block_num_blocks;
109 	/* length of name array in bootmem blocks */
110 	u32 named_block_name_len;
111 	/* address of named memory block descriptors */
112 	u64 named_block_array_addr;
113 };
114 
115 /**
116  * Initialize the boot alloc memory structures. This is
117  * normally called inside of cvmx_user_app_init()
118  *
119  * @param mem_desc_addr	Address of the free memory list
120  * @return
121  */
122 int cvmx_bootmem_init(u64 mem_desc_addr);
123 
124 /**
125  * Allocate a block of memory from the free list that was passed
126  * to the application by the bootloader.
127  * This is an allocate-only algorithm, so freeing memory is not possible.
128  *
129  * @param size      Size in bytes of block to allocate
130  * @param alignment Alignment required - must be power of 2
131  *
132  * Return: pointer to block of memory, NULL on error
133  */
134 void *cvmx_bootmem_alloc(u64 size, u64 alignment);
135 
136 /**
137  * Allocate a block of memory from the free list that was passed
138  * to the application by the bootloader from a specific node.
139  * This is an allocate-only algorithm, so freeing memory is not possible.
140  *
141  * @param node	The node to allocate memory from
142  * @param size  Size in bytes of block to allocate
143  * @param alignment Alignment required - must be power of 2
144  *
145  * Return: pointer to block of memory, NULL on error
146  */
147 void *cvmx_bootmem_alloc_node(u64 node, u64 size, u64 alignment);
148 
149 /**
150  * Allocate a block of memory from the free list that was
151  * passed to the application by the bootloader at a specific
152  * address. This is an allocate-only algorithm, so
153  * freeing memory is not possible. Allocation will fail if
154  * memory cannot be allocated at the specified address.
155  *
156  * @param size      Size in bytes of block to allocate
157  * @param address   Physical address to allocate memory at.  If this
158  *                  memory is not available, the allocation fails.
159  * @param alignment Alignment required - must be power of 2
160  * Return: pointer to block of memory, NULL on error
161  */
162 void *cvmx_bootmem_alloc_address(u64 size, u64 address,
163 				 u64 alignment);
164 
165 /**
166  * Allocate a block of memory from the free list that was
167  * passed to the application by the bootloader within a specified
168  * address range. This is an allocate-only algorithm, so
169  * freeing memory is not possible. Allocation will fail if
170  * memory cannot be allocated in the requested range.
171  *
172  * @param size      Size in bytes of block to allocate
173  * @param min_addr  defines the minimum address of the range
174  * @param max_addr  defines the maximum address of the range
175  * @param alignment Alignment required - must be power of 2
176  * Return: pointer to block of memory, NULL on error
177  */
178 void *cvmx_bootmem_alloc_range(u64 size, u64 alignment,
179 			       u64 min_addr, u64 max_addr);
180 
181 /**
182  * Allocate a block of memory from the free list that was passed
183  * to the application by the bootloader, and assign it a name in the
184  * global named block table.  (part of the cvmx_bootmem_descriptor_t structure)
185  * Named blocks can later be freed.
186  *
187  * @param size  Size in bytes of block to allocate
188  * @param alignment Alignment required - must be power of 2
189  * @param name  name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
190  *
191  * Return: pointer to block of memory, NULL on error
192  */
193 void *cvmx_bootmem_alloc_named(u64 size, u64 alignment,
194 			       const char *name);
195 
196 /**
197  * Allocate a block of memory from the free list that was passed
198  * to the application by the bootloader, and assign it a name in the
199  * global named block table.  (part of the cvmx_bootmem_descriptor_t structure)
200  * Named blocks can later be freed.
201  *
202  * @param size Size in bytes of block to allocate
203  * @param alignment Alignment required - must be power of 2
204  * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
205  * @param flags     Flags to control options for the allocation.
206  *
207  * Return: pointer to block of memory, NULL on error
208  */
209 void *cvmx_bootmem_alloc_named_flags(u64 size, u64 alignment,
210 				     const char *name, u32 flags);
211 
212 /**
213  * Allocate a block of memory from the free list that was passed
214  * to the application by the bootloader, and assign it a name in the
215  * global named block table.  (part of the cvmx_bootmem_descriptor_t structure)
216  * Named blocks can later be freed.
217  *
218  * @param size    Size in bytes of block to allocate
219  * @param address Physical address to allocate memory at.  If this
220  *                memory is not available, the allocation fails.
221  * @param name    name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
222  *
223  * Return: pointer to block of memory, NULL on error
224  */
225 void *cvmx_bootmem_alloc_named_address(u64 size, u64 address,
226 				       const char *name);
227 
228 /**
229  * Allocate a block of memory from a specific range of the free list
230  * that was passed to the application by the bootloader, and assign it
231  * a name in the global named block table.  (part of the
232  * cvmx_bootmem_descriptor_t structure) Named blocks can later be
233  * freed.  If request cannot be satisfied within the address range
234  * specified, NULL is returned
235  *
236  * @param size      Size in bytes of block to allocate
237  * @param min_addr  minimum address of range
238  * @param max_addr  maximum address of range
239  * @param align  Alignment of memory to be allocated. (must be a power of 2)
240  * @param name   name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
241  *
242  * Return: pointer to block of memory, NULL on error
243  */
244 void *cvmx_bootmem_alloc_named_range(u64 size, u64 min_addr,
245 				     u64 max_addr, u64 align,
246 				     const char *name);
247 
248 /**
249  * Allocate if needed a block of memory from a specific range of the
250  * free list that was passed to the application by the bootloader, and
251  * assign it a name in the global named block table.  (part of the
252  * cvmx_bootmem_descriptor_t structure) Named blocks can later be
253  * freed.  If the requested name block is already allocated, return
254  * the pointer to block of memory.  If request cannot be satisfied
255  * within the address range specified, NULL is returned
256  *
257  * @param size   Size in bytes of block to allocate
258  * @param min_addr  minimum address of range
259  * @param max_addr  maximum address of range
260  * @param align  Alignment of memory to be allocated. (must be a power of 2)
261  * @param name   name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
262  * @param init   Initialization function
263  *
264  * The initialization function is optional, if omitted the named block
265  * is initialized to all zeros when it is created, i.e. once.
266  *
267  * Return: pointer to block of memory, NULL on error
268  */
269 void *cvmx_bootmem_alloc_named_range_once(u64 size,
270 					  u64 min_addr,
271 					  u64 max_addr,
272 					  u64 align,
273 					  const char *name,
274 					  void (*init)(void *));
275 
276 /**
277  * Allocate all free memory starting at the start address.  This is used to
278  * prevent any free blocks from later being allocated within the reserved space.
279  * Note that any memory allocated with this function cannot be later freed.
280  *
281  * @param start_addr  Starting address to reserve
282  * @param size        Size in bytes to reserve starting at start_addr
283  * @param name        Name to assign to reserved blocks
284  * @param flags       Flags to use when reserving memory
285  *
286  * Return: 0 on failure,
287  *         !0 on success
288  */
289 int cvmx_bootmem_reserve_memory(u64 start_addr, u64 size,
290 				const char *name, u32 flags);
291 
292 /**
293  * Frees a previously allocated named bootmem block.
294  *
295  * @param name   name of block to free
296  *
297  * Return: 0 on failure,
298  *         !0 on success
299  */
300 int cvmx_bootmem_free_named(const char *name);
301 
302 /**
303  * Finds a named bootmem block by name.
304  *
305  * @param name   name of block to free
306  *
307  * Return: pointer to named block descriptor on success
308  *         0 on failure
309  */
310 const struct cvmx_bootmem_named_block_desc *
311 cvmx_bootmem_find_named_block(const char *name);
312 
313 /**
314  * Returns the size of available memory in bytes, only
315  * counting blocks that are at least as big as the minimum block
316  * size.
317  *
318  * @param min_block_size
319  *               Minimum block size to count in total.
320  *
321  * Return: Number of bytes available for allocation that meet the
322  * block size requirement
323  */
324 u64 cvmx_bootmem_available_mem(u64 min_block_size);
325 
326 /**
327  * Prints out the list of named blocks that have been allocated
328  * along with their addresses and sizes.
329  * This is primarily used for debugging purposes
330  */
331 void cvmx_bootmem_print_named(void);
332 
333 /**
334  * Allocates a block of physical memory from the free list, at
335  * (optional) requested address and alignment.
336  *
337  * @param req_size size of region to allocate.  All requests are
338  * rounded up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size
339  *
340  * @param address_min Minimum address that block can occupy.
341  *
342  * @param address_max Specifies the maximum address_min (inclusive)
343  * that the allocation can use.
344  *
345  * @param alignment Requested alignment of the block.  If this
346  *                  alignment cannot be met, the allocation fails.
347  *                  This must be a power of 2.  (Note: Alignment of
348  *                  CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
349  *                  internally enforced.  Requested alignments of less
350  *                  than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
351  *                  CVMX_BOOTMEM_ALIGNMENT_SIZE.)
352  * @param flags     Flags to control options for the allocation.
353  *
354  * Return: physical address of block allocated, or -1 on failure
355  */
356 s64 cvmx_bootmem_phy_alloc(u64 req_size, u64 address_min, u64 address_max,
357 			   u64 alignment, u32 flags);
358 
359 /**
360  * Allocates a named block of physical memory from the free list, at
361  * (optional) requested address and alignment.
362  *
363  * @param size size of region to allocate.  All requests are rounded
364  * up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size
365  *
366  * @param min_addr  Minimum address that block can occupy.
367  *
368  * @param max_addr Specifies the maximum address_min (inclusive) that
369  * the allocation can use.
370  *
371  * @param alignment Requested alignment of the block.  If this
372  *                  alignment cannot be met, the allocation fails.
373  *                  This must be a power of 2.  (Note: Alignment of
374  *                  CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
375  *                  internally enforced.  Requested alignments of less
376  *                  than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
377  *                  CVMX_BOOTMEM_ALIGNMENT_SIZE.)
378  *
379  * @param name      name to assign to named block
380  *
381  * @param flags     Flags to control options for the allocation.
382  *
383  * Return: physical address of block allocated, or -1 on failure
384  */
385 s64 cvmx_bootmem_phy_named_block_alloc(u64 size, u64 min_addr, u64 max_addr,
386 				       u64 alignment, const char *name,
387 				       u32 flags);
388 
389 /**
390  * Finds a named memory block by name.
391  * Also used for finding an unused entry in the named block table.
392  *
393  * @param name Name of memory block to find.  If NULL pointer given,
394  *             then finds unused descriptor, if available.
395  *
396  * @param flags  Flags to control options for the allocation.
397  *
398  * Return: Physical address of the memory block descriptor, zero if not
399  *         found. If zero returned when name parameter is NULL, then no
400  *         memory block descriptors are available.
401  */
402 u64 cvmx_bootmem_phy_named_block_find(const char *name, u32 flags);
403 
404 /**
405  * Returns the size of available memory in bytes, only
406  * counting blocks that are at least as big as the minimum block
407  * size.
408  *
409  * @param min_block_size
410  *               Minimum block size to count in total.
411  *
412  * Return: Number of bytes available for allocation that meet the
413  * block size requirement
414  */
415 u64 cvmx_bootmem_phy_available_mem(u64 min_block_size);
416 
417 /**
418  * Frees a named block.
419  *
420  * @param name   name of block to free
421  * @param flags  flags for passing options
422  *
423  * Return: 0 on failure
424  *         1 on success
425  */
426 int cvmx_bootmem_phy_named_block_free(const char *name, u32 flags);
427 
428 /**
429  * Frees a block to the bootmem allocator list.  This must
430  * be used with care, as the size provided must match the size
431  * of the block that was allocated, or the list will become
432  * corrupted.
433  *
434  * IMPORTANT:  This is only intended to be used as part of named block
435  * frees and initial population of the free memory list.
436  *                                                      *
437  *
438  * @param phy_addr physical address of block
439  * @param size     size of block in bytes.
440  * @param flags    flags for passing options
441  *
442  * Return: 1 on success,
443  *         0 on failure
444  */
445 int __cvmx_bootmem_phy_free(u64 phy_addr, u64 size, u32 flags);
446 
447 /**
448  * Prints the list of currently allocated named blocks
449  *
450  */
451 void cvmx_bootmem_phy_named_block_print(void);
452 
453 /**
454  * Prints the list of available memory.
455  *
456  */
457 void cvmx_bootmem_phy_list_print(void);
458 
459 /**
460  * This function initializes the free memory list used by cvmx_bootmem.
461  * This must be called before any allocations can be done.
462  *
463  * @param mem_size Total memory available, in bytes
464  *
465  * @param low_reserved_bytes Number of bytes to reserve (leave out of
466  * free list) at address 0x0.
467  *
468  * @param desc_buffer Buffer for the bootmem descriptor.  This must be
469  *                 a 32 bit addressable address.
470  *
471  * Return: 1 on success
472  *         0 on failure
473  */
474 s64 cvmx_bootmem_phy_mem_list_init(u64 mem_size, u32 low_reserved_bytes,
475 				   struct cvmx_bootmem_desc *desc_buffer);
476 
477 /**
478  * This function initializes the free memory list used by cvmx_bootmem.
479  * This must be called before any allocations can be done.
480  *
481  * @param nodemask Nodemask - one bit per node (bit0->node0, bit1->node1,...)
482  *
483  * @param mem_size[] Array of memory sizes in MBytes per node ([0]->node0,...)
484  *
485  * @param low_reserved_bytes Number of bytes to reserve (leave out of
486  * free list) at address 0x0.
487  *
488  * @param desc_buffer Buffer for the bootmem descriptor.  This must be
489  *                 a 32 bit addressable address.
490  *
491  * Return: 1 on success
492  *         0 on failure
493  */
494 s64 cvmx_bootmem_phy_mem_list_init_multi(u8 nodemask, u32 mem_size[],
495 					 u32 low_reserved_bytes,
496 					 struct cvmx_bootmem_desc *desc_buffer);
497 /**
498  * Locks the bootmem allocator.  This is useful in certain situations
499  * where multiple allocations must be made without being interrupted.
500  * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
501  *
502  */
503 void cvmx_bootmem_lock(void);
504 
505 /**
506  * Unlocks the bootmem allocator.  This is useful in certain situations
507  * where multiple allocations must be made without being interrupted.
508  * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
509  *
510  */
511 void cvmx_bootmem_unlock(void);
512 
513 /**
514  * Internal use function to get the current descriptor pointer
515  */
516 void *__cvmx_bootmem_internal_get_desc_ptr(void);
517 
518 /**
519  * Internal use.  This is userd to get a pointer to a physical
520  * address.  For linux n32 the physical address in mmaped to a virtual
521  * address and the virtual address is returned.  For n64 the address
522  * is converted to an xkphys address and the xkhpys address is
523  * returned.
524  */
525 void *__cvmx_phys_addr_to_ptr(u64 phys, int size);
526 const struct cvmx_bootmem_named_block_desc *
527 __cvmx_bootmem_find_named_block_flags(const char *name, u32 flags);
528 void *cvmx_bootmem_alloc_named_range_flags(u64 size, u64 min_addr,
529 					   u64 max_addr, u64 align,
530 					   const char *name, u32 flags);
531 u64 cvmx_bootmem_phy_alloc_range(u64 size, u64 alignment,
532 				 u64 min_addr, u64 max_addr);
533 
534 #endif /*   __CVMX_BOOTMEM_H__ */
535