root/arch/powerpc/boot/wii.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mipc_check_address
  2. mipc_get_infohdr
  3. mipc_get_mem2_boundary
  4. platform_fixups
  5. platform_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * arch/powerpc/boot/wii.c
   4  *
   5  * Nintendo Wii bootwrapper support
   6  * Copyright (C) 2008-2009 The GameCube Linux Team
   7  * Copyright (C) 2008,2009 Albert Herranz
   8  */
   9 
  10 #include <stddef.h>
  11 #include "stdio.h"
  12 #include "types.h"
  13 #include "io.h"
  14 #include "ops.h"
  15 
  16 #include "ugecon.h"
  17 
  18 BSS_STACK(8192);
  19 
  20 #define HW_REG(x)               ((void *)(x))
  21 
  22 #define EXI_CTRL                HW_REG(0x0d800070)
  23 #define EXI_CTRL_ENABLE         (1<<0)
  24 
  25 #define MEM2_TOP                (0x10000000 + 64*1024*1024)
  26 #define FIRMWARE_DEFAULT_SIZE   (12*1024*1024)
  27 
  28 
  29 struct mipc_infohdr {
  30         char magic[3];
  31         u8 version;
  32         u32 mem2_boundary;
  33         u32 ipc_in;
  34         size_t ipc_in_size;
  35         u32 ipc_out;
  36         size_t ipc_out_size;
  37 };
  38 
  39 static int mipc_check_address(u32 pa)
  40 {
  41         /* only MEM2 addresses */
  42         if (pa < 0x10000000 || pa > 0x14000000)
  43                 return -EINVAL;
  44         return 0;
  45 }
  46 
  47 static struct mipc_infohdr *mipc_get_infohdr(void)
  48 {
  49         struct mipc_infohdr **hdrp, *hdr;
  50 
  51         /* 'mini' header pointer is the last word of MEM2 memory */
  52         hdrp = (struct mipc_infohdr **)0x13fffffc;
  53         if (mipc_check_address((u32)hdrp)) {
  54                 printf("mini: invalid hdrp %08X\n", (u32)hdrp);
  55                 hdr = NULL;
  56                 goto out;
  57         }
  58 
  59         hdr = *hdrp;
  60         if (mipc_check_address((u32)hdr)) {
  61                 printf("mini: invalid hdr %08X\n", (u32)hdr);
  62                 hdr = NULL;
  63                 goto out;
  64         }
  65         if (memcmp(hdr->magic, "IPC", 3)) {
  66                 printf("mini: invalid magic\n");
  67                 hdr = NULL;
  68                 goto out;
  69         }
  70 
  71 out:
  72         return hdr;
  73 }
  74 
  75 static int mipc_get_mem2_boundary(u32 *mem2_boundary)
  76 {
  77         struct mipc_infohdr *hdr;
  78         int error;
  79 
  80         hdr = mipc_get_infohdr();
  81         if (!hdr) {
  82                 error = -1;
  83                 goto out;
  84         }
  85 
  86         if (mipc_check_address(hdr->mem2_boundary)) {
  87                 printf("mini: invalid mem2_boundary %08X\n",
  88                        hdr->mem2_boundary);
  89                 error = -EINVAL;
  90                 goto out;
  91         }
  92         *mem2_boundary = hdr->mem2_boundary;
  93         error = 0;
  94 out:
  95         return error;
  96 
  97 }
  98 
  99 static void platform_fixups(void)
 100 {
 101         void *mem;
 102         u32 reg[4];
 103         u32 mem2_boundary;
 104         int len;
 105         int error;
 106 
 107         mem = finddevice("/memory");
 108         if (!mem)
 109                 fatal("Can't find memory node\n");
 110 
 111         /* two ranges of (address, size) words */
 112         len = getprop(mem, "reg", reg, sizeof(reg));
 113         if (len != sizeof(reg)) {
 114                 /* nothing to do */
 115                 goto out;
 116         }
 117 
 118         /* retrieve MEM2 boundary from 'mini' */
 119         error = mipc_get_mem2_boundary(&mem2_boundary);
 120         if (error) {
 121                 /* if that fails use a sane value */
 122                 mem2_boundary = MEM2_TOP - FIRMWARE_DEFAULT_SIZE;
 123         }
 124 
 125         if (mem2_boundary > reg[2] && mem2_boundary < reg[2] + reg[3]) {
 126                 reg[3] = mem2_boundary - reg[2];
 127                 printf("top of MEM2 @ %08X\n", reg[2] + reg[3]);
 128                 setprop(mem, "reg", reg, sizeof(reg));
 129         }
 130 
 131 out:
 132         return;
 133 }
 134 
 135 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
 136 {
 137         u32 heapsize = 24*1024*1024 - (u32)_end;
 138 
 139         simple_alloc_init(_end, heapsize, 32, 64);
 140         fdt_init(_dtb_start);
 141 
 142         /*
 143          * 'mini' boots the Broadway processor with EXI disabled.
 144          * We need it enabled before probing for the USB Gecko.
 145          */
 146         out_be32(EXI_CTRL, in_be32(EXI_CTRL) | EXI_CTRL_ENABLE);
 147 
 148         if (ug_probe())
 149                 console_ops.write = ug_console_write;
 150 
 151         platform_ops.fixups = platform_fixups;
 152 }
 153 

/* [<][>][^][v][top][bottom][index][help] */