of.c (2129B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) Paul Mackerras 1997. 4 */ 5#include <stdarg.h> 6#include <stddef.h> 7#include "types.h" 8#include "elf.h" 9#include "string.h" 10#include "stdio.h" 11#include "page.h" 12#include "ops.h" 13 14#include "of.h" 15 16/* Value picked to match that used by yaboot */ 17#define PROG_START 0x01400000 /* only used on 64-bit systems */ 18#define RAM_END (512<<20) /* Fixme: use OF */ 19#define ONE_MB 0x100000 20 21 22 23static unsigned long claim_base; 24 25void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 26 unsigned long r6, unsigned long r7); 27 28static void *of_try_claim(unsigned long size) 29{ 30 unsigned long addr = 0; 31 32 if (claim_base == 0) 33 claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); 34 35 for(; claim_base < RAM_END; claim_base += ONE_MB) { 36#ifdef DEBUG 37 printf(" trying: 0x%08lx\n\r", claim_base); 38#endif 39 addr = (unsigned long) of_claim(claim_base, size, 0); 40 if (addr != PROM_ERROR) 41 break; 42 } 43 if (addr == 0) 44 return NULL; 45 claim_base = PAGE_ALIGN(claim_base + size); 46 return (void *)addr; 47} 48 49static void of_image_hdr(const void *hdr) 50{ 51 const Elf64_Ehdr *elf64 = hdr; 52 53 if (elf64->e_ident[EI_CLASS] == ELFCLASS64) { 54 /* 55 * Maintain a "magic" minimum address. This keeps some older 56 * firmware platforms running. 57 */ 58 if (claim_base < PROG_START) 59 claim_base = PROG_START; 60 } 61} 62 63static void of_platform_init(unsigned long a1, unsigned long a2, void *promptr) 64{ 65 platform_ops.image_hdr = of_image_hdr; 66 platform_ops.malloc = of_try_claim; 67 platform_ops.exit = of_exit; 68 platform_ops.vmlinux_alloc = of_vmlinux_alloc; 69 70 dt_ops.finddevice = of_finddevice; 71 dt_ops.getprop = of_getprop; 72 dt_ops.setprop = of_setprop; 73 74 of_console_init(); 75 76 of_init(promptr); 77 loader_info.promptr = promptr; 78 if (a1 && a2 && a2 != 0xdeadbeef) { 79 loader_info.initrd_addr = a1; 80 loader_info.initrd_size = a2; 81 } 82} 83 84void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 85 unsigned long r6, unsigned long r7) 86{ 87 /* Detect OF vs. ePAPR boot */ 88 if (r5) 89 of_platform_init(r3, r4, (void *)r5); 90 else 91 epapr_platform_init(r3, r4, r5, r6, r7); 92} 93