efi: Move common EFI stub code from x86 arch code to common location
[firefly-linux-kernel-4.4.55.git] / drivers / firmware / efi / efi-stub-helper.c
1 /*
2  * Helper functions used by the EFI stub on multiple
3  * architectures. This should be #included by the EFI stub
4  * implementation files.
5  *
6  * Copyright 2011 Intel Corporation; author Matt Fleming
7  *
8  * This file is part of the Linux kernel, and is made available
9  * under the terms of the GNU General Public License version 2.
10  *
11  */
12 #define EFI_READ_CHUNK_SIZE     (1024 * 1024)
13
14 struct initrd {
15         efi_file_handle_t *handle;
16         u64 size;
17 };
18
19
20
21
22 static void efi_char16_printk(efi_char16_t *str)
23 {
24         struct efi_simple_text_output_protocol *out;
25
26         out = (struct efi_simple_text_output_protocol *)sys_table->con_out;
27         efi_call_phys2(out->output_string, out, str);
28 }
29
30 static void efi_printk(char *str)
31 {
32         char *s8;
33
34         for (s8 = str; *s8; s8++) {
35                 efi_char16_t ch[2] = { 0 };
36
37                 ch[0] = *s8;
38                 if (*s8 == '\n') {
39                         efi_char16_t nl[2] = { '\r', 0 };
40                         efi_char16_printk(nl);
41                 }
42
43                 efi_char16_printk(ch);
44         }
45 }
46
47
48 static efi_status_t __get_map(efi_memory_desc_t **map, unsigned long *map_size,
49                               unsigned long *desc_size)
50 {
51         efi_memory_desc_t *m = NULL;
52         efi_status_t status;
53         unsigned long key;
54         u32 desc_version;
55
56         *map_size = sizeof(*m) * 32;
57 again:
58         /*
59          * Add an additional efi_memory_desc_t because we're doing an
60          * allocation which may be in a new descriptor region.
61          */
62         *map_size += sizeof(*m);
63         status = efi_call_phys3(sys_table->boottime->allocate_pool,
64                                 EFI_LOADER_DATA, *map_size, (void **)&m);
65         if (status != EFI_SUCCESS)
66                 goto fail;
67
68         status = efi_call_phys5(sys_table->boottime->get_memory_map, map_size,
69                                 m, &key, desc_size, &desc_version);
70         if (status == EFI_BUFFER_TOO_SMALL) {
71                 efi_call_phys1(sys_table->boottime->free_pool, m);
72                 goto again;
73         }
74
75         if (status != EFI_SUCCESS)
76                 efi_call_phys1(sys_table->boottime->free_pool, m);
77
78 fail:
79         *map = m;
80         return status;
81 }
82
83 /*
84  * Allocate at the highest possible address that is not above 'max'.
85  */
86 static efi_status_t high_alloc(unsigned long size, unsigned long align,
87                               unsigned long *addr, unsigned long max)
88 {
89         unsigned long map_size, desc_size;
90         efi_memory_desc_t *map;
91         efi_status_t status;
92         unsigned long nr_pages;
93         u64 max_addr = 0;
94         int i;
95
96         status = __get_map(&map, &map_size, &desc_size);
97         if (status != EFI_SUCCESS)
98                 goto fail;
99
100         nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
101 again:
102         for (i = 0; i < map_size / desc_size; i++) {
103                 efi_memory_desc_t *desc;
104                 unsigned long m = (unsigned long)map;
105                 u64 start, end;
106
107                 desc = (efi_memory_desc_t *)(m + (i * desc_size));
108                 if (desc->type != EFI_CONVENTIONAL_MEMORY)
109                         continue;
110
111                 if (desc->num_pages < nr_pages)
112                         continue;
113
114                 start = desc->phys_addr;
115                 end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
116
117                 if ((start + size) > end || (start + size) > max)
118                         continue;
119
120                 if (end - size > max)
121                         end = max;
122
123                 if (round_down(end - size, align) < start)
124                         continue;
125
126                 start = round_down(end - size, align);
127
128                 /*
129                  * Don't allocate at 0x0. It will confuse code that
130                  * checks pointers against NULL.
131                  */
132                 if (start == 0x0)
133                         continue;
134
135                 if (start > max_addr)
136                         max_addr = start;
137         }
138
139         if (!max_addr)
140                 status = EFI_NOT_FOUND;
141         else {
142                 status = efi_call_phys4(sys_table->boottime->allocate_pages,
143                                         EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
144                                         nr_pages, &max_addr);
145                 if (status != EFI_SUCCESS) {
146                         max = max_addr;
147                         max_addr = 0;
148                         goto again;
149                 }
150
151                 *addr = max_addr;
152         }
153
154 free_pool:
155         efi_call_phys1(sys_table->boottime->free_pool, map);
156
157 fail:
158         return status;
159 }
160
161 /*
162  * Allocate at the lowest possible address.
163  */
164 static efi_status_t low_alloc(unsigned long size, unsigned long align,
165                               unsigned long *addr)
166 {
167         unsigned long map_size, desc_size;
168         efi_memory_desc_t *map;
169         efi_status_t status;
170         unsigned long nr_pages;
171         int i;
172
173         status = __get_map(&map, &map_size, &desc_size);
174         if (status != EFI_SUCCESS)
175                 goto fail;
176
177         nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
178         for (i = 0; i < map_size / desc_size; i++) {
179                 efi_memory_desc_t *desc;
180                 unsigned long m = (unsigned long)map;
181                 u64 start, end;
182
183                 desc = (efi_memory_desc_t *)(m + (i * desc_size));
184
185                 if (desc->type != EFI_CONVENTIONAL_MEMORY)
186                         continue;
187
188                 if (desc->num_pages < nr_pages)
189                         continue;
190
191                 start = desc->phys_addr;
192                 end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
193
194                 /*
195                  * Don't allocate at 0x0. It will confuse code that
196                  * checks pointers against NULL. Skip the first 8
197                  * bytes so we start at a nice even number.
198                  */
199                 if (start == 0x0)
200                         start += 8;
201
202                 start = round_up(start, align);
203                 if ((start + size) > end)
204                         continue;
205
206                 status = efi_call_phys4(sys_table->boottime->allocate_pages,
207                                         EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
208                                         nr_pages, &start);
209                 if (status == EFI_SUCCESS) {
210                         *addr = start;
211                         break;
212                 }
213         }
214
215         if (i == map_size / desc_size)
216                 status = EFI_NOT_FOUND;
217
218 free_pool:
219         efi_call_phys1(sys_table->boottime->free_pool, map);
220 fail:
221         return status;
222 }
223
224 static void low_free(unsigned long size, unsigned long addr)
225 {
226         unsigned long nr_pages;
227
228         nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
229         efi_call_phys2(sys_table->boottime->free_pages, addr, nr_pages);
230 }
231
232
233 /*
234  * Check the cmdline for a LILO-style initrd= arguments.
235  *
236  * We only support loading an initrd from the same filesystem as the
237  * kernel image.
238  */
239 static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
240                                     struct setup_header *hdr)
241 {
242         struct initrd *initrds;
243         unsigned long initrd_addr;
244         efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
245         u64 initrd_total;
246         efi_file_io_interface_t *io;
247         efi_file_handle_t *fh;
248         efi_status_t status;
249         int nr_initrds;
250         char *str;
251         int i, j, k;
252
253         initrd_addr = 0;
254         initrd_total = 0;
255
256         str = (char *)(unsigned long)hdr->cmd_line_ptr;
257
258         j = 0;                  /* See close_handles */
259
260         if (!str || !*str)
261                 return EFI_SUCCESS;
262
263         for (nr_initrds = 0; *str; nr_initrds++) {
264                 str = strstr(str, "initrd=");
265                 if (!str)
266                         break;
267
268                 str += 7;
269
270                 /* Skip any leading slashes */
271                 while (*str == '/' || *str == '\\')
272                         str++;
273
274                 while (*str && *str != ' ' && *str != '\n')
275                         str++;
276         }
277
278         if (!nr_initrds)
279                 return EFI_SUCCESS;
280
281         status = efi_call_phys3(sys_table->boottime->allocate_pool,
282                                 EFI_LOADER_DATA,
283                                 nr_initrds * sizeof(*initrds),
284                                 &initrds);
285         if (status != EFI_SUCCESS) {
286                 efi_printk("Failed to alloc mem for initrds\n");
287                 goto fail;
288         }
289
290         str = (char *)(unsigned long)hdr->cmd_line_ptr;
291         for (i = 0; i < nr_initrds; i++) {
292                 struct initrd *initrd;
293                 efi_file_handle_t *h;
294                 efi_file_info_t *info;
295                 efi_char16_t filename_16[256];
296                 unsigned long info_sz;
297                 efi_guid_t info_guid = EFI_FILE_INFO_ID;
298                 efi_char16_t *p;
299                 u64 file_sz;
300
301                 str = strstr(str, "initrd=");
302                 if (!str)
303                         break;
304
305                 str += 7;
306
307                 initrd = &initrds[i];
308                 p = filename_16;
309
310                 /* Skip any leading slashes */
311                 while (*str == '/' || *str == '\\')
312                         str++;
313
314                 while (*str && *str != ' ' && *str != '\n') {
315                         if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
316                                 break;
317
318                         if (*str == '/') {
319                                 *p++ = '\\';
320                                 *str++;
321                         } else {
322                                 *p++ = *str++;
323                         }
324                 }
325
326                 *p = '\0';
327
328                 /* Only open the volume once. */
329                 if (!i) {
330                         efi_boot_services_t *boottime;
331
332                         boottime = sys_table->boottime;
333
334                         status = efi_call_phys3(boottime->handle_protocol,
335                                         image->device_handle, &fs_proto, &io);
336                         if (status != EFI_SUCCESS) {
337                                 efi_printk("Failed to handle fs_proto\n");
338                                 goto free_initrds;
339                         }
340
341                         status = efi_call_phys2(io->open_volume, io, &fh);
342                         if (status != EFI_SUCCESS) {
343                                 efi_printk("Failed to open volume\n");
344                                 goto free_initrds;
345                         }
346                 }
347
348                 status = efi_call_phys5(fh->open, fh, &h, filename_16,
349                                         EFI_FILE_MODE_READ, (u64)0);
350                 if (status != EFI_SUCCESS) {
351                         efi_printk("Failed to open initrd file: ");
352                         efi_char16_printk(filename_16);
353                         efi_printk("\n");
354                         goto close_handles;
355                 }
356
357                 initrd->handle = h;
358
359                 info_sz = 0;
360                 status = efi_call_phys4(h->get_info, h, &info_guid,
361                                         &info_sz, NULL);
362                 if (status != EFI_BUFFER_TOO_SMALL) {
363                         efi_printk("Failed to get initrd info size\n");
364                         goto close_handles;
365                 }
366
367 grow:
368                 status = efi_call_phys3(sys_table->boottime->allocate_pool,
369                                         EFI_LOADER_DATA, info_sz, &info);
370                 if (status != EFI_SUCCESS) {
371                         efi_printk("Failed to alloc mem for initrd info\n");
372                         goto close_handles;
373                 }
374
375                 status = efi_call_phys4(h->get_info, h, &info_guid,
376                                         &info_sz, info);
377                 if (status == EFI_BUFFER_TOO_SMALL) {
378                         efi_call_phys1(sys_table->boottime->free_pool, info);
379                         goto grow;
380                 }
381
382                 file_sz = info->file_size;
383                 efi_call_phys1(sys_table->boottime->free_pool, info);
384
385                 if (status != EFI_SUCCESS) {
386                         efi_printk("Failed to get initrd info\n");
387                         goto close_handles;
388                 }
389
390                 initrd->size = file_sz;
391                 initrd_total += file_sz;
392         }
393
394         if (initrd_total) {
395                 unsigned long addr;
396
397                 /*
398                  * Multiple initrd's need to be at consecutive
399                  * addresses in memory, so allocate enough memory for
400                  * all the initrd's.
401                  */
402                 status = high_alloc(initrd_total, 0x1000,
403                                    &initrd_addr, hdr->initrd_addr_max);
404                 if (status != EFI_SUCCESS) {
405                         efi_printk("Failed to alloc highmem for initrds\n");
406                         goto close_handles;
407                 }
408
409                 /* We've run out of free low memory. */
410                 if (initrd_addr > hdr->initrd_addr_max) {
411                         efi_printk("We've run out of free low memory\n");
412                         status = EFI_INVALID_PARAMETER;
413                         goto free_initrd_total;
414                 }
415
416                 addr = initrd_addr;
417                 for (j = 0; j < nr_initrds; j++) {
418                         u64 size;
419
420                         size = initrds[j].size;
421                         while (size) {
422                                 u64 chunksize;
423                                 if (size > EFI_READ_CHUNK_SIZE)
424                                         chunksize = EFI_READ_CHUNK_SIZE;
425                                 else
426                                         chunksize = size;
427                                 status = efi_call_phys3(fh->read,
428                                                         initrds[j].handle,
429                                                         &chunksize, addr);
430                                 if (status != EFI_SUCCESS) {
431                                         efi_printk("Failed to read initrd\n");
432                                         goto free_initrd_total;
433                                 }
434                                 addr += chunksize;
435                                 size -= chunksize;
436                         }
437
438                         efi_call_phys1(fh->close, initrds[j].handle);
439                 }
440
441         }
442
443         efi_call_phys1(sys_table->boottime->free_pool, initrds);
444
445         hdr->ramdisk_image = initrd_addr;
446         hdr->ramdisk_size = initrd_total;
447
448         return status;
449
450 free_initrd_total:
451         low_free(initrd_total, initrd_addr);
452
453 close_handles:
454         for (k = j; k < i; k++)
455                 efi_call_phys1(fh->close, initrds[k].handle);
456 free_initrds:
457         efi_call_phys1(sys_table->boottime->free_pool, initrds);
458 fail:
459         hdr->ramdisk_image = 0;
460         hdr->ramdisk_size = 0;
461
462         return status;
463 }