1 /* 2 * Copyright (C) Paul Mackerras 1997. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9 #include <stdarg.h> 10 #include <stddef.h> 11 #include "types.h" 12 #include "elf.h" 13 #include "string.h" 14 #include "stdio.h" 15 #include "page.h" 16 #include "ops.h" 17 18 #include "of.h" 19 20 /* Value picked to match that used by yaboot */ 21 #define PROG_START 0x01400000 /* only used on 64-bit systems */ 22 #define RAM_END (512<<20) /* Fixme: use OF */ 23 #define ONE_MB 0x100000 24 25 26 27 static unsigned long claim_base; 28 29 static void *of_try_claim(unsigned long size) 30 { 31 unsigned long addr = 0; 32 33 if (claim_base == 0) 34 claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); 35 36 for(; claim_base < RAM_END; claim_base += ONE_MB) { 37 #ifdef DEBUG 38 printf(" trying: 0x%08lx\n\r", claim_base); 39 #endif 40 addr = (unsigned long)of_claim(claim_base, size, 0); 41 if ((void *)addr != (void *)-1) 42 break; 43 } 44 if (addr == 0) 45 return NULL; 46 claim_base = PAGE_ALIGN(claim_base + size); 47 return (void *)addr; 48 } 49 50 static void of_image_hdr(const void *hdr) 51 { 52 const Elf64_Ehdr *elf64 = hdr; 53 54 if (elf64->e_ident[EI_CLASS] == ELFCLASS64) { 55 /* 56 * Maintain a "magic" minimum address. This keeps some older 57 * firmware platforms running. 58 */ 59 if (claim_base < PROG_START) 60 claim_base = PROG_START; 61 } 62 } 63 64 void platform_init(unsigned long a1, unsigned long a2, void *promptr) 65 { 66 platform_ops.image_hdr = of_image_hdr; 67 platform_ops.malloc = of_try_claim; 68 platform_ops.exit = of_exit; 69 platform_ops.vmlinux_alloc = of_vmlinux_alloc; 70 71 dt_ops.finddevice = of_finddevice; 72 dt_ops.getprop = of_getprop; 73 dt_ops.setprop = of_setprop; 74 75 of_console_init(); 76 77 of_init(promptr); 78 loader_info.promptr = promptr; 79 if (a1 && a2 && a2 != 0xdeadbeef) { 80 loader_info.initrd_addr = a1; 81 loader_info.initrd_size = a2; 82 } 83 } 84