configs: meson64_android: define raw parts for bootloader
[platform/kernel/u-boot.git] / lib / abuf.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Handles a buffer that can be allocated and freed
4  *
5  * Copyright 2021 Google LLC
6  * Written by Simon Glass <sjg@chromium.org>
7  */
8
9 #include <common.h>
10 #include <abuf.h>
11 #include <malloc.h>
12 #include <mapmem.h>
13 #include <string.h>
14
15 void abuf_set(struct abuf *abuf, void *data, size_t size)
16 {
17         abuf_uninit(abuf);
18         abuf->data = data;
19         abuf->size = size;
20 }
21
22 void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size)
23 {
24         abuf_set(abuf, map_sysmem(addr, size), size);
25 }
26
27 bool abuf_realloc(struct abuf *abuf, size_t new_size)
28 {
29         void *ptr;
30
31         if (!new_size) {
32                 /* easy case, just need to uninit, freeing any allocation */
33                 abuf_uninit(abuf);
34                 return true;
35         } else if (abuf->alloced) {
36                 /* currently allocated, so need to reallocate */
37                 ptr = realloc(abuf->data, new_size);
38                 if (!ptr)
39                         return false;
40                 abuf->data = ptr;
41                 abuf->size = new_size;
42                 return true;
43         } else if (new_size <= abuf->size) {
44                 /*
45                  * not currently alloced and new size is no larger. Just update
46                  * it. Data is lost off the end if new_size < abuf->size
47                  */
48                 abuf->size = new_size;
49                 return true;
50         } else {
51                 /* not currently allocated and new size is larger. Alloc and
52                  * copy in data. The new space is not inited.
53                  */
54                 ptr = memdup(abuf->data, new_size);
55                 if (!ptr)
56                         return false;
57                 abuf->data = ptr;
58                 abuf->size = new_size;
59                 abuf->alloced = true;
60                 return true;
61         }
62 }
63
64 void *abuf_uninit_move(struct abuf *abuf, size_t *sizep)
65 {
66         void *ptr;
67
68         if (sizep)
69                 *sizep = abuf->size;
70         if (!abuf->size)
71                 return NULL;
72         if (abuf->alloced) {
73                 ptr = abuf->data;
74         } else {
75                 ptr = memdup(abuf->data, abuf->size);
76                 if (!ptr)
77                         return NULL;
78         }
79         /* Clear everything out so there is no record of the data */
80         abuf_init(abuf);
81
82         return ptr;
83 }
84
85 void abuf_init_set(struct abuf *abuf, void *data, size_t size)
86 {
87         abuf_init(abuf);
88         abuf_set(abuf, data, size);
89 }
90
91 void abuf_init_move(struct abuf *abuf, void *data, size_t size)
92 {
93         abuf_init_set(abuf, data, size);
94         abuf->alloced = true;
95 }
96
97 void abuf_uninit(struct abuf *abuf)
98 {
99         if (abuf->alloced)
100                 free(abuf->data);
101         abuf_init(abuf);
102 }
103
104 void abuf_init(struct abuf *abuf)
105 {
106         abuf->data = NULL;
107         abuf->size = 0;
108         abuf->alloced = false;
109 }