source: grub-pc/trunk/fuentes/grub-core/kern/ieee1275/cmain.c @ 22

Last change on this file since 22 was 22, checked in by mabarracus, 4 years ago

updated version and apply net.ifnames=0 into debian/rules

File size: 7.3 KB
Line 
1/* cmain.c - Startup code for the PowerPC.  */
2/*
3 *  GRUB  --  GRand Unified Bootloader
4 *  Copyright (C) 2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
5 *
6 *  GRUB is free software: you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation, either version 3 of the License, or
9 *  (at your option) any later version.
10 *
11 *  GRUB is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <grub/kernel.h>
21#include <grub/misc.h>
22#include <grub/types.h>
23#include <grub/ieee1275/ieee1275.h>
24
25int (*grub_ieee1275_entry_fn) (void *) GRUB_IEEE1275_ENTRY_FN_ATTRIBUTE;
26
27grub_ieee1275_phandle_t grub_ieee1275_chosen;
28grub_ieee1275_ihandle_t grub_ieee1275_mmu;
29
30static grub_uint32_t grub_ieee1275_flags;
31
32
33
34int
35grub_ieee1275_test_flag (enum grub_ieee1275_flag flag)
36{
37  return (grub_ieee1275_flags & (1 << flag));
38}
39
40void
41grub_ieee1275_set_flag (enum grub_ieee1275_flag flag)
42{
43  grub_ieee1275_flags |= (1 << flag);
44}
45
46static void
47grub_ieee1275_find_options (void)
48{
49  grub_ieee1275_phandle_t root;
50  grub_ieee1275_phandle_t options;
51  grub_ieee1275_phandle_t openprom;
52  grub_ieee1275_phandle_t bootrom;
53  int rc;
54  grub_uint32_t realmode = 0;
55  char tmp[256];
56  int is_smartfirmware = 0;
57  int is_olpc = 0;
58  int is_qemu = 0;
59  grub_ssize_t actual;
60
61#ifdef __sparc__
62  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
63#endif
64
65  grub_ieee1275_finddevice ("/", &root);
66  grub_ieee1275_finddevice ("/options", &options);
67  grub_ieee1275_finddevice ("/openprom", &openprom);
68
69  rc = grub_ieee1275_get_integer_property (options, "real-mode?", &realmode,
70                                           sizeof realmode, 0);
71  if (((rc >= 0) && realmode) || (grub_ieee1275_mmu == 0))
72    grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE);
73
74  rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright",
75                                   tmp, sizeof (tmp), 0);
76  if (rc >= 0 && !grub_strncmp (tmp, "SmartFirmware(tm)",
77                                sizeof ("SmartFirmware(tm)") - 1))
78    is_smartfirmware = 1;
79
80  rc = grub_ieee1275_get_property (root, "architecture",
81                                   tmp, sizeof (tmp), 0);
82  if (rc >= 0 && !grub_strcmp (tmp, "OLPC"))
83    is_olpc = 1;
84
85  rc = grub_ieee1275_get_property (root, "model",
86                                   tmp, sizeof (tmp), 0);
87  if (rc >= 0 && (!grub_strcmp (tmp, "Emulated PC")
88                  || !grub_strcmp (tmp, "IBM pSeries (emulated by qemu)"))) {
89    is_qemu = 1;
90  }
91
92  if (rc >= 0 && grub_strncmp (tmp, "IBM", 3) == 0)
93    grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS);
94
95  /* Old Macs have no key repeat, newer ones have fully working one.
96     The ones inbetween when repeated key generates an escaoe sequence
97     only the escape is repeated. With this workaround however a fast
98     e.g. down arrow-ESC is perceived as down arrow-down arrow which is
99     also annoying but is less so than the original bug of exiting from
100     the current window on arrow repeat. To avoid unaffected users suffering
101     from this workaround match only exact models known to have this bug.
102   */
103  if (rc >= 0 && grub_strcmp (tmp, "PowerBook3,3") == 0)
104    grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT);
105
106  rc = grub_ieee1275_get_property (root, "compatible",
107                                   tmp, sizeof (tmp), &actual);
108  if (rc >= 0)
109    {
110      char *ptr;
111      for (ptr = tmp; ptr - tmp < actual; ptr += grub_strlen (ptr) + 1)
112        {
113          if (grub_memcmp (ptr, "MacRISC", sizeof ("MacRISC") - 1) == 0
114              && (ptr[sizeof ("MacRISC") - 1] == 0
115                  || grub_isdigit (ptr[sizeof ("MacRISC") - 1])))
116            {
117              grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS);
118              grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX);
119              grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN);
120              grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN);
121              break;
122            }
123        }
124    }
125
126  if (is_smartfirmware)
127    {
128      /* Broken in all versions */
129      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
130
131      /* There are two incompatible ways of checking the version number.  Try
132         both. */
133      rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version",
134                                       tmp, sizeof (tmp), 0);
135      if (rc < 0)
136        rc = grub_ieee1275_get_property (openprom, "firmware-version",
137                                         tmp, sizeof (tmp), 0);
138      if (rc >= 0)
139        {
140          /* It is tempting to implement a version parser to set the flags for
141             e.g. 1.3 and below.  However, there's a special situation here.
142             3rd party updates which fix the partition bugs are common, and for
143             some reason their fixes aren't being merged into trunk.  So for
144             example we know that 1.2 and 1.3 are broken, but there's 1.2.99
145             and 1.3.99 which are known good (and applying this workaround
146             would cause breakage). */
147          if (!grub_strcmp (tmp, "1.0")
148              || !grub_strcmp (tmp, "1.1")
149              || !grub_strcmp (tmp, "1.2")
150              || !grub_strcmp (tmp, "1.3"))
151            {
152              grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
153              grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS);
154            }
155        }
156    }
157
158  if (is_olpc)
159    {
160      /* OLPC / XO laptops have three kinds of storage devices:
161
162         - NAND flash.  These are accessible via OFW callbacks, but:
163           - Follow strange semantics, imposed by hardware constraints.
164           - Its ABI is undocumented, and not stable.
165           They lack "device_type" property, which conveniently makes GRUB
166           skip them.
167
168         - USB drives.  Not accessible, because OFW shuts down the controller
169           in order to prevent collisions with applications accessing it
170           directly.  Even worse, attempts to access it will NOT return
171           control to the caller, so we have to avoid probing them.
172
173         - SD cards.  These work fine.
174
175         To avoid breakage, we only need to skip USB probing.  However,
176         since detecting SD cards is more reliable, we do that instead.
177      */
178
179      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY);
180      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF);
181    }
182
183  if (is_qemu)
184    {
185      /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB.  */
186      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM);
187
188      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF);
189    }
190
191  if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)
192      || ! grub_ieee1275_finddevice ("/boot-rom", &bootrom))
193    {
194      rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0);
195      if (rc >= 0 && !grub_strncmp (tmp, "PPC Open Hack'Ware",
196                                    sizeof ("PPC Open Hack'Ware") - 1))
197        {
198          grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
199          grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS);
200          grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET);
201          grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM);
202          grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_ANSI);
203        }
204    }
205}
206
207void
208grub_ieee1275_init (void)
209{
210  grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen);
211
212  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "mmu", &grub_ieee1275_mmu,
213                                          sizeof grub_ieee1275_mmu, 0) < 0)
214    grub_ieee1275_mmu = 0;
215
216  grub_ieee1275_find_options ();
217}
Note: See TracBrowser for help on using the repository browser.