sun4prom.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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.                                 
  105. p = (char *)&sun4_idprom;
  106. for (i = 0; i < sizeof(sun4_idprom); i++) {
  107. __asm__ __volatile__ ("lduba [%1] %2, %0" : "=r" (x) :
  108.       "r" (AC_IDPROM + i), "i" (ASI_CONTROL));
  109. *p++ = x;
  110. }
  111. memset(&sun4romvec,0,sizeof(sun4romvec));
  112. sun4_romvec = (linux_sun4_romvec *) SUN4_PROM_VECTOR;
  113. sun4romvec.pv_romvers = 40;
  114. sun4romvec.pv_nodeops = &sun4_nodeops;
  115. sun4romvec.pv_reboot = sun4_romvec->reboot;
  116. sun4romvec.pv_abort = sun4_romvec->abortentry;
  117. sun4romvec.pv_halt = sun4_romvec->exittomon;
  118. sun4romvec.pv_synchook = (void (**)(void))&synch_hook;
  119. sun4romvec.pv_setctxt = sun4_romvec->setcxsegmap;
  120. sun4romvec.pv_v0bootargs = sun4_romvec->bootParam;
  121. sun4romvec.pv_nbgetchar = sun4_romvec->mayget;
  122. sun4romvec.pv_nbputchar = sun4_romvec->mayput;
  123. sun4romvec.pv_stdin = sun4_romvec->insource;
  124. sun4romvec.pv_stdout = sun4_romvec->outsink;
  125. /*
  126.  * We turn on the LEDs to let folks without monitors or
  127.  * terminals know we booted.   Nothing too fancy now.  They
  128.  * are all on, except for LED 5, which blinks.   When we
  129.  * have more time, we can teach the penguin to say "By your
  130.  * command" or "Activating turbo boost, Michael". :-)
  131.  */
  132. sun4_romvec->setLEDs(0x0);
  133. printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %dn",
  134. sun4_romvec->monid,
  135. sun4_romvec->romvecversion);
  136. return &sun4romvec;
  137. }