Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* $Id: init.c,v 1.10 1999/09/21 14:35:59 davem Exp $ |
| 2 | * init.c: Initialize internal variables used by the PROM |
| 3 | * library functions. |
| 4 | * |
| 5 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) |
| 6 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
| 7 | */ |
| 8 | |
| 9 | #include <linux/kernel.h> |
| 10 | #include <linux/init.h> |
| 11 | #include <linux/string.h> |
| 12 | #include <linux/ctype.h> |
| 13 | |
| 14 | #include <asm/openprom.h> |
| 15 | #include <asm/oplib.h> |
| 16 | |
| 17 | enum prom_major_version prom_vers; |
| 18 | unsigned int prom_rev, prom_prev; |
| 19 | |
| 20 | /* The root node of the prom device tree. */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 21 | int prom_stdin, prom_stdout; |
| 22 | int prom_chosen_node; |
| 23 | |
| 24 | /* You must call prom_init() before you attempt to use any of the |
| 25 | * routines in the prom library. It returns 0 on success, 1 on |
| 26 | * failure. It gets passed the pointer to the PROM vector. |
| 27 | */ |
| 28 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 29 | extern void prom_cif_init(void *, void *); |
| 30 | |
| 31 | void __init prom_init(void *cif_handler, void *cif_stack) |
| 32 | { |
| 33 | char buffer[80], *p; |
| 34 | int ints[3]; |
| 35 | int node; |
| 36 | int i = 0; |
| 37 | int bufadjust; |
| 38 | |
| 39 | prom_vers = PROM_P1275; |
| 40 | |
| 41 | prom_cif_init(cif_handler, cif_stack); |
| 42 | |
David S. Miller | bff06d5 | 2005-09-22 20:11:33 -0700 | [diff] [blame] | 43 | prom_chosen_node = prom_finddevice(prom_chosen_path); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 | if (!prom_chosen_node || prom_chosen_node == -1) |
| 45 | prom_halt(); |
| 46 | |
David S. Miller | d82ace7 | 2006-02-09 02:52:44 -0800 | [diff] [blame^] | 47 | prom_stdin = prom_getint(prom_chosen_node, "stdin"); |
| 48 | prom_stdout = prom_getint(prom_chosen_node, "stdout"); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 49 | |
| 50 | node = prom_finddevice("/openprom"); |
| 51 | if (!node || node == -1) |
| 52 | prom_halt(); |
| 53 | |
David S. Miller | d82ace7 | 2006-02-09 02:52:44 -0800 | [diff] [blame^] | 54 | prom_getstring(node, "version", buffer, sizeof (buffer)); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 55 | |
David S. Miller | d82ace7 | 2006-02-09 02:52:44 -0800 | [diff] [blame^] | 56 | prom_printf("\n"); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 57 | |
David S. Miller | d82ace7 | 2006-02-09 02:52:44 -0800 | [diff] [blame^] | 58 | if (strncmp(buffer, "OBP ", 4)) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 59 | goto strange_version; |
| 60 | |
| 61 | /* |
| 62 | * Version field is expected to be 'OBP xx.yy.zz date...' |
| 63 | * However, Sun can't stick to this format very well, so |
| 64 | * we need to check for 'OBP xx.yy.zz date...' and adjust |
| 65 | * accordingly. -spot |
| 66 | */ |
| 67 | |
David S. Miller | d82ace7 | 2006-02-09 02:52:44 -0800 | [diff] [blame^] | 68 | if (strncmp(buffer, "OBP ", 5)) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 69 | bufadjust = 4; |
| 70 | else |
| 71 | bufadjust = 5; |
| 72 | |
| 73 | p = buffer + bufadjust; |
| 74 | while (p && isdigit(*p) && i < 3) { |
| 75 | ints[i++] = simple_strtoul(p, NULL, 0); |
| 76 | if ((p = strchr(p, '.')) != NULL) |
| 77 | p++; |
| 78 | } |
| 79 | if (i != 3) |
| 80 | goto strange_version; |
| 81 | |
| 82 | prom_rev = ints[1]; |
| 83 | prom_prev = (ints[0] << 16) | (ints[1] << 8) | ints[2]; |
| 84 | |
David S. Miller | d82ace7 | 2006-02-09 02:52:44 -0800 | [diff] [blame^] | 85 | printk("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + bufadjust); |
| 86 | printk("PROMLIB: Root node compatible: %s\n", prom_root_compatible); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 87 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 | /* Initialization successful. */ |
| 89 | return; |
| 90 | |
| 91 | strange_version: |
| 92 | prom_printf ("Strange OBP version `%s'.\n", buffer); |
| 93 | prom_halt (); |
| 94 | } |