sun4prom.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright (C) 1996 The Australian National University.
  3. * Copyright (C) 1996 Fujitsu Laboratories Limited
  4. * Copyright (C) 1997 Michael A. Griffith (grif@acm.org)
  5. * Copyright (C) 1997 Sun Weenie (ko@ko.reno.nv.us)
  6. * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  7. *
  8. * This software may be distributed under the terms of the Gnu
  9. * Public License version 2 or later
  10. *
  11. * fake a really simple Sun prom for the SUN4
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/string.h>
  15. #include <asm/oplib.h>
  16. #include <asm/idprom.h>
  17. #include <asm/machines.h>
  18. #include <asm/sun4prom.h>
  19. #include <asm/asi.h>
  20. #include <asm/contregs.h>
  21. #include <linux/init.h>
  22. static struct linux_romvec sun4romvec;
  23. static struct idprom sun4_idprom;
  24. struct property {
  25. char *name;
  26. char *value;
  27. int length;
  28. };
  29. struct node {
  30. int level;
  31. struct property *properties;
  32. };
  33. struct property null_properties = { NULL, NULL, -1 };
  34. struct property root_properties[] = {
  35. {"device_type", "cpu", 4},
  36. {"idprom", (char *)&sun4_idprom, sizeof(struct idprom)},
  37. {NULL, NULL, -1}
  38. };
  39. struct node nodes[] = {
  40. { 0, &null_properties },
  41. { 0, root_properties },
  42. { -1,&null_properties }
  43. };
  44. static int no_nextnode(int node)
  45. {
  46. if (nodes[node].level == nodes[node+1].level)
  47. return node+1;
  48. return -1;
  49. }
  50. static int no_child(int node)
  51. {
  52. if (nodes[node].level == nodes[node+1].level-1)
  53. return node+1;
  54. return -1;
  55. }
  56. static struct property *find_property(int node,char *name)
  57. {
  58. struct property *prop = &nodes[node].properties[0];
  59. while (prop && prop->name) {
  60. if (strcmp(prop->name,name) == 0) return prop;
  61. prop++;
  62. }
  63. return NULL;
  64. }
  65. static int no_proplen(int node,char *name)
  66. {
  67. struct property *prop = find_property(node,name);
  68. if (prop) return prop->length;
  69. return -1;
  70. }
  71. static int no_getprop(int node,char *name,char *value)
  72. {
  73. struct property *prop = find_property(node,name);
  74. if (prop) {
  75. memcpy(value,prop->value,prop->length);
  76. return 1;
  77. }
  78. return -1;
  79. }
  80. static int no_setprop(int node,char *name,char *value,int len)
  81. {
  82. return -1;
  83. }
  84. static char *no_nextprop(int node,char *name)
  85. {
  86. struct property *prop = find_property(node,name);
  87. if (prop) return prop[1].name;
  88. return NULL;
  89. }
  90. static struct linux_nodeops sun4_nodeops = {
  91. no_nextnode,
  92. no_child,
  93. no_proplen,
  94. no_getprop,
  95. no_setprop,
  96. no_nextprop
  97. };
  98. static int synch_hook;
  99. struct linux_romvec * __init sun4_prom_init(void)
  100. {
  101. int i;
  102. unsigned char x;
  103. char *p;
  104. p = (char *)&sun4_idprom;
  105. for (i = 0; i < sizeof(sun4_idprom); i++) {
  106. __asm__ __volatile__ ("lduba [%1] %2, %0" : "=r" (x) :
  107. "r" (AC_IDPROM + i), "i" (ASI_CONTROL));
  108. *p++ = x;
  109. }
  110. memset(&sun4romvec,0,sizeof(sun4romvec));
  111. sun4_romvec = (linux_sun4_romvec *) SUN4_PROM_VECTOR;
  112. sun4romvec.pv_romvers = 40;
  113. sun4romvec.pv_nodeops = &sun4_nodeops;
  114. sun4romvec.pv_reboot = sun4_romvec->reboot;
  115. sun4romvec.pv_abort = sun4_romvec->abortentry;
  116. sun4romvec.pv_halt = sun4_romvec->exittomon;
  117. sun4romvec.pv_synchook = (void (**)(void))&synch_hook;
  118. sun4romvec.pv_setctxt = sun4_romvec->setcxsegmap;
  119. sun4romvec.pv_v0bootargs = sun4_romvec->bootParam;
  120. sun4romvec.pv_nbgetchar = sun4_romvec->mayget;
  121. sun4romvec.pv_nbputchar = sun4_romvec->mayput;
  122. sun4romvec.pv_stdin = sun4_romvec->insource;
  123. sun4romvec.pv_stdout = sun4_romvec->outsink;
  124. /*
  125. * We turn on the LEDs to let folks without monitors or
  126. * terminals know we booted. Nothing too fancy now. They
  127. * are all on, except for LED 5, which blinks. When we
  128. * have more time, we can teach the penguin to say "By your
  129. * command" or "Activating turbo boost, Michael". :-)
  130. */
  131. sun4_romvec->setLEDs(NULL);
  132. printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n",
  133. sun4_romvec->monid,
  134. sun4_romvec->romvecversion);
  135. return &sun4romvec;
  136. }