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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: starfire.c,v 1.10 2001/04/14 21:13:45 davem Exp $
  2.  * starfire.c: Starfire/E10000 support.
  3.  *
  4.  * Copyright (C) 1998 David S. Miller (davem@redhat.com)
  5.  * Copyright (C) 2000 Anton Blanchard (anton@samba.org)
  6.  */
  7. #include <linux/kernel.h>
  8. #include <linux/slab.h>
  9. #include <asm/page.h>
  10. #include <asm/oplib.h>
  11. #include <asm/smp.h>
  12. #include <asm/upa.h>
  13. #include <asm/starfire.h>
  14. /*
  15.  * A few places around the kernel check this to see if
  16.  * they need to call us to do things in a Starfire specific
  17.  * way.
  18.  */
  19. int this_is_starfire = 0;
  20. void check_if_starfire(void)
  21. {
  22. int ssnode = prom_finddevice("/ssp-serial");
  23. if(ssnode != 0 && ssnode != -1)
  24. this_is_starfire = 1;
  25. }
  26. void starfire_cpu_setup(void)
  27. {
  28. if (this_is_starfire) {
  29. /*
  30.  * We do this in starfire_translate and xcall_deliver. When we fix our cpu
  31.  * arrays to support > 64 processors we can use the real upaid instead
  32.  * of the logical cpuid in __cpu_number_map etc, then we can get rid of
  33.  * the translations everywhere. - Anton
  34.  */
  35. #if 0
  36. int i;
  37. /*
  38.  * Now must fixup cpu MIDs.  OBP gave us a logical
  39.  * linear cpuid number, not the real upaid.
  40.  */
  41. for(i = 0; i < linux_num_cpus; i++) {
  42. unsigned int mid = linux_cpus[i].mid;
  43. mid = (((mid & 0x3c) << 1) |
  44.        ((mid & 0x40) >> 4) |
  45.        (mid & 0x3));
  46. linux_cpus[i].mid = mid;
  47. }
  48. #endif
  49. }
  50. }
  51. int starfire_hard_smp_processor_id(void)
  52. {
  53. return upa_readl(0x1fff40000d0UL);
  54. }
  55. /*
  56.  * Each Starfire board has 32 registers which perform translation
  57.  * and delivery of traditional interrupt packets into the extended
  58.  * Starfire hardware format.  Essentially UPAID's now have 2 more
  59.  * bits than in all previous Sun5 systems.
  60.  */
  61. struct starfire_irqinfo {
  62. unsigned long imap_slots[32];
  63. unsigned long tregs[32];
  64. struct starfire_irqinfo *next;
  65. int upaid, hwmid;
  66. };
  67. static struct starfire_irqinfo *sflist = NULL;
  68. /* Beam me up Scott(McNeil)y... */
  69. void *starfire_hookup(int upaid)
  70. {
  71. struct starfire_irqinfo *p;
  72. unsigned long treg_base, hwmid, i;
  73. p = kmalloc(sizeof(*p), GFP_KERNEL);
  74. if(!p) {
  75. prom_printf("starfire_hookup: No memory, this is insane.n");
  76. prom_halt();
  77. }
  78. treg_base = 0x100fc000000UL;
  79. hwmid = ((upaid & 0x3c) << 1) |
  80. ((upaid & 0x40) >> 4) |
  81. (upaid & 0x3);
  82. p->hwmid = hwmid;
  83. treg_base += (hwmid << 33UL);
  84. treg_base += 0x200UL;
  85. for(i = 0; i < 32; i++) {
  86. p->imap_slots[i] = 0UL;
  87. p->tregs[i] = treg_base + (i * 0x10UL);
  88. /* Lets play it safe and not overwrite existing mappings */
  89. if (upa_readl(p->tregs[i]) != 0)
  90. p->imap_slots[i] = 0xdeadbeaf;
  91. }
  92. p->upaid = upaid;
  93. p->next = sflist;
  94. sflist = p;
  95. return (void *) p;
  96. }
  97. unsigned int starfire_translate(unsigned long imap,
  98. unsigned int upaid)
  99. {
  100. struct starfire_irqinfo *p;
  101. unsigned int bus_hwmid;
  102. unsigned int i;
  103. bus_hwmid = (((unsigned long)imap) >> 33) & 0x7f;
  104. for(p = sflist; p != NULL; p = p->next)
  105. if(p->hwmid == bus_hwmid)
  106. break;
  107. if(p == NULL) {
  108. prom_printf("XFIRE: Cannot find irqinfo for imap %016lxn",
  109.     ((unsigned long)imap));
  110. prom_halt();
  111. }
  112. for(i = 0; i < 32; i++) {
  113. if(p->imap_slots[i] == imap ||
  114.    p->imap_slots[i] == 0UL)
  115. break;
  116. }
  117. if(i == 32) {
  118. printk("starfire_translate: Are you kidding me?n");
  119. panic("Lucy in the sky....");
  120. }
  121. p->imap_slots[i] = imap;
  122. /* map to real upaid */
  123. upaid = (((upaid & 0x3c) << 1) |
  124.        ((upaid & 0x40) >> 4) |
  125.        (upaid & 0x3));
  126. upa_writel(upaid, p->tregs[i]);
  127. return i;
  128. }