Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) Paul Mackerras 1997.
0004  */
0005 #include <stdarg.h>
0006 #include <stddef.h>
0007 #include "types.h"
0008 #include "elf.h"
0009 #include "string.h"
0010 #include "stdio.h"
0011 #include "page.h"
0012 #include "ops.h"
0013 
0014 #include "of.h"
0015 
0016 /* Value picked to match that used by yaboot */
0017 #define PROG_START  0x01400000  /* only used on 64-bit systems */
0018 #define RAM_END     (512<<20)   /* Fixme: use OF */
0019 #define ONE_MB      0x100000
0020 
0021 
0022 
0023 static unsigned long claim_base;
0024 
0025 void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
0026              unsigned long r6, unsigned long r7);
0027 
0028 static void *of_try_claim(unsigned long size)
0029 {
0030     unsigned long addr = 0;
0031 
0032     if (claim_base == 0)
0033         claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
0034 
0035     for(; claim_base < RAM_END; claim_base += ONE_MB) {
0036 #ifdef DEBUG
0037         printf("    trying: 0x%08lx\n\r", claim_base);
0038 #endif
0039         addr = (unsigned long) of_claim(claim_base, size, 0);
0040         if (addr != PROM_ERROR)
0041             break;
0042     }
0043     if (addr == 0)
0044         return NULL;
0045     claim_base = PAGE_ALIGN(claim_base + size);
0046     return (void *)addr;
0047 }
0048 
0049 static void of_image_hdr(const void *hdr)
0050 {
0051     const Elf64_Ehdr *elf64 = hdr;
0052 
0053     if (elf64->e_ident[EI_CLASS] == ELFCLASS64) {
0054         /*
0055          * Maintain a "magic" minimum address. This keeps some older
0056          * firmware platforms running.
0057          */
0058         if (claim_base < PROG_START)
0059             claim_base = PROG_START;
0060     }
0061 }
0062 
0063 static void of_platform_init(unsigned long a1, unsigned long a2, void *promptr)
0064 {
0065     platform_ops.image_hdr = of_image_hdr;
0066     platform_ops.malloc = of_try_claim;
0067     platform_ops.exit = of_exit;
0068     platform_ops.vmlinux_alloc = of_vmlinux_alloc;
0069 
0070     dt_ops.finddevice = of_finddevice;
0071     dt_ops.getprop = of_getprop;
0072     dt_ops.setprop = of_setprop;
0073 
0074     of_console_init();
0075 
0076     of_init(promptr);
0077     loader_info.promptr = promptr;
0078     if (a1 && a2 && a2 != 0xdeadbeef) {
0079         loader_info.initrd_addr = a1;
0080         loader_info.initrd_size = a2;
0081     }
0082 }
0083 
0084 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
0085            unsigned long r6, unsigned long r7)
0086 {
0087     /* Detect OF vs. ePAPR boot */
0088     if (r5)
0089         of_platform_init(r3, r4, (void *)r5);
0090     else
0091         epapr_platform_init(r3, r4, r5, r6, r7);
0092 }
0093