linux/arch/powerpc/boot/of.c
<<
>>
Prefs
   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
  27static unsigned long claim_base;
  28
  29void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
  30                         unsigned long r6, unsigned long r7);
  31
  32static 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
  53static 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
  67static 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
  88void 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