18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) Paul Mackerras 1997. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci#include <stdarg.h> 68c2ecf20Sopenharmony_ci#include <stddef.h> 78c2ecf20Sopenharmony_ci#include "types.h" 88c2ecf20Sopenharmony_ci#include "elf.h" 98c2ecf20Sopenharmony_ci#include "string.h" 108c2ecf20Sopenharmony_ci#include "stdio.h" 118c2ecf20Sopenharmony_ci#include "page.h" 128c2ecf20Sopenharmony_ci#include "ops.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include "of.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* Value picked to match that used by yaboot */ 178c2ecf20Sopenharmony_ci#define PROG_START 0x01400000 /* only used on 64-bit systems */ 188c2ecf20Sopenharmony_ci#define RAM_END (512<<20) /* Fixme: use OF */ 198c2ecf20Sopenharmony_ci#define ONE_MB 0x100000 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic unsigned long claim_base; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_civoid epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 268c2ecf20Sopenharmony_ci unsigned long r6, unsigned long r7); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic void *of_try_claim(unsigned long size) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci unsigned long addr = 0; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci if (claim_base == 0) 338c2ecf20Sopenharmony_ci claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci for(; claim_base < RAM_END; claim_base += ONE_MB) { 368c2ecf20Sopenharmony_ci#ifdef DEBUG 378c2ecf20Sopenharmony_ci printf(" trying: 0x%08lx\n\r", claim_base); 388c2ecf20Sopenharmony_ci#endif 398c2ecf20Sopenharmony_ci addr = (unsigned long) of_claim(claim_base, size, 0); 408c2ecf20Sopenharmony_ci if (addr != PROM_ERROR) 418c2ecf20Sopenharmony_ci break; 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci if (addr == 0) 448c2ecf20Sopenharmony_ci return NULL; 458c2ecf20Sopenharmony_ci claim_base = PAGE_ALIGN(claim_base + size); 468c2ecf20Sopenharmony_ci return (void *)addr; 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic void of_image_hdr(const void *hdr) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci const Elf64_Ehdr *elf64 = hdr; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (elf64->e_ident[EI_CLASS] == ELFCLASS64) { 548c2ecf20Sopenharmony_ci /* 558c2ecf20Sopenharmony_ci * Maintain a "magic" minimum address. This keeps some older 568c2ecf20Sopenharmony_ci * firmware platforms running. 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci if (claim_base < PROG_START) 598c2ecf20Sopenharmony_ci claim_base = PROG_START; 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic void of_platform_init(unsigned long a1, unsigned long a2, void *promptr) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci platform_ops.image_hdr = of_image_hdr; 668c2ecf20Sopenharmony_ci platform_ops.malloc = of_try_claim; 678c2ecf20Sopenharmony_ci platform_ops.exit = of_exit; 688c2ecf20Sopenharmony_ci platform_ops.vmlinux_alloc = of_vmlinux_alloc; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci dt_ops.finddevice = of_finddevice; 718c2ecf20Sopenharmony_ci dt_ops.getprop = of_getprop; 728c2ecf20Sopenharmony_ci dt_ops.setprop = of_setprop; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci of_console_init(); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci of_init(promptr); 778c2ecf20Sopenharmony_ci loader_info.promptr = promptr; 788c2ecf20Sopenharmony_ci if (a1 && a2 && a2 != 0xdeadbeef) { 798c2ecf20Sopenharmony_ci loader_info.initrd_addr = a1; 808c2ecf20Sopenharmony_ci loader_info.initrd_size = a2; 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_civoid platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 858c2ecf20Sopenharmony_ci unsigned long r6, unsigned long r7) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci /* Detect OF vs. ePAPR boot */ 888c2ecf20Sopenharmony_ci if (r5) 898c2ecf20Sopenharmony_ci of_platform_init(r3, r4, (void *)r5); 908c2ecf20Sopenharmony_ci else 918c2ecf20Sopenharmony_ci epapr_platform_init(r3, r4, r5, r6, r7); 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 94