Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Merge in the ppc64 version of the prom code.

This brings in the ppc64 version of prom_init.c, prom.c and btext.c
and makes them work for ppc32. This also brings in the new calling
convention, where the first entry to the kernel (with r5 != 0) goes
to the prom_init code, which then restarts from the beginning (with
r5 == 0) after it has done its stuff.

For now this also brings in the ppc32 version of setup.c. It also
merges lmb.h.

Signed-off-by: Paul Mackerras <paulus@samba.org>

+6507 -48
+7 -4
arch/powerpc/kernel/Makefile
··· 5 5 ifeq ($(CONFIG_PPC64),y) 6 6 EXTRA_CFLAGS += -mno-minimal-toc 7 7 endif 8 - 9 8 ifeq ($(CONFIG_PPC32),y) 10 - extra-$(CONFIG_PPC_STD_MMU) := head.o 9 + CFLAGS_prom_init.o += -fPIC 11 10 endif 11 + 12 + extra-$(CONFIG_PPC_STD_MMU) := head.o 12 13 extra-$(CONFIG_PPC64) := head_64.o 13 14 extra-$(CONFIG_40x) := head_4xx.o 14 15 extra-$(CONFIG_44x) := head_44x.o ··· 19 18 extra-$(CONFIG_PPC_FPU) += fpu.o 20 19 extra-y += vmlinux.lds 21 20 22 - obj-y := traps.o 23 - obj-$(CONFIG_PPC32) += semaphore.o process.o 21 + obj-y := traps.o prom.o semaphore.o 22 + obj-$(CONFIG_PPC32) += setup.o process.o 24 23 obj-$(CONFIG_PPC64) += idle_power4.o 25 24 ifeq ($(CONFIG_PPC32),y) 25 + obj-$(CONFIG_PPC_OF) += prom_init.o 26 26 obj-$(CONFIG_MODULES) += ppc_ksyms.o 27 27 endif 28 28 obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 29 + obj-$(CONFIG_BOOTX_TEXT) += btext.o 29 30 30 31 ifeq ($(CONFIG_PPC_ISERIES),y) 31 32 arch/powerpc/kernel/head_64.o: arch/powerpc/platforms/iseries/lparmap.s
+852
arch/powerpc/kernel/btext.c
··· 1 + /* 2 + * Procedures for drawing on the screen early on in the boot process. 3 + * 4 + * Benjamin Herrenschmidt <benh@kernel.crashing.org> 5 + */ 6 + #include <linux/config.h> 7 + #include <linux/kernel.h> 8 + #include <linux/string.h> 9 + #include <linux/init.h> 10 + #include <linux/module.h> 11 + 12 + #include <asm/sections.h> 13 + #include <asm/prom.h> 14 + #include <asm/btext.h> 15 + #include <asm/prom.h> 16 + #include <asm/page.h> 17 + #include <asm/mmu.h> 18 + #include <asm/pgtable.h> 19 + #include <asm/io.h> 20 + #include <asm/lmb.h> 21 + #include <asm/processor.h> 22 + 23 + #define NO_SCROLL 24 + 25 + #ifndef NO_SCROLL 26 + static void scrollscreen(void); 27 + #endif 28 + 29 + static void draw_byte(unsigned char c, long locX, long locY); 30 + static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb); 31 + static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); 32 + static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); 33 + 34 + static int g_loc_X; 35 + static int g_loc_Y; 36 + static int g_max_loc_X; 37 + static int g_max_loc_Y; 38 + 39 + static int dispDeviceRowBytes; 40 + static int dispDeviceDepth; 41 + static int dispDeviceRect[4]; 42 + static unsigned char *dispDeviceBase, *logicalDisplayBase; 43 + 44 + unsigned long disp_BAT[2] __initdata = {0, 0}; 45 + 46 + #define cmapsz (16*256) 47 + 48 + static unsigned char vga_font[cmapsz]; 49 + 50 + int boot_text_mapped; 51 + int force_printk_to_btext = 0; 52 + 53 + 54 + /* Calc BAT values for mapping the display and store them 55 + * in disp_BAT. Those values are then used from head.S to map 56 + * the display during identify_machine() and MMU_Init() 57 + * 58 + * The display is mapped to virtual address 0xD0000000, rather 59 + * than 1:1, because some some CHRP machines put the frame buffer 60 + * in the region starting at 0xC0000000 (KERNELBASE). 61 + * This mapping is temporary and will disappear as soon as the 62 + * setup done by MMU_Init() is applied. 63 + * 64 + * For now, we align the BAT and then map 8Mb on 601 and 16Mb 65 + * on other PPCs. This may cause trouble if the framebuffer 66 + * is really badly aligned, but I didn't encounter this case 67 + * yet. 68 + */ 69 + void __init 70 + btext_prepare_BAT(void) 71 + { 72 + unsigned long vaddr = KERNELBASE + 0x10000000; 73 + unsigned long addr; 74 + unsigned long lowbits; 75 + 76 + addr = (unsigned long)dispDeviceBase; 77 + if (!addr) { 78 + boot_text_mapped = 0; 79 + return; 80 + } 81 + if (PVR_VER(mfspr(SPRN_PVR)) != 1) { 82 + /* 603, 604, G3, G4, ... */ 83 + lowbits = addr & ~0xFF000000UL; 84 + addr &= 0xFF000000UL; 85 + disp_BAT[0] = vaddr | (BL_16M<<2) | 2; 86 + disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); 87 + } else { 88 + /* 601 */ 89 + lowbits = addr & ~0xFF800000UL; 90 + addr &= 0xFF800000UL; 91 + disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4; 92 + disp_BAT[1] = addr | BL_8M | 0x40; 93 + } 94 + logicalDisplayBase = (void *) (vaddr + lowbits); 95 + } 96 + 97 + /* This function will enable the early boot text when doing OF booting. This 98 + * way, xmon output should work too 99 + */ 100 + void __init 101 + btext_setup_display(int width, int height, int depth, int pitch, 102 + unsigned long address) 103 + { 104 + g_loc_X = 0; 105 + g_loc_Y = 0; 106 + g_max_loc_X = width / 8; 107 + g_max_loc_Y = height / 16; 108 + logicalDisplayBase = (unsigned char *)address; 109 + dispDeviceBase = (unsigned char *)address; 110 + dispDeviceRowBytes = pitch; 111 + dispDeviceDepth = depth; 112 + dispDeviceRect[0] = dispDeviceRect[1] = 0; 113 + dispDeviceRect[2] = width; 114 + dispDeviceRect[3] = height; 115 + boot_text_mapped = 1; 116 + } 117 + 118 + /* Here's a small text engine to use during early boot 119 + * or for debugging purposes 120 + * 121 + * todo: 122 + * 123 + * - build some kind of vgacon with it to enable early printk 124 + * - move to a separate file 125 + * - add a few video driver hooks to keep in sync with display 126 + * changes. 127 + */ 128 + 129 + void map_boot_text(void) 130 + { 131 + unsigned long base, offset, size; 132 + unsigned char *vbase; 133 + 134 + /* By default, we are no longer mapped */ 135 + boot_text_mapped = 0; 136 + if (dispDeviceBase == 0) 137 + return; 138 + base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL; 139 + offset = ((unsigned long) dispDeviceBase) - base; 140 + size = dispDeviceRowBytes * dispDeviceRect[3] + offset 141 + + dispDeviceRect[0]; 142 + vbase = __ioremap(base, size, _PAGE_NO_CACHE); 143 + if (vbase == 0) 144 + return; 145 + logicalDisplayBase = vbase + offset; 146 + boot_text_mapped = 1; 147 + } 148 + 149 + int btext_initialize(struct device_node *np) 150 + { 151 + unsigned int width, height, depth, pitch; 152 + unsigned long address = 0; 153 + u32 *prop; 154 + 155 + prop = (u32 *)get_property(np, "width", NULL); 156 + if (prop == NULL) 157 + return -EINVAL; 158 + width = *prop; 159 + prop = (u32 *)get_property(np, "height", NULL); 160 + if (prop == NULL) 161 + return -EINVAL; 162 + height = *prop; 163 + prop = (u32 *)get_property(np, "depth", NULL); 164 + if (prop == NULL) 165 + return -EINVAL; 166 + depth = *prop; 167 + pitch = width * ((depth + 7) / 8); 168 + prop = (u32 *)get_property(np, "linebytes", NULL); 169 + if (prop) 170 + pitch = *prop; 171 + if (pitch == 1) 172 + pitch = 0x1000; 173 + prop = (u32 *)get_property(np, "address", NULL); 174 + if (prop) 175 + address = *prop; 176 + 177 + /* FIXME: Add support for PCI reg properties */ 178 + 179 + if (address == 0) 180 + return -EINVAL; 181 + 182 + g_loc_X = 0; 183 + g_loc_Y = 0; 184 + g_max_loc_X = width / 8; 185 + g_max_loc_Y = height / 16; 186 + logicalDisplayBase = (unsigned char *)address; 187 + dispDeviceBase = (unsigned char *)address; 188 + dispDeviceRowBytes = pitch; 189 + dispDeviceDepth = depth; 190 + dispDeviceRect[0] = dispDeviceRect[1] = 0; 191 + dispDeviceRect[2] = width; 192 + dispDeviceRect[3] = height; 193 + 194 + map_boot_text(); 195 + 196 + return 0; 197 + } 198 + 199 + void __init init_boot_display(void) 200 + { 201 + char *name; 202 + struct device_node *np = NULL; 203 + int rc = -ENODEV; 204 + 205 + printk("trying to initialize btext ...\n"); 206 + 207 + name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 208 + if (name != NULL) { 209 + np = of_find_node_by_path(name); 210 + if (np != NULL) { 211 + if (strcmp(np->type, "display") != 0) { 212 + printk("boot stdout isn't a display !\n"); 213 + of_node_put(np); 214 + np = NULL; 215 + } 216 + } 217 + } 218 + if (np) 219 + rc = btext_initialize(np); 220 + if (rc == 0) 221 + return; 222 + 223 + for (np = NULL; (np = of_find_node_by_type(np, "display"));) { 224 + if (get_property(np, "linux,opened", NULL)) { 225 + printk("trying %s ...\n", np->full_name); 226 + rc = btext_initialize(np); 227 + printk("result: %d\n", rc); 228 + } 229 + if (rc == 0) 230 + return; 231 + } 232 + } 233 + 234 + /* Calc the base address of a given point (x,y) */ 235 + static unsigned char * calc_base(int x, int y) 236 + { 237 + unsigned char *base; 238 + 239 + base = logicalDisplayBase; 240 + if (base == 0) 241 + base = dispDeviceBase; 242 + base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3); 243 + base += (y + dispDeviceRect[1]) * dispDeviceRowBytes; 244 + return base; 245 + } 246 + 247 + /* Adjust the display to a new resolution */ 248 + void btext_update_display(unsigned long phys, int width, int height, 249 + int depth, int pitch) 250 + { 251 + if (dispDeviceBase == 0) 252 + return; 253 + 254 + /* check it's the same frame buffer (within 256MB) */ 255 + if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000) 256 + return; 257 + 258 + dispDeviceBase = (__u8 *) phys; 259 + dispDeviceRect[0] = 0; 260 + dispDeviceRect[1] = 0; 261 + dispDeviceRect[2] = width; 262 + dispDeviceRect[3] = height; 263 + dispDeviceDepth = depth; 264 + dispDeviceRowBytes = pitch; 265 + if (boot_text_mapped) { 266 + iounmap(logicalDisplayBase); 267 + boot_text_mapped = 0; 268 + } 269 + map_boot_text(); 270 + g_loc_X = 0; 271 + g_loc_Y = 0; 272 + g_max_loc_X = width / 8; 273 + g_max_loc_Y = height / 16; 274 + } 275 + EXPORT_SYMBOL(btext_update_display); 276 + 277 + void btext_clearscreen(void) 278 + { 279 + unsigned long *base = (unsigned long *)calc_base(0, 0); 280 + unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * 281 + (dispDeviceDepth >> 3)) >> 3; 282 + int i,j; 283 + 284 + for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++) 285 + { 286 + unsigned long *ptr = base; 287 + for(j=width; j; --j) 288 + *(ptr++) = 0; 289 + base += (dispDeviceRowBytes >> 3); 290 + } 291 + } 292 + 293 + #ifndef NO_SCROLL 294 + static void scrollscreen(void) 295 + { 296 + unsigned long *src = (unsigned long *)calc_base(0,16); 297 + unsigned long *dst = (unsigned long *)calc_base(0,0); 298 + unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * 299 + (dispDeviceDepth >> 3)) >> 3; 300 + int i,j; 301 + 302 + for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++) 303 + { 304 + unsigned long *src_ptr = src; 305 + unsigned long *dst_ptr = dst; 306 + for(j=width; j; --j) 307 + *(dst_ptr++) = *(src_ptr++); 308 + src += (dispDeviceRowBytes >> 3); 309 + dst += (dispDeviceRowBytes >> 3); 310 + } 311 + for (i=0; i<16; i++) 312 + { 313 + unsigned long *dst_ptr = dst; 314 + for(j=width; j; --j) 315 + *(dst_ptr++) = 0; 316 + dst += (dispDeviceRowBytes >> 3); 317 + } 318 + } 319 + #endif /* ndef NO_SCROLL */ 320 + 321 + void btext_drawchar(char c) 322 + { 323 + int cline = 0; 324 + #ifdef NO_SCROLL 325 + int x; 326 + #endif 327 + if (!boot_text_mapped) 328 + return; 329 + 330 + switch (c) { 331 + case '\b': 332 + if (g_loc_X > 0) 333 + --g_loc_X; 334 + break; 335 + case '\t': 336 + g_loc_X = (g_loc_X & -8) + 8; 337 + break; 338 + case '\r': 339 + g_loc_X = 0; 340 + break; 341 + case '\n': 342 + g_loc_X = 0; 343 + g_loc_Y++; 344 + cline = 1; 345 + break; 346 + default: 347 + draw_byte(c, g_loc_X++, g_loc_Y); 348 + } 349 + if (g_loc_X >= g_max_loc_X) { 350 + g_loc_X = 0; 351 + g_loc_Y++; 352 + cline = 1; 353 + } 354 + #ifndef NO_SCROLL 355 + while (g_loc_Y >= g_max_loc_Y) { 356 + scrollscreen(); 357 + g_loc_Y--; 358 + } 359 + #else 360 + /* wrap around from bottom to top of screen so we don't 361 + waste time scrolling each line. -- paulus. */ 362 + if (g_loc_Y >= g_max_loc_Y) 363 + g_loc_Y = 0; 364 + if (cline) { 365 + for (x = 0; x < g_max_loc_X; ++x) 366 + draw_byte(' ', x, g_loc_Y); 367 + } 368 + #endif 369 + } 370 + 371 + void btext_drawstring(const char *c) 372 + { 373 + if (!boot_text_mapped) 374 + return; 375 + while (*c) 376 + btext_drawchar(*c++); 377 + } 378 + 379 + void btext_drawhex(unsigned long v) 380 + { 381 + char *hex_table = "0123456789abcdef"; 382 + 383 + if (!boot_text_mapped) 384 + return; 385 + #ifdef CONFIG_PPC64 386 + btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]); 387 + btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]); 388 + btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]); 389 + btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]); 390 + btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]); 391 + btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]); 392 + btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]); 393 + btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]); 394 + #endif 395 + btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]); 396 + btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]); 397 + btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]); 398 + btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]); 399 + btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]); 400 + btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]); 401 + btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]); 402 + btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]); 403 + btext_drawchar(' '); 404 + } 405 + 406 + static void draw_byte(unsigned char c, long locX, long locY) 407 + { 408 + unsigned char *base = calc_base(locX << 3, locY << 4); 409 + unsigned char *font = &vga_font[((unsigned int)c) * 16]; 410 + int rb = dispDeviceRowBytes; 411 + 412 + switch(dispDeviceDepth) { 413 + case 24: 414 + case 32: 415 + draw_byte_32(font, (unsigned int *)base, rb); 416 + break; 417 + case 15: 418 + case 16: 419 + draw_byte_16(font, (unsigned int *)base, rb); 420 + break; 421 + case 8: 422 + draw_byte_8(font, (unsigned int *)base, rb); 423 + break; 424 + } 425 + } 426 + 427 + static unsigned int expand_bits_8[16] = { 428 + 0x00000000, 429 + 0x000000ff, 430 + 0x0000ff00, 431 + 0x0000ffff, 432 + 0x00ff0000, 433 + 0x00ff00ff, 434 + 0x00ffff00, 435 + 0x00ffffff, 436 + 0xff000000, 437 + 0xff0000ff, 438 + 0xff00ff00, 439 + 0xff00ffff, 440 + 0xffff0000, 441 + 0xffff00ff, 442 + 0xffffff00, 443 + 0xffffffff 444 + }; 445 + 446 + static unsigned int expand_bits_16[4] = { 447 + 0x00000000, 448 + 0x0000ffff, 449 + 0xffff0000, 450 + 0xffffffff 451 + }; 452 + 453 + 454 + static void draw_byte_32(unsigned char *font, unsigned int *base, int rb) 455 + { 456 + int l, bits; 457 + int fg = 0xFFFFFFFFUL; 458 + int bg = 0x00000000UL; 459 + 460 + for (l = 0; l < 16; ++l) 461 + { 462 + bits = *font++; 463 + base[0] = (-(bits >> 7) & fg) ^ bg; 464 + base[1] = (-((bits >> 6) & 1) & fg) ^ bg; 465 + base[2] = (-((bits >> 5) & 1) & fg) ^ bg; 466 + base[3] = (-((bits >> 4) & 1) & fg) ^ bg; 467 + base[4] = (-((bits >> 3) & 1) & fg) ^ bg; 468 + base[5] = (-((bits >> 2) & 1) & fg) ^ bg; 469 + base[6] = (-((bits >> 1) & 1) & fg) ^ bg; 470 + base[7] = (-(bits & 1) & fg) ^ bg; 471 + base = (unsigned int *) ((char *)base + rb); 472 + } 473 + } 474 + 475 + static void draw_byte_16(unsigned char *font, unsigned int *base, int rb) 476 + { 477 + int l, bits; 478 + int fg = 0xFFFFFFFFUL; 479 + int bg = 0x00000000UL; 480 + unsigned int *eb = (int *)expand_bits_16; 481 + 482 + for (l = 0; l < 16; ++l) 483 + { 484 + bits = *font++; 485 + base[0] = (eb[bits >> 6] & fg) ^ bg; 486 + base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg; 487 + base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg; 488 + base[3] = (eb[bits & 3] & fg) ^ bg; 489 + base = (unsigned int *) ((char *)base + rb); 490 + } 491 + } 492 + 493 + static void draw_byte_8(unsigned char *font, unsigned int *base, int rb) 494 + { 495 + int l, bits; 496 + int fg = 0x0F0F0F0FUL; 497 + int bg = 0x00000000UL; 498 + unsigned int *eb = (int *)expand_bits_8; 499 + 500 + for (l = 0; l < 16; ++l) 501 + { 502 + bits = *font++; 503 + base[0] = (eb[bits >> 4] & fg) ^ bg; 504 + base[1] = (eb[bits & 0xf] & fg) ^ bg; 505 + base = (unsigned int *) ((char *)base + rb); 506 + } 507 + } 508 + 509 + static unsigned char vga_font[cmapsz] = { 510 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 511 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 512 + 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 513 + 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 514 + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 515 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 516 + 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 517 + 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 518 + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 519 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 520 + 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 521 + 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 522 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 523 + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 524 + 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 525 + 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 526 + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 527 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 528 + 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 529 + 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 530 + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 531 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 532 + 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 533 + 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 534 + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 535 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 536 + 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 537 + 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 538 + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 539 + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 540 + 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 541 + 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 542 + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 543 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 544 + 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 545 + 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 546 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 547 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 548 + 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 549 + 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 550 + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 551 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 552 + 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 553 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 554 + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 555 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 556 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 557 + 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 558 + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 559 + 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 560 + 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 561 + 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 562 + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 563 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 564 + 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 565 + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 566 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 567 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 568 + 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 569 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 570 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 571 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 572 + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 573 + 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 574 + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 575 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 576 + 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 577 + 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 578 + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 579 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 580 + 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 581 + 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 582 + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 583 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 584 + 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 585 + 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 586 + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 587 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 588 + 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 589 + 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 590 + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 591 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 592 + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 593 + 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 594 + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 595 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 596 + 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 597 + 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 598 + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 599 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 600 + 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 601 + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 602 + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 603 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 604 + 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 605 + 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 606 + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 607 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 608 + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 609 + 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 610 + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 611 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 612 + 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 613 + 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 614 + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 615 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 616 + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 617 + 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 618 + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 619 + 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 620 + 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 621 + 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 622 + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 623 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 624 + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 625 + 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 626 + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 627 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 628 + 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 629 + 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 630 + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 631 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 632 + 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 633 + 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 634 + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 635 + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 636 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 637 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 638 + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 639 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 640 + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 641 + 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 642 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 643 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 644 + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 645 + 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 646 + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 647 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 648 + 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 649 + 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 650 + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 651 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 652 + 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 653 + 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 654 + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 655 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 656 + 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 657 + 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 658 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 659 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 660 + 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 661 + 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 662 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 663 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 664 + 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 665 + 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 666 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 667 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 668 + 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 669 + 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 670 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 671 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 672 + 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 673 + 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 674 + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 675 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 676 + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 677 + 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 678 + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 679 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 680 + 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 681 + 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 682 + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 683 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 684 + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 685 + 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 686 + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 687 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 688 + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 689 + 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 690 + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 691 + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 692 + 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 693 + 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 694 + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 695 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 696 + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 697 + 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 698 + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 699 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 700 + 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 701 + 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 702 + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 703 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 704 + 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 705 + 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 706 + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 707 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 708 + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 709 + 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 710 + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 711 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 712 + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 713 + 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 714 + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 715 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 716 + 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 717 + 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 718 + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 719 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 720 + 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 721 + 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, 722 + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 723 + 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 724 + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 725 + 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 726 + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 727 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 728 + 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 729 + 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 730 + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 731 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 732 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 733 + 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 734 + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 735 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 736 + 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 737 + 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 738 + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 739 + 0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 740 + 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 741 + 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 742 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 743 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 744 + 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 745 + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 746 + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 747 + 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 748 + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 749 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 750 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 751 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 752 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 753 + 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 754 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 755 + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 756 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 757 + 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 758 + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 759 + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 760 + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 761 + 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 762 + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 763 + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 764 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 765 + 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 766 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 767 + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 768 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 769 + 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 770 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 771 + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 772 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 773 + 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 774 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 775 + 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 776 + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 777 + 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 778 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 779 + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 780 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 781 + 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 782 + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 783 + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 784 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 785 + 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 786 + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 787 + 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 788 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 789 + 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 790 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 791 + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 792 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 793 + 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 794 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 795 + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 796 + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 797 + 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 798 + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 799 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 800 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 801 + 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 802 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 803 + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 804 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 805 + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 806 + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 807 + 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 808 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 809 + 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 810 + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 811 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 812 + 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 813 + 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 814 + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 815 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 816 + 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 817 + 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 818 + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 819 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 820 + 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 821 + 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 822 + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 823 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 824 + 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 825 + 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 826 + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 827 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 828 + 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 829 + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 830 + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 831 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 832 + 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 833 + 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 834 + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 835 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 836 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 837 + 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 838 + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 839 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 840 + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 841 + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 842 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 843 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 844 + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 845 + 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 846 + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 847 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 848 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 849 + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 850 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 851 + 0x00, 0x00, 0x00, 0x00, 852 + };
+7 -9
arch/powerpc/kernel/head.S
··· 134 134 * because OF may have I/O devices mapped into that area 135 135 * (particularly on CHRP). 136 136 */ 137 - mr r31,r3 /* save parameters */ 137 + cmpwi 0,r5,0 138 + beq 1f 139 + bl prom_init 140 + trap 141 + 142 + 1: mr r31,r3 /* save parameters */ 138 143 mr r30,r4 139 - mr r29,r5 140 - mr r28,r6 141 - mr r27,r7 142 144 li r24,0 /* cpu # */ 143 145 144 146 /* ··· 206 204 * On CHRP, we are loaded at 0x10000 since OF on CHRP uses 207 205 * the exception vectors at 0 (and therefore this copy 208 206 * overwrites OF's exception vectors with our own). 209 - * If the MMU is already turned on, we copy stuff to KERNELBASE, 210 - * otherwise we copy it to 0. 207 + * The MMU is off at this point. 211 208 */ 212 209 bl reloc_offset 213 210 mr r26,r3 ··· 1188 1187 */ 1189 1188 mr r3,r31 1190 1189 mr r4,r30 1191 - mr r5,r29 1192 - mr r6,r28 1193 - mr r7,r27 1194 1190 bl machine_init 1195 1191 bl MMU_init 1196 1192
-30
arch/powerpc/kernel/ppc_ksyms.c
··· 212 212 EXPORT_SYMBOL(sys_ctrler); 213 213 EXPORT_SYMBOL(pmac_newworld); 214 214 #endif 215 - #ifdef CONFIG_PPC_OF 216 - EXPORT_SYMBOL(find_devices); 217 - EXPORT_SYMBOL(find_type_devices); 218 - EXPORT_SYMBOL(find_compatible_devices); 219 - EXPORT_SYMBOL(find_path_device); 220 - EXPORT_SYMBOL(device_is_compatible); 221 - EXPORT_SYMBOL(machine_is_compatible); 222 - EXPORT_SYMBOL(find_all_nodes); 223 - EXPORT_SYMBOL(get_property); 224 - EXPORT_SYMBOL(request_OF_resource); 225 - EXPORT_SYMBOL(release_OF_resource); 226 - EXPORT_SYMBOL(pci_busdev_to_OF_node); 227 - EXPORT_SYMBOL(pci_device_to_OF_node); 228 - EXPORT_SYMBOL(pci_device_from_OF_node); 229 - EXPORT_SYMBOL(of_find_node_by_name); 230 - EXPORT_SYMBOL(of_find_node_by_type); 231 - EXPORT_SYMBOL(of_find_compatible_node); 232 - EXPORT_SYMBOL(of_find_node_by_path); 233 - EXPORT_SYMBOL(of_find_all_nodes); 234 - EXPORT_SYMBOL(of_get_parent); 235 - EXPORT_SYMBOL(of_get_next_child); 236 - EXPORT_SYMBOL(of_node_get); 237 - EXPORT_SYMBOL(of_node_put); 238 - #endif /* CONFIG_PPC_OF */ 239 - #if defined(CONFIG_BOOTX_TEXT) 240 - EXPORT_SYMBOL(btext_update_display); 241 - #endif 242 - #if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC) 243 - EXPORT_SYMBOL(note_scsi_host); 244 - #endif 245 215 #ifdef CONFIG_VT 246 216 EXPORT_SYMBOL(kd_mksound); 247 217 #endif
+2141
arch/powerpc/kernel/prom.c
··· 1 + /* 2 + * Procedures for creating, accessing and interpreting the device tree. 3 + * 4 + * Paul Mackerras August 1996. 5 + * Copyright (C) 1996-2005 Paul Mackerras. 6 + * 7 + * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. 8 + * {engebret|bergner}@us.ibm.com 9 + * 10 + * This program is free software; you can redistribute it and/or 11 + * modify it under the terms of the GNU General Public License 12 + * as published by the Free Software Foundation; either version 13 + * 2 of the License, or (at your option) any later version. 14 + */ 15 + 16 + #undef DEBUG 17 + 18 + #include <stdarg.h> 19 + #include <linux/config.h> 20 + #include <linux/kernel.h> 21 + #include <linux/string.h> 22 + #include <linux/init.h> 23 + #include <linux/threads.h> 24 + #include <linux/spinlock.h> 25 + #include <linux/types.h> 26 + #include <linux/pci.h> 27 + #include <linux/stringify.h> 28 + #include <linux/delay.h> 29 + #include <linux/initrd.h> 30 + #include <linux/bitops.h> 31 + #include <linux/module.h> 32 + 33 + #include <asm/prom.h> 34 + #include <asm/rtas.h> 35 + #include <asm/lmb.h> 36 + #include <asm/page.h> 37 + #include <asm/processor.h> 38 + #include <asm/irq.h> 39 + #include <asm/io.h> 40 + #include <asm/smp.h> 41 + #include <asm/system.h> 42 + #include <asm/mmu.h> 43 + #include <asm/pgtable.h> 44 + #include <asm/pci.h> 45 + #include <asm/iommu.h> 46 + #include <asm/btext.h> 47 + #include <asm/sections.h> 48 + #include <asm/machdep.h> 49 + #include <asm/pSeries_reconfig.h> 50 + 51 + #ifdef DEBUG 52 + #define DBG(fmt...) printk(KERN_ERR fmt) 53 + #else 54 + #define DBG(fmt...) 55 + #endif 56 + 57 + struct pci_reg_property { 58 + struct pci_address addr; 59 + u32 size_hi; 60 + u32 size_lo; 61 + }; 62 + 63 + struct isa_reg_property { 64 + u32 space; 65 + u32 address; 66 + u32 size; 67 + }; 68 + 69 + 70 + typedef int interpret_func(struct device_node *, unsigned long *, 71 + int, int, int); 72 + 73 + extern struct rtas_t rtas; 74 + extern struct lmb lmb; 75 + extern unsigned long klimit; 76 + 77 + static unsigned long memory_limit; 78 + 79 + static int __initdata dt_root_addr_cells; 80 + static int __initdata dt_root_size_cells; 81 + 82 + #ifdef CONFIG_PPC64 83 + static int __initdata iommu_is_off; 84 + int __initdata iommu_force_on; 85 + extern unsigned long tce_alloc_start, tce_alloc_end; 86 + #endif 87 + 88 + typedef u32 cell_t; 89 + 90 + #if 0 91 + static struct boot_param_header *initial_boot_params __initdata; 92 + #else 93 + struct boot_param_header *initial_boot_params; 94 + #endif 95 + 96 + static struct device_node *allnodes = NULL; 97 + 98 + /* use when traversing tree through the allnext, child, sibling, 99 + * or parent members of struct device_node. 100 + */ 101 + static DEFINE_RWLOCK(devtree_lock); 102 + 103 + /* export that to outside world */ 104 + struct device_node *of_chosen; 105 + 106 + struct device_node *dflt_interrupt_controller; 107 + int num_interrupt_controllers; 108 + 109 + u32 rtas_data; 110 + u32 rtas_entry; 111 + 112 + /* 113 + * Wrapper for allocating memory for various data that needs to be 114 + * attached to device nodes as they are processed at boot or when 115 + * added to the device tree later (e.g. DLPAR). At boot there is 116 + * already a region reserved so we just increment *mem_start by size; 117 + * otherwise we call kmalloc. 118 + */ 119 + static void * prom_alloc(unsigned long size, unsigned long *mem_start) 120 + { 121 + unsigned long tmp; 122 + 123 + if (!mem_start) 124 + return kmalloc(size, GFP_KERNEL); 125 + 126 + tmp = *mem_start; 127 + *mem_start += size; 128 + return (void *)tmp; 129 + } 130 + 131 + /* 132 + * Find the device_node with a given phandle. 133 + */ 134 + static struct device_node * find_phandle(phandle ph) 135 + { 136 + struct device_node *np; 137 + 138 + for (np = allnodes; np != 0; np = np->allnext) 139 + if (np->linux_phandle == ph) 140 + return np; 141 + return NULL; 142 + } 143 + 144 + /* 145 + * Find the interrupt parent of a node. 146 + */ 147 + static struct device_node * __devinit intr_parent(struct device_node *p) 148 + { 149 + phandle *parp; 150 + 151 + parp = (phandle *) get_property(p, "interrupt-parent", NULL); 152 + if (parp == NULL) 153 + return p->parent; 154 + p = find_phandle(*parp); 155 + if (p != NULL) 156 + return p; 157 + /* 158 + * On a powermac booted with BootX, we don't get to know the 159 + * phandles for any nodes, so find_phandle will return NULL. 160 + * Fortunately these machines only have one interrupt controller 161 + * so there isn't in fact any ambiguity. -- paulus 162 + */ 163 + if (num_interrupt_controllers == 1) 164 + p = dflt_interrupt_controller; 165 + return p; 166 + } 167 + 168 + /* 169 + * Find out the size of each entry of the interrupts property 170 + * for a node. 171 + */ 172 + int __devinit prom_n_intr_cells(struct device_node *np) 173 + { 174 + struct device_node *p; 175 + unsigned int *icp; 176 + 177 + for (p = np; (p = intr_parent(p)) != NULL; ) { 178 + icp = (unsigned int *) 179 + get_property(p, "#interrupt-cells", NULL); 180 + if (icp != NULL) 181 + return *icp; 182 + if (get_property(p, "interrupt-controller", NULL) != NULL 183 + || get_property(p, "interrupt-map", NULL) != NULL) { 184 + printk("oops, node %s doesn't have #interrupt-cells\n", 185 + p->full_name); 186 + return 1; 187 + } 188 + } 189 + #ifdef DEBUG_IRQ 190 + printk("prom_n_intr_cells failed for %s\n", np->full_name); 191 + #endif 192 + return 1; 193 + } 194 + 195 + /* 196 + * Map an interrupt from a device up to the platform interrupt 197 + * descriptor. 198 + */ 199 + static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler, 200 + struct device_node *np, unsigned int *ints, 201 + int nintrc) 202 + { 203 + struct device_node *p, *ipar; 204 + unsigned int *imap, *imask, *ip; 205 + int i, imaplen, match; 206 + int newintrc = 0, newaddrc = 0; 207 + unsigned int *reg; 208 + int naddrc; 209 + 210 + reg = (unsigned int *) get_property(np, "reg", NULL); 211 + naddrc = prom_n_addr_cells(np); 212 + p = intr_parent(np); 213 + while (p != NULL) { 214 + if (get_property(p, "interrupt-controller", NULL) != NULL) 215 + /* this node is an interrupt controller, stop here */ 216 + break; 217 + imap = (unsigned int *) 218 + get_property(p, "interrupt-map", &imaplen); 219 + if (imap == NULL) { 220 + p = intr_parent(p); 221 + continue; 222 + } 223 + imask = (unsigned int *) 224 + get_property(p, "interrupt-map-mask", NULL); 225 + if (imask == NULL) { 226 + printk("oops, %s has interrupt-map but no mask\n", 227 + p->full_name); 228 + return 0; 229 + } 230 + imaplen /= sizeof(unsigned int); 231 + match = 0; 232 + ipar = NULL; 233 + while (imaplen > 0 && !match) { 234 + /* check the child-interrupt field */ 235 + match = 1; 236 + for (i = 0; i < naddrc && match; ++i) 237 + match = ((reg[i] ^ imap[i]) & imask[i]) == 0; 238 + for (; i < naddrc + nintrc && match; ++i) 239 + match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0; 240 + imap += naddrc + nintrc; 241 + imaplen -= naddrc + nintrc; 242 + /* grab the interrupt parent */ 243 + ipar = find_phandle((phandle) *imap++); 244 + --imaplen; 245 + if (ipar == NULL && num_interrupt_controllers == 1) 246 + /* cope with BootX not giving us phandles */ 247 + ipar = dflt_interrupt_controller; 248 + if (ipar == NULL) { 249 + printk("oops, no int parent %x in map of %s\n", 250 + imap[-1], p->full_name); 251 + return 0; 252 + } 253 + /* find the parent's # addr and intr cells */ 254 + ip = (unsigned int *) 255 + get_property(ipar, "#interrupt-cells", NULL); 256 + if (ip == NULL) { 257 + printk("oops, no #interrupt-cells on %s\n", 258 + ipar->full_name); 259 + return 0; 260 + } 261 + newintrc = *ip; 262 + ip = (unsigned int *) 263 + get_property(ipar, "#address-cells", NULL); 264 + newaddrc = (ip == NULL)? 0: *ip; 265 + imap += newaddrc + newintrc; 266 + imaplen -= newaddrc + newintrc; 267 + } 268 + if (imaplen < 0) { 269 + printk("oops, error decoding int-map on %s, len=%d\n", 270 + p->full_name, imaplen); 271 + return 0; 272 + } 273 + if (!match) { 274 + #ifdef DEBUG_IRQ 275 + printk("oops, no match in %s int-map for %s\n", 276 + p->full_name, np->full_name); 277 + #endif 278 + return 0; 279 + } 280 + p = ipar; 281 + naddrc = newaddrc; 282 + nintrc = newintrc; 283 + ints = imap - nintrc; 284 + reg = ints - naddrc; 285 + } 286 + if (p == NULL) { 287 + #ifdef DEBUG_IRQ 288 + printk("hmmm, int tree for %s doesn't have ctrler\n", 289 + np->full_name); 290 + #endif 291 + return 0; 292 + } 293 + *irq = ints; 294 + *ictrler = p; 295 + return nintrc; 296 + } 297 + 298 + static int __devinit finish_node_interrupts(struct device_node *np, 299 + unsigned long *mem_start, 300 + int measure_only) 301 + { 302 + unsigned int *ints; 303 + int intlen, intrcells, intrcount; 304 + int i, j, n; 305 + unsigned int *irq, virq; 306 + struct device_node *ic; 307 + 308 + ints = (unsigned int *) get_property(np, "interrupts", &intlen); 309 + if (ints == NULL) 310 + return 0; 311 + intrcells = prom_n_intr_cells(np); 312 + intlen /= intrcells * sizeof(unsigned int); 313 + 314 + np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); 315 + if (!np->intrs) 316 + return -ENOMEM; 317 + 318 + if (measure_only) 319 + return 0; 320 + 321 + intrcount = 0; 322 + for (i = 0; i < intlen; ++i, ints += intrcells) { 323 + n = map_interrupt(&irq, &ic, np, ints, intrcells); 324 + if (n <= 0) 325 + continue; 326 + 327 + /* don't map IRQ numbers under a cascaded 8259 controller */ 328 + if (ic && device_is_compatible(ic, "chrp,iic")) { 329 + np->intrs[intrcount].line = irq[0]; 330 + } else { 331 + #ifdef CONFIG_PPC64 332 + virq = virt_irq_create_mapping(irq[0]); 333 + if (virq == NO_IRQ) { 334 + printk(KERN_CRIT "Could not allocate interrupt" 335 + " number for %s\n", np->full_name); 336 + continue; 337 + } 338 + virq = irq_offset_up(virq); 339 + #else 340 + virq = irq[0]; 341 + #endif 342 + np->intrs[intrcount].line = virq; 343 + } 344 + 345 + #ifdef CONFIG_PPC64 346 + /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ 347 + if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) { 348 + char *name = get_property(ic->parent, "name", NULL); 349 + if (name && !strcmp(name, "u3")) 350 + np->intrs[intrcount].line += 128; 351 + else if (!(name && !strcmp(name, "mac-io"))) 352 + /* ignore other cascaded controllers, such as 353 + the k2-sata-root */ 354 + break; 355 + } 356 + #endif 357 + np->intrs[intrcount].sense = 1; 358 + if (n > 1) 359 + np->intrs[intrcount].sense = irq[1]; 360 + if (n > 2) { 361 + printk("hmmm, got %d intr cells for %s:", n, 362 + np->full_name); 363 + for (j = 0; j < n; ++j) 364 + printk(" %d", irq[j]); 365 + printk("\n"); 366 + } 367 + ++intrcount; 368 + } 369 + np->n_intrs = intrcount; 370 + 371 + return 0; 372 + } 373 + 374 + static int __devinit interpret_pci_props(struct device_node *np, 375 + unsigned long *mem_start, 376 + int naddrc, int nsizec, 377 + int measure_only) 378 + { 379 + struct address_range *adr; 380 + struct pci_reg_property *pci_addrs; 381 + int i, l, n_addrs; 382 + 383 + pci_addrs = (struct pci_reg_property *) 384 + get_property(np, "assigned-addresses", &l); 385 + if (!pci_addrs) 386 + return 0; 387 + 388 + n_addrs = l / sizeof(*pci_addrs); 389 + 390 + adr = prom_alloc(n_addrs * sizeof(*adr), mem_start); 391 + if (!adr) 392 + return -ENOMEM; 393 + 394 + if (measure_only) 395 + return 0; 396 + 397 + np->addrs = adr; 398 + np->n_addrs = n_addrs; 399 + 400 + for (i = 0; i < n_addrs; i++) { 401 + adr[i].space = pci_addrs[i].addr.a_hi; 402 + adr[i].address = pci_addrs[i].addr.a_lo | 403 + ((u64)pci_addrs[i].addr.a_mid << 32); 404 + adr[i].size = pci_addrs[i].size_lo; 405 + } 406 + 407 + return 0; 408 + } 409 + 410 + static int __init interpret_dbdma_props(struct device_node *np, 411 + unsigned long *mem_start, 412 + int naddrc, int nsizec, 413 + int measure_only) 414 + { 415 + struct reg_property32 *rp; 416 + struct address_range *adr; 417 + unsigned long base_address; 418 + int i, l; 419 + struct device_node *db; 420 + 421 + base_address = 0; 422 + if (!measure_only) { 423 + for (db = np->parent; db != NULL; db = db->parent) { 424 + if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) { 425 + base_address = db->addrs[0].address; 426 + break; 427 + } 428 + } 429 + } 430 + 431 + rp = (struct reg_property32 *) get_property(np, "reg", &l); 432 + if (rp != 0 && l >= sizeof(struct reg_property32)) { 433 + i = 0; 434 + adr = (struct address_range *) (*mem_start); 435 + while ((l -= sizeof(struct reg_property32)) >= 0) { 436 + if (!measure_only) { 437 + adr[i].space = 2; 438 + adr[i].address = rp[i].address + base_address; 439 + adr[i].size = rp[i].size; 440 + } 441 + ++i; 442 + } 443 + np->addrs = adr; 444 + np->n_addrs = i; 445 + (*mem_start) += i * sizeof(struct address_range); 446 + } 447 + 448 + return 0; 449 + } 450 + 451 + static int __init interpret_macio_props(struct device_node *np, 452 + unsigned long *mem_start, 453 + int naddrc, int nsizec, 454 + int measure_only) 455 + { 456 + struct reg_property32 *rp; 457 + struct address_range *adr; 458 + unsigned long base_address; 459 + int i, l; 460 + struct device_node *db; 461 + 462 + base_address = 0; 463 + if (!measure_only) { 464 + for (db = np->parent; db != NULL; db = db->parent) { 465 + if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) { 466 + base_address = db->addrs[0].address; 467 + break; 468 + } 469 + } 470 + } 471 + 472 + rp = (struct reg_property32 *) get_property(np, "reg", &l); 473 + if (rp != 0 && l >= sizeof(struct reg_property32)) { 474 + i = 0; 475 + adr = (struct address_range *) (*mem_start); 476 + while ((l -= sizeof(struct reg_property32)) >= 0) { 477 + if (!measure_only) { 478 + adr[i].space = 2; 479 + adr[i].address = rp[i].address + base_address; 480 + adr[i].size = rp[i].size; 481 + } 482 + ++i; 483 + } 484 + np->addrs = adr; 485 + np->n_addrs = i; 486 + (*mem_start) += i * sizeof(struct address_range); 487 + } 488 + 489 + return 0; 490 + } 491 + 492 + static int __init interpret_isa_props(struct device_node *np, 493 + unsigned long *mem_start, 494 + int naddrc, int nsizec, 495 + int measure_only) 496 + { 497 + struct isa_reg_property *rp; 498 + struct address_range *adr; 499 + int i, l; 500 + 501 + rp = (struct isa_reg_property *) get_property(np, "reg", &l); 502 + if (rp != 0 && l >= sizeof(struct isa_reg_property)) { 503 + i = 0; 504 + adr = (struct address_range *) (*mem_start); 505 + while ((l -= sizeof(struct isa_reg_property)) >= 0) { 506 + if (!measure_only) { 507 + adr[i].space = rp[i].space; 508 + adr[i].address = rp[i].address; 509 + adr[i].size = rp[i].size; 510 + } 511 + ++i; 512 + } 513 + np->addrs = adr; 514 + np->n_addrs = i; 515 + (*mem_start) += i * sizeof(struct address_range); 516 + } 517 + 518 + return 0; 519 + } 520 + 521 + static int __init interpret_root_props(struct device_node *np, 522 + unsigned long *mem_start, 523 + int naddrc, int nsizec, 524 + int measure_only) 525 + { 526 + struct address_range *adr; 527 + int i, l; 528 + unsigned int *rp; 529 + int rpsize = (naddrc + nsizec) * sizeof(unsigned int); 530 + 531 + rp = (unsigned int *) get_property(np, "reg", &l); 532 + if (rp != 0 && l >= rpsize) { 533 + i = 0; 534 + adr = (struct address_range *) (*mem_start); 535 + while ((l -= rpsize) >= 0) { 536 + if (!measure_only) { 537 + adr[i].space = 0; 538 + adr[i].address = rp[naddrc - 1]; 539 + adr[i].size = rp[naddrc + nsizec - 1]; 540 + } 541 + ++i; 542 + rp += naddrc + nsizec; 543 + } 544 + np->addrs = adr; 545 + np->n_addrs = i; 546 + (*mem_start) += i * sizeof(struct address_range); 547 + } 548 + 549 + return 0; 550 + } 551 + 552 + static int __devinit finish_node(struct device_node *np, 553 + unsigned long *mem_start, 554 + interpret_func *ifunc, 555 + int naddrc, int nsizec, 556 + int measure_only) 557 + { 558 + struct device_node *child; 559 + int *ip, rc = 0; 560 + 561 + /* get the device addresses and interrupts */ 562 + if (ifunc != NULL) 563 + rc = ifunc(np, mem_start, naddrc, nsizec, measure_only); 564 + if (rc) 565 + goto out; 566 + 567 + rc = finish_node_interrupts(np, mem_start, measure_only); 568 + if (rc) 569 + goto out; 570 + 571 + /* Look for #address-cells and #size-cells properties. */ 572 + ip = (int *) get_property(np, "#address-cells", NULL); 573 + if (ip != NULL) 574 + naddrc = *ip; 575 + ip = (int *) get_property(np, "#size-cells", NULL); 576 + if (ip != NULL) 577 + nsizec = *ip; 578 + 579 + if (!strcmp(np->name, "device-tree") || np->parent == NULL) 580 + ifunc = interpret_root_props; 581 + else if (np->type == 0) 582 + ifunc = NULL; 583 + else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci")) 584 + ifunc = interpret_pci_props; 585 + else if (!strcmp(np->type, "dbdma")) 586 + ifunc = interpret_dbdma_props; 587 + else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props) 588 + ifunc = interpret_macio_props; 589 + else if (!strcmp(np->type, "isa")) 590 + ifunc = interpret_isa_props; 591 + else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3")) 592 + ifunc = interpret_root_props; 593 + else if (!((ifunc == interpret_dbdma_props 594 + || ifunc == interpret_macio_props) 595 + && (!strcmp(np->type, "escc") 596 + || !strcmp(np->type, "media-bay")))) 597 + ifunc = NULL; 598 + 599 + for (child = np->child; child != NULL; child = child->sibling) { 600 + rc = finish_node(child, mem_start, ifunc, 601 + naddrc, nsizec, measure_only); 602 + if (rc) 603 + goto out; 604 + } 605 + out: 606 + return rc; 607 + } 608 + 609 + static void __init scan_interrupt_controllers(void) 610 + { 611 + struct device_node *np; 612 + int n = 0; 613 + char *name, *ic; 614 + int iclen; 615 + 616 + for (np = allnodes; np != NULL; np = np->allnext) { 617 + ic = get_property(np, "interrupt-controller", &iclen); 618 + name = get_property(np, "name", NULL); 619 + /* checking iclen makes sure we don't get a false 620 + match on /chosen.interrupt_controller */ 621 + if ((name != NULL 622 + && strcmp(name, "interrupt-controller") == 0) 623 + || (ic != NULL && iclen == 0 624 + && strcmp(name, "AppleKiwi"))) { 625 + if (n == 0) 626 + dflt_interrupt_controller = np; 627 + ++n; 628 + } 629 + } 630 + num_interrupt_controllers = n; 631 + } 632 + 633 + /** 634 + * finish_device_tree is called once things are running normally 635 + * (i.e. with text and data mapped to the address they were linked at). 636 + * It traverses the device tree and fills in some of the additional, 637 + * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt 638 + * mapping is also initialized at this point. 639 + */ 640 + void __init finish_device_tree(void) 641 + { 642 + unsigned long start, end, size = 0; 643 + 644 + DBG(" -> finish_device_tree\n"); 645 + 646 + #ifdef CONFIG_PPC64 647 + /* Initialize virtual IRQ map */ 648 + virt_irq_init(); 649 + #endif 650 + scan_interrupt_controllers(); 651 + 652 + /* 653 + * Finish device-tree (pre-parsing some properties etc...) 654 + * We do this in 2 passes. One with "measure_only" set, which 655 + * will only measure the amount of memory needed, then we can 656 + * allocate that memory, and call finish_node again. However, 657 + * we must be careful as most routines will fail nowadays when 658 + * prom_alloc() returns 0, so we must make sure our first pass 659 + * doesn't start at 0. We pre-initialize size to 16 for that 660 + * reason and then remove those additional 16 bytes 661 + */ 662 + size = 16; 663 + finish_node(allnodes, &size, NULL, 0, 0, 1); 664 + size -= 16; 665 + end = start = (unsigned long) __va(lmb_alloc(size, 128)); 666 + finish_node(allnodes, &end, NULL, 0, 0, 0); 667 + BUG_ON(end != start + size); 668 + 669 + DBG(" <- finish_device_tree\n"); 670 + } 671 + 672 + static inline char *find_flat_dt_string(u32 offset) 673 + { 674 + return ((char *)initial_boot_params) + 675 + initial_boot_params->off_dt_strings + offset; 676 + } 677 + 678 + /** 679 + * This function is used to scan the flattened device-tree, it is 680 + * used to extract the memory informations at boot before we can 681 + * unflatten the tree 682 + */ 683 + static int __init scan_flat_dt(int (*it)(unsigned long node, 684 + const char *uname, int depth, 685 + void *data), 686 + void *data) 687 + { 688 + unsigned long p = ((unsigned long)initial_boot_params) + 689 + initial_boot_params->off_dt_struct; 690 + int rc = 0; 691 + int depth = -1; 692 + 693 + do { 694 + u32 tag = *((u32 *)p); 695 + char *pathp; 696 + 697 + p += 4; 698 + if (tag == OF_DT_END_NODE) { 699 + depth --; 700 + continue; 701 + } 702 + if (tag == OF_DT_NOP) 703 + continue; 704 + if (tag == OF_DT_END) 705 + break; 706 + if (tag == OF_DT_PROP) { 707 + u32 sz = *((u32 *)p); 708 + p += 8; 709 + if (initial_boot_params->version < 0x10) 710 + p = _ALIGN(p, sz >= 8 ? 8 : 4); 711 + p += sz; 712 + p = _ALIGN(p, 4); 713 + continue; 714 + } 715 + if (tag != OF_DT_BEGIN_NODE) { 716 + printk(KERN_WARNING "Invalid tag %x scanning flattened" 717 + " device tree !\n", tag); 718 + return -EINVAL; 719 + } 720 + depth++; 721 + pathp = (char *)p; 722 + p = _ALIGN(p + strlen(pathp) + 1, 4); 723 + if ((*pathp) == '/') { 724 + char *lp, *np; 725 + for (lp = NULL, np = pathp; *np; np++) 726 + if ((*np) == '/') 727 + lp = np+1; 728 + if (lp != NULL) 729 + pathp = lp; 730 + } 731 + rc = it(p, pathp, depth, data); 732 + if (rc != 0) 733 + break; 734 + } while(1); 735 + 736 + return rc; 737 + } 738 + 739 + /** 740 + * This function can be used within scan_flattened_dt callback to get 741 + * access to properties 742 + */ 743 + static void* __init get_flat_dt_prop(unsigned long node, const char *name, 744 + unsigned long *size) 745 + { 746 + unsigned long p = node; 747 + 748 + do { 749 + u32 tag = *((u32 *)p); 750 + u32 sz, noff; 751 + const char *nstr; 752 + 753 + p += 4; 754 + if (tag == OF_DT_NOP) 755 + continue; 756 + if (tag != OF_DT_PROP) 757 + return NULL; 758 + 759 + sz = *((u32 *)p); 760 + noff = *((u32 *)(p + 4)); 761 + p += 8; 762 + if (initial_boot_params->version < 0x10) 763 + p = _ALIGN(p, sz >= 8 ? 8 : 4); 764 + 765 + nstr = find_flat_dt_string(noff); 766 + if (nstr == NULL) { 767 + printk(KERN_WARNING "Can't find property index" 768 + " name !\n"); 769 + return NULL; 770 + } 771 + if (strcmp(name, nstr) == 0) { 772 + if (size) 773 + *size = sz; 774 + return (void *)p; 775 + } 776 + p += sz; 777 + p = _ALIGN(p, 4); 778 + } while(1); 779 + } 780 + 781 + static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, 782 + unsigned long align) 783 + { 784 + void *res; 785 + 786 + *mem = _ALIGN(*mem, align); 787 + res = (void *)*mem; 788 + *mem += size; 789 + 790 + return res; 791 + } 792 + 793 + static unsigned long __init unflatten_dt_node(unsigned long mem, 794 + unsigned long *p, 795 + struct device_node *dad, 796 + struct device_node ***allnextpp, 797 + unsigned long fpsize) 798 + { 799 + struct device_node *np; 800 + struct property *pp, **prev_pp = NULL; 801 + char *pathp; 802 + u32 tag; 803 + unsigned int l, allocl; 804 + int has_name = 0; 805 + int new_format = 0; 806 + 807 + tag = *((u32 *)(*p)); 808 + if (tag != OF_DT_BEGIN_NODE) { 809 + printk("Weird tag at start of node: %x\n", tag); 810 + return mem; 811 + } 812 + *p += 4; 813 + pathp = (char *)*p; 814 + l = allocl = strlen(pathp) + 1; 815 + *p = _ALIGN(*p + l, 4); 816 + 817 + /* version 0x10 has a more compact unit name here instead of the full 818 + * path. we accumulate the full path size using "fpsize", we'll rebuild 819 + * it later. We detect this because the first character of the name is 820 + * not '/'. 821 + */ 822 + if ((*pathp) != '/') { 823 + new_format = 1; 824 + if (fpsize == 0) { 825 + /* root node: special case. fpsize accounts for path 826 + * plus terminating zero. root node only has '/', so 827 + * fpsize should be 2, but we want to avoid the first 828 + * level nodes to have two '/' so we use fpsize 1 here 829 + */ 830 + fpsize = 1; 831 + allocl = 2; 832 + } else { 833 + /* account for '/' and path size minus terminal 0 834 + * already in 'l' 835 + */ 836 + fpsize += l; 837 + allocl = fpsize; 838 + } 839 + } 840 + 841 + 842 + np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, 843 + __alignof__(struct device_node)); 844 + if (allnextpp) { 845 + memset(np, 0, sizeof(*np)); 846 + np->full_name = ((char*)np) + sizeof(struct device_node); 847 + if (new_format) { 848 + char *p = np->full_name; 849 + /* rebuild full path for new format */ 850 + if (dad && dad->parent) { 851 + strcpy(p, dad->full_name); 852 + #ifdef DEBUG 853 + if ((strlen(p) + l + 1) != allocl) { 854 + DBG("%s: p: %d, l: %d, a: %d\n", 855 + pathp, strlen(p), l, allocl); 856 + } 857 + #endif 858 + p += strlen(p); 859 + } 860 + *(p++) = '/'; 861 + memcpy(p, pathp, l); 862 + } else 863 + memcpy(np->full_name, pathp, l); 864 + prev_pp = &np->properties; 865 + **allnextpp = np; 866 + *allnextpp = &np->allnext; 867 + if (dad != NULL) { 868 + np->parent = dad; 869 + /* we temporarily use the next field as `last_child'*/ 870 + if (dad->next == 0) 871 + dad->child = np; 872 + else 873 + dad->next->sibling = np; 874 + dad->next = np; 875 + } 876 + kref_init(&np->kref); 877 + } 878 + while(1) { 879 + u32 sz, noff; 880 + char *pname; 881 + 882 + tag = *((u32 *)(*p)); 883 + if (tag == OF_DT_NOP) { 884 + *p += 4; 885 + continue; 886 + } 887 + if (tag != OF_DT_PROP) 888 + break; 889 + *p += 4; 890 + sz = *((u32 *)(*p)); 891 + noff = *((u32 *)((*p) + 4)); 892 + *p += 8; 893 + if (initial_boot_params->version < 0x10) 894 + *p = _ALIGN(*p, sz >= 8 ? 8 : 4); 895 + 896 + pname = find_flat_dt_string(noff); 897 + if (pname == NULL) { 898 + printk("Can't find property name in list !\n"); 899 + break; 900 + } 901 + if (strcmp(pname, "name") == 0) 902 + has_name = 1; 903 + l = strlen(pname) + 1; 904 + pp = unflatten_dt_alloc(&mem, sizeof(struct property), 905 + __alignof__(struct property)); 906 + if (allnextpp) { 907 + if (strcmp(pname, "linux,phandle") == 0) { 908 + np->node = *((u32 *)*p); 909 + if (np->linux_phandle == 0) 910 + np->linux_phandle = np->node; 911 + } 912 + if (strcmp(pname, "ibm,phandle") == 0) 913 + np->linux_phandle = *((u32 *)*p); 914 + pp->name = pname; 915 + pp->length = sz; 916 + pp->value = (void *)*p; 917 + *prev_pp = pp; 918 + prev_pp = &pp->next; 919 + } 920 + *p = _ALIGN((*p) + sz, 4); 921 + } 922 + /* with version 0x10 we may not have the name property, recreate 923 + * it here from the unit name if absent 924 + */ 925 + if (!has_name) { 926 + char *p = pathp, *ps = pathp, *pa = NULL; 927 + int sz; 928 + 929 + while (*p) { 930 + if ((*p) == '@') 931 + pa = p; 932 + if ((*p) == '/') 933 + ps = p + 1; 934 + p++; 935 + } 936 + if (pa < ps) 937 + pa = p; 938 + sz = (pa - ps) + 1; 939 + pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, 940 + __alignof__(struct property)); 941 + if (allnextpp) { 942 + pp->name = "name"; 943 + pp->length = sz; 944 + pp->value = (unsigned char *)(pp + 1); 945 + *prev_pp = pp; 946 + prev_pp = &pp->next; 947 + memcpy(pp->value, ps, sz - 1); 948 + ((char *)pp->value)[sz - 1] = 0; 949 + DBG("fixed up name for %s -> %s\n", pathp, pp->value); 950 + } 951 + } 952 + if (allnextpp) { 953 + *prev_pp = NULL; 954 + np->name = get_property(np, "name", NULL); 955 + np->type = get_property(np, "device_type", NULL); 956 + 957 + if (!np->name) 958 + np->name = "<NULL>"; 959 + if (!np->type) 960 + np->type = "<NULL>"; 961 + } 962 + while (tag == OF_DT_BEGIN_NODE) { 963 + mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); 964 + tag = *((u32 *)(*p)); 965 + } 966 + if (tag != OF_DT_END_NODE) { 967 + printk("Weird tag at end of node: %x\n", tag); 968 + return mem; 969 + } 970 + *p += 4; 971 + return mem; 972 + } 973 + 974 + 975 + /** 976 + * unflattens the device-tree passed by the firmware, creating the 977 + * tree of struct device_node. It also fills the "name" and "type" 978 + * pointers of the nodes so the normal device-tree walking functions 979 + * can be used (this used to be done by finish_device_tree) 980 + */ 981 + void __init unflatten_device_tree(void) 982 + { 983 + unsigned long start, mem, size; 984 + struct device_node **allnextp = &allnodes; 985 + char *p = NULL; 986 + int l = 0; 987 + 988 + DBG(" -> unflatten_device_tree()\n"); 989 + 990 + /* First pass, scan for size */ 991 + start = ((unsigned long)initial_boot_params) + 992 + initial_boot_params->off_dt_struct; 993 + size = unflatten_dt_node(0, &start, NULL, NULL, 0); 994 + size = (size | 3) + 1; 995 + 996 + DBG(" size is %lx, allocating...\n", size); 997 + 998 + /* Allocate memory for the expanded device tree */ 999 + mem = lmb_alloc(size + 4, __alignof__(struct device_node)); 1000 + if (!mem) { 1001 + DBG("Couldn't allocate memory with lmb_alloc()!\n"); 1002 + panic("Couldn't allocate memory with lmb_alloc()!\n"); 1003 + } 1004 + mem = (unsigned long) __va(mem); 1005 + 1006 + ((u32 *)mem)[size / 4] = 0xdeadbeef; 1007 + 1008 + DBG(" unflattening %lx...\n", mem); 1009 + 1010 + /* Second pass, do actual unflattening */ 1011 + start = ((unsigned long)initial_boot_params) + 1012 + initial_boot_params->off_dt_struct; 1013 + unflatten_dt_node(mem, &start, NULL, &allnextp, 0); 1014 + if (*((u32 *)start) != OF_DT_END) 1015 + printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start)); 1016 + if (((u32 *)mem)[size / 4] != 0xdeadbeef) 1017 + printk(KERN_WARNING "End of tree marker overwritten: %08x\n", 1018 + ((u32 *)mem)[size / 4] ); 1019 + *allnextp = NULL; 1020 + 1021 + /* Get pointer to OF "/chosen" node for use everywhere */ 1022 + of_chosen = of_find_node_by_path("/chosen"); 1023 + 1024 + /* Retreive command line */ 1025 + if (of_chosen != NULL) { 1026 + p = (char *)get_property(of_chosen, "bootargs", &l); 1027 + if (p != NULL && l > 0) 1028 + strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE)); 1029 + } 1030 + #ifdef CONFIG_CMDLINE 1031 + if (l == 0 || (l == 1 && (*p) == 0)) 1032 + strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); 1033 + #endif /* CONFIG_CMDLINE */ 1034 + 1035 + DBG("Command line is: %s\n", cmd_line); 1036 + 1037 + DBG(" <- unflatten_device_tree()\n"); 1038 + } 1039 + 1040 + 1041 + static int __init early_init_dt_scan_cpus(unsigned long node, 1042 + const char *uname, int depth, void *data) 1043 + { 1044 + char *type = get_flat_dt_prop(node, "device_type", NULL); 1045 + u32 *prop; 1046 + unsigned long size = 0; 1047 + 1048 + /* We are scanning "cpu" nodes only */ 1049 + if (type == NULL || strcmp(type, "cpu") != 0) 1050 + return 0; 1051 + 1052 + #ifdef CONFIG_PPC_PSERIES 1053 + /* On LPAR, look for the first ibm,pft-size property for the hash table size 1054 + */ 1055 + if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) { 1056 + u32 *pft_size; 1057 + pft_size = get_flat_dt_prop(node, "ibm,pft-size", NULL); 1058 + if (pft_size != NULL) { 1059 + /* pft_size[0] is the NUMA CEC cookie */ 1060 + ppc64_pft_size = pft_size[1]; 1061 + } 1062 + } 1063 + #endif 1064 + 1065 + #ifdef CONFIG_PPC64 1066 + if (initial_boot_params && initial_boot_params->version >= 2) { 1067 + /* version 2 of the kexec param format adds the phys cpuid 1068 + * of booted proc. 1069 + */ 1070 + boot_cpuid_phys = initial_boot_params->boot_cpuid_phys; 1071 + boot_cpuid = 0; 1072 + } else { 1073 + /* Check if it's the boot-cpu, set it's hw index in paca now */ 1074 + if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) { 1075 + u32 *prop = get_flat_dt_prop(node, "reg", NULL); 1076 + set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop); 1077 + boot_cpuid_phys = get_hard_smp_processor_id(0); 1078 + } 1079 + } 1080 + #endif 1081 + 1082 + #ifdef CONFIG_ALTIVEC 1083 + /* Check if we have a VMX and eventually update CPU features */ 1084 + prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", &size); 1085 + if (prop && (*prop) > 0) { 1086 + cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; 1087 + cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; 1088 + } 1089 + 1090 + /* Same goes for Apple's "altivec" property */ 1091 + prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL); 1092 + if (prop) { 1093 + cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; 1094 + cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; 1095 + } 1096 + #endif /* CONFIG_ALTIVEC */ 1097 + 1098 + #ifdef CONFIG_PPC_PSERIES 1099 + /* 1100 + * Check for an SMT capable CPU and set the CPU feature. We do 1101 + * this by looking at the size of the ibm,ppc-interrupt-server#s 1102 + * property 1103 + */ 1104 + prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", 1105 + &size); 1106 + cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; 1107 + if (prop && ((size / sizeof(u32)) > 1)) 1108 + cur_cpu_spec->cpu_features |= CPU_FTR_SMT; 1109 + #endif 1110 + 1111 + return 0; 1112 + } 1113 + 1114 + static int __init early_init_dt_scan_chosen(unsigned long node, 1115 + const char *uname, int depth, void *data) 1116 + { 1117 + u32 *prop; 1118 + unsigned long *lprop; 1119 + 1120 + DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname); 1121 + 1122 + if (depth != 1 || strcmp(uname, "chosen") != 0) 1123 + return 0; 1124 + 1125 + /* get platform type */ 1126 + prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL); 1127 + if (prop == NULL) 1128 + return 0; 1129 + #ifdef CONFIG_PPC64 1130 + systemcfg->platform = *prop; 1131 + #else 1132 + _machine = *prop; 1133 + #endif 1134 + 1135 + #ifdef CONFIG_PPC64 1136 + /* check if iommu is forced on or off */ 1137 + if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) 1138 + iommu_is_off = 1; 1139 + if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL) 1140 + iommu_force_on = 1; 1141 + #endif 1142 + 1143 + lprop = get_flat_dt_prop(node, "linux,memory-limit", NULL); 1144 + if (lprop) 1145 + memory_limit = *lprop; 1146 + 1147 + #ifdef CONFIG_PPC64 1148 + lprop = get_flat_dt_prop(node, "linux,tce-alloc-start", NULL); 1149 + if (lprop) 1150 + tce_alloc_start = *lprop; 1151 + lprop = get_flat_dt_prop(node, "linux,tce-alloc-end", NULL); 1152 + if (lprop) 1153 + tce_alloc_end = *lprop; 1154 + #endif 1155 + 1156 + #ifdef CONFIG_PPC_RTAS 1157 + /* To help early debugging via the front panel, we retreive a minimal 1158 + * set of RTAS infos now if available 1159 + */ 1160 + { 1161 + u64 *basep, *entryp; 1162 + 1163 + basep = get_flat_dt_prop(node, "linux,rtas-base", NULL); 1164 + entryp = get_flat_dt_prop(node, "linux,rtas-entry", NULL); 1165 + prop = get_flat_dt_prop(node, "linux,rtas-size", NULL); 1166 + if (basep && entryp && prop) { 1167 + rtas.base = *basep; 1168 + rtas.entry = *entryp; 1169 + rtas.size = *prop; 1170 + } 1171 + } 1172 + #endif /* CONFIG_PPC_RTAS */ 1173 + 1174 + /* break now */ 1175 + return 1; 1176 + } 1177 + 1178 + static int __init early_init_dt_scan_root(unsigned long node, 1179 + const char *uname, int depth, void *data) 1180 + { 1181 + u32 *prop; 1182 + 1183 + if (depth != 0) 1184 + return 0; 1185 + 1186 + prop = get_flat_dt_prop(node, "#size-cells", NULL); 1187 + dt_root_size_cells = (prop == NULL) ? 1 : *prop; 1188 + DBG("dt_root_size_cells = %x\n", dt_root_size_cells); 1189 + 1190 + prop = get_flat_dt_prop(node, "#address-cells", NULL); 1191 + dt_root_addr_cells = (prop == NULL) ? 2 : *prop; 1192 + DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells); 1193 + 1194 + /* break now */ 1195 + return 1; 1196 + } 1197 + 1198 + static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) 1199 + { 1200 + cell_t *p = *cellp; 1201 + unsigned long r; 1202 + 1203 + /* Ignore more than 2 cells */ 1204 + while (s > sizeof(unsigned long) / 4) { 1205 + p++; 1206 + s--; 1207 + } 1208 + r = *p++; 1209 + #ifdef CONFIG_PPC64 1210 + if (s > 1) { 1211 + r <<= 32; 1212 + r |= *(p++); 1213 + s--; 1214 + } 1215 + #endif 1216 + 1217 + *cellp = p; 1218 + return r; 1219 + } 1220 + 1221 + 1222 + static int __init early_init_dt_scan_memory(unsigned long node, 1223 + const char *uname, int depth, void *data) 1224 + { 1225 + char *type = get_flat_dt_prop(node, "device_type", NULL); 1226 + cell_t *reg, *endp; 1227 + unsigned long l; 1228 + 1229 + /* We are scanning "memory" nodes only */ 1230 + if (type == NULL || strcmp(type, "memory") != 0) 1231 + return 0; 1232 + 1233 + reg = (cell_t *)get_flat_dt_prop(node, "reg", &l); 1234 + if (reg == NULL) 1235 + return 0; 1236 + 1237 + endp = reg + (l / sizeof(cell_t)); 1238 + 1239 + DBG("memory scan node %s ..., reg size %ld, data: %x %x %x %x, ...\n", 1240 + uname, l, reg[0], reg[1], reg[2], reg[3]); 1241 + 1242 + while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { 1243 + unsigned long base, size; 1244 + 1245 + base = dt_mem_next_cell(dt_root_addr_cells, &reg); 1246 + size = dt_mem_next_cell(dt_root_size_cells, &reg); 1247 + 1248 + if (size == 0) 1249 + continue; 1250 + DBG(" - %lx , %lx\n", base, size); 1251 + #ifdef CONFIG_PPC64 1252 + if (iommu_is_off) { 1253 + if (base >= 0x80000000ul) 1254 + continue; 1255 + if ((base + size) > 0x80000000ul) 1256 + size = 0x80000000ul - base; 1257 + } 1258 + #endif 1259 + lmb_add(base, size); 1260 + } 1261 + return 0; 1262 + } 1263 + 1264 + static void __init early_reserve_mem(void) 1265 + { 1266 + unsigned long base, size; 1267 + unsigned long *reserve_map; 1268 + 1269 + reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) + 1270 + initial_boot_params->off_mem_rsvmap); 1271 + while (1) { 1272 + base = *(reserve_map++); 1273 + size = *(reserve_map++); 1274 + if (size == 0) 1275 + break; 1276 + DBG("reserving: %lx -> %lx\n", base, size); 1277 + lmb_reserve(base, size); 1278 + } 1279 + 1280 + #if 0 1281 + DBG("memory reserved, lmbs :\n"); 1282 + lmb_dump_all(); 1283 + #endif 1284 + } 1285 + 1286 + void __init early_init_devtree(void *params) 1287 + { 1288 + DBG(" -> early_init_devtree()\n"); 1289 + 1290 + /* Setup flat device-tree pointer */ 1291 + initial_boot_params = params; 1292 + 1293 + /* Retrieve various informations from the /chosen node of the 1294 + * device-tree, including the platform type, initrd location and 1295 + * size, TCE reserve, and more ... 1296 + */ 1297 + scan_flat_dt(early_init_dt_scan_chosen, NULL); 1298 + 1299 + /* Scan memory nodes and rebuild LMBs */ 1300 + lmb_init(); 1301 + scan_flat_dt(early_init_dt_scan_root, NULL); 1302 + scan_flat_dt(early_init_dt_scan_memory, NULL); 1303 + lmb_enforce_memory_limit(memory_limit); 1304 + lmb_analyze(); 1305 + #ifdef CONFIG_PPC64 1306 + systemcfg->physicalMemorySize = lmb_phys_mem_size(); 1307 + #endif 1308 + lmb_reserve(0, __pa(klimit)); 1309 + 1310 + DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); 1311 + 1312 + /* Reserve LMB regions used by kernel, initrd, dt, etc... */ 1313 + early_reserve_mem(); 1314 + 1315 + DBG("Scanning CPUs ...\n"); 1316 + 1317 + /* Retreive hash table size from flattened tree plus other 1318 + * CPU related informations (altivec support, boot CPU ID, ...) 1319 + */ 1320 + scan_flat_dt(early_init_dt_scan_cpus, NULL); 1321 + 1322 + #ifdef CONFIG_PPC_PSERIES 1323 + /* If hash size wasn't obtained above, we calculate it now based on 1324 + * the total RAM size 1325 + */ 1326 + if (ppc64_pft_size == 0) { 1327 + unsigned long rnd_mem_size, pteg_count; 1328 + 1329 + /* round mem_size up to next power of 2 */ 1330 + rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize); 1331 + if (rnd_mem_size < systemcfg->physicalMemorySize) 1332 + rnd_mem_size <<= 1; 1333 + 1334 + /* # pages / 2 */ 1335 + pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11); 1336 + 1337 + ppc64_pft_size = __ilog2(pteg_count << 7); 1338 + } 1339 + 1340 + DBG("Hash pftSize: %x\n", (int)ppc64_pft_size); 1341 + #endif 1342 + DBG(" <- early_init_devtree()\n"); 1343 + } 1344 + 1345 + #undef printk 1346 + 1347 + int 1348 + prom_n_addr_cells(struct device_node* np) 1349 + { 1350 + int* ip; 1351 + do { 1352 + if (np->parent) 1353 + np = np->parent; 1354 + ip = (int *) get_property(np, "#address-cells", NULL); 1355 + if (ip != NULL) 1356 + return *ip; 1357 + } while (np->parent); 1358 + /* No #address-cells property for the root node, default to 1 */ 1359 + return 1; 1360 + } 1361 + 1362 + int 1363 + prom_n_size_cells(struct device_node* np) 1364 + { 1365 + int* ip; 1366 + do { 1367 + if (np->parent) 1368 + np = np->parent; 1369 + ip = (int *) get_property(np, "#size-cells", NULL); 1370 + if (ip != NULL) 1371 + return *ip; 1372 + } while (np->parent); 1373 + /* No #size-cells property for the root node, default to 1 */ 1374 + return 1; 1375 + } 1376 + 1377 + /** 1378 + * Work out the sense (active-low level / active-high edge) 1379 + * of each interrupt from the device tree. 1380 + */ 1381 + void __init prom_get_irq_senses(unsigned char *senses, int off, int max) 1382 + { 1383 + struct device_node *np; 1384 + int i, j; 1385 + 1386 + /* default to level-triggered */ 1387 + memset(senses, 1, max - off); 1388 + 1389 + for (np = allnodes; np != 0; np = np->allnext) { 1390 + for (j = 0; j < np->n_intrs; j++) { 1391 + i = np->intrs[j].line; 1392 + if (i >= off && i < max) 1393 + senses[i-off] = np->intrs[j].sense ? 1394 + IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE : 1395 + IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE; 1396 + } 1397 + } 1398 + } 1399 + 1400 + /** 1401 + * Construct and return a list of the device_nodes with a given name. 1402 + */ 1403 + struct device_node *find_devices(const char *name) 1404 + { 1405 + struct device_node *head, **prevp, *np; 1406 + 1407 + prevp = &head; 1408 + for (np = allnodes; np != 0; np = np->allnext) { 1409 + if (np->name != 0 && strcasecmp(np->name, name) == 0) { 1410 + *prevp = np; 1411 + prevp = &np->next; 1412 + } 1413 + } 1414 + *prevp = NULL; 1415 + return head; 1416 + } 1417 + EXPORT_SYMBOL(find_devices); 1418 + 1419 + /** 1420 + * Construct and return a list of the device_nodes with a given type. 1421 + */ 1422 + struct device_node *find_type_devices(const char *type) 1423 + { 1424 + struct device_node *head, **prevp, *np; 1425 + 1426 + prevp = &head; 1427 + for (np = allnodes; np != 0; np = np->allnext) { 1428 + if (np->type != 0 && strcasecmp(np->type, type) == 0) { 1429 + *prevp = np; 1430 + prevp = &np->next; 1431 + } 1432 + } 1433 + *prevp = NULL; 1434 + return head; 1435 + } 1436 + EXPORT_SYMBOL(find_type_devices); 1437 + 1438 + /** 1439 + * Returns all nodes linked together 1440 + */ 1441 + struct device_node *find_all_nodes(void) 1442 + { 1443 + struct device_node *head, **prevp, *np; 1444 + 1445 + prevp = &head; 1446 + for (np = allnodes; np != 0; np = np->allnext) { 1447 + *prevp = np; 1448 + prevp = &np->next; 1449 + } 1450 + *prevp = NULL; 1451 + return head; 1452 + } 1453 + EXPORT_SYMBOL(find_all_nodes); 1454 + 1455 + /** Checks if the given "compat" string matches one of the strings in 1456 + * the device's "compatible" property 1457 + */ 1458 + int device_is_compatible(struct device_node *device, const char *compat) 1459 + { 1460 + const char* cp; 1461 + int cplen, l; 1462 + 1463 + cp = (char *) get_property(device, "compatible", &cplen); 1464 + if (cp == NULL) 1465 + return 0; 1466 + while (cplen > 0) { 1467 + if (strncasecmp(cp, compat, strlen(compat)) == 0) 1468 + return 1; 1469 + l = strlen(cp) + 1; 1470 + cp += l; 1471 + cplen -= l; 1472 + } 1473 + 1474 + return 0; 1475 + } 1476 + EXPORT_SYMBOL(device_is_compatible); 1477 + 1478 + 1479 + /** 1480 + * Indicates whether the root node has a given value in its 1481 + * compatible property. 1482 + */ 1483 + int machine_is_compatible(const char *compat) 1484 + { 1485 + struct device_node *root; 1486 + int rc = 0; 1487 + 1488 + root = of_find_node_by_path("/"); 1489 + if (root) { 1490 + rc = device_is_compatible(root, compat); 1491 + of_node_put(root); 1492 + } 1493 + return rc; 1494 + } 1495 + EXPORT_SYMBOL(machine_is_compatible); 1496 + 1497 + /** 1498 + * Construct and return a list of the device_nodes with a given type 1499 + * and compatible property. 1500 + */ 1501 + struct device_node *find_compatible_devices(const char *type, 1502 + const char *compat) 1503 + { 1504 + struct device_node *head, **prevp, *np; 1505 + 1506 + prevp = &head; 1507 + for (np = allnodes; np != 0; np = np->allnext) { 1508 + if (type != NULL 1509 + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) 1510 + continue; 1511 + if (device_is_compatible(np, compat)) { 1512 + *prevp = np; 1513 + prevp = &np->next; 1514 + } 1515 + } 1516 + *prevp = NULL; 1517 + return head; 1518 + } 1519 + EXPORT_SYMBOL(find_compatible_devices); 1520 + 1521 + /** 1522 + * Find the device_node with a given full_name. 1523 + */ 1524 + struct device_node *find_path_device(const char *path) 1525 + { 1526 + struct device_node *np; 1527 + 1528 + for (np = allnodes; np != 0; np = np->allnext) 1529 + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) 1530 + return np; 1531 + return NULL; 1532 + } 1533 + EXPORT_SYMBOL(find_path_device); 1534 + 1535 + /******* 1536 + * 1537 + * New implementation of the OF "find" APIs, return a refcounted 1538 + * object, call of_node_put() when done. The device tree and list 1539 + * are protected by a rw_lock. 1540 + * 1541 + * Note that property management will need some locking as well, 1542 + * this isn't dealt with yet. 1543 + * 1544 + *******/ 1545 + 1546 + /** 1547 + * of_find_node_by_name - Find a node by its "name" property 1548 + * @from: The node to start searching from or NULL, the node 1549 + * you pass will not be searched, only the next one 1550 + * will; typically, you pass what the previous call 1551 + * returned. of_node_put() will be called on it 1552 + * @name: The name string to match against 1553 + * 1554 + * Returns a node pointer with refcount incremented, use 1555 + * of_node_put() on it when done. 1556 + */ 1557 + struct device_node *of_find_node_by_name(struct device_node *from, 1558 + const char *name) 1559 + { 1560 + struct device_node *np; 1561 + 1562 + read_lock(&devtree_lock); 1563 + np = from ? from->allnext : allnodes; 1564 + for (; np != 0; np = np->allnext) 1565 + if (np->name != 0 && strcasecmp(np->name, name) == 0 1566 + && of_node_get(np)) 1567 + break; 1568 + if (from) 1569 + of_node_put(from); 1570 + read_unlock(&devtree_lock); 1571 + return np; 1572 + } 1573 + EXPORT_SYMBOL(of_find_node_by_name); 1574 + 1575 + /** 1576 + * of_find_node_by_type - Find a node by its "device_type" property 1577 + * @from: The node to start searching from or NULL, the node 1578 + * you pass will not be searched, only the next one 1579 + * will; typically, you pass what the previous call 1580 + * returned. of_node_put() will be called on it 1581 + * @name: The type string to match against 1582 + * 1583 + * Returns a node pointer with refcount incremented, use 1584 + * of_node_put() on it when done. 1585 + */ 1586 + struct device_node *of_find_node_by_type(struct device_node *from, 1587 + const char *type) 1588 + { 1589 + struct device_node *np; 1590 + 1591 + read_lock(&devtree_lock); 1592 + np = from ? from->allnext : allnodes; 1593 + for (; np != 0; np = np->allnext) 1594 + if (np->type != 0 && strcasecmp(np->type, type) == 0 1595 + && of_node_get(np)) 1596 + break; 1597 + if (from) 1598 + of_node_put(from); 1599 + read_unlock(&devtree_lock); 1600 + return np; 1601 + } 1602 + EXPORT_SYMBOL(of_find_node_by_type); 1603 + 1604 + /** 1605 + * of_find_compatible_node - Find a node based on type and one of the 1606 + * tokens in its "compatible" property 1607 + * @from: The node to start searching from or NULL, the node 1608 + * you pass will not be searched, only the next one 1609 + * will; typically, you pass what the previous call 1610 + * returned. of_node_put() will be called on it 1611 + * @type: The type string to match "device_type" or NULL to ignore 1612 + * @compatible: The string to match to one of the tokens in the device 1613 + * "compatible" list. 1614 + * 1615 + * Returns a node pointer with refcount incremented, use 1616 + * of_node_put() on it when done. 1617 + */ 1618 + struct device_node *of_find_compatible_node(struct device_node *from, 1619 + const char *type, const char *compatible) 1620 + { 1621 + struct device_node *np; 1622 + 1623 + read_lock(&devtree_lock); 1624 + np = from ? from->allnext : allnodes; 1625 + for (; np != 0; np = np->allnext) { 1626 + if (type != NULL 1627 + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) 1628 + continue; 1629 + if (device_is_compatible(np, compatible) && of_node_get(np)) 1630 + break; 1631 + } 1632 + if (from) 1633 + of_node_put(from); 1634 + read_unlock(&devtree_lock); 1635 + return np; 1636 + } 1637 + EXPORT_SYMBOL(of_find_compatible_node); 1638 + 1639 + /** 1640 + * of_find_node_by_path - Find a node matching a full OF path 1641 + * @path: The full path to match 1642 + * 1643 + * Returns a node pointer with refcount incremented, use 1644 + * of_node_put() on it when done. 1645 + */ 1646 + struct device_node *of_find_node_by_path(const char *path) 1647 + { 1648 + struct device_node *np = allnodes; 1649 + 1650 + read_lock(&devtree_lock); 1651 + for (; np != 0; np = np->allnext) { 1652 + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0 1653 + && of_node_get(np)) 1654 + break; 1655 + } 1656 + read_unlock(&devtree_lock); 1657 + return np; 1658 + } 1659 + EXPORT_SYMBOL(of_find_node_by_path); 1660 + 1661 + /** 1662 + * of_find_node_by_phandle - Find a node given a phandle 1663 + * @handle: phandle of the node to find 1664 + * 1665 + * Returns a node pointer with refcount incremented, use 1666 + * of_node_put() on it when done. 1667 + */ 1668 + struct device_node *of_find_node_by_phandle(phandle handle) 1669 + { 1670 + struct device_node *np; 1671 + 1672 + read_lock(&devtree_lock); 1673 + for (np = allnodes; np != 0; np = np->allnext) 1674 + if (np->linux_phandle == handle) 1675 + break; 1676 + if (np) 1677 + of_node_get(np); 1678 + read_unlock(&devtree_lock); 1679 + return np; 1680 + } 1681 + EXPORT_SYMBOL(of_find_node_by_phandle); 1682 + 1683 + /** 1684 + * of_find_all_nodes - Get next node in global list 1685 + * @prev: Previous node or NULL to start iteration 1686 + * of_node_put() will be called on it 1687 + * 1688 + * Returns a node pointer with refcount incremented, use 1689 + * of_node_put() on it when done. 1690 + */ 1691 + struct device_node *of_find_all_nodes(struct device_node *prev) 1692 + { 1693 + struct device_node *np; 1694 + 1695 + read_lock(&devtree_lock); 1696 + np = prev ? prev->allnext : allnodes; 1697 + for (; np != 0; np = np->allnext) 1698 + if (of_node_get(np)) 1699 + break; 1700 + if (prev) 1701 + of_node_put(prev); 1702 + read_unlock(&devtree_lock); 1703 + return np; 1704 + } 1705 + EXPORT_SYMBOL(of_find_all_nodes); 1706 + 1707 + /** 1708 + * of_get_parent - Get a node's parent if any 1709 + * @node: Node to get parent 1710 + * 1711 + * Returns a node pointer with refcount incremented, use 1712 + * of_node_put() on it when done. 1713 + */ 1714 + struct device_node *of_get_parent(const struct device_node *node) 1715 + { 1716 + struct device_node *np; 1717 + 1718 + if (!node) 1719 + return NULL; 1720 + 1721 + read_lock(&devtree_lock); 1722 + np = of_node_get(node->parent); 1723 + read_unlock(&devtree_lock); 1724 + return np; 1725 + } 1726 + EXPORT_SYMBOL(of_get_parent); 1727 + 1728 + /** 1729 + * of_get_next_child - Iterate a node childs 1730 + * @node: parent node 1731 + * @prev: previous child of the parent node, or NULL to get first 1732 + * 1733 + * Returns a node pointer with refcount incremented, use 1734 + * of_node_put() on it when done. 1735 + */ 1736 + struct device_node *of_get_next_child(const struct device_node *node, 1737 + struct device_node *prev) 1738 + { 1739 + struct device_node *next; 1740 + 1741 + read_lock(&devtree_lock); 1742 + next = prev ? prev->sibling : node->child; 1743 + for (; next != 0; next = next->sibling) 1744 + if (of_node_get(next)) 1745 + break; 1746 + if (prev) 1747 + of_node_put(prev); 1748 + read_unlock(&devtree_lock); 1749 + return next; 1750 + } 1751 + EXPORT_SYMBOL(of_get_next_child); 1752 + 1753 + /** 1754 + * of_node_get - Increment refcount of a node 1755 + * @node: Node to inc refcount, NULL is supported to 1756 + * simplify writing of callers 1757 + * 1758 + * Returns node. 1759 + */ 1760 + struct device_node *of_node_get(struct device_node *node) 1761 + { 1762 + if (node) 1763 + kref_get(&node->kref); 1764 + return node; 1765 + } 1766 + EXPORT_SYMBOL(of_node_get); 1767 + 1768 + static inline struct device_node * kref_to_device_node(struct kref *kref) 1769 + { 1770 + return container_of(kref, struct device_node, kref); 1771 + } 1772 + 1773 + /** 1774 + * of_node_release - release a dynamically allocated node 1775 + * @kref: kref element of the node to be released 1776 + * 1777 + * In of_node_put() this function is passed to kref_put() 1778 + * as the destructor. 1779 + */ 1780 + static void of_node_release(struct kref *kref) 1781 + { 1782 + struct device_node *node = kref_to_device_node(kref); 1783 + struct property *prop = node->properties; 1784 + 1785 + if (!OF_IS_DYNAMIC(node)) 1786 + return; 1787 + while (prop) { 1788 + struct property *next = prop->next; 1789 + kfree(prop->name); 1790 + kfree(prop->value); 1791 + kfree(prop); 1792 + prop = next; 1793 + } 1794 + kfree(node->intrs); 1795 + kfree(node->addrs); 1796 + kfree(node->full_name); 1797 + kfree(node->data); 1798 + kfree(node); 1799 + } 1800 + 1801 + /** 1802 + * of_node_put - Decrement refcount of a node 1803 + * @node: Node to dec refcount, NULL is supported to 1804 + * simplify writing of callers 1805 + * 1806 + */ 1807 + void of_node_put(struct device_node *node) 1808 + { 1809 + if (node) 1810 + kref_put(&node->kref, of_node_release); 1811 + } 1812 + EXPORT_SYMBOL(of_node_put); 1813 + 1814 + /* 1815 + * Plug a device node into the tree and global list. 1816 + */ 1817 + void of_attach_node(struct device_node *np) 1818 + { 1819 + write_lock(&devtree_lock); 1820 + np->sibling = np->parent->child; 1821 + np->allnext = allnodes; 1822 + np->parent->child = np; 1823 + allnodes = np; 1824 + write_unlock(&devtree_lock); 1825 + } 1826 + 1827 + /* 1828 + * "Unplug" a node from the device tree. The caller must hold 1829 + * a reference to the node. The memory associated with the node 1830 + * is not freed until its refcount goes to zero. 1831 + */ 1832 + void of_detach_node(const struct device_node *np) 1833 + { 1834 + struct device_node *parent; 1835 + 1836 + write_lock(&devtree_lock); 1837 + 1838 + parent = np->parent; 1839 + 1840 + if (allnodes == np) 1841 + allnodes = np->allnext; 1842 + else { 1843 + struct device_node *prev; 1844 + for (prev = allnodes; 1845 + prev->allnext != np; 1846 + prev = prev->allnext) 1847 + ; 1848 + prev->allnext = np->allnext; 1849 + } 1850 + 1851 + if (parent->child == np) 1852 + parent->child = np->sibling; 1853 + else { 1854 + struct device_node *prevsib; 1855 + for (prevsib = np->parent->child; 1856 + prevsib->sibling != np; 1857 + prevsib = prevsib->sibling) 1858 + ; 1859 + prevsib->sibling = np->sibling; 1860 + } 1861 + 1862 + write_unlock(&devtree_lock); 1863 + } 1864 + 1865 + #ifdef CONFIG_PPC_PSERIES 1866 + /* 1867 + * Fix up the uninitialized fields in a new device node: 1868 + * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields 1869 + * 1870 + * A lot of boot-time code is duplicated here, because functions such 1871 + * as finish_node_interrupts, interpret_pci_props, etc. cannot use the 1872 + * slab allocator. 1873 + * 1874 + * This should probably be split up into smaller chunks. 1875 + */ 1876 + 1877 + static int of_finish_dynamic_node(struct device_node *node, 1878 + unsigned long *unused1, int unused2, 1879 + int unused3, int unused4) 1880 + { 1881 + struct device_node *parent = of_get_parent(node); 1882 + int err = 0; 1883 + phandle *ibm_phandle; 1884 + 1885 + node->name = get_property(node, "name", NULL); 1886 + node->type = get_property(node, "device_type", NULL); 1887 + 1888 + if (!parent) { 1889 + err = -ENODEV; 1890 + goto out; 1891 + } 1892 + 1893 + /* We don't support that function on PowerMac, at least 1894 + * not yet 1895 + */ 1896 + if (systemcfg->platform == PLATFORM_POWERMAC) 1897 + return -ENODEV; 1898 + 1899 + /* fix up new node's linux_phandle field */ 1900 + if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL))) 1901 + node->linux_phandle = *ibm_phandle; 1902 + 1903 + out: 1904 + of_node_put(parent); 1905 + return err; 1906 + } 1907 + 1908 + static int prom_reconfig_notifier(struct notifier_block *nb, 1909 + unsigned long action, void *node) 1910 + { 1911 + int err; 1912 + 1913 + switch (action) { 1914 + case PSERIES_RECONFIG_ADD: 1915 + err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0); 1916 + if (err < 0) { 1917 + printk(KERN_ERR "finish_node returned %d\n", err); 1918 + err = NOTIFY_BAD; 1919 + } 1920 + break; 1921 + default: 1922 + err = NOTIFY_DONE; 1923 + break; 1924 + } 1925 + return err; 1926 + } 1927 + 1928 + static struct notifier_block prom_reconfig_nb = { 1929 + .notifier_call = prom_reconfig_notifier, 1930 + .priority = 10, /* This one needs to run first */ 1931 + }; 1932 + 1933 + static int __init prom_reconfig_setup(void) 1934 + { 1935 + return pSeries_reconfig_notifier_register(&prom_reconfig_nb); 1936 + } 1937 + __initcall(prom_reconfig_setup); 1938 + #endif 1939 + 1940 + /* 1941 + * Find a property with a given name for a given node 1942 + * and return the value. 1943 + */ 1944 + unsigned char *get_property(struct device_node *np, const char *name, 1945 + int *lenp) 1946 + { 1947 + struct property *pp; 1948 + 1949 + for (pp = np->properties; pp != 0; pp = pp->next) 1950 + if (strcmp(pp->name, name) == 0) { 1951 + if (lenp != 0) 1952 + *lenp = pp->length; 1953 + return pp->value; 1954 + } 1955 + return NULL; 1956 + } 1957 + EXPORT_SYMBOL(get_property); 1958 + 1959 + /* 1960 + * Add a property to a node 1961 + */ 1962 + void prom_add_property(struct device_node* np, struct property* prop) 1963 + { 1964 + struct property **next = &np->properties; 1965 + 1966 + prop->next = NULL; 1967 + while (*next) 1968 + next = &(*next)->next; 1969 + *next = prop; 1970 + } 1971 + 1972 + /* I quickly hacked that one, check against spec ! */ 1973 + static inline unsigned long 1974 + bus_space_to_resource_flags(unsigned int bus_space) 1975 + { 1976 + u8 space = (bus_space >> 24) & 0xf; 1977 + if (space == 0) 1978 + space = 0x02; 1979 + if (space == 0x02) 1980 + return IORESOURCE_MEM; 1981 + else if (space == 0x01) 1982 + return IORESOURCE_IO; 1983 + else { 1984 + printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n", 1985 + bus_space); 1986 + return 0; 1987 + } 1988 + } 1989 + 1990 + static struct resource *find_parent_pci_resource(struct pci_dev* pdev, 1991 + struct address_range *range) 1992 + { 1993 + unsigned long mask; 1994 + int i; 1995 + 1996 + /* Check this one */ 1997 + mask = bus_space_to_resource_flags(range->space); 1998 + for (i=0; i<DEVICE_COUNT_RESOURCE; i++) { 1999 + if ((pdev->resource[i].flags & mask) == mask && 2000 + pdev->resource[i].start <= range->address && 2001 + pdev->resource[i].end > range->address) { 2002 + if ((range->address + range->size - 1) > pdev->resource[i].end) { 2003 + /* Add better message */ 2004 + printk(KERN_WARNING "PCI/OF resource overlap !\n"); 2005 + return NULL; 2006 + } 2007 + break; 2008 + } 2009 + } 2010 + if (i == DEVICE_COUNT_RESOURCE) 2011 + return NULL; 2012 + return &pdev->resource[i]; 2013 + } 2014 + 2015 + /* 2016 + * Request an OF device resource. Currently handles child of PCI devices, 2017 + * or other nodes attached to the root node. Ultimately, put some 2018 + * link to resources in the OF node. 2019 + */ 2020 + struct resource *request_OF_resource(struct device_node* node, int index, 2021 + const char* name_postfix) 2022 + { 2023 + struct pci_dev* pcidev; 2024 + u8 pci_bus, pci_devfn; 2025 + unsigned long iomask; 2026 + struct device_node* nd; 2027 + struct resource* parent; 2028 + struct resource *res = NULL; 2029 + int nlen, plen; 2030 + 2031 + if (index >= node->n_addrs) 2032 + goto fail; 2033 + 2034 + /* Sanity check on bus space */ 2035 + iomask = bus_space_to_resource_flags(node->addrs[index].space); 2036 + if (iomask & IORESOURCE_MEM) 2037 + parent = &iomem_resource; 2038 + else if (iomask & IORESOURCE_IO) 2039 + parent = &ioport_resource; 2040 + else 2041 + goto fail; 2042 + 2043 + /* Find a PCI parent if any */ 2044 + nd = node; 2045 + pcidev = NULL; 2046 + while (nd) { 2047 + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) 2048 + pcidev = pci_find_slot(pci_bus, pci_devfn); 2049 + if (pcidev) break; 2050 + nd = nd->parent; 2051 + } 2052 + if (pcidev) 2053 + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); 2054 + if (!parent) { 2055 + printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", 2056 + node->name); 2057 + goto fail; 2058 + } 2059 + 2060 + res = __request_region(parent, node->addrs[index].address, 2061 + node->addrs[index].size, NULL); 2062 + if (!res) 2063 + goto fail; 2064 + nlen = strlen(node->name); 2065 + plen = name_postfix ? strlen(name_postfix) : 0; 2066 + res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL); 2067 + if (res->name) { 2068 + strcpy((char *)res->name, node->name); 2069 + if (plen) 2070 + strcpy((char *)res->name+nlen, name_postfix); 2071 + } 2072 + return res; 2073 + fail: 2074 + return NULL; 2075 + } 2076 + EXPORT_SYMBOL(request_OF_resource); 2077 + 2078 + int release_OF_resource(struct device_node *node, int index) 2079 + { 2080 + struct pci_dev* pcidev; 2081 + u8 pci_bus, pci_devfn; 2082 + unsigned long iomask, start, end; 2083 + struct device_node* nd; 2084 + struct resource* parent; 2085 + struct resource *res = NULL; 2086 + 2087 + if (index >= node->n_addrs) 2088 + return -EINVAL; 2089 + 2090 + /* Sanity check on bus space */ 2091 + iomask = bus_space_to_resource_flags(node->addrs[index].space); 2092 + if (iomask & IORESOURCE_MEM) 2093 + parent = &iomem_resource; 2094 + else if (iomask & IORESOURCE_IO) 2095 + parent = &ioport_resource; 2096 + else 2097 + return -EINVAL; 2098 + 2099 + /* Find a PCI parent if any */ 2100 + nd = node; 2101 + pcidev = NULL; 2102 + while(nd) { 2103 + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) 2104 + pcidev = pci_find_slot(pci_bus, pci_devfn); 2105 + if (pcidev) break; 2106 + nd = nd->parent; 2107 + } 2108 + if (pcidev) 2109 + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); 2110 + if (!parent) { 2111 + printk(KERN_WARNING "release_OF_resource(%s), parent not found\n", 2112 + node->name); 2113 + return -ENODEV; 2114 + } 2115 + 2116 + /* Find us in the parent and its childs */ 2117 + res = parent->child; 2118 + start = node->addrs[index].address; 2119 + end = start + node->addrs[index].size - 1; 2120 + while (res) { 2121 + if (res->start == start && res->end == end && 2122 + (res->flags & IORESOURCE_BUSY)) 2123 + break; 2124 + if (res->start <= start && res->end >= end) 2125 + res = res->child; 2126 + else 2127 + res = res->sibling; 2128 + } 2129 + if (!res) 2130 + return -ENODEV; 2131 + 2132 + if (res->name) { 2133 + kfree(res->name); 2134 + res->name = NULL; 2135 + } 2136 + release_resource(res); 2137 + kfree(res); 2138 + 2139 + return 0; 2140 + } 2141 + EXPORT_SYMBOL(release_OF_resource);
+2126
arch/powerpc/kernel/prom_init.c
··· 1 + /* 2 + * Procedures for interfacing to Open Firmware. 3 + * 4 + * Paul Mackerras August 1996. 5 + * Copyright (C) 1996-2005 Paul Mackerras. 6 + * 7 + * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. 8 + * {engebret|bergner}@us.ibm.com 9 + * 10 + * This program is free software; you can redistribute it and/or 11 + * modify it under the terms of the GNU General Public License 12 + * as published by the Free Software Foundation; either version 13 + * 2 of the License, or (at your option) any later version. 14 + */ 15 + 16 + #undef DEBUG_PROM 17 + 18 + #include <stdarg.h> 19 + #include <linux/config.h> 20 + #include <linux/kernel.h> 21 + #include <linux/string.h> 22 + #include <linux/init.h> 23 + #include <linux/threads.h> 24 + #include <linux/spinlock.h> 25 + #include <linux/types.h> 26 + #include <linux/pci.h> 27 + #include <linux/proc_fs.h> 28 + #include <linux/stringify.h> 29 + #include <linux/delay.h> 30 + #include <linux/initrd.h> 31 + #include <linux/bitops.h> 32 + #include <asm/prom.h> 33 + #include <asm/rtas.h> 34 + #include <asm/page.h> 35 + #include <asm/processor.h> 36 + #include <asm/irq.h> 37 + #include <asm/io.h> 38 + #include <asm/smp.h> 39 + #include <asm/system.h> 40 + #include <asm/mmu.h> 41 + #include <asm/pgtable.h> 42 + #include <asm/pci.h> 43 + #include <asm/iommu.h> 44 + #include <asm/bootinfo.h> 45 + #include <asm/btext.h> 46 + #include <asm/sections.h> 47 + #include <asm/machdep.h> 48 + 49 + #ifdef CONFIG_LOGO_LINUX_CLUT224 50 + #include <linux/linux_logo.h> 51 + extern const struct linux_logo logo_linux_clut224; 52 + #endif 53 + 54 + /* 55 + * Properties whose value is longer than this get excluded from our 56 + * copy of the device tree. This value does need to be big enough to 57 + * ensure that we don't lose things like the interrupt-map property 58 + * on a PCI-PCI bridge. 59 + */ 60 + #define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024) 61 + 62 + /* 63 + * Eventually bump that one up 64 + */ 65 + #define DEVTREE_CHUNK_SIZE 0x100000 66 + 67 + /* 68 + * This is the size of the local memory reserve map that gets copied 69 + * into the boot params passed to the kernel. That size is totally 70 + * flexible as the kernel just reads the list until it encounters an 71 + * entry with size 0, so it can be changed without breaking binary 72 + * compatibility 73 + */ 74 + #define MEM_RESERVE_MAP_SIZE 8 75 + 76 + /* 77 + * prom_init() is called very early on, before the kernel text 78 + * and data have been mapped to KERNELBASE. At this point the code 79 + * is running at whatever address it has been loaded at. 80 + * On ppc32 we compile with -mrelocatable, which means that references 81 + * to extern and static variables get relocated automatically. 82 + * On ppc64 we have to relocate the references explicitly with 83 + * RELOC. (Note that strings count as static variables.) 84 + * 85 + * Because OF may have mapped I/O devices into the area starting at 86 + * KERNELBASE, particularly on CHRP machines, we can't safely call 87 + * OF once the kernel has been mapped to KERNELBASE. Therefore all 88 + * OF calls must be done within prom_init(). 89 + * 90 + * ADDR is used in calls to call_prom. The 4th and following 91 + * arguments to call_prom should be 32-bit values. 92 + * On ppc64, 64 bit values are truncated to 32 bits (and 93 + * fortunately don't get interpreted as two arguments). 94 + */ 95 + #ifdef CONFIG_PPC64 96 + #define RELOC(x) (*PTRRELOC(&(x))) 97 + #define ADDR(x) (u32) add_reloc_offset((unsigned long)(x)) 98 + #else 99 + #define RELOC(x) (x) 100 + #define ADDR(x) (u32) (x) 101 + #endif 102 + 103 + #define PROM_BUG() do { \ 104 + prom_printf("kernel BUG at %s line 0x%x!\n", \ 105 + RELOC(__FILE__), __LINE__); \ 106 + __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \ 107 + } while (0) 108 + 109 + #ifdef DEBUG_PROM 110 + #define prom_debug(x...) prom_printf(x) 111 + #else 112 + #define prom_debug(x...) 113 + #endif 114 + 115 + #ifdef CONFIG_PPC32 116 + #define PLATFORM_POWERMAC _MACH_Pmac 117 + #define PLATFORM_CHRP _MACH_chrp 118 + #endif 119 + 120 + 121 + typedef u32 prom_arg_t; 122 + 123 + struct prom_args { 124 + u32 service; 125 + u32 nargs; 126 + u32 nret; 127 + prom_arg_t args[10]; 128 + }; 129 + 130 + struct prom_t { 131 + ihandle root; 132 + ihandle chosen; 133 + int cpu; 134 + ihandle stdout; 135 + }; 136 + 137 + struct mem_map_entry { 138 + unsigned long base; 139 + unsigned long size; 140 + }; 141 + 142 + typedef u32 cell_t; 143 + 144 + extern void __start(unsigned long r3, unsigned long r4, unsigned long r5); 145 + 146 + #ifdef CONFIG_PPC64 147 + extern void enter_prom(struct prom_args *args, unsigned long entry); 148 + #else 149 + static inline void enter_prom(struct prom_args *args, unsigned long entry) 150 + { 151 + ((void (*)(struct prom_args *))entry)(args); 152 + } 153 + #endif 154 + 155 + extern void copy_and_flush(unsigned long dest, unsigned long src, 156 + unsigned long size, unsigned long offset); 157 + 158 + /* prom structure */ 159 + static struct prom_t __initdata prom; 160 + 161 + static unsigned long prom_entry __initdata; 162 + 163 + #define PROM_SCRATCH_SIZE 256 164 + 165 + static char __initdata of_stdout_device[256]; 166 + static char __initdata prom_scratch[PROM_SCRATCH_SIZE]; 167 + 168 + static unsigned long __initdata dt_header_start; 169 + static unsigned long __initdata dt_struct_start, dt_struct_end; 170 + static unsigned long __initdata dt_string_start, dt_string_end; 171 + 172 + static unsigned long __initdata prom_initrd_start, prom_initrd_end; 173 + 174 + #ifdef CONFIG_PPC64 175 + static int __initdata iommu_force_on; 176 + static int __initdata ppc64_iommu_off; 177 + static unsigned long __initdata prom_tce_alloc_start; 178 + static unsigned long __initdata prom_tce_alloc_end; 179 + #endif 180 + 181 + static int __initdata of_platform; 182 + 183 + static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; 184 + 185 + static unsigned long __initdata prom_memory_limit; 186 + 187 + static unsigned long __initdata alloc_top; 188 + static unsigned long __initdata alloc_top_high; 189 + static unsigned long __initdata alloc_bottom; 190 + static unsigned long __initdata rmo_top; 191 + static unsigned long __initdata ram_top; 192 + 193 + static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; 194 + static int __initdata mem_reserve_cnt; 195 + 196 + static cell_t __initdata regbuf[1024]; 197 + 198 + 199 + #define MAX_CPU_THREADS 2 200 + 201 + /* TO GO */ 202 + #ifdef CONFIG_HMT 203 + struct { 204 + unsigned int pir; 205 + unsigned int threadid; 206 + } hmt_thread_data[NR_CPUS]; 207 + #endif /* CONFIG_HMT */ 208 + 209 + /* 210 + * Error results ... some OF calls will return "-1" on error, some 211 + * will return 0, some will return either. To simplify, here are 212 + * macros to use with any ihandle or phandle return value to check if 213 + * it is valid 214 + */ 215 + 216 + #define PROM_ERROR (-1u) 217 + #define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR) 218 + #define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR) 219 + 220 + 221 + /* This is the one and *ONLY* place where we actually call open 222 + * firmware. 223 + */ 224 + 225 + static int __init call_prom(const char *service, int nargs, int nret, ...) 226 + { 227 + int i; 228 + struct prom_args args; 229 + va_list list; 230 + 231 + args.service = ADDR(service); 232 + args.nargs = nargs; 233 + args.nret = nret; 234 + 235 + va_start(list, nret); 236 + for (i = 0; i < nargs; i++) 237 + args.args[i] = va_arg(list, prom_arg_t); 238 + va_end(list); 239 + 240 + for (i = 0; i < nret; i++) 241 + args.args[nargs+i] = 0; 242 + 243 + enter_prom(&args, RELOC(prom_entry)); 244 + 245 + return (nret > 0) ? args.args[nargs] : 0; 246 + } 247 + 248 + static int __init call_prom_ret(const char *service, int nargs, int nret, 249 + prom_arg_t *rets, ...) 250 + { 251 + int i; 252 + struct prom_args args; 253 + va_list list; 254 + 255 + args.service = ADDR(service); 256 + args.nargs = nargs; 257 + args.nret = nret; 258 + 259 + va_start(list, rets); 260 + for (i = 0; i < nargs; i++) 261 + args.args[i] = va_arg(list, prom_arg_t); 262 + va_end(list); 263 + 264 + for (i = 0; i < nret; i++) 265 + rets[nargs+i] = 0; 266 + 267 + enter_prom(&args, RELOC(prom_entry)); 268 + 269 + if (rets != NULL) 270 + for (i = 1; i < nret; ++i) 271 + rets[i] = args.args[nargs+i]; 272 + 273 + return (nret > 0) ? args.args[nargs] : 0; 274 + } 275 + 276 + 277 + static unsigned int __init prom_claim(unsigned long virt, unsigned long size, 278 + unsigned long align) 279 + { 280 + return (unsigned int)call_prom("claim", 3, 1, 281 + (prom_arg_t)virt, (prom_arg_t)size, 282 + (prom_arg_t)align); 283 + } 284 + 285 + static void __init prom_print(const char *msg) 286 + { 287 + const char *p, *q; 288 + struct prom_t *_prom = &RELOC(prom); 289 + 290 + if (_prom->stdout == 0) 291 + return; 292 + 293 + for (p = msg; *p != 0; p = q) { 294 + for (q = p; *q != 0 && *q != '\n'; ++q) 295 + ; 296 + if (q > p) 297 + call_prom("write", 3, 1, _prom->stdout, p, q - p); 298 + if (*q == 0) 299 + break; 300 + ++q; 301 + call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2); 302 + } 303 + } 304 + 305 + 306 + static void __init prom_print_hex(unsigned long val) 307 + { 308 + int i, nibbles = sizeof(val)*2; 309 + char buf[sizeof(val)*2+1]; 310 + struct prom_t *_prom = &RELOC(prom); 311 + 312 + for (i = nibbles-1; i >= 0; i--) { 313 + buf[i] = (val & 0xf) + '0'; 314 + if (buf[i] > '9') 315 + buf[i] += ('a'-'0'-10); 316 + val >>= 4; 317 + } 318 + buf[nibbles] = '\0'; 319 + call_prom("write", 3, 1, _prom->stdout, buf, nibbles); 320 + } 321 + 322 + 323 + static void __init prom_printf(const char *format, ...) 324 + { 325 + const char *p, *q, *s; 326 + va_list args; 327 + unsigned long v; 328 + struct prom_t *_prom = &RELOC(prom); 329 + 330 + va_start(args, format); 331 + #ifdef CONFIG_PPC64 332 + format = PTRRELOC(format); 333 + #endif 334 + for (p = format; *p != 0; p = q) { 335 + for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q) 336 + ; 337 + if (q > p) 338 + call_prom("write", 3, 1, _prom->stdout, p, q - p); 339 + if (*q == 0) 340 + break; 341 + if (*q == '\n') { 342 + ++q; 343 + call_prom("write", 3, 1, _prom->stdout, 344 + ADDR("\r\n"), 2); 345 + continue; 346 + } 347 + ++q; 348 + if (*q == 0) 349 + break; 350 + switch (*q) { 351 + case 's': 352 + ++q; 353 + s = va_arg(args, const char *); 354 + prom_print(s); 355 + break; 356 + case 'x': 357 + ++q; 358 + v = va_arg(args, unsigned long); 359 + prom_print_hex(v); 360 + break; 361 + } 362 + } 363 + } 364 + 365 + 366 + static void __init __attribute__((noreturn)) prom_panic(const char *reason) 367 + { 368 + #ifdef CONFIG_PPC64 369 + reason = PTRRELOC(reason); 370 + #endif 371 + prom_print(reason); 372 + /* ToDo: should put up an SRC here on p/iSeries */ 373 + call_prom("exit", 0, 0); 374 + 375 + for (;;) /* should never get here */ 376 + ; 377 + } 378 + 379 + 380 + static int __init prom_next_node(phandle *nodep) 381 + { 382 + phandle node; 383 + 384 + if ((node = *nodep) != 0 385 + && (*nodep = call_prom("child", 1, 1, node)) != 0) 386 + return 1; 387 + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) 388 + return 1; 389 + for (;;) { 390 + if ((node = call_prom("parent", 1, 1, node)) == 0) 391 + return 0; 392 + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) 393 + return 1; 394 + } 395 + } 396 + 397 + static int __init prom_getprop(phandle node, const char *pname, 398 + void *value, size_t valuelen) 399 + { 400 + return call_prom("getprop", 4, 1, node, ADDR(pname), 401 + (u32)(unsigned long) value, (u32) valuelen); 402 + } 403 + 404 + static int __init prom_getproplen(phandle node, const char *pname) 405 + { 406 + return call_prom("getproplen", 2, 1, node, ADDR(pname)); 407 + } 408 + 409 + static int __init prom_setprop(phandle node, const char *pname, 410 + void *value, size_t valuelen) 411 + { 412 + return call_prom("setprop", 4, 1, node, ADDR(pname), 413 + (u32)(unsigned long) value, (u32) valuelen); 414 + } 415 + 416 + /* We can't use the standard versions because of RELOC headaches. */ 417 + #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 418 + || ('a' <= (c) && (c) <= 'f') \ 419 + || ('A' <= (c) && (c) <= 'F')) 420 + 421 + #define isdigit(c) ('0' <= (c) && (c) <= '9') 422 + #define islower(c) ('a' <= (c) && (c) <= 'z') 423 + #define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c)) 424 + 425 + unsigned long prom_strtoul(const char *cp, const char **endp) 426 + { 427 + unsigned long result = 0, base = 10, value; 428 + 429 + if (*cp == '0') { 430 + base = 8; 431 + cp++; 432 + if (toupper(*cp) == 'X') { 433 + cp++; 434 + base = 16; 435 + } 436 + } 437 + 438 + while (isxdigit(*cp) && 439 + (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) { 440 + result = result * base + value; 441 + cp++; 442 + } 443 + 444 + if (endp) 445 + *endp = cp; 446 + 447 + return result; 448 + } 449 + 450 + unsigned long prom_memparse(const char *ptr, const char **retptr) 451 + { 452 + unsigned long ret = prom_strtoul(ptr, retptr); 453 + int shift = 0; 454 + 455 + /* 456 + * We can't use a switch here because GCC *may* generate a 457 + * jump table which won't work, because we're not running at 458 + * the address we're linked at. 459 + */ 460 + if ('G' == **retptr || 'g' == **retptr) 461 + shift = 30; 462 + 463 + if ('M' == **retptr || 'm' == **retptr) 464 + shift = 20; 465 + 466 + if ('K' == **retptr || 'k' == **retptr) 467 + shift = 10; 468 + 469 + if (shift) { 470 + ret <<= shift; 471 + (*retptr)++; 472 + } 473 + 474 + return ret; 475 + } 476 + 477 + /* 478 + * Early parsing of the command line passed to the kernel, used for 479 + * "mem=x" and the options that affect the iommu 480 + */ 481 + static void __init early_cmdline_parse(void) 482 + { 483 + struct prom_t *_prom = &RELOC(prom); 484 + char *opt, *p; 485 + int l = 0; 486 + 487 + RELOC(prom_cmd_line[0]) = 0; 488 + p = RELOC(prom_cmd_line); 489 + if ((long)_prom->chosen > 0) 490 + l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1); 491 + #ifdef CONFIG_CMDLINE 492 + if (l == 0) /* dbl check */ 493 + strlcpy(RELOC(prom_cmd_line), 494 + RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line)); 495 + #endif /* CONFIG_CMDLINE */ 496 + prom_printf("command line: %s\n", RELOC(prom_cmd_line)); 497 + 498 + #ifdef CONFIG_PPC64 499 + opt = strstr(RELOC(prom_cmd_line), RELOC("iommu=")); 500 + if (opt) { 501 + prom_printf("iommu opt is: %s\n", opt); 502 + opt += 6; 503 + while (*opt && *opt == ' ') 504 + opt++; 505 + if (!strncmp(opt, RELOC("off"), 3)) 506 + RELOC(ppc64_iommu_off) = 1; 507 + else if (!strncmp(opt, RELOC("force"), 5)) 508 + RELOC(iommu_force_on) = 1; 509 + } 510 + #endif 511 + 512 + opt = strstr(RELOC(prom_cmd_line), RELOC("mem=")); 513 + if (opt) { 514 + opt += 4; 515 + RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt); 516 + #ifdef CONFIG_PPC64 517 + /* Align to 16 MB == size of ppc64 large page */ 518 + RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); 519 + #endif 520 + } 521 + } 522 + 523 + #ifdef CONFIG_PPC_PSERIES 524 + /* 525 + * To tell the firmware what our capabilities are, we have to pass 526 + * it a fake 32-bit ELF header containing a couple of PT_NOTE sections 527 + * that contain structures that contain the actual values. 528 + */ 529 + static struct fake_elf { 530 + Elf32_Ehdr elfhdr; 531 + Elf32_Phdr phdr[2]; 532 + struct chrpnote { 533 + u32 namesz; 534 + u32 descsz; 535 + u32 type; 536 + char name[8]; /* "PowerPC" */ 537 + struct chrpdesc { 538 + u32 real_mode; 539 + u32 real_base; 540 + u32 real_size; 541 + u32 virt_base; 542 + u32 virt_size; 543 + u32 load_base; 544 + } chrpdesc; 545 + } chrpnote; 546 + struct rpanote { 547 + u32 namesz; 548 + u32 descsz; 549 + u32 type; 550 + char name[24]; /* "IBM,RPA-Client-Config" */ 551 + struct rpadesc { 552 + u32 lpar_affinity; 553 + u32 min_rmo_size; 554 + u32 min_rmo_percent; 555 + u32 max_pft_size; 556 + u32 splpar; 557 + u32 min_load; 558 + u32 new_mem_def; 559 + u32 ignore_me; 560 + } rpadesc; 561 + } rpanote; 562 + } fake_elf = { 563 + .elfhdr = { 564 + .e_ident = { 0x7f, 'E', 'L', 'F', 565 + ELFCLASS32, ELFDATA2MSB, EV_CURRENT }, 566 + .e_type = ET_EXEC, /* yeah right */ 567 + .e_machine = EM_PPC, 568 + .e_version = EV_CURRENT, 569 + .e_phoff = offsetof(struct fake_elf, phdr), 570 + .e_phentsize = sizeof(Elf32_Phdr), 571 + .e_phnum = 2 572 + }, 573 + .phdr = { 574 + [0] = { 575 + .p_type = PT_NOTE, 576 + .p_offset = offsetof(struct fake_elf, chrpnote), 577 + .p_filesz = sizeof(struct chrpnote) 578 + }, [1] = { 579 + .p_type = PT_NOTE, 580 + .p_offset = offsetof(struct fake_elf, rpanote), 581 + .p_filesz = sizeof(struct rpanote) 582 + } 583 + }, 584 + .chrpnote = { 585 + .namesz = sizeof("PowerPC"), 586 + .descsz = sizeof(struct chrpdesc), 587 + .type = 0x1275, 588 + .name = "PowerPC", 589 + .chrpdesc = { 590 + .real_mode = ~0U, /* ~0 means "don't care" */ 591 + .real_base = ~0U, 592 + .real_size = ~0U, 593 + .virt_base = ~0U, 594 + .virt_size = ~0U, 595 + .load_base = ~0U 596 + }, 597 + }, 598 + .rpanote = { 599 + .namesz = sizeof("IBM,RPA-Client-Config"), 600 + .descsz = sizeof(struct rpadesc), 601 + .type = 0x12759999, 602 + .name = "IBM,RPA-Client-Config", 603 + .rpadesc = { 604 + .lpar_affinity = 0, 605 + .min_rmo_size = 64, /* in megabytes */ 606 + .min_rmo_percent = 0, 607 + .max_pft_size = 48, /* 2^48 bytes max PFT size */ 608 + .splpar = 1, 609 + .min_load = ~0U, 610 + .new_mem_def = 0 611 + } 612 + } 613 + }; 614 + 615 + static void __init prom_send_capabilities(void) 616 + { 617 + ihandle elfloader; 618 + 619 + elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); 620 + if (elfloader == 0) { 621 + prom_printf("couldn't open /packages/elf-loader\n"); 622 + return; 623 + } 624 + call_prom("call-method", 3, 1, ADDR("process-elf-header"), 625 + elfloader, ADDR(&fake_elf)); 626 + call_prom("close", 1, 0, elfloader); 627 + } 628 + #endif 629 + 630 + /* 631 + * Memory allocation strategy... our layout is normally: 632 + * 633 + * at 14Mb or more we have vmlinux, then a gap and initrd. In some 634 + * rare cases, initrd might end up being before the kernel though. 635 + * We assume this won't override the final kernel at 0, we have no 636 + * provision to handle that in this version, but it should hopefully 637 + * never happen. 638 + * 639 + * alloc_top is set to the top of RMO, eventually shrink down if the 640 + * TCEs overlap 641 + * 642 + * alloc_bottom is set to the top of kernel/initrd 643 + * 644 + * from there, allocations are done this way : rtas is allocated 645 + * topmost, and the device-tree is allocated from the bottom. We try 646 + * to grow the device-tree allocation as we progress. If we can't, 647 + * then we fail, we don't currently have a facility to restart 648 + * elsewhere, but that shouldn't be necessary. 649 + * 650 + * Note that calls to reserve_mem have to be done explicitly, memory 651 + * allocated with either alloc_up or alloc_down isn't automatically 652 + * reserved. 653 + */ 654 + 655 + 656 + /* 657 + * Allocates memory in the RMO upward from the kernel/initrd 658 + * 659 + * When align is 0, this is a special case, it means to allocate in place 660 + * at the current location of alloc_bottom or fail (that is basically 661 + * extending the previous allocation). Used for the device-tree flattening 662 + */ 663 + static unsigned long __init alloc_up(unsigned long size, unsigned long align) 664 + { 665 + unsigned long base = _ALIGN_UP(RELOC(alloc_bottom), align); 666 + unsigned long addr = 0; 667 + 668 + prom_debug("alloc_up(%x, %x)\n", size, align); 669 + if (RELOC(ram_top) == 0) 670 + prom_panic("alloc_up() called with mem not initialized\n"); 671 + 672 + if (align) 673 + base = _ALIGN_UP(RELOC(alloc_bottom), align); 674 + else 675 + base = RELOC(alloc_bottom); 676 + 677 + for(; (base + size) <= RELOC(alloc_top); 678 + base = _ALIGN_UP(base + 0x100000, align)) { 679 + prom_debug(" trying: 0x%x\n\r", base); 680 + addr = (unsigned long)prom_claim(base, size, 0); 681 + if (addr != PROM_ERROR) 682 + break; 683 + addr = 0; 684 + if (align == 0) 685 + break; 686 + } 687 + if (addr == 0) 688 + return 0; 689 + RELOC(alloc_bottom) = addr; 690 + 691 + prom_debug(" -> %x\n", addr); 692 + prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); 693 + prom_debug(" alloc_top : %x\n", RELOC(alloc_top)); 694 + prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); 695 + prom_debug(" rmo_top : %x\n", RELOC(rmo_top)); 696 + prom_debug(" ram_top : %x\n", RELOC(ram_top)); 697 + 698 + return addr; 699 + } 700 + 701 + /* 702 + * Allocates memory downward, either from top of RMO, or if highmem 703 + * is set, from the top of RAM. Note that this one doesn't handle 704 + * failures. It does claim memory if highmem is not set. 705 + */ 706 + static unsigned long __init alloc_down(unsigned long size, unsigned long align, 707 + int highmem) 708 + { 709 + unsigned long base, addr = 0; 710 + 711 + prom_debug("alloc_down(%x, %x, %s)\n", size, align, 712 + highmem ? RELOC("(high)") : RELOC("(low)")); 713 + if (RELOC(ram_top) == 0) 714 + prom_panic("alloc_down() called with mem not initialized\n"); 715 + 716 + if (highmem) { 717 + /* Carve out storage for the TCE table. */ 718 + addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align); 719 + if (addr <= RELOC(alloc_bottom)) 720 + return 0; 721 + /* Will we bump into the RMO ? If yes, check out that we 722 + * didn't overlap existing allocations there, if we did, 723 + * we are dead, we must be the first in town ! 724 + */ 725 + if (addr < RELOC(rmo_top)) { 726 + /* Good, we are first */ 727 + if (RELOC(alloc_top) == RELOC(rmo_top)) 728 + RELOC(alloc_top) = RELOC(rmo_top) = addr; 729 + else 730 + return 0; 731 + } 732 + RELOC(alloc_top_high) = addr; 733 + goto bail; 734 + } 735 + 736 + base = _ALIGN_DOWN(RELOC(alloc_top) - size, align); 737 + for (; base > RELOC(alloc_bottom); 738 + base = _ALIGN_DOWN(base - 0x100000, align)) { 739 + prom_debug(" trying: 0x%x\n\r", base); 740 + addr = (unsigned long)prom_claim(base, size, 0); 741 + if (addr != PROM_ERROR) 742 + break; 743 + addr = 0; 744 + } 745 + if (addr == 0) 746 + return 0; 747 + RELOC(alloc_top) = addr; 748 + 749 + bail: 750 + prom_debug(" -> %x\n", addr); 751 + prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); 752 + prom_debug(" alloc_top : %x\n", RELOC(alloc_top)); 753 + prom_debug(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); 754 + prom_debug(" rmo_top : %x\n", RELOC(rmo_top)); 755 + prom_debug(" ram_top : %x\n", RELOC(ram_top)); 756 + 757 + return addr; 758 + } 759 + 760 + /* 761 + * Parse a "reg" cell 762 + */ 763 + static unsigned long __init prom_next_cell(int s, cell_t **cellp) 764 + { 765 + cell_t *p = *cellp; 766 + unsigned long r = 0; 767 + 768 + /* Ignore more than 2 cells */ 769 + while (s > sizeof(unsigned long) / 4) { 770 + p++; 771 + s--; 772 + } 773 + r = *p++; 774 + #ifdef CONFIG_PPC64 775 + if (s) { 776 + r <<= 32; 777 + r |= *(p++); 778 + } 779 + #endif 780 + *cellp = p; 781 + return r; 782 + } 783 + 784 + /* 785 + * Very dumb function for adding to the memory reserve list, but 786 + * we don't need anything smarter at this point 787 + * 788 + * XXX Eventually check for collisions. They should NEVER happen. 789 + * If problems seem to show up, it would be a good start to track 790 + * them down. 791 + */ 792 + static void reserve_mem(unsigned long base, unsigned long size) 793 + { 794 + unsigned long top = base + size; 795 + unsigned long cnt = RELOC(mem_reserve_cnt); 796 + 797 + if (size == 0) 798 + return; 799 + 800 + /* We need to always keep one empty entry so that we 801 + * have our terminator with "size" set to 0 since we are 802 + * dumb and just copy this entire array to the boot params 803 + */ 804 + base = _ALIGN_DOWN(base, PAGE_SIZE); 805 + top = _ALIGN_UP(top, PAGE_SIZE); 806 + size = top - base; 807 + 808 + if (cnt >= (MEM_RESERVE_MAP_SIZE - 1)) 809 + prom_panic("Memory reserve map exhausted !\n"); 810 + RELOC(mem_reserve_map)[cnt].base = base; 811 + RELOC(mem_reserve_map)[cnt].size = size; 812 + RELOC(mem_reserve_cnt) = cnt + 1; 813 + } 814 + 815 + /* 816 + * Initialize memory allocation mecanism, parse "memory" nodes and 817 + * obtain that way the top of memory and RMO to setup out local allocator 818 + */ 819 + static void __init prom_init_mem(void) 820 + { 821 + phandle node; 822 + char *path, type[64]; 823 + unsigned int plen; 824 + cell_t *p, *endp; 825 + struct prom_t *_prom = &RELOC(prom); 826 + u32 rac, rsc; 827 + 828 + /* 829 + * We iterate the memory nodes to find 830 + * 1) top of RMO (first node) 831 + * 2) top of memory 832 + */ 833 + rac = 2; 834 + prom_getprop(_prom->root, "#address-cells", &rac, sizeof(rac)); 835 + rsc = 1; 836 + prom_getprop(_prom->root, "#size-cells", &rsc, sizeof(rsc)); 837 + prom_debug("root_addr_cells: %x\n", (unsigned long) rac); 838 + prom_debug("root_size_cells: %x\n", (unsigned long) rsc); 839 + 840 + prom_debug("scanning memory:\n"); 841 + path = RELOC(prom_scratch); 842 + 843 + for (node = 0; prom_next_node(&node); ) { 844 + type[0] = 0; 845 + prom_getprop(node, "device_type", type, sizeof(type)); 846 + 847 + if (strcmp(type, RELOC("memory"))) 848 + continue; 849 + 850 + plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf)); 851 + if (plen > sizeof(regbuf)) { 852 + prom_printf("memory node too large for buffer !\n"); 853 + plen = sizeof(regbuf); 854 + } 855 + p = RELOC(regbuf); 856 + endp = p + (plen / sizeof(cell_t)); 857 + 858 + #ifdef DEBUG_PROM 859 + memset(path, 0, PROM_SCRATCH_SIZE); 860 + call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1); 861 + prom_debug(" node %s :\n", path); 862 + #endif /* DEBUG_PROM */ 863 + 864 + while ((endp - p) >= (rac + rsc)) { 865 + unsigned long base, size; 866 + 867 + base = prom_next_cell(rac, &p); 868 + size = prom_next_cell(rsc, &p); 869 + 870 + if (size == 0) 871 + continue; 872 + prom_debug(" %x %x\n", base, size); 873 + if (base == 0) 874 + RELOC(rmo_top) = size; 875 + if ((base + size) > RELOC(ram_top)) 876 + RELOC(ram_top) = base + size; 877 + } 878 + } 879 + 880 + RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000); 881 + 882 + /* Check if we have an initrd after the kernel, if we do move our bottom 883 + * point to after it 884 + */ 885 + if (RELOC(prom_initrd_start)) { 886 + if (RELOC(prom_initrd_end) > RELOC(alloc_bottom)) 887 + RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end)); 888 + } 889 + 890 + /* 891 + * If prom_memory_limit is set we reduce the upper limits *except* for 892 + * alloc_top_high. This must be the real top of RAM so we can put 893 + * TCE's up there. 894 + */ 895 + 896 + RELOC(alloc_top_high) = RELOC(ram_top); 897 + 898 + if (RELOC(prom_memory_limit)) { 899 + if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) { 900 + prom_printf("Ignoring mem=%x <= alloc_bottom.\n", 901 + RELOC(prom_memory_limit)); 902 + RELOC(prom_memory_limit) = 0; 903 + } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) { 904 + prom_printf("Ignoring mem=%x >= ram_top.\n", 905 + RELOC(prom_memory_limit)); 906 + RELOC(prom_memory_limit) = 0; 907 + } else { 908 + RELOC(ram_top) = RELOC(prom_memory_limit); 909 + RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit)); 910 + } 911 + } 912 + 913 + /* 914 + * Setup our top alloc point, that is top of RMO or top of 915 + * segment 0 when running non-LPAR. 916 + * Some RS64 machines have buggy firmware where claims up at 917 + * 1GB fail. Cap at 768MB as a workaround. 918 + * Since 768MB is plenty of room, and we need to cap to something 919 + * reasonable on 32-bit, cap at 768MB on all machines. 920 + */ 921 + if (!RELOC(rmo_top)) 922 + RELOC(rmo_top) = RELOC(ram_top); 923 + RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top)); 924 + RELOC(alloc_top) = RELOC(rmo_top); 925 + 926 + prom_printf("memory layout at init:\n"); 927 + prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit)); 928 + prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom)); 929 + prom_printf(" alloc_top : %x\n", RELOC(alloc_top)); 930 + prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); 931 + prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); 932 + prom_printf(" ram_top : %x\n", RELOC(ram_top)); 933 + } 934 + 935 + 936 + /* 937 + * Allocate room for and instantiate RTAS 938 + */ 939 + static void __init prom_instantiate_rtas(void) 940 + { 941 + phandle rtas_node; 942 + ihandle rtas_inst; 943 + u32 base, entry = 0; 944 + u32 size = 0; 945 + 946 + prom_debug("prom_instantiate_rtas: start...\n"); 947 + 948 + rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas")); 949 + prom_debug("rtas_node: %x\n", rtas_node); 950 + if (!PHANDLE_VALID(rtas_node)) 951 + return; 952 + 953 + prom_getprop(rtas_node, "rtas-size", &size, sizeof(size)); 954 + if (size == 0) 955 + return; 956 + 957 + base = alloc_down(size, PAGE_SIZE, 0); 958 + if (base == 0) { 959 + prom_printf("RTAS allocation failed !\n"); 960 + return; 961 + } 962 + 963 + rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); 964 + if (!IHANDLE_VALID(rtas_inst)) { 965 + prom_printf("opening rtas package failed"); 966 + return; 967 + } 968 + 969 + prom_printf("instantiating rtas at 0x%x ...", base); 970 + 971 + if (call_prom_ret("call-method", 3, 2, &entry, 972 + ADDR("instantiate-rtas"), 973 + rtas_inst, base) == PROM_ERROR 974 + || entry == 0) { 975 + prom_printf(" failed\n"); 976 + return; 977 + } 978 + prom_printf(" done\n"); 979 + 980 + reserve_mem(base, size); 981 + 982 + prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); 983 + prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); 984 + 985 + prom_debug("rtas base = 0x%x\n", base); 986 + prom_debug("rtas entry = 0x%x\n", entry); 987 + prom_debug("rtas size = 0x%x\n", (long)size); 988 + 989 + prom_debug("prom_instantiate_rtas: end...\n"); 990 + } 991 + 992 + #ifdef CONFIG_PPC64 993 + /* 994 + * Allocate room for and initialize TCE tables 995 + */ 996 + static void __init prom_initialize_tce_table(void) 997 + { 998 + phandle node; 999 + ihandle phb_node; 1000 + char compatible[64], type[64], model[64]; 1001 + char *path = RELOC(prom_scratch); 1002 + u64 base, align; 1003 + u32 minalign, minsize; 1004 + u64 tce_entry, *tce_entryp; 1005 + u64 local_alloc_top, local_alloc_bottom; 1006 + u64 i; 1007 + 1008 + if (RELOC(ppc64_iommu_off)) 1009 + return; 1010 + 1011 + prom_debug("starting prom_initialize_tce_table\n"); 1012 + 1013 + /* Cache current top of allocs so we reserve a single block */ 1014 + local_alloc_top = RELOC(alloc_top_high); 1015 + local_alloc_bottom = local_alloc_top; 1016 + 1017 + /* Search all nodes looking for PHBs. */ 1018 + for (node = 0; prom_next_node(&node); ) { 1019 + compatible[0] = 0; 1020 + type[0] = 0; 1021 + model[0] = 0; 1022 + prom_getprop(node, "compatible", 1023 + compatible, sizeof(compatible)); 1024 + prom_getprop(node, "device_type", type, sizeof(type)); 1025 + prom_getprop(node, "model", model, sizeof(model)); 1026 + 1027 + if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL)) 1028 + continue; 1029 + 1030 + /* Keep the old logic in tack to avoid regression. */ 1031 + if (compatible[0] != 0) { 1032 + if ((strstr(compatible, RELOC("python")) == NULL) && 1033 + (strstr(compatible, RELOC("Speedwagon")) == NULL) && 1034 + (strstr(compatible, RELOC("Winnipeg")) == NULL)) 1035 + continue; 1036 + } else if (model[0] != 0) { 1037 + if ((strstr(model, RELOC("ython")) == NULL) && 1038 + (strstr(model, RELOC("peedwagon")) == NULL) && 1039 + (strstr(model, RELOC("innipeg")) == NULL)) 1040 + continue; 1041 + } 1042 + 1043 + if (prom_getprop(node, "tce-table-minalign", &minalign, 1044 + sizeof(minalign)) == PROM_ERROR) 1045 + minalign = 0; 1046 + if (prom_getprop(node, "tce-table-minsize", &minsize, 1047 + sizeof(minsize)) == PROM_ERROR) 1048 + minsize = 4UL << 20; 1049 + 1050 + /* 1051 + * Even though we read what OF wants, we just set the table 1052 + * size to 4 MB. This is enough to map 2GB of PCI DMA space. 1053 + * By doing this, we avoid the pitfalls of trying to DMA to 1054 + * MMIO space and the DMA alias hole. 1055 + * 1056 + * On POWER4, firmware sets the TCE region by assuming 1057 + * each TCE table is 8MB. Using this memory for anything 1058 + * else will impact performance, so we always allocate 8MB. 1059 + * Anton 1060 + */ 1061 + if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) 1062 + minsize = 8UL << 20; 1063 + else 1064 + minsize = 4UL << 20; 1065 + 1066 + /* Align to the greater of the align or size */ 1067 + align = max(minalign, minsize); 1068 + base = alloc_down(minsize, align, 1); 1069 + if (base == 0) 1070 + prom_panic("ERROR, cannot find space for TCE table.\n"); 1071 + if (base < local_alloc_bottom) 1072 + local_alloc_bottom = base; 1073 + 1074 + /* Save away the TCE table attributes for later use. */ 1075 + prom_setprop(node, "linux,tce-base", &base, sizeof(base)); 1076 + prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize)); 1077 + 1078 + /* It seems OF doesn't null-terminate the path :-( */ 1079 + memset(path, 0, sizeof(path)); 1080 + /* Call OF to setup the TCE hardware */ 1081 + if (call_prom("package-to-path", 3, 1, node, 1082 + path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) { 1083 + prom_printf("package-to-path failed\n"); 1084 + } 1085 + 1086 + prom_debug("TCE table: %s\n", path); 1087 + prom_debug("\tnode = 0x%x\n", node); 1088 + prom_debug("\tbase = 0x%x\n", base); 1089 + prom_debug("\tsize = 0x%x\n", minsize); 1090 + 1091 + /* Initialize the table to have a one-to-one mapping 1092 + * over the allocated size. 1093 + */ 1094 + tce_entryp = (unsigned long *)base; 1095 + for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) { 1096 + tce_entry = (i << PAGE_SHIFT); 1097 + tce_entry |= 0x3; 1098 + *tce_entryp = tce_entry; 1099 + } 1100 + 1101 + prom_printf("opening PHB %s", path); 1102 + phb_node = call_prom("open", 1, 1, path); 1103 + if (phb_node == 0) 1104 + prom_printf("... failed\n"); 1105 + else 1106 + prom_printf("... done\n"); 1107 + 1108 + call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"), 1109 + phb_node, -1, minsize, 1110 + (u32) base, (u32) (base >> 32)); 1111 + call_prom("close", 1, 0, phb_node); 1112 + } 1113 + 1114 + reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom); 1115 + 1116 + if (RELOC(prom_memory_limit)) { 1117 + /* 1118 + * We align the start to a 16MB boundary so we can map 1119 + * the TCE area using large pages if possible. 1120 + * The end should be the top of RAM so no need to align it. 1121 + */ 1122 + RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, 1123 + 0x1000000); 1124 + RELOC(prom_tce_alloc_end) = local_alloc_top; 1125 + } 1126 + 1127 + /* Flag the first invalid entry */ 1128 + prom_debug("ending prom_initialize_tce_table\n"); 1129 + } 1130 + #endif 1131 + 1132 + /* 1133 + * With CHRP SMP we need to use the OF to start the other processors. 1134 + * We can't wait until smp_boot_cpus (the OF is trashed by then) 1135 + * so we have to put the processors into a holding pattern controlled 1136 + * by the kernel (not OF) before we destroy the OF. 1137 + * 1138 + * This uses a chunk of low memory, puts some holding pattern 1139 + * code there and sends the other processors off to there until 1140 + * smp_boot_cpus tells them to do something. The holding pattern 1141 + * checks that address until its cpu # is there, when it is that 1142 + * cpu jumps to __secondary_start(). smp_boot_cpus() takes care 1143 + * of setting those values. 1144 + * 1145 + * We also use physical address 0x4 here to tell when a cpu 1146 + * is in its holding pattern code. 1147 + * 1148 + * -- Cort 1149 + */ 1150 + static void __init prom_hold_cpus(void) 1151 + { 1152 + #ifdef CONFIG_PPC64 1153 + unsigned long i; 1154 + unsigned int reg; 1155 + phandle node; 1156 + char type[64]; 1157 + int cpuid = 0; 1158 + unsigned int interrupt_server[MAX_CPU_THREADS]; 1159 + unsigned int cpu_threads, hw_cpu_num; 1160 + int propsize; 1161 + extern void __secondary_hold(void); 1162 + extern unsigned long __secondary_hold_spinloop; 1163 + extern unsigned long __secondary_hold_acknowledge; 1164 + unsigned long *spinloop 1165 + = (void *) __pa(&__secondary_hold_spinloop); 1166 + unsigned long *acknowledge 1167 + = (void *) __pa(&__secondary_hold_acknowledge); 1168 + #ifdef CONFIG_PPC64 1169 + unsigned long secondary_hold 1170 + = __pa(*PTRRELOC((unsigned long *)__secondary_hold)); 1171 + #else 1172 + unsigned long secondary_hold = __pa(&__secondary_hold); 1173 + #endif 1174 + struct prom_t *_prom = &RELOC(prom); 1175 + 1176 + prom_debug("prom_hold_cpus: start...\n"); 1177 + prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); 1178 + prom_debug(" 1) *spinloop = 0x%x\n", *spinloop); 1179 + prom_debug(" 1) acknowledge = 0x%x\n", 1180 + (unsigned long)acknowledge); 1181 + prom_debug(" 1) *acknowledge = 0x%x\n", *acknowledge); 1182 + prom_debug(" 1) secondary_hold = 0x%x\n", secondary_hold); 1183 + 1184 + /* Set the common spinloop variable, so all of the secondary cpus 1185 + * will block when they are awakened from their OF spinloop. 1186 + * This must occur for both SMP and non SMP kernels, since OF will 1187 + * be trashed when we move the kernel. 1188 + */ 1189 + *spinloop = 0; 1190 + 1191 + #ifdef CONFIG_HMT 1192 + for (i = 0; i < NR_CPUS; i++) { 1193 + RELOC(hmt_thread_data)[i].pir = 0xdeadbeef; 1194 + } 1195 + #endif 1196 + /* look for cpus */ 1197 + for (node = 0; prom_next_node(&node); ) { 1198 + type[0] = 0; 1199 + prom_getprop(node, "device_type", type, sizeof(type)); 1200 + if (strcmp(type, RELOC("cpu")) != 0) 1201 + continue; 1202 + 1203 + /* Skip non-configured cpus. */ 1204 + if (prom_getprop(node, "status", type, sizeof(type)) > 0) 1205 + if (strcmp(type, RELOC("okay")) != 0) 1206 + continue; 1207 + 1208 + reg = -1; 1209 + prom_getprop(node, "reg", &reg, sizeof(reg)); 1210 + 1211 + prom_debug("\ncpuid = 0x%x\n", cpuid); 1212 + prom_debug("cpu hw idx = 0x%x\n", reg); 1213 + 1214 + /* Init the acknowledge var which will be reset by 1215 + * the secondary cpu when it awakens from its OF 1216 + * spinloop. 1217 + */ 1218 + *acknowledge = (unsigned long)-1; 1219 + 1220 + propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s", 1221 + &interrupt_server, 1222 + sizeof(interrupt_server)); 1223 + if (propsize < 0) { 1224 + /* no property. old hardware has no SMT */ 1225 + cpu_threads = 1; 1226 + interrupt_server[0] = reg; /* fake it with phys id */ 1227 + } else { 1228 + /* We have a threaded processor */ 1229 + cpu_threads = propsize / sizeof(u32); 1230 + if (cpu_threads > MAX_CPU_THREADS) { 1231 + prom_printf("SMT: too many threads!\n" 1232 + "SMT: found %x, max is %x\n", 1233 + cpu_threads, MAX_CPU_THREADS); 1234 + cpu_threads = 1; /* ToDo: panic? */ 1235 + } 1236 + } 1237 + 1238 + hw_cpu_num = interrupt_server[0]; 1239 + if (hw_cpu_num != _prom->cpu) { 1240 + /* Primary Thread of non-boot cpu */ 1241 + prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg); 1242 + call_prom("start-cpu", 3, 0, node, 1243 + secondary_hold, reg); 1244 + 1245 + for ( i = 0 ; (i < 100000000) && 1246 + (*acknowledge == ((unsigned long)-1)); i++ ) 1247 + mb(); 1248 + 1249 + if (*acknowledge == reg) { 1250 + prom_printf("done\n"); 1251 + /* We have to get every CPU out of OF, 1252 + * even if we never start it. */ 1253 + if (cpuid >= NR_CPUS) 1254 + goto next; 1255 + } else { 1256 + prom_printf("failed: %x\n", *acknowledge); 1257 + } 1258 + } 1259 + #ifdef CONFIG_SMP 1260 + else 1261 + prom_printf("%x : boot cpu %x\n", cpuid, reg); 1262 + #endif 1263 + next: 1264 + #ifdef CONFIG_SMP 1265 + /* Init paca for secondary threads. They start later. */ 1266 + for (i=1; i < cpu_threads; i++) { 1267 + cpuid++; 1268 + if (cpuid >= NR_CPUS) 1269 + continue; 1270 + } 1271 + #endif /* CONFIG_SMP */ 1272 + cpuid++; 1273 + } 1274 + #ifdef CONFIG_HMT 1275 + /* Only enable HMT on processors that provide support. */ 1276 + if (__is_processor(PV_PULSAR) || 1277 + __is_processor(PV_ICESTAR) || 1278 + __is_processor(PV_SSTAR)) { 1279 + prom_printf(" starting secondary threads\n"); 1280 + 1281 + for (i = 0; i < NR_CPUS; i += 2) { 1282 + if (!cpu_online(i)) 1283 + continue; 1284 + 1285 + if (i == 0) { 1286 + unsigned long pir = mfspr(SPRN_PIR); 1287 + if (__is_processor(PV_PULSAR)) { 1288 + RELOC(hmt_thread_data)[i].pir = 1289 + pir & 0x1f; 1290 + } else { 1291 + RELOC(hmt_thread_data)[i].pir = 1292 + pir & 0x3ff; 1293 + } 1294 + } 1295 + } 1296 + } else { 1297 + prom_printf("Processor is not HMT capable\n"); 1298 + } 1299 + #endif 1300 + 1301 + if (cpuid > NR_CPUS) 1302 + prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS) 1303 + ") exceeded: ignoring extras\n"); 1304 + 1305 + prom_debug("prom_hold_cpus: end...\n"); 1306 + #endif 1307 + } 1308 + 1309 + 1310 + static void __init prom_init_client_services(unsigned long pp) 1311 + { 1312 + struct prom_t *_prom = &RELOC(prom); 1313 + 1314 + /* Get a handle to the prom entry point before anything else */ 1315 + RELOC(prom_entry) = pp; 1316 + 1317 + /* get a handle for the stdout device */ 1318 + _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); 1319 + if (!PHANDLE_VALID(_prom->chosen)) 1320 + prom_panic("cannot find chosen"); /* msg won't be printed :( */ 1321 + 1322 + /* get device tree root */ 1323 + _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); 1324 + if (!PHANDLE_VALID(_prom->root)) 1325 + prom_panic("cannot find device tree root"); /* msg won't be printed :( */ 1326 + } 1327 + 1328 + static void __init prom_init_stdout(void) 1329 + { 1330 + struct prom_t *_prom = &RELOC(prom); 1331 + char *path = RELOC(of_stdout_device); 1332 + char type[16]; 1333 + u32 val; 1334 + 1335 + if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0) 1336 + prom_panic("cannot find stdout"); 1337 + 1338 + _prom->stdout = val; 1339 + 1340 + /* Get the full OF pathname of the stdout device */ 1341 + memset(path, 0, 256); 1342 + call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255); 1343 + val = call_prom("instance-to-package", 1, 1, _prom->stdout); 1344 + prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val)); 1345 + prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device)); 1346 + prom_setprop(_prom->chosen, "linux,stdout-path", 1347 + RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1); 1348 + 1349 + /* If it's a display, note it */ 1350 + memset(type, 0, sizeof(type)); 1351 + prom_getprop(val, "device_type", type, sizeof(type)); 1352 + if (strcmp(type, RELOC("display")) == 0) 1353 + prom_setprop(val, "linux,boot-display", NULL, 0); 1354 + } 1355 + 1356 + static void __init prom_close_stdin(void) 1357 + { 1358 + struct prom_t *_prom = &RELOC(prom); 1359 + ihandle val; 1360 + 1361 + if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0) 1362 + call_prom("close", 1, 0, val); 1363 + } 1364 + 1365 + static int __init prom_find_machine_type(void) 1366 + { 1367 + struct prom_t *_prom = &RELOC(prom); 1368 + char compat[256]; 1369 + int len, i = 0; 1370 + phandle rtas; 1371 + 1372 + len = prom_getprop(_prom->root, "compatible", 1373 + compat, sizeof(compat)-1); 1374 + if (len > 0) { 1375 + compat[len] = 0; 1376 + while (i < len) { 1377 + char *p = &compat[i]; 1378 + int sl = strlen(p); 1379 + if (sl == 0) 1380 + break; 1381 + if (strstr(p, RELOC("Power Macintosh")) || 1382 + strstr(p, RELOC("MacRISC4"))) 1383 + return PLATFORM_POWERMAC; 1384 + #ifdef CONFIG_PPC64 1385 + if (strstr(p, RELOC("Momentum,Maple"))) 1386 + return PLATFORM_MAPLE; 1387 + #endif 1388 + i += sl + 1; 1389 + } 1390 + } 1391 + #ifdef CONFIG_PPC64 1392 + /* Default to pSeries. We need to know if we are running LPAR */ 1393 + rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); 1394 + if (PHANDLE_VALID(rtas)) { 1395 + int x = prom_getproplen(rtas, "ibm,hypertas-functions"); 1396 + if (x != PROM_ERROR) { 1397 + prom_printf("Hypertas detected, assuming LPAR !\n"); 1398 + return PLATFORM_PSERIES_LPAR; 1399 + } 1400 + } 1401 + return PLATFORM_PSERIES; 1402 + #else 1403 + return PLATFORM_CHRP; 1404 + #endif 1405 + } 1406 + 1407 + static int __init setup_disp(phandle dp) 1408 + { 1409 + #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) 1410 + int width = 640, height = 480, depth = 8, pitch; 1411 + unsigned address; 1412 + u32 addrs[8][5]; 1413 + int i, naddrs; 1414 + char name[32]; 1415 + char *getprop = "getprop"; 1416 + 1417 + prom_printf("Initializing screen: "); 1418 + 1419 + memset(name, 0, sizeof(name)); 1420 + call_prom(getprop, 4, 1, dp, "name", name, sizeof(name)); 1421 + name[sizeof(name)-1] = 0; 1422 + prom_print(name); 1423 + prom_print("\n"); 1424 + call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width)); 1425 + call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height)); 1426 + call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth)); 1427 + pitch = width * ((depth + 7) / 8); 1428 + call_prom(getprop, 4, 1, dp, "linebytes", 1429 + &pitch, sizeof(pitch)); 1430 + if (pitch == 1) 1431 + pitch = 0x1000; /* for strange IBM display */ 1432 + address = 0; 1433 + call_prom(getprop, 4, 1, dp, "address", &address, sizeof(address)); 1434 + if (address == 0) { 1435 + /* look for an assigned address with a size of >= 1MB */ 1436 + naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses", 1437 + addrs, sizeof(addrs)); 1438 + naddrs /= 20; 1439 + for (i = 0; i < naddrs; ++i) { 1440 + if (addrs[i][4] >= (1 << 20)) { 1441 + address = addrs[i][2]; 1442 + /* use the BE aperture if possible */ 1443 + if (addrs[i][4] >= (16 << 20)) 1444 + address += (8 << 20); 1445 + break; 1446 + } 1447 + } 1448 + if (address == 0) { 1449 + prom_print("Failed to get address\n"); 1450 + return 0; 1451 + } 1452 + } 1453 + /* kludge for valkyrie */ 1454 + if (strcmp(name, "valkyrie") == 0) 1455 + address += 0x1000; 1456 + 1457 + prom_printf("\n\n\n\naddress = %x\n", address); 1458 + btext_setup_display(width, height, depth, pitch, address); 1459 + #endif /* CONFIG_BOOTX_TEXT && CONFIG_PPC32 */ 1460 + return 1; 1461 + } 1462 + 1463 + static int __init prom_set_color(ihandle ih, int i, int r, int g, int b) 1464 + { 1465 + return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r); 1466 + } 1467 + 1468 + /* 1469 + * If we have a display that we don't know how to drive, 1470 + * we will want to try to execute OF's open method for it 1471 + * later. However, OF will probably fall over if we do that 1472 + * we've taken over the MMU. 1473 + * So we check whether we will need to open the display, 1474 + * and if so, open it now. 1475 + */ 1476 + static void __init prom_check_displays(void) 1477 + { 1478 + char type[16], *path; 1479 + phandle node; 1480 + ihandle ih; 1481 + int i; 1482 + int got_display = 0; 1483 + 1484 + static unsigned char default_colors[] = { 1485 + 0x00, 0x00, 0x00, 1486 + 0x00, 0x00, 0xaa, 1487 + 0x00, 0xaa, 0x00, 1488 + 0x00, 0xaa, 0xaa, 1489 + 0xaa, 0x00, 0x00, 1490 + 0xaa, 0x00, 0xaa, 1491 + 0xaa, 0xaa, 0x00, 1492 + 0xaa, 0xaa, 0xaa, 1493 + 0x55, 0x55, 0x55, 1494 + 0x55, 0x55, 0xff, 1495 + 0x55, 0xff, 0x55, 1496 + 0x55, 0xff, 0xff, 1497 + 0xff, 0x55, 0x55, 1498 + 0xff, 0x55, 0xff, 1499 + 0xff, 0xff, 0x55, 1500 + 0xff, 0xff, 0xff 1501 + }; 1502 + const unsigned char *clut; 1503 + 1504 + prom_printf("Looking for displays\n"); 1505 + for (node = 0; prom_next_node(&node); ) { 1506 + memset(type, 0, sizeof(type)); 1507 + prom_getprop(node, "device_type", type, sizeof(type)); 1508 + if (strcmp(type, RELOC("display")) != 0) 1509 + continue; 1510 + 1511 + /* It seems OF doesn't null-terminate the path :-( */ 1512 + path = RELOC(prom_scratch); 1513 + memset(path, 0, PROM_SCRATCH_SIZE); 1514 + 1515 + /* 1516 + * leave some room at the end of the path for appending extra 1517 + * arguments 1518 + */ 1519 + if (call_prom("package-to-path", 3, 1, node, path, 1520 + PROM_SCRATCH_SIZE-10) == PROM_ERROR) 1521 + continue; 1522 + prom_printf("found display : %s, opening ... ", path); 1523 + 1524 + ih = call_prom("open", 1, 1, path); 1525 + if (ih == 0) { 1526 + prom_printf("failed\n"); 1527 + continue; 1528 + } 1529 + 1530 + /* Success */ 1531 + prom_printf("done\n"); 1532 + prom_setprop(node, "linux,opened", NULL, 0); 1533 + 1534 + /* Setup a usable color table when the appropriate 1535 + * method is available. Should update this to set-colors */ 1536 + clut = RELOC(default_colors); 1537 + for (i = 0; i < 32; i++, clut += 3) 1538 + if (prom_set_color(ih, i, clut[0], clut[1], 1539 + clut[2]) != 0) 1540 + break; 1541 + 1542 + #ifdef CONFIG_LOGO_LINUX_CLUT224 1543 + clut = PTRRELOC(RELOC(logo_linux_clut224.clut)); 1544 + for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3) 1545 + if (prom_set_color(ih, i + 32, clut[0], clut[1], 1546 + clut[2]) != 0) 1547 + break; 1548 + #endif /* CONFIG_LOGO_LINUX_CLUT224 */ 1549 + if (!got_display) 1550 + got_display = setup_disp(node); 1551 + } 1552 + } 1553 + 1554 + 1555 + /* Return (relocated) pointer to this much memory: moves initrd if reqd. */ 1556 + static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, 1557 + unsigned long needed, unsigned long align) 1558 + { 1559 + void *ret; 1560 + 1561 + *mem_start = _ALIGN(*mem_start, align); 1562 + while ((*mem_start + needed) > *mem_end) { 1563 + unsigned long room, chunk; 1564 + 1565 + prom_debug("Chunk exhausted, claiming more at %x...\n", 1566 + RELOC(alloc_bottom)); 1567 + room = RELOC(alloc_top) - RELOC(alloc_bottom); 1568 + if (room > DEVTREE_CHUNK_SIZE) 1569 + room = DEVTREE_CHUNK_SIZE; 1570 + if (room < PAGE_SIZE) 1571 + prom_panic("No memory for flatten_device_tree (no room)"); 1572 + chunk = alloc_up(room, 0); 1573 + if (chunk == 0) 1574 + prom_panic("No memory for flatten_device_tree (claim failed)"); 1575 + *mem_end = RELOC(alloc_top); 1576 + } 1577 + 1578 + ret = (void *)*mem_start; 1579 + *mem_start += needed; 1580 + 1581 + return ret; 1582 + } 1583 + 1584 + #define dt_push_token(token, mem_start, mem_end) \ 1585 + do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0) 1586 + 1587 + static unsigned long __init dt_find_string(char *str) 1588 + { 1589 + char *s, *os; 1590 + 1591 + s = os = (char *)RELOC(dt_string_start); 1592 + s += 4; 1593 + while (s < (char *)RELOC(dt_string_end)) { 1594 + if (strcmp(s, str) == 0) 1595 + return s - os; 1596 + s += strlen(s) + 1; 1597 + } 1598 + return 0; 1599 + } 1600 + 1601 + /* 1602 + * The Open Firmware 1275 specification states properties must be 31 bytes or 1603 + * less, however not all firmwares obey this. Make it 64 bytes to be safe. 1604 + */ 1605 + #define MAX_PROPERTY_NAME 64 1606 + 1607 + static void __init scan_dt_build_strings(phandle node, 1608 + unsigned long *mem_start, 1609 + unsigned long *mem_end) 1610 + { 1611 + char *prev_name, *namep, *sstart; 1612 + unsigned long soff; 1613 + phandle child; 1614 + 1615 + sstart = (char *)RELOC(dt_string_start); 1616 + 1617 + /* get and store all property names */ 1618 + prev_name = RELOC(""); 1619 + for (;;) { 1620 + /* 64 is max len of name including nul. */ 1621 + namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1); 1622 + if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) { 1623 + /* No more nodes: unwind alloc */ 1624 + *mem_start = (unsigned long)namep; 1625 + break; 1626 + } 1627 + 1628 + /* skip "name" */ 1629 + if (strcmp(namep, RELOC("name")) == 0) { 1630 + *mem_start = (unsigned long)namep; 1631 + prev_name = RELOC("name"); 1632 + continue; 1633 + } 1634 + /* get/create string entry */ 1635 + soff = dt_find_string(namep); 1636 + if (soff != 0) { 1637 + *mem_start = (unsigned long)namep; 1638 + namep = sstart + soff; 1639 + } else { 1640 + /* Trim off some if we can */ 1641 + *mem_start = (unsigned long)namep + strlen(namep) + 1; 1642 + RELOC(dt_string_end) = *mem_start; 1643 + } 1644 + prev_name = namep; 1645 + } 1646 + 1647 + /* do all our children */ 1648 + child = call_prom("child", 1, 1, node); 1649 + while (child != 0) { 1650 + scan_dt_build_strings(child, mem_start, mem_end); 1651 + child = call_prom("peer", 1, 1, child); 1652 + } 1653 + } 1654 + 1655 + static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, 1656 + unsigned long *mem_end) 1657 + { 1658 + phandle child; 1659 + char *namep, *prev_name, *sstart, *p, *ep, *lp, *path; 1660 + unsigned long soff; 1661 + unsigned char *valp; 1662 + static char pname[MAX_PROPERTY_NAME]; 1663 + int l; 1664 + 1665 + dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end); 1666 + 1667 + /* get the node's full name */ 1668 + namep = (char *)*mem_start; 1669 + l = call_prom("package-to-path", 3, 1, node, 1670 + namep, *mem_end - *mem_start); 1671 + if (l >= 0) { 1672 + /* Didn't fit? Get more room. */ 1673 + if ((l+1) > (*mem_end - *mem_start)) { 1674 + namep = make_room(mem_start, mem_end, l+1, 1); 1675 + call_prom("package-to-path", 3, 1, node, namep, l); 1676 + } 1677 + namep[l] = '\0'; 1678 + 1679 + /* Fixup an Apple bug where they have bogus \0 chars in the 1680 + * middle of the path in some properties 1681 + */ 1682 + for (p = namep, ep = namep + l; p < ep; p++) 1683 + if (*p == '\0') { 1684 + memmove(p, p+1, ep - p); 1685 + ep--; l--; p--; 1686 + } 1687 + 1688 + /* now try to extract the unit name in that mess */ 1689 + for (p = namep, lp = NULL; *p; p++) 1690 + if (*p == '/') 1691 + lp = p + 1; 1692 + if (lp != NULL) 1693 + memmove(namep, lp, strlen(lp) + 1); 1694 + *mem_start = _ALIGN(((unsigned long) namep) + 1695 + strlen(namep) + 1, 4); 1696 + } 1697 + 1698 + /* get it again for debugging */ 1699 + path = RELOC(prom_scratch); 1700 + memset(path, 0, PROM_SCRATCH_SIZE); 1701 + call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1); 1702 + 1703 + /* get and store all properties */ 1704 + prev_name = RELOC(""); 1705 + sstart = (char *)RELOC(dt_string_start); 1706 + for (;;) { 1707 + if (call_prom("nextprop", 3, 1, node, prev_name, 1708 + RELOC(pname)) != 1) 1709 + break; 1710 + 1711 + /* skip "name" */ 1712 + if (strcmp(RELOC(pname), RELOC("name")) == 0) { 1713 + prev_name = RELOC("name"); 1714 + continue; 1715 + } 1716 + 1717 + /* find string offset */ 1718 + soff = dt_find_string(RELOC(pname)); 1719 + if (soff == 0) { 1720 + prom_printf("WARNING: Can't find string index for" 1721 + " <%s>, node %s\n", RELOC(pname), path); 1722 + break; 1723 + } 1724 + prev_name = sstart + soff; 1725 + 1726 + /* get length */ 1727 + l = call_prom("getproplen", 2, 1, node, RELOC(pname)); 1728 + 1729 + /* sanity checks */ 1730 + if (l == PROM_ERROR) 1731 + continue; 1732 + if (l > MAX_PROPERTY_LENGTH) { 1733 + prom_printf("WARNING: ignoring large property "); 1734 + /* It seems OF doesn't null-terminate the path :-( */ 1735 + prom_printf("[%s] ", path); 1736 + prom_printf("%s length 0x%x\n", RELOC(pname), l); 1737 + continue; 1738 + } 1739 + 1740 + /* push property head */ 1741 + dt_push_token(OF_DT_PROP, mem_start, mem_end); 1742 + dt_push_token(l, mem_start, mem_end); 1743 + dt_push_token(soff, mem_start, mem_end); 1744 + 1745 + /* push property content */ 1746 + valp = make_room(mem_start, mem_end, l, 4); 1747 + call_prom("getprop", 4, 1, node, RELOC(pname), valp, l); 1748 + *mem_start = _ALIGN(*mem_start, 4); 1749 + } 1750 + 1751 + /* Add a "linux,phandle" property. */ 1752 + soff = dt_find_string(RELOC("linux,phandle")); 1753 + if (soff == 0) 1754 + prom_printf("WARNING: Can't find string index for" 1755 + " <linux-phandle> node %s\n", path); 1756 + else { 1757 + dt_push_token(OF_DT_PROP, mem_start, mem_end); 1758 + dt_push_token(4, mem_start, mem_end); 1759 + dt_push_token(soff, mem_start, mem_end); 1760 + valp = make_room(mem_start, mem_end, 4, 4); 1761 + *(u32 *)valp = node; 1762 + } 1763 + 1764 + /* do all our children */ 1765 + child = call_prom("child", 1, 1, node); 1766 + while (child != 0) { 1767 + scan_dt_build_struct(child, mem_start, mem_end); 1768 + child = call_prom("peer", 1, 1, child); 1769 + } 1770 + 1771 + dt_push_token(OF_DT_END_NODE, mem_start, mem_end); 1772 + } 1773 + 1774 + static void __init flatten_device_tree(void) 1775 + { 1776 + phandle root; 1777 + unsigned long mem_start, mem_end, room; 1778 + struct boot_param_header *hdr; 1779 + struct prom_t *_prom = &RELOC(prom); 1780 + char *namep; 1781 + u64 *rsvmap; 1782 + 1783 + /* 1784 + * Check how much room we have between alloc top & bottom (+/- a 1785 + * few pages), crop to 4Mb, as this is our "chuck" size 1786 + */ 1787 + room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000; 1788 + if (room > DEVTREE_CHUNK_SIZE) 1789 + room = DEVTREE_CHUNK_SIZE; 1790 + prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom)); 1791 + 1792 + /* Now try to claim that */ 1793 + mem_start = (unsigned long)alloc_up(room, PAGE_SIZE); 1794 + if (mem_start == 0) 1795 + prom_panic("Can't allocate initial device-tree chunk\n"); 1796 + mem_end = RELOC(alloc_top); 1797 + 1798 + /* Get root of tree */ 1799 + root = call_prom("peer", 1, 1, (phandle)0); 1800 + if (root == (phandle)0) 1801 + prom_panic ("couldn't get device tree root\n"); 1802 + 1803 + /* Build header and make room for mem rsv map */ 1804 + mem_start = _ALIGN(mem_start, 4); 1805 + hdr = make_room(&mem_start, &mem_end, 1806 + sizeof(struct boot_param_header), 4); 1807 + RELOC(dt_header_start) = (unsigned long)hdr; 1808 + rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8); 1809 + 1810 + /* Start of strings */ 1811 + mem_start = PAGE_ALIGN(mem_start); 1812 + RELOC(dt_string_start) = mem_start; 1813 + mem_start += 4; /* hole */ 1814 + 1815 + /* Add "linux,phandle" in there, we'll need it */ 1816 + namep = make_room(&mem_start, &mem_end, 16, 1); 1817 + strcpy(namep, RELOC("linux,phandle")); 1818 + mem_start = (unsigned long)namep + strlen(namep) + 1; 1819 + 1820 + /* Build string array */ 1821 + prom_printf("Building dt strings...\n"); 1822 + scan_dt_build_strings(root, &mem_start, &mem_end); 1823 + RELOC(dt_string_end) = mem_start; 1824 + 1825 + /* Build structure */ 1826 + mem_start = PAGE_ALIGN(mem_start); 1827 + RELOC(dt_struct_start) = mem_start; 1828 + prom_printf("Building dt structure...\n"); 1829 + scan_dt_build_struct(root, &mem_start, &mem_end); 1830 + dt_push_token(OF_DT_END, &mem_start, &mem_end); 1831 + RELOC(dt_struct_end) = PAGE_ALIGN(mem_start); 1832 + 1833 + /* Finish header */ 1834 + hdr->boot_cpuid_phys = _prom->cpu; 1835 + hdr->magic = OF_DT_HEADER; 1836 + hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start); 1837 + hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start); 1838 + hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start); 1839 + hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start); 1840 + hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start); 1841 + hdr->version = OF_DT_VERSION; 1842 + /* Version 16 is not backward compatible */ 1843 + hdr->last_comp_version = 0x10; 1844 + 1845 + /* Reserve the whole thing and copy the reserve map in, we 1846 + * also bump mem_reserve_cnt to cause further reservations to 1847 + * fail since it's too late. 1848 + */ 1849 + reserve_mem(RELOC(dt_header_start), hdr->totalsize); 1850 + memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map)); 1851 + 1852 + #ifdef DEBUG_PROM 1853 + { 1854 + int i; 1855 + prom_printf("reserved memory map:\n"); 1856 + for (i = 0; i < RELOC(mem_reserve_cnt); i++) 1857 + prom_printf(" %x - %x\n", 1858 + RELOC(mem_reserve_map)[i].base, 1859 + RELOC(mem_reserve_map)[i].size); 1860 + } 1861 + #endif 1862 + RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE; 1863 + 1864 + prom_printf("Device tree strings 0x%x -> 0x%x\n", 1865 + RELOC(dt_string_start), RELOC(dt_string_end)); 1866 + prom_printf("Device tree struct 0x%x -> 0x%x\n", 1867 + RELOC(dt_struct_start), RELOC(dt_struct_end)); 1868 + 1869 + } 1870 + 1871 + 1872 + static void __init fixup_device_tree(void) 1873 + { 1874 + #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC) 1875 + phandle u3, i2c, mpic; 1876 + u32 u3_rev; 1877 + u32 interrupts[2]; 1878 + u32 parent; 1879 + 1880 + /* Some G5s have a missing interrupt definition, fix it up here */ 1881 + u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); 1882 + if (!PHANDLE_VALID(u3)) 1883 + return; 1884 + i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); 1885 + if (!PHANDLE_VALID(i2c)) 1886 + return; 1887 + mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); 1888 + if (!PHANDLE_VALID(mpic)) 1889 + return; 1890 + 1891 + /* check if proper rev of u3 */ 1892 + if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) 1893 + == PROM_ERROR) 1894 + return; 1895 + if (u3_rev != 0x35 && u3_rev != 0x37) 1896 + return; 1897 + /* does it need fixup ? */ 1898 + if (prom_getproplen(i2c, "interrupts") > 0) 1899 + return; 1900 + 1901 + prom_printf("fixing up bogus interrupts for u3 i2c...\n"); 1902 + 1903 + /* interrupt on this revision of u3 is number 0 and level */ 1904 + interrupts[0] = 0; 1905 + interrupts[1] = 1; 1906 + prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts)); 1907 + parent = (u32)mpic; 1908 + prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent)); 1909 + #endif 1910 + } 1911 + 1912 + 1913 + static void __init prom_find_boot_cpu(void) 1914 + { 1915 + struct prom_t *_prom = &RELOC(prom); 1916 + u32 getprop_rval; 1917 + ihandle prom_cpu; 1918 + phandle cpu_pkg; 1919 + 1920 + if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0) 1921 + prom_panic("cannot find boot cpu"); 1922 + 1923 + cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu); 1924 + 1925 + prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); 1926 + _prom->cpu = getprop_rval; 1927 + 1928 + prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu); 1929 + } 1930 + 1931 + static void __init prom_check_initrd(unsigned long r3, unsigned long r4) 1932 + { 1933 + #ifdef CONFIG_BLK_DEV_INITRD 1934 + struct prom_t *_prom = &RELOC(prom); 1935 + 1936 + if (r3 && r4 && r4 != 0xdeadbeef) { 1937 + unsigned long val; 1938 + 1939 + RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; 1940 + RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; 1941 + 1942 + val = RELOC(prom_initrd_start); 1943 + prom_setprop(_prom->chosen, "linux,initrd-start", &val, 1944 + sizeof(val)); 1945 + val = RELOC(prom_initrd_end); 1946 + prom_setprop(_prom->chosen, "linux,initrd-end", &val, 1947 + sizeof(val)); 1948 + 1949 + reserve_mem(RELOC(prom_initrd_start), 1950 + RELOC(prom_initrd_end) - RELOC(prom_initrd_start)); 1951 + 1952 + prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start)); 1953 + prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end)); 1954 + } 1955 + #endif /* CONFIG_BLK_DEV_INITRD */ 1956 + } 1957 + 1958 + /* 1959 + * We enter here early on, when the Open Firmware prom is still 1960 + * handling exceptions and the MMU hash table for us. 1961 + */ 1962 + 1963 + unsigned long __init prom_init(unsigned long r3, unsigned long r4, 1964 + unsigned long pp, 1965 + unsigned long r6, unsigned long r7) 1966 + { 1967 + struct prom_t *_prom; 1968 + extern char _stext[]; 1969 + unsigned long hdr; 1970 + u32 getprop_rval; 1971 + 1972 + #ifdef CONFIG_PPC32 1973 + unsigned long offset = reloc_offset(); 1974 + reloc_got2(offset); 1975 + #endif 1976 + 1977 + _prom = &RELOC(prom); 1978 + 1979 + /* 1980 + * First zero the BSS 1981 + */ 1982 + memset(&RELOC(__bss_start), 0, __bss_stop - __bss_start); 1983 + 1984 + /* 1985 + * Init interface to Open Firmware, get some node references, 1986 + * like /chosen 1987 + */ 1988 + prom_init_client_services(pp); 1989 + 1990 + /* 1991 + * Init prom stdout device 1992 + */ 1993 + prom_init_stdout(); 1994 + 1995 + /* 1996 + * Check for an initrd 1997 + */ 1998 + prom_check_initrd(r3, r4); 1999 + 2000 + /* 2001 + * Get default machine type. At this point, we do not differentiate 2002 + * between pSeries SMP and pSeries LPAR 2003 + */ 2004 + RELOC(of_platform) = prom_find_machine_type(); 2005 + getprop_rval = RELOC(of_platform); 2006 + prom_setprop(_prom->chosen, "linux,platform", 2007 + &getprop_rval, sizeof(getprop_rval)); 2008 + 2009 + #ifdef CONFIG_PPC_PSERIES 2010 + /* 2011 + * On pSeries, inform the firmware about our capabilities 2012 + */ 2013 + if (RELOC(of_platform) & PLATFORM_PSERIES) 2014 + prom_send_capabilities(); 2015 + #endif 2016 + 2017 + #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_BPA) 2018 + /* 2019 + * On pSeries and BPA, copy the CPU hold code 2020 + */ 2021 + if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA)) 2022 + copy_and_flush(0, KERNELBASE - offset, 0x100, 0); 2023 + #endif 2024 + 2025 + /* 2026 + * Do early parsing of command line 2027 + */ 2028 + early_cmdline_parse(); 2029 + 2030 + /* 2031 + * Initialize memory management within prom_init 2032 + */ 2033 + prom_init_mem(); 2034 + 2035 + /* 2036 + * Determine which cpu is actually running right _now_ 2037 + */ 2038 + prom_find_boot_cpu(); 2039 + 2040 + /* 2041 + * Initialize display devices 2042 + */ 2043 + prom_check_displays(); 2044 + 2045 + #ifdef CONFIG_PPC64 2046 + /* 2047 + * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else 2048 + * that uses the allocator, we need to make sure we get the top of memory 2049 + * available for us here... 2050 + */ 2051 + if (RELOC(of_platform) == PLATFORM_PSERIES) 2052 + prom_initialize_tce_table(); 2053 + #endif 2054 + 2055 + /* 2056 + * On non-powermacs, try to instantiate RTAS and puts all CPUs 2057 + * in spin-loops. PowerMacs don't have a working RTAS and use 2058 + * a different way to spin CPUs 2059 + */ 2060 + if (RELOC(of_platform) != PLATFORM_POWERMAC) { 2061 + prom_instantiate_rtas(); 2062 + prom_hold_cpus(); 2063 + } 2064 + 2065 + /* 2066 + * Fill in some infos for use by the kernel later on 2067 + */ 2068 + if (RELOC(prom_memory_limit)) 2069 + prom_setprop(_prom->chosen, "linux,memory-limit", 2070 + &RELOC(prom_memory_limit), 2071 + sizeof(prom_memory_limit)); 2072 + #ifdef CONFIG_PPC64 2073 + if (RELOC(ppc64_iommu_off)) 2074 + prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0); 2075 + 2076 + if (RELOC(iommu_force_on)) 2077 + prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0); 2078 + 2079 + if (RELOC(prom_tce_alloc_start)) { 2080 + prom_setprop(_prom->chosen, "linux,tce-alloc-start", 2081 + &RELOC(prom_tce_alloc_start), 2082 + sizeof(prom_tce_alloc_start)); 2083 + prom_setprop(_prom->chosen, "linux,tce-alloc-end", 2084 + &RELOC(prom_tce_alloc_end), 2085 + sizeof(prom_tce_alloc_end)); 2086 + } 2087 + #endif 2088 + 2089 + /* 2090 + * Fixup any known bugs in the device-tree 2091 + */ 2092 + fixup_device_tree(); 2093 + 2094 + /* 2095 + * Now finally create the flattened device-tree 2096 + */ 2097 + prom_printf("copying OF device tree ...\n"); 2098 + flatten_device_tree(); 2099 + 2100 + /* in case stdin is USB and still active on IBM machines... */ 2101 + prom_close_stdin(); 2102 + 2103 + /* 2104 + * Call OF "quiesce" method to shut down pending DMA's from 2105 + * devices etc... 2106 + */ 2107 + prom_printf("Calling quiesce ...\n"); 2108 + call_prom("quiesce", 0, 0); 2109 + 2110 + /* 2111 + * And finally, call the kernel passing it the flattened device 2112 + * tree and NULL as r5, thus triggering the new entry point which 2113 + * is common to us and kexec 2114 + */ 2115 + hdr = RELOC(dt_header_start); 2116 + prom_printf("returning from prom_init\n"); 2117 + prom_debug("->dt_header_start=0x%x\n", hdr); 2118 + 2119 + #ifdef CONFIG_PPC32 2120 + reloc_got2(-offset); 2121 + #endif 2122 + 2123 + __start(hdr, 0, 0); 2124 + 2125 + return 0; 2126 + }
+678
arch/powerpc/kernel/setup.c
··· 1 + /* 2 + * Common prep/pmac/chrp boot and setup code. 3 + */ 4 + 5 + #include <linux/config.h> 6 + #include <linux/module.h> 7 + #include <linux/string.h> 8 + #include <linux/sched.h> 9 + #include <linux/init.h> 10 + #include <linux/kernel.h> 11 + #include <linux/reboot.h> 12 + #include <linux/delay.h> 13 + #include <linux/initrd.h> 14 + #include <linux/ide.h> 15 + #include <linux/tty.h> 16 + #include <linux/bootmem.h> 17 + #include <linux/seq_file.h> 18 + #include <linux/root_dev.h> 19 + #include <linux/cpu.h> 20 + #include <linux/console.h> 21 + 22 + #include <asm/residual.h> 23 + #include <asm/io.h> 24 + #include <asm/prom.h> 25 + #include <asm/processor.h> 26 + #include <asm/pgtable.h> 27 + #include <asm/bootinfo.h> 28 + #include <asm/setup.h> 29 + #include <asm/amigappc.h> 30 + #include <asm/smp.h> 31 + #include <asm/elf.h> 32 + #include <asm/cputable.h> 33 + #include <asm/bootx.h> 34 + #include <asm/btext.h> 35 + #include <asm/machdep.h> 36 + #include <asm/uaccess.h> 37 + #include <asm/system.h> 38 + #include <asm/pmac_feature.h> 39 + #include <asm/sections.h> 40 + #include <asm/nvram.h> 41 + #include <asm/xmon.h> 42 + #include <asm/ocp.h> 43 + 44 + #define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \ 45 + defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ 46 + defined(CONFIG_PPC_MPC52xx)) 47 + 48 + #if USES_PPC_SYS 49 + #include <asm/ppc_sys.h> 50 + #endif 51 + 52 + #if defined CONFIG_KGDB 53 + #include <asm/kgdb.h> 54 + #endif 55 + 56 + extern void platform_init(void); 57 + extern void bootx_init(unsigned long r4, unsigned long phys); 58 + 59 + extern void ppc6xx_idle(void); 60 + extern void power4_idle(void); 61 + 62 + boot_infos_t *boot_infos; 63 + struct ide_machdep_calls ppc_ide_md; 64 + 65 + /* Used with the BI_MEMSIZE bootinfo parameter to store the memory 66 + size value reported by the boot loader. */ 67 + unsigned long boot_mem_size; 68 + 69 + unsigned long ISA_DMA_THRESHOLD; 70 + unsigned int DMA_MODE_READ; 71 + unsigned int DMA_MODE_WRITE; 72 + 73 + #ifdef CONFIG_PPC_MULTIPLATFORM 74 + int _machine = 0; 75 + 76 + extern void prep_init(void); 77 + extern void pmac_init(void); 78 + extern void chrp_init(void); 79 + 80 + dev_t boot_dev; 81 + #endif /* CONFIG_PPC_MULTIPLATFORM */ 82 + 83 + #ifdef CONFIG_MAGIC_SYSRQ 84 + unsigned long SYSRQ_KEY = 0x54; 85 + #endif /* CONFIG_MAGIC_SYSRQ */ 86 + 87 + #ifdef CONFIG_VGA_CONSOLE 88 + unsigned long vgacon_remap_base; 89 + #endif 90 + 91 + struct machdep_calls ppc_md; 92 + 93 + /* 94 + * These are used in binfmt_elf.c to put aux entries on the stack 95 + * for each elf executable being started. 96 + */ 97 + int dcache_bsize; 98 + int icache_bsize; 99 + int ucache_bsize; 100 + 101 + #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \ 102 + defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA) 103 + struct screen_info screen_info = { 104 + 0, 25, /* orig-x, orig-y */ 105 + 0, /* unused */ 106 + 0, /* orig-video-page */ 107 + 0, /* orig-video-mode */ 108 + 80, /* orig-video-cols */ 109 + 0,0,0, /* ega_ax, ega_bx, ega_cx */ 110 + 25, /* orig-video-lines */ 111 + 1, /* orig-video-isVGA */ 112 + 16 /* orig-video-points */ 113 + }; 114 + #endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */ 115 + 116 + void machine_restart(char *cmd) 117 + { 118 + #ifdef CONFIG_NVRAM 119 + nvram_sync(); 120 + #endif 121 + ppc_md.restart(cmd); 122 + } 123 + 124 + void machine_power_off(void) 125 + { 126 + #ifdef CONFIG_NVRAM 127 + nvram_sync(); 128 + #endif 129 + ppc_md.power_off(); 130 + } 131 + 132 + void machine_halt(void) 133 + { 134 + #ifdef CONFIG_NVRAM 135 + nvram_sync(); 136 + #endif 137 + ppc_md.halt(); 138 + } 139 + 140 + void (*pm_power_off)(void) = machine_power_off; 141 + 142 + #ifdef CONFIG_TAU 143 + extern u32 cpu_temp(unsigned long cpu); 144 + extern u32 cpu_temp_both(unsigned long cpu); 145 + #endif /* CONFIG_TAU */ 146 + 147 + int show_cpuinfo(struct seq_file *m, void *v) 148 + { 149 + int i = (int) v - 1; 150 + int err = 0; 151 + unsigned int pvr; 152 + unsigned short maj, min; 153 + unsigned long lpj; 154 + 155 + if (i >= NR_CPUS) { 156 + /* Show summary information */ 157 + #ifdef CONFIG_SMP 158 + unsigned long bogosum = 0; 159 + for (i = 0; i < NR_CPUS; ++i) 160 + if (cpu_online(i)) 161 + bogosum += cpu_data[i].loops_per_jiffy; 162 + seq_printf(m, "total bogomips\t: %lu.%02lu\n", 163 + bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); 164 + #endif /* CONFIG_SMP */ 165 + 166 + if (ppc_md.show_cpuinfo != NULL) 167 + err = ppc_md.show_cpuinfo(m); 168 + return err; 169 + } 170 + 171 + #ifdef CONFIG_SMP 172 + if (!cpu_online(i)) 173 + return 0; 174 + pvr = cpu_data[i].pvr; 175 + lpj = cpu_data[i].loops_per_jiffy; 176 + #else 177 + pvr = mfspr(SPRN_PVR); 178 + lpj = loops_per_jiffy; 179 + #endif 180 + 181 + seq_printf(m, "processor\t: %d\n", i); 182 + seq_printf(m, "cpu\t\t: "); 183 + 184 + if (cur_cpu_spec->pvr_mask) 185 + seq_printf(m, "%s", cur_cpu_spec->cpu_name); 186 + else 187 + seq_printf(m, "unknown (%08x)", pvr); 188 + #ifdef CONFIG_ALTIVEC 189 + if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) 190 + seq_printf(m, ", altivec supported"); 191 + #endif 192 + seq_printf(m, "\n"); 193 + 194 + #ifdef CONFIG_TAU 195 + if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) { 196 + #ifdef CONFIG_TAU_AVERAGE 197 + /* more straightforward, but potentially misleading */ 198 + seq_printf(m, "temperature \t: %u C (uncalibrated)\n", 199 + cpu_temp(i)); 200 + #else 201 + /* show the actual temp sensor range */ 202 + u32 temp; 203 + temp = cpu_temp_both(i); 204 + seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", 205 + temp & 0xff, temp >> 16); 206 + #endif 207 + } 208 + #endif /* CONFIG_TAU */ 209 + 210 + if (ppc_md.show_percpuinfo != NULL) { 211 + err = ppc_md.show_percpuinfo(m, i); 212 + if (err) 213 + return err; 214 + } 215 + 216 + /* If we are a Freescale core do a simple check so 217 + * we dont have to keep adding cases in the future */ 218 + if ((PVR_VER(pvr) & 0x8000) == 0x8000) { 219 + maj = PVR_MAJ(pvr); 220 + min = PVR_MIN(pvr); 221 + } else { 222 + switch (PVR_VER(pvr)) { 223 + case 0x0020: /* 403 family */ 224 + maj = PVR_MAJ(pvr) + 1; 225 + min = PVR_MIN(pvr); 226 + break; 227 + case 0x1008: /* 740P/750P ?? */ 228 + maj = ((pvr >> 8) & 0xFF) - 1; 229 + min = pvr & 0xFF; 230 + break; 231 + default: 232 + maj = (pvr >> 8) & 0xFF; 233 + min = pvr & 0xFF; 234 + break; 235 + } 236 + } 237 + 238 + seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", 239 + maj, min, PVR_VER(pvr), PVR_REV(pvr)); 240 + 241 + seq_printf(m, "bogomips\t: %lu.%02lu\n", 242 + lpj / (500000/HZ), (lpj / (5000/HZ)) % 100); 243 + 244 + #if USES_PPC_SYS 245 + if (cur_ppc_sys_spec->ppc_sys_name) 246 + seq_printf(m, "chipset\t\t: %s\n", 247 + cur_ppc_sys_spec->ppc_sys_name); 248 + #endif 249 + 250 + #ifdef CONFIG_SMP 251 + seq_printf(m, "\n"); 252 + #endif 253 + 254 + return 0; 255 + } 256 + 257 + static void *c_start(struct seq_file *m, loff_t *pos) 258 + { 259 + int i = *pos; 260 + 261 + return i <= NR_CPUS? (void *) (i + 1): NULL; 262 + } 263 + 264 + static void *c_next(struct seq_file *m, void *v, loff_t *pos) 265 + { 266 + ++*pos; 267 + return c_start(m, pos); 268 + } 269 + 270 + static void c_stop(struct seq_file *m, void *v) 271 + { 272 + } 273 + 274 + struct seq_operations cpuinfo_op = { 275 + .start =c_start, 276 + .next = c_next, 277 + .stop = c_stop, 278 + .show = show_cpuinfo, 279 + }; 280 + 281 + /* 282 + * We're called here very early in the boot. We determine the machine 283 + * type and call the appropriate low-level setup functions. 284 + * -- Cort <cort@fsmlabs.com> 285 + * 286 + * Note that the kernel may be running at an address which is different 287 + * from the address that it was linked at, so we must use RELOC/PTRRELOC 288 + * to access static data (including strings). -- paulus 289 + */ 290 + unsigned long __init early_init(unsigned long dt_ptr) 291 + { 292 + unsigned long offset = reloc_offset(); 293 + 294 + reloc_got2(offset); 295 + 296 + /* 297 + * Identify the CPU type and fix up code sections 298 + * that depend on which cpu we have. 299 + */ 300 + identify_cpu(offset, 0); 301 + do_cpu_ftr_fixups(offset); 302 + 303 + #ifdef CONFIG_BOOTX_TEXT 304 + btext_prepare_BAT(); 305 + #endif 306 + 307 + reloc_got2(-offset); 308 + 309 + return KERNELBASE + offset; 310 + } 311 + 312 + #ifdef CONFIG_PPC_OF 313 + /* 314 + * Assume here that all clock rates are the same in a 315 + * smp system. -- Cort 316 + */ 317 + int 318 + of_show_percpuinfo(struct seq_file *m, int i) 319 + { 320 + struct device_node *cpu_node; 321 + u32 *fp; 322 + int s; 323 + 324 + cpu_node = find_type_devices("cpu"); 325 + if (!cpu_node) 326 + return 0; 327 + for (s = 0; s < i && cpu_node->next; s++) 328 + cpu_node = cpu_node->next; 329 + fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL); 330 + if (fp) 331 + seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000); 332 + return 0; 333 + } 334 + 335 + void __init 336 + intuit_machine_type(void) 337 + { 338 + char *model; 339 + struct device_node *root; 340 + 341 + /* ask the OF info if we're a chrp or pmac */ 342 + root = find_path_device("/"); 343 + if (root != 0) { 344 + /* assume pmac unless proven to be chrp -- Cort */ 345 + _machine = _MACH_Pmac; 346 + model = get_property(root, "device_type", NULL); 347 + if (model && !strncmp("chrp", model, 4)) 348 + _machine = _MACH_chrp; 349 + else { 350 + model = get_property(root, "model", NULL); 351 + if (model && !strncmp(model, "IBM", 3)) 352 + _machine = _MACH_chrp; 353 + } 354 + } 355 + } 356 + #endif 357 + 358 + #ifdef CONFIG_PPC_MULTIPLATFORM 359 + /* 360 + * The PPC_MULTIPLATFORM version of platform_init... 361 + */ 362 + void __init platform_init(void) 363 + { 364 + /* if we didn't get any bootinfo telling us what we are... */ 365 + if (_machine == 0) { 366 + /* prep boot loader tells us if we're prep or not */ 367 + if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) 368 + _machine = _MACH_prep; 369 + } 370 + 371 + #ifdef CONFIG_PPC_PREP 372 + /* not much more to do here, if prep */ 373 + if (_machine == _MACH_prep) { 374 + prep_init(); 375 + return; 376 + } 377 + #endif 378 + 379 + #ifdef CONFIG_ADB 380 + if (strstr(cmd_line, "adb_sync")) { 381 + extern int __adb_probe_sync; 382 + __adb_probe_sync = 1; 383 + } 384 + #endif /* CONFIG_ADB */ 385 + 386 + switch (_machine) { 387 + #ifdef CONFIG_PPC_PMAC 388 + case _MACH_Pmac: 389 + pmac_init(); 390 + break; 391 + #endif 392 + #ifdef CONFIG_PPC_CHRP 393 + case _MACH_chrp: 394 + chrp_init(); 395 + break; 396 + #endif 397 + } 398 + } 399 + 400 + #ifdef CONFIG_SERIAL_CORE_CONSOLE 401 + extern char *of_stdout_device; 402 + 403 + static int __init set_preferred_console(void) 404 + { 405 + struct device_node *prom_stdout; 406 + char *name; 407 + int offset = 0; 408 + 409 + if (of_stdout_device == NULL) 410 + return -ENODEV; 411 + 412 + /* The user has requested a console so this is already set up. */ 413 + if (strstr(saved_command_line, "console=")) 414 + return -EBUSY; 415 + 416 + prom_stdout = find_path_device(of_stdout_device); 417 + if (!prom_stdout) 418 + return -ENODEV; 419 + 420 + name = (char *)get_property(prom_stdout, "name", NULL); 421 + if (!name) 422 + return -ENODEV; 423 + 424 + if (strcmp(name, "serial") == 0) { 425 + int i; 426 + u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); 427 + if (i > 8) { 428 + switch (reg[1]) { 429 + case 0x3f8: 430 + offset = 0; 431 + break; 432 + case 0x2f8: 433 + offset = 1; 434 + break; 435 + case 0x898: 436 + offset = 2; 437 + break; 438 + case 0x890: 439 + offset = 3; 440 + break; 441 + default: 442 + /* We dont recognise the serial port */ 443 + return -ENODEV; 444 + } 445 + } 446 + } else if (strcmp(name, "ch-a") == 0) 447 + offset = 0; 448 + else if (strcmp(name, "ch-b") == 0) 449 + offset = 1; 450 + else 451 + return -ENODEV; 452 + return add_preferred_console("ttyS", offset, NULL); 453 + } 454 + console_initcall(set_preferred_console); 455 + #endif /* CONFIG_SERIAL_CORE_CONSOLE */ 456 + #endif /* CONFIG_PPC_MULTIPLATFORM */ 457 + 458 + struct bi_record *find_bootinfo(void) 459 + { 460 + struct bi_record *rec; 461 + 462 + rec = (struct bi_record *)_ALIGN((ulong)__bss_start+(1<<20)-1,(1<<20)); 463 + if ( rec->tag != BI_FIRST ) { 464 + /* 465 + * This 0x10000 offset is a terrible hack but it will go away when 466 + * we have the bootloader handle all the relocation and 467 + * prom calls -- Cort 468 + */ 469 + rec = (struct bi_record *)_ALIGN((ulong)__bss_start+0x10000+(1<<20)-1,(1<<20)); 470 + if ( rec->tag != BI_FIRST ) 471 + return NULL; 472 + } 473 + return rec; 474 + } 475 + 476 + /* 477 + * Find out what kind of machine we're on and save any data we need 478 + * from the early boot process (devtree is copied on pmac by prom_init()). 479 + * This is called very early on the boot process, after a minimal 480 + * MMU environment has been set up but before MMU_init is called. 481 + */ 482 + void __init machine_init(unsigned long dt_ptr, unsigned long phys) 483 + { 484 + early_init_devtree(__va(dt_ptr)); 485 + 486 + #ifdef CONFIG_CMDLINE 487 + strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); 488 + #endif /* CONFIG_CMDLINE */ 489 + 490 + #ifdef CONFIG_6xx 491 + ppc_md.power_save = ppc6xx_idle; 492 + #endif 493 + #ifdef CONFIG_POWER4 494 + ppc_md.power_save = power4_idle; 495 + #endif 496 + 497 + platform_init(); 498 + 499 + if (ppc_md.progress) 500 + ppc_md.progress("id mach(): done", 0x200); 501 + } 502 + 503 + #ifdef CONFIG_BOOKE_WDT 504 + /* Checks wdt=x and wdt_period=xx command-line option */ 505 + int __init early_parse_wdt(char *p) 506 + { 507 + if (p && strncmp(p, "0", 1) != 0) 508 + booke_wdt_enabled = 1; 509 + 510 + return 0; 511 + } 512 + early_param("wdt", early_parse_wdt); 513 + 514 + int __init early_parse_wdt_period (char *p) 515 + { 516 + if (p) 517 + booke_wdt_period = simple_strtoul(p, NULL, 0); 518 + 519 + return 0; 520 + } 521 + early_param("wdt_period", early_parse_wdt_period); 522 + #endif /* CONFIG_BOOKE_WDT */ 523 + 524 + /* Checks "l2cr=xxxx" command-line option */ 525 + int __init ppc_setup_l2cr(char *str) 526 + { 527 + if (cpu_has_feature(CPU_FTR_L2CR)) { 528 + unsigned long val = simple_strtoul(str, NULL, 0); 529 + printk(KERN_INFO "l2cr set to %lx\n", val); 530 + _set_L2CR(0); /* force invalidate by disable cache */ 531 + _set_L2CR(val); /* and enable it */ 532 + } 533 + return 1; 534 + } 535 + __setup("l2cr=", ppc_setup_l2cr); 536 + 537 + #ifdef CONFIG_GENERIC_NVRAM 538 + 539 + /* Generic nvram hooks used by drivers/char/gen_nvram.c */ 540 + unsigned char nvram_read_byte(int addr) 541 + { 542 + if (ppc_md.nvram_read_val) 543 + return ppc_md.nvram_read_val(addr); 544 + return 0xff; 545 + } 546 + EXPORT_SYMBOL(nvram_read_byte); 547 + 548 + void nvram_write_byte(unsigned char val, int addr) 549 + { 550 + if (ppc_md.nvram_write_val) 551 + ppc_md.nvram_write_val(addr, val); 552 + } 553 + EXPORT_SYMBOL(nvram_write_byte); 554 + 555 + void nvram_sync(void) 556 + { 557 + if (ppc_md.nvram_sync) 558 + ppc_md.nvram_sync(); 559 + } 560 + EXPORT_SYMBOL(nvram_sync); 561 + 562 + #endif /* CONFIG_NVRAM */ 563 + 564 + static struct cpu cpu_devices[NR_CPUS]; 565 + 566 + int __init ppc_init(void) 567 + { 568 + int i; 569 + 570 + /* clear the progress line */ 571 + if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); 572 + 573 + /* register CPU devices */ 574 + for (i = 0; i < NR_CPUS; i++) 575 + if (cpu_possible(i)) 576 + register_cpu(&cpu_devices[i], i, NULL); 577 + 578 + /* call platform init */ 579 + if (ppc_md.init != NULL) { 580 + ppc_md.init(); 581 + } 582 + return 0; 583 + } 584 + 585 + arch_initcall(ppc_init); 586 + 587 + /* Warning, IO base is not yet inited */ 588 + void __init setup_arch(char **cmdline_p) 589 + { 590 + extern char *klimit; 591 + extern void do_init_bootmem(void); 592 + 593 + /* so udelay does something sensible, assume <= 1000 bogomips */ 594 + loops_per_jiffy = 500000000 / HZ; 595 + 596 + #ifdef CONFIG_BOOTX_TEXT 597 + map_boot_text(); 598 + #endif 599 + 600 + unflatten_device_tree(); 601 + finish_device_tree(); 602 + 603 + #ifdef CONFIG_PPC_MULTIPLATFORM 604 + /* This could be called "early setup arch", it must be done 605 + * now because xmon need it 606 + */ 607 + if (_machine == _MACH_Pmac) 608 + pmac_feature_init(); /* New cool way */ 609 + #endif 610 + 611 + #ifdef CONFIG_XMON 612 + xmon_map_scc(); 613 + if (strstr(cmd_line, "xmon")) 614 + xmon(NULL); 615 + #endif /* CONFIG_XMON */ 616 + if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); 617 + 618 + #if defined(CONFIG_KGDB) 619 + if (ppc_md.kgdb_map_scc) 620 + ppc_md.kgdb_map_scc(); 621 + set_debug_traps(); 622 + if (strstr(cmd_line, "gdb")) { 623 + if (ppc_md.progress) 624 + ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000); 625 + printk("kgdb breakpoint activated\n"); 626 + breakpoint(); 627 + } 628 + #endif 629 + 630 + /* 631 + * Set cache line size based on type of cpu as a default. 632 + * Systems with OF can look in the properties on the cpu node(s) 633 + * for a possibly more accurate value. 634 + */ 635 + if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { 636 + dcache_bsize = cur_cpu_spec->dcache_bsize; 637 + icache_bsize = cur_cpu_spec->icache_bsize; 638 + ucache_bsize = 0; 639 + } else 640 + ucache_bsize = dcache_bsize = icache_bsize 641 + = cur_cpu_spec->dcache_bsize; 642 + 643 + /* reboot on panic */ 644 + panic_timeout = 180; 645 + 646 + init_mm.start_code = PAGE_OFFSET; 647 + init_mm.end_code = (unsigned long) _etext; 648 + init_mm.end_data = (unsigned long) _edata; 649 + init_mm.brk = (unsigned long) klimit; 650 + 651 + /* Save unparsed command line copy for /proc/cmdline */ 652 + strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); 653 + *cmdline_p = cmd_line; 654 + 655 + parse_early_param(); 656 + 657 + /* set up the bootmem stuff with available memory */ 658 + do_init_bootmem(); 659 + if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); 660 + 661 + #ifdef CONFIG_PPC_OCP 662 + /* Initialize OCP device list */ 663 + ocp_early_init(); 664 + if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab); 665 + #endif 666 + 667 + #ifdef CONFIG_DUMMY_CONSOLE 668 + conswitchp = &dummy_con; 669 + #endif 670 + 671 + ppc_md.setup_arch(); 672 + if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); 673 + 674 + paging_init(); 675 + 676 + /* this is for modules since _machine can be a define -- Cort */ 677 + ppc_md.ppc_machine = _machine; 678 + }
+6 -5
arch/powerpc/platforms/powermac/pmac_setup.c
··· 101 101 int ppc_override_l2cr_value; 102 102 int has_l2cache = 0; 103 103 104 + int pmac_newworld = 1; 105 + 104 106 static int current_root_goodness = -1; 105 107 106 108 extern int pmac_newworld; ··· 357 355 } 358 356 } 359 357 360 - extern char *bootpath; 361 - extern char *bootdevice; 358 + char *bootpath; 359 + char *bootdevice; 362 360 void *boot_host; 363 361 int boot_target; 364 362 int boot_part; ··· 393 391 } 394 392 } 395 393 } 394 + EXPORT_SYMBOL(note_scsi_host); 396 395 #endif 397 396 398 397 #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) ··· 568 565 pmac_power_off(); 569 566 } 570 567 571 - void __init 572 - pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, 573 - unsigned long r6, unsigned long r7) 568 + void __init pmac_init(void) 574 569 { 575 570 /* isa_io_base gets set in pmac_find_bridges */ 576 571 isa_mem_base = PMAC_ISA_MEM_BASE;
+3
include/asm-powerpc/cputable.h
··· 57 57 58 58 extern struct cpu_spec *cur_cpu_spec; 59 59 60 + extern void identify_cpu(unsigned long offset, unsigned long cpu); 61 + extern void do_cpu_ftr_fixups(unsigned long offset); 62 + 60 63 #endif /* __ASSEMBLY__ */ 61 64 62 65 /* CPU kernel features */
+112
include/asm-powerpc/iommu.h
··· 1 + /* 2 + * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation 3 + * Rewrite, cleanup: 4 + * Copyright (C) 2004 Olof Johansson <olof@austin.ibm.com>, IBM Corporation 5 + * 6 + * This program 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 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program 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 this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #ifndef _ASM_IOMMU_H 22 + #define _ASM_IOMMU_H 23 + 24 + #include <asm/types.h> 25 + #include <linux/spinlock.h> 26 + #include <linux/device.h> 27 + #include <linux/dma-mapping.h> 28 + 29 + /* 30 + * IOMAP_MAX_ORDER defines the largest contiguous block 31 + * of dma space we can get. IOMAP_MAX_ORDER = 13 32 + * allows up to 2**12 pages (4096 * 4096) = 16 MB 33 + */ 34 + #define IOMAP_MAX_ORDER 13 35 + 36 + struct iommu_table { 37 + unsigned long it_busno; /* Bus number this table belongs to */ 38 + unsigned long it_size; /* Size of iommu table in entries */ 39 + unsigned long it_offset; /* Offset into global table */ 40 + unsigned long it_base; /* mapped address of tce table */ 41 + unsigned long it_index; /* which iommu table this is */ 42 + unsigned long it_type; /* type: PCI or Virtual Bus */ 43 + unsigned long it_blocksize; /* Entries in each block (cacheline) */ 44 + unsigned long it_hint; /* Hint for next alloc */ 45 + unsigned long it_largehint; /* Hint for large allocs */ 46 + unsigned long it_halfpoint; /* Breaking point for small/large allocs */ 47 + spinlock_t it_lock; /* Protects it_map */ 48 + unsigned long *it_map; /* A simple allocation bitmap for now */ 49 + }; 50 + 51 + struct scatterlist; 52 + struct device_node; 53 + 54 + #ifdef CONFIG_PPC_MULTIPLATFORM 55 + 56 + /* Walks all buses and creates iommu tables */ 57 + extern void iommu_setup_pSeries(void); 58 + extern void iommu_setup_u3(void); 59 + 60 + /* Frees table for an individual device node */ 61 + extern void iommu_free_table(struct device_node *dn); 62 + 63 + #endif /* CONFIG_PPC_MULTIPLATFORM */ 64 + 65 + #ifdef CONFIG_PPC_PSERIES 66 + 67 + /* Creates table for an individual device node */ 68 + extern void iommu_devnode_init_pSeries(struct device_node *dn); 69 + 70 + #endif /* CONFIG_PPC_PSERIES */ 71 + 72 + #ifdef CONFIG_PPC_ISERIES 73 + 74 + /* Creates table for an individual device node */ 75 + extern void iommu_devnode_init_iSeries(struct device_node *dn); 76 + 77 + #endif /* CONFIG_PPC_ISERIES */ 78 + 79 + /* Initializes an iommu_table based in values set in the passed-in 80 + * structure 81 + */ 82 + extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); 83 + 84 + extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, 85 + struct scatterlist *sglist, int nelems, 86 + enum dma_data_direction direction); 87 + extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, 88 + int nelems, enum dma_data_direction direction); 89 + 90 + extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, 91 + dma_addr_t *dma_handle, unsigned int __nocast flag); 92 + extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, 93 + void *vaddr, dma_addr_t dma_handle); 94 + extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, 95 + size_t size, enum dma_data_direction direction); 96 + extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, 97 + size_t size, enum dma_data_direction direction); 98 + 99 + extern void iommu_init_early_pSeries(void); 100 + extern void iommu_init_early_iSeries(void); 101 + extern void iommu_init_early_u3(void); 102 + 103 + #ifdef CONFIG_PCI 104 + extern void pci_iommu_init(void); 105 + extern void pci_direct_iommu_init(void); 106 + #else 107 + static inline void pci_iommu_init(void) { } 108 + #endif 109 + 110 + extern void alloc_u3_dart_table(void); 111 + 112 + #endif /* _ASM_IOMMU_H */
+81
include/asm-powerpc/lmb.h
··· 1 + #ifndef _PPC64_LMB_H 2 + #define _PPC64_LMB_H 3 + 4 + /* 5 + * Definitions for talking to the Open Firmware PROM on 6 + * Power Macintosh computers. 7 + * 8 + * Copyright (C) 2001 Peter Bergner, IBM Corp. 9 + * 10 + * This program is free software; you can redistribute it and/or 11 + * modify it under the terms of the GNU General Public License 12 + * as published by the Free Software Foundation; either version 13 + * 2 of the License, or (at your option) any later version. 14 + */ 15 + 16 + #include <linux/init.h> 17 + #include <asm/prom.h> 18 + 19 + #define MAX_LMB_REGIONS 128 20 + 21 + #define LMB_ALLOC_ANYWHERE 0 22 + 23 + struct lmb_property { 24 + unsigned long base; 25 + unsigned long size; 26 + }; 27 + 28 + struct lmb_region { 29 + unsigned long cnt; 30 + unsigned long size; 31 + struct lmb_property region[MAX_LMB_REGIONS+1]; 32 + }; 33 + 34 + struct lmb { 35 + unsigned long debug; 36 + unsigned long rmo_size; 37 + struct lmb_region memory; 38 + struct lmb_region reserved; 39 + }; 40 + 41 + extern struct lmb lmb; 42 + 43 + extern void __init lmb_init(void); 44 + extern void __init lmb_analyze(void); 45 + extern long __init lmb_add(unsigned long, unsigned long); 46 + extern long __init lmb_reserve(unsigned long, unsigned long); 47 + extern unsigned long __init lmb_alloc(unsigned long, unsigned long); 48 + extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long, 49 + unsigned long); 50 + extern unsigned long __init lmb_phys_mem_size(void); 51 + extern unsigned long __init lmb_end_of_DRAM(void); 52 + extern unsigned long __init lmb_abs_to_phys(unsigned long); 53 + extern void __init lmb_enforce_memory_limit(unsigned long); 54 + 55 + extern void lmb_dump_all(void); 56 + 57 + extern unsigned long io_hole_start; 58 + 59 + static inline unsigned long 60 + lmb_size_bytes(struct lmb_region *type, unsigned long region_nr) 61 + { 62 + return type->region[region_nr].size; 63 + } 64 + static inline unsigned long 65 + lmb_size_pages(struct lmb_region *type, unsigned long region_nr) 66 + { 67 + return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT; 68 + } 69 + static inline unsigned long 70 + lmb_start_pfn(struct lmb_region *type, unsigned long region_nr) 71 + { 72 + return type->region[region_nr].base >> PAGE_SHIFT; 73 + } 74 + static inline unsigned long 75 + lmb_end_pfn(struct lmb_region *type, unsigned long region_nr) 76 + { 77 + return lmb_start_pfn(type, region_nr) + 78 + lmb_size_pages(type, region_nr); 79 + } 80 + 81 + #endif /* _PPC64_LMB_H */
+25
include/asm-powerpc/pSeries_reconfig.h
··· 1 + #ifndef _PPC64_PSERIES_RECONFIG_H 2 + #define _PPC64_PSERIES_RECONFIG_H 3 + 4 + #include <linux/notifier.h> 5 + 6 + /* 7 + * Use this API if your code needs to know about OF device nodes being 8 + * added or removed on pSeries systems. 9 + */ 10 + 11 + #define PSERIES_RECONFIG_ADD 0x0001 12 + #define PSERIES_RECONFIG_REMOVE 0x0002 13 + 14 + #ifdef CONFIG_PPC_PSERIES 15 + extern int pSeries_reconfig_notifier_register(struct notifier_block *); 16 + extern void pSeries_reconfig_notifier_unregister(struct notifier_block *); 17 + #else /* !CONFIG_PPC_PSERIES */ 18 + static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb) 19 + { 20 + return 0; 21 + } 22 + static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } 23 + #endif /* CONFIG_PPC_PSERIES */ 24 + 25 + #endif /* _PPC64_PSERIES_RECONFIG_H */
+215
include/asm-powerpc/prom.h
··· 1 + #ifndef _POWERPC_PROM_H 2 + #define _POWERPC_PROM_H 3 + #ifdef __KERNEL__ 4 + 5 + /* 6 + * Definitions for talking to the Open Firmware PROM on 7 + * Power Macintosh computers. 8 + * 9 + * Copyright (C) 1996-2005 Paul Mackerras. 10 + * 11 + * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp. 12 + * 13 + * This program is free software; you can redistribute it and/or 14 + * modify it under the terms of the GNU General Public License 15 + * as published by the Free Software Foundation; either version 16 + * 2 of the License, or (at your option) any later version. 17 + */ 18 + #include <linux/types.h> 19 + #include <linux/proc_fs.h> 20 + #include <asm/atomic.h> 21 + 22 + /* Definitions used by the flattened device tree */ 23 + #define OF_DT_HEADER 0xd00dfeed /* marker */ 24 + #define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ 25 + #define OF_DT_END_NODE 0x2 /* End node */ 26 + #define OF_DT_PROP 0x3 /* Property: name off, size, 27 + * content */ 28 + #define OF_DT_NOP 0x4 /* nop */ 29 + #define OF_DT_END 0x9 30 + 31 + #define OF_DT_VERSION 0x10 32 + 33 + /* 34 + * This is what gets passed to the kernel by prom_init or kexec 35 + * 36 + * The dt struct contains the device tree structure, full pathes and 37 + * property contents. The dt strings contain a separate block with just 38 + * the strings for the property names, and is fully page aligned and 39 + * self contained in a page, so that it can be kept around by the kernel, 40 + * each property name appears only once in this page (cheap compression) 41 + * 42 + * the mem_rsvmap contains a map of reserved ranges of physical memory, 43 + * passing it here instead of in the device-tree itself greatly simplifies 44 + * the job of everybody. It's just a list of u64 pairs (base/size) that 45 + * ends when size is 0 46 + */ 47 + struct boot_param_header 48 + { 49 + u32 magic; /* magic word OF_DT_HEADER */ 50 + u32 totalsize; /* total size of DT block */ 51 + u32 off_dt_struct; /* offset to structure */ 52 + u32 off_dt_strings; /* offset to strings */ 53 + u32 off_mem_rsvmap; /* offset to memory reserve map */ 54 + u32 version; /* format version */ 55 + u32 last_comp_version; /* last compatible version */ 56 + /* version 2 fields below */ 57 + u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ 58 + /* version 3 fields below */ 59 + u32 dt_strings_size; /* size of the DT strings block */ 60 + }; 61 + 62 + 63 + 64 + typedef u32 phandle; 65 + typedef u32 ihandle; 66 + 67 + struct address_range { 68 + unsigned long space; 69 + unsigned long address; 70 + unsigned long size; 71 + }; 72 + 73 + struct interrupt_info { 74 + int line; 75 + int sense; /* +ve/-ve logic, edge or level, etc. */ 76 + }; 77 + 78 + struct pci_address { 79 + u32 a_hi; 80 + u32 a_mid; 81 + u32 a_lo; 82 + }; 83 + 84 + struct isa_address { 85 + u32 a_hi; 86 + u32 a_lo; 87 + }; 88 + 89 + struct isa_range { 90 + struct isa_address isa_addr; 91 + struct pci_address pci_addr; 92 + unsigned int size; 93 + }; 94 + 95 + struct reg_property { 96 + unsigned long address; 97 + unsigned long size; 98 + }; 99 + 100 + struct reg_property32 { 101 + unsigned int address; 102 + unsigned int size; 103 + }; 104 + 105 + struct reg_property64 { 106 + unsigned long address; 107 + unsigned long size; 108 + }; 109 + 110 + struct property { 111 + char *name; 112 + int length; 113 + unsigned char *value; 114 + struct property *next; 115 + }; 116 + 117 + struct device_node { 118 + char *name; 119 + char *type; 120 + phandle node; 121 + phandle linux_phandle; 122 + int n_addrs; 123 + struct address_range *addrs; 124 + int n_intrs; 125 + struct interrupt_info *intrs; 126 + char *full_name; 127 + 128 + struct property *properties; 129 + struct device_node *parent; 130 + struct device_node *child; 131 + struct device_node *sibling; 132 + struct device_node *next; /* next device of same type */ 133 + struct device_node *allnext; /* next in list of all nodes */ 134 + struct proc_dir_entry *pde; /* this node's proc directory */ 135 + struct kref kref; 136 + unsigned long _flags; 137 + void *data; 138 + }; 139 + 140 + extern struct device_node *of_chosen; 141 + 142 + /* flag descriptions */ 143 + #define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ 144 + 145 + #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) 146 + #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) 147 + 148 + #define HAVE_ARCH_DEVTREE_FIXUPS 149 + 150 + static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de) 151 + { 152 + dn->pde = de; 153 + } 154 + 155 + 156 + /* OBSOLETE: Old style node lookup */ 157 + extern struct device_node *find_devices(const char *name); 158 + extern struct device_node *find_type_devices(const char *type); 159 + extern struct device_node *find_path_device(const char *path); 160 + extern struct device_node *find_compatible_devices(const char *type, 161 + const char *compat); 162 + extern struct device_node *find_all_nodes(void); 163 + 164 + /* New style node lookup */ 165 + extern struct device_node *of_find_node_by_name(struct device_node *from, 166 + const char *name); 167 + extern struct device_node *of_find_node_by_type(struct device_node *from, 168 + const char *type); 169 + extern struct device_node *of_find_compatible_node(struct device_node *from, 170 + const char *type, const char *compat); 171 + extern struct device_node *of_find_node_by_path(const char *path); 172 + extern struct device_node *of_find_node_by_phandle(phandle handle); 173 + extern struct device_node *of_find_all_nodes(struct device_node *prev); 174 + extern struct device_node *of_get_parent(const struct device_node *node); 175 + extern struct device_node *of_get_next_child(const struct device_node *node, 176 + struct device_node *prev); 177 + extern struct device_node *of_node_get(struct device_node *node); 178 + extern void of_node_put(struct device_node *node); 179 + 180 + /* For updating the device tree at runtime */ 181 + extern void of_attach_node(struct device_node *); 182 + extern void of_detach_node(const struct device_node *); 183 + 184 + /* Other Prototypes */ 185 + extern void finish_device_tree(void); 186 + extern void unflatten_device_tree(void); 187 + extern void early_init_devtree(void *); 188 + extern int device_is_compatible(struct device_node *device, const char *); 189 + extern int machine_is_compatible(const char *compat); 190 + extern unsigned char *get_property(struct device_node *node, const char *name, 191 + int *lenp); 192 + extern void print_properties(struct device_node *node); 193 + extern int prom_n_addr_cells(struct device_node* np); 194 + extern int prom_n_size_cells(struct device_node* np); 195 + extern int prom_n_intr_cells(struct device_node* np); 196 + extern void prom_get_irq_senses(unsigned char *senses, int off, int max); 197 + extern void prom_add_property(struct device_node* np, struct property* prop); 198 + 199 + /* 200 + * PCI <-> OF matching functions 201 + * (XXX should these be here?) 202 + */ 203 + struct pci_bus; 204 + struct pci_dev; 205 + extern int pci_device_from_OF_node(struct device_node *node, 206 + u8* bus, u8* devfn); 207 + extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int); 208 + extern struct device_node* pci_device_to_OF_node(struct pci_dev *); 209 + extern void pci_create_OF_bus_map(void); 210 + extern struct resource *request_OF_resource(struct device_node* node, 211 + int index, const char* name_postfix); 212 + extern int release_OF_resource(struct device_node* node, int index); 213 + 214 + #endif /* __KERNEL__ */ 215 + #endif /* _POWERPC_PROM_H */
+249
include/asm-powerpc/rtas.h
··· 1 + #ifndef _POWERPC_RTAS_H 2 + #define _POWERPC_RTAS_H 3 + 4 + #include <linux/spinlock.h> 5 + #include <asm/page.h> 6 + 7 + /* 8 + * Definitions for talking to the RTAS on CHRP machines. 9 + * 10 + * Copyright (C) 2001 Peter Bergner 11 + * Copyright (C) 2001 PPC 64 Team, IBM Corp 12 + * 13 + * This program is free software; you can redistribute it and/or 14 + * modify it under the terms of the GNU General Public License 15 + * as published by the Free Software Foundation; either version 16 + * 2 of the License, or (at your option) any later version. 17 + */ 18 + 19 + #define RTAS_UNKNOWN_SERVICE (-1) 20 + #define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */ 21 + 22 + /* Buffer size for ppc_rtas system call. */ 23 + #define RTAS_RMOBUF_MAX (64 * 1024) 24 + 25 + /* RTAS return status codes */ 26 + #define RTAS_BUSY -2 /* RTAS Busy */ 27 + #define RTAS_EXTENDED_DELAY_MIN 9900 28 + #define RTAS_EXTENDED_DELAY_MAX 9905 29 + 30 + /* 31 + * In general to call RTAS use rtas_token("string") to lookup 32 + * an RTAS token for the given string (e.g. "event-scan"). 33 + * To actually perform the call use 34 + * ret = rtas_call(token, n_in, n_out, ...) 35 + * Where n_in is the number of input parameters and 36 + * n_out is the number of output parameters 37 + * 38 + * If the "string" is invalid on this system, RTAS_UNKNOWN_SERVICE 39 + * will be returned as a token. rtas_call() does look for this 40 + * token and error out gracefully so rtas_call(rtas_token("str"), ...) 41 + * may be safely used for one-shot calls to RTAS. 42 + * 43 + */ 44 + 45 + typedef u32 rtas_arg_t; 46 + 47 + struct rtas_args { 48 + u32 token; 49 + u32 nargs; 50 + u32 nret; 51 + rtas_arg_t args[16]; 52 + rtas_arg_t *rets; /* Pointer to return values in args[]. */ 53 + }; 54 + 55 + extern struct rtas_args rtas_stop_self_args; 56 + 57 + struct rtas_t { 58 + unsigned long entry; /* physical address pointer */ 59 + unsigned long base; /* physical address pointer */ 60 + unsigned long size; 61 + spinlock_t lock; 62 + struct rtas_args args; 63 + struct device_node *dev; /* virtual address pointer */ 64 + }; 65 + 66 + /* RTAS event classes */ 67 + #define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */ 68 + #define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */ 69 + #define RTAS_POWERMGM_EVENTS 0x20000000 /* set bit 2 */ 70 + #define RTAS_HOTPLUG_EVENTS 0x10000000 /* set bit 3 */ 71 + #define RTAS_EVENT_SCAN_ALL_EVENTS 0xf0000000 72 + 73 + /* RTAS event severity */ 74 + #define RTAS_SEVERITY_FATAL 0x5 75 + #define RTAS_SEVERITY_ERROR 0x4 76 + #define RTAS_SEVERITY_ERROR_SYNC 0x3 77 + #define RTAS_SEVERITY_WARNING 0x2 78 + #define RTAS_SEVERITY_EVENT 0x1 79 + #define RTAS_SEVERITY_NO_ERROR 0x0 80 + 81 + /* RTAS event disposition */ 82 + #define RTAS_DISP_FULLY_RECOVERED 0x0 83 + #define RTAS_DISP_LIMITED_RECOVERY 0x1 84 + #define RTAS_DISP_NOT_RECOVERED 0x2 85 + 86 + /* RTAS event initiator */ 87 + #define RTAS_INITIATOR_UNKNOWN 0x0 88 + #define RTAS_INITIATOR_CPU 0x1 89 + #define RTAS_INITIATOR_PCI 0x2 90 + #define RTAS_INITIATOR_ISA 0x3 91 + #define RTAS_INITIATOR_MEMORY 0x4 92 + #define RTAS_INITIATOR_POWERMGM 0x5 93 + 94 + /* RTAS event target */ 95 + #define RTAS_TARGET_UNKNOWN 0x0 96 + #define RTAS_TARGET_CPU 0x1 97 + #define RTAS_TARGET_PCI 0x2 98 + #define RTAS_TARGET_ISA 0x3 99 + #define RTAS_TARGET_MEMORY 0x4 100 + #define RTAS_TARGET_POWERMGM 0x5 101 + 102 + /* RTAS event type */ 103 + #define RTAS_TYPE_RETRY 0x01 104 + #define RTAS_TYPE_TCE_ERR 0x02 105 + #define RTAS_TYPE_INTERN_DEV_FAIL 0x03 106 + #define RTAS_TYPE_TIMEOUT 0x04 107 + #define RTAS_TYPE_DATA_PARITY 0x05 108 + #define RTAS_TYPE_ADDR_PARITY 0x06 109 + #define RTAS_TYPE_CACHE_PARITY 0x07 110 + #define RTAS_TYPE_ADDR_INVALID 0x08 111 + #define RTAS_TYPE_ECC_UNCORR 0x09 112 + #define RTAS_TYPE_ECC_CORR 0x0a 113 + #define RTAS_TYPE_EPOW 0x40 114 + #define RTAS_TYPE_PLATFORM 0xE0 115 + #define RTAS_TYPE_IO 0xE1 116 + #define RTAS_TYPE_INFO 0xE2 117 + #define RTAS_TYPE_DEALLOC 0xE3 118 + #define RTAS_TYPE_DUMP 0xE4 119 + /* I don't add PowerMGM events right now, this is a different topic */ 120 + #define RTAS_TYPE_PMGM_POWER_SW_ON 0x60 121 + #define RTAS_TYPE_PMGM_POWER_SW_OFF 0x61 122 + #define RTAS_TYPE_PMGM_LID_OPEN 0x62 123 + #define RTAS_TYPE_PMGM_LID_CLOSE 0x63 124 + #define RTAS_TYPE_PMGM_SLEEP_BTN 0x64 125 + #define RTAS_TYPE_PMGM_WAKE_BTN 0x65 126 + #define RTAS_TYPE_PMGM_BATTERY_WARN 0x66 127 + #define RTAS_TYPE_PMGM_BATTERY_CRIT 0x67 128 + #define RTAS_TYPE_PMGM_SWITCH_TO_BAT 0x68 129 + #define RTAS_TYPE_PMGM_SWITCH_TO_AC 0x69 130 + #define RTAS_TYPE_PMGM_KBD_OR_MOUSE 0x6a 131 + #define RTAS_TYPE_PMGM_ENCLOS_OPEN 0x6b 132 + #define RTAS_TYPE_PMGM_ENCLOS_CLOSED 0x6c 133 + #define RTAS_TYPE_PMGM_RING_INDICATE 0x6d 134 + #define RTAS_TYPE_PMGM_LAN_ATTENTION 0x6e 135 + #define RTAS_TYPE_PMGM_TIME_ALARM 0x6f 136 + #define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70 137 + #define RTAS_TYPE_PMGM_SERVICE_PROC 0x71 138 + 139 + struct rtas_error_log { 140 + unsigned long version:8; /* Architectural version */ 141 + unsigned long severity:3; /* Severity level of error */ 142 + unsigned long disposition:2; /* Degree of recovery */ 143 + unsigned long extended:1; /* extended log present? */ 144 + unsigned long /* reserved */ :2; /* Reserved for future use */ 145 + unsigned long initiator:4; /* Initiator of event */ 146 + unsigned long target:4; /* Target of failed operation */ 147 + unsigned long type:8; /* General event or error*/ 148 + unsigned long extended_log_length:32; /* length in bytes */ 149 + unsigned char buffer[1]; 150 + }; 151 + 152 + struct flash_block { 153 + char *data; 154 + unsigned long length; 155 + }; 156 + 157 + /* This struct is very similar but not identical to 158 + * that needed by the rtas flash update. 159 + * All we need to do for rtas is rewrite num_blocks 160 + * into a version/length and translate the pointers 161 + * to absolute. 162 + */ 163 + #define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block)) 164 + struct flash_block_list { 165 + unsigned long num_blocks; 166 + struct flash_block_list *next; 167 + struct flash_block blocks[FLASH_BLOCKS_PER_NODE]; 168 + }; 169 + struct flash_block_list_header { /* just the header of flash_block_list */ 170 + unsigned long num_blocks; 171 + struct flash_block_list *next; 172 + }; 173 + extern struct flash_block_list_header rtas_firmware_flash_list; 174 + 175 + extern struct rtas_t rtas; 176 + 177 + extern void enter_rtas(unsigned long); 178 + extern int rtas_token(const char *service); 179 + extern int rtas_call(int token, int, int, int *, ...); 180 + extern void call_rtas_display_status(unsigned char); 181 + extern void rtas_restart(char *cmd); 182 + extern void rtas_power_off(void); 183 + extern void rtas_halt(void); 184 + extern void rtas_os_term(char *str); 185 + extern int rtas_get_sensor(int sensor, int index, int *state); 186 + extern int rtas_get_power_level(int powerdomain, int *level); 187 + extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); 188 + extern int rtas_set_indicator(int indicator, int index, int new_value); 189 + extern void rtas_progress(char *s, unsigned short hex); 190 + extern void rtas_initialize(void); 191 + 192 + struct rtc_time; 193 + extern void rtas_get_boot_time(struct rtc_time *rtc_time); 194 + extern void rtas_get_rtc_time(struct rtc_time *rtc_time); 195 + extern int rtas_set_rtc_time(struct rtc_time *rtc_time); 196 + 197 + /* Given an RTAS status code of 9900..9905 compute the hinted delay */ 198 + unsigned int rtas_extended_busy_delay_time(int status); 199 + static inline int rtas_is_extended_busy(int status) 200 + { 201 + return status >= 9900 && status <= 9909; 202 + } 203 + 204 + extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); 205 + 206 + /* Error types logged. */ 207 + #define ERR_FLAG_ALREADY_LOGGED 0x0 208 + #define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ 209 + #define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */ 210 + #define ERR_TYPE_KERNEL_PANIC 0x4 /* from panic() */ 211 + 212 + /* All the types and not flags */ 213 + #define ERR_TYPE_MASK (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC) 214 + 215 + #define RTAS_DEBUG KERN_DEBUG "RTAS: " 216 + 217 + #define RTAS_ERROR_LOG_MAX 2048 218 + 219 + /* 220 + * Return the firmware-specified size of the error log buffer 221 + * for all rtas calls that require an error buffer argument. 222 + * This includes 'check-exception' and 'rtas-last-error'. 223 + */ 224 + extern int rtas_get_error_log_max(void); 225 + 226 + /* Event Scan Parameters */ 227 + #define EVENT_SCAN_ALL_EVENTS 0xf0000000 228 + #define SURVEILLANCE_TOKEN 9000 229 + #define LOG_NUMBER 64 /* must be a power of two */ 230 + #define LOG_NUMBER_MASK (LOG_NUMBER-1) 231 + 232 + /* Some RTAS ops require a data buffer and that buffer must be < 4G. 233 + * Rather than having a memory allocator, just use this buffer 234 + * (get the lock first), make the RTAS call. Copy the data instead 235 + * of holding the buffer for long. 236 + */ 237 + 238 + #define RTAS_DATA_BUF_SIZE 4096 239 + extern spinlock_t rtas_data_buf_lock; 240 + extern char rtas_data_buf[RTAS_DATA_BUF_SIZE]; 241 + 242 + extern void rtas_stop_self(void); 243 + 244 + /* RMO buffer reserved for user-space RTAS use */ 245 + extern unsigned long rtas_rmo_buf; 246 + 247 + #define GLOBAL_INTERRUPT_QUEUE 9005 248 + 249 + #endif /* _POWERPC_RTAS_H */
+5
include/asm-powerpc/system.h
··· 346 346 347 347 #define arch_align_stack(x) (x) 348 348 349 + /* Used in very early kernel initialization. */ 349 350 extern unsigned long reloc_offset(void); 351 + extern unsigned long add_reloc_offset(unsigned long); 352 + extern void reloc_got2(unsigned long); 353 + 354 + #define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x))) 350 355 351 356 #endif /* __KERNEL__ */ 352 357 #endif /* _ASM_POWERPC_SYSTEM_H */