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 void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 30 unsigned long r6, unsigned long r7); 31 32 static void *of_try_claim(unsigned long size) 33 { 34 unsigned long addr = 0; 35 36 if (claim_base == 0) 37 claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); 38 39 for(; claim_base < RAM_END; claim_base += ONE_MB) { 40 #ifdef DEBUG 41 printf(" trying: 0x%08lx\n\r", claim_base); 42 #endif 43 addr = (unsigned long) of_claim(claim_base, size, 0); 44 if (addr != PROM_ERROR) 45 break; 46 } 47 if (addr == 0) 48 return NULL; 49 claim_base = PAGE_ALIGN(claim_base + size); 50 return (void *)addr; 51 } 52 53 static void of_image_hdr(const void *hdr) 54 { 55 const Elf64_Ehdr *elf64 = hdr; 56 57 if (elf64->e_ident[EI_CLASS] == ELFCLASS64) { 58 /* 59 * Maintain a "magic" minimum address. This keeps some older 60 * firmware platforms running. 61 */ 62 if (claim_base < PROG_START) 63 claim_base = PROG_START; 64 } 65 } 66 67 static void of_platform_init(unsigned long a1, unsigned long a2, void *promptr) 68 { 69 platform_ops.image_hdr = of_image_hdr; 70 platform_ops.malloc = of_try_claim; 71 platform_ops.exit = of_exit; 72 platform_ops.vmlinux_alloc = of_vmlinux_alloc; 73 74 dt_ops.finddevice = of_finddevice; 75 dt_ops.getprop = of_getprop; 76 dt_ops.setprop = of_setprop; 77 78 of_console_init(); 79 80 of_init(promptr); 81 loader_info.promptr = promptr; 82 if (a1 && a2 && a2 != 0xdeadbeef) { 83 loader_info.initrd_addr = a1; 84 loader_info.initrd_size = a2; 85 } 86 } 87 88 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 89 unsigned long r6, unsigned long r7) 90 { 91 /* Detect OF vs. ePAPR boot */ 92 if (r5) 93 of_platform_init(r3, r4, (void *)r5); 94 else 95 epapr_platform_init(r3, r4, r5, r6, r7); 96 } 97 98