1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <types.h>
21#include <string.h>
22#include <cbmem.h>
23#include <console/console.h>
24
25#if 1
26#define debug(x...) printk_debug(x)
27#else
28#define debug(x...)
29#endif
30
31
32
33
34#define CBMEM_TOC_RESERVED 512
35#define MAX_CBMEM_ENTRIES 16
36#define CBMEM_MAGIC 0x434f5245
37
38static void *cbmem_base;
39static int cbmem_size;
40
41struct cbmem_entry {
42 u32 magic;
43 u32 id;
44 u64 base;
45 u64 size;
46} __attribute__((packed));
47
48#ifndef __ROMCC__
49struct cbmem_entry *bss_cbmem_toc;
50#endif
51
52
53
54
55
56
57
58
59
60
61
62void cbmem_init(u64 baseaddr, u64 size)
63{
64 struct cbmem_entry *cbmem_toc;
65 cbmem_toc = (struct cbmem_entry *)(unsigned long)baseaddr;
66
67#ifndef __ROMCC__
68 bss_cbmem_toc = cbmem_toc;
69#endif
70
71 debug("Initializing CBMEM area to 0x%llx (%lld bytes)\n", baseaddr, size);
72
73 if (size < (64 * 1024)) {
74 debug("Increase CBMEM size!!\n");
75 for (;;) ;
76 }
77
78 memset(cbmem_toc, 0, CBMEM_TOC_RESERVED);
79
80 cbmem_toc[0] = (struct cbmem_entry) {
81 .magic = CBMEM_MAGIC,
82 .id = CBMEM_ID_FREESPACE,
83 .base = baseaddr + CBMEM_TOC_RESERVED,
84 .size = size - CBMEM_TOC_RESERVED
85 };
86}
87
88int cbmem_reinit(u64 baseaddr)
89{
90 struct cbmem_entry *cbmem_toc;
91 cbmem_toc = (struct cbmem_entry *)(unsigned long)baseaddr;
92
93 debug("Re-Initializing CBMEM area to 0x%lx\n", (unsigned long)baseaddr);
94#ifndef __ROMCC__
95 bss_cbmem_toc = cbmem_toc;
96#endif
97
98 return (cbmem_toc[0].magic == CBMEM_MAGIC);
99}
100
101void *cbmem_add(u32 id, u64 size)
102{
103 struct cbmem_entry *cbmem_toc;
104 int i;
105#ifdef __ROMCC__
106 cbmem_toc = (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE);
107#else
108 cbmem_toc = bss_cbmem_toc;
109#endif
110
111 if (cbmem_toc == NULL) {
112 return NULL;
113 }
114
115 if (cbmem_toc[0].magic != CBMEM_MAGIC) {
116 printk_err("ERROR: CBMEM was not initialized yet.\n");
117 return NULL;
118 }
119
120
121 if (size > cbmem_toc[0].size) {
122 printk_err("ERROR: Not enough memory for table %x\n", id);
123 return NULL;
124 }
125
126
127
128 size = ALIGN(size, 512) < cbmem_toc[0].size ?
129 ALIGN(size, 512) : cbmem_toc[0].size;
130
131
132 for (i = 0; i < MAX_CBMEM_ENTRIES; i++) {
133 if (cbmem_toc[i].id == CBMEM_ID_NONE)
134 break;
135 }
136
137 if (i >= MAX_CBMEM_ENTRIES) {
138 printk_err("ERROR: No more CBMEM entries available.\n");
139 return NULL;
140 }
141
142 debug("Adding CBMEM entry as no. %d\n", i);
143
144 cbmem_toc[i] = (struct cbmem_entry) {
145 .magic = CBMEM_MAGIC,
146 .id = id,
147 .base = cbmem_toc[0].base,
148 .size = size
149 };
150
151 cbmem_toc[0].base += size;
152 cbmem_toc[0].size -= size;
153
154 return (void *)cbmem_toc[i].base;
155}
156
157void *cbmem_find(u32 id)
158{
159 struct cbmem_entry *cbmem_toc;
160 int i;
161#ifdef __ROMCC__
162 cbmem_toc = (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE);
163#else
164 cbmem_toc = bss_cbmem_toc;
165#endif
166
167 if (cbmem_toc == NULL)
168 return NULL;
169
170 for (i = 0; i < MAX_CBMEM_ENTRIES; i++) {
171 if (cbmem_toc[i].id == id)
172 return (void *)(unsigned long)cbmem_toc[i].base;
173 }
174
175 return (void *)NULL;
176}
177
178#ifndef __ROMCC__
179#if CONFIG_HAVE_ACPI_RESUME
180extern u8 acpi_slp_type;
181#endif
182extern uint64_t high_tables_base, high_tables_size;
183
184void cbmem_initialize(void)
185{
186#if CONFIG_HAVE_ACPI_RESUME
187 if (acpi_slp_type == 3) {
188 if (!cbmem_reinit(high_tables_base)) {
189
190 acpi_slp_type == 0;
191 cbmem_init(high_tables_base, high_tables_size);
192 }
193 } else {
194 cbmem_init(high_tables_base, high_tables_size);
195 }
196#else
197 cbmem_init(high_tables_base, high_tables_size);
198#endif
199 cbmem_arch_init();
200}
201
202#ifndef __ROMCC__
203void cbmem_list(void)
204{
205 struct cbmem_entry *cbmem_toc;
206 int i;
207#ifdef __ROMCC__
208 cbmem_toc = (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE);
209#else
210 cbmem_toc = bss_cbmem_toc;
211#endif
212
213 if (cbmem_toc == NULL)
214 return;
215
216 for (i = 0; i < MAX_CBMEM_ENTRIES; i++) {
217
218 if (cbmem_toc[i].magic != CBMEM_MAGIC)
219 continue;
220 printk_debug("%2d. ", i);
221 switch (cbmem_toc[i].id) {
222 case CBMEM_ID_FREESPACE: printk_debug("FREE SPACE "); break;
223 case CBMEM_ID_GDT: printk_debug("GDT "); break;
224 case CBMEM_ID_ACPI: printk_debug("ACPI "); break;
225 case CBMEM_ID_CBTABLE: printk_debug("COREBOOT "); break;
226 case CBMEM_ID_PIRQ: printk_debug("IRQ TABLE "); break;
227 case CBMEM_ID_MPTABLE: printk_debug("SMP TABLE "); break;
228 case CBMEM_ID_RESUME: printk_debug("ACPI RESUME"); break;
229 default: printk_debug("%08x ", cbmem_toc[i].id);
230 }
231 printk_debug("%08llx ", cbmem_toc[i].base);
232 printk_debug("%08llx\n", cbmem_toc[i].size);
233 }
234}
235#endif
236
237#endif
238
239