sn2_smp.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * SN2 Platform specific SMP Support
  3.  *
  4.  * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
  5.  * 
  6.  * This program is free software; you can redistribute it and/or modify it 
  7.  * under the terms of version 2 of the GNU General Public License 
  8.  * as published by the Free Software Foundation.
  9.  * 
  10.  * This program is distributed in the hope that it would be useful, but 
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
  13.  * 
  14.  * Further, this software is distributed without any warranty that it is 
  15.  * free of the rightful claim of any third person regarding infringement 
  16.  * or the like.  Any license provided herein, whether implied or 
  17.  * otherwise, applies only to this software file.  Patent licenses, if 
  18.  * any, provided herein do not apply to combinations of this program with 
  19.  * other software, or any other product whatsoever.
  20.  * 
  21.  * You should have received a copy of the GNU General Public 
  22.  * License along with this program; if not, write the Free Software 
  23.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  24.  * 
  25.  * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
  26.  * Mountain View, CA  94043, or:
  27.  * 
  28.  * http://www.sgi.com 
  29.  * 
  30.  * For further information regarding this notice, see: 
  31.  * 
  32.  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  33.  */
  34. #include <linux/init.h>
  35. #include <linux/kernel.h>
  36. #include <linux/spinlock.h>
  37. #include <linux/threads.h>
  38. #include <linux/sched.h>
  39. #include <linux/smp.h>
  40. #include <linux/interrupt.h>
  41. #include <linux/irq.h>
  42. #include <linux/mmzone.h>
  43. #include <asm/processor.h>
  44. #include <asm/irq.h>
  45. #include <asm/sal.h>
  46. #include <asm/system.h>
  47. #include <asm/io.h>
  48. #include <asm/smp.h>
  49. #include <asm/hw_irq.h>
  50. #include <asm/current.h>
  51. #include <asm/sn/sn_cpuid.h>
  52. #include <asm/sn/addrs.h>
  53. #include <asm/sn/sn2/shub_mmr.h>
  54. /**
  55.  * sn2_global_tlb_purge - globally purge translation cache of virtual address range
  56.  * @start: start of virtual address range
  57.  * @end: end of virtual address range
  58.  * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
  59.  *
  60.  * Purges the translation caches of all processors of the given virtual address
  61.  * range.
  62.  */
  63. void
  64. sn2_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
  65. {
  66. int cnode, nasid;
  67. volatile long *ptc0, *ptc1, *piows;
  68. unsigned long ws, next, data0, data1;
  69. piows = (long*)LOCAL_MMR_ADDR(get_slice() ? SH_PIO_WRITE_STATUS_1 : SH_PIO_WRITE_STATUS_0);
  70. data0 = (1UL<<SH_PTC_0_A_SHFT) |
  71. (nbits<<SH_PTC_0_PS_SHFT) |
  72. ((ia64_get_rr(start)>>8)<<SH_PTC_0_RID_SHFT) |
  73. (1UL<<SH_PTC_0_START_SHFT);
  74. ptc0 = (long*)GLOBAL_MMR_ADDR(0, SH_PTC_0);
  75. ptc1 = (long*)GLOBAL_MMR_ADDR(0, SH_PTC_1);
  76. do {
  77. *(piows+1) = -1; /* use alias address to clear bits*/
  78. next = start;
  79. do {
  80. for (cnode = 0; cnode < numnodes; cnode++) {
  81. nasid = cnodeid_to_nasid(cnode);
  82. ptc0 = CHANGE_NASID(nasid, ptc0);
  83. ptc1 = CHANGE_NASID(nasid, ptc1);
  84. data1 = next | (1UL<<SH_PTC_1_START_SHFT);
  85. *ptc0 = data0;
  86. *ptc1 = data1;
  87. }
  88. next += (1UL << nbits);
  89. } while (next < end);
  90. while ((ws = *piows) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
  91. ;
  92. } while (ws & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK);
  93. }
  94. /**
  95.  * sn_send_IPI_phys - send an IPI to a Nasid and slice
  96.  * @physid: physical cpuid to receive the interrupt.
  97.  * @vector: command to send
  98.  * @delivery_mode: delivery mechanism
  99.  *
  100.  * Sends an IPI (interprocessor interrupt) to the processor specified by
  101.  * @physid
  102.  *
  103.  * @delivery_mode can be one of the following
  104.  *
  105.  * %IA64_IPI_DM_INT - pend an interrupt
  106.  * %IA64_IPI_DM_PMI - pend a PMI
  107.  * %IA64_IPI_DM_NMI - pend an NMI
  108.  * %IA64_IPI_DM_INIT - pend an INIT interrupt
  109.  */
  110. void
  111. sn_send_IPI_phys(long physid, int vector, int delivery_mode)
  112. {
  113. long nasid, slice;
  114. long *p, val;
  115. nasid = cpu_physical_id_to_nasid(physid);
  116.         slice = cpu_physical_id_to_slice(physid);
  117. p = (long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT);
  118. val =   (1UL<<SH_IPI_INT_SEND_SHFT) | 
  119. (physid<<SH_IPI_INT_PID_SHFT) | 
  120.         ((long)delivery_mode<<SH_IPI_INT_TYPE_SHFT) | 
  121. ((long)vector<<SH_IPI_INT_IDX_SHFT) |
  122. (0x000feeUL<<SH_IPI_INT_BASE_SHFT);
  123. #if defined(BRINGUP)
  124. {
  125. static int count=0;
  126. if (count++ < 10) printk("ZZ sendIPI 0x%x vec %d, nasid 0x%lx, slice %ld, adr 0x%lx, val 0x%lxn",
  127. smp_processor_id(), vector, nasid, slice, (long)p, val);
  128. }
  129. #endif
  130. mb();
  131. *p = val;
  132. }
  133. /**
  134.  * sn2_send_IPI - send an IPI to a processor
  135.  * @cpuid: target of the IPI
  136.  * @vector: command to send
  137.  * @delivery_mode: delivery mechanism
  138.  * @redirect: redirect the IPI?
  139.  *
  140.  * Sends an IPI (InterProcessor Interrupt) to the processor specified by
  141.  * @cpuid.  @vector specifies the command to send, while @delivery_mode can 
  142.  * be one of the following
  143.  *
  144.  * %IA64_IPI_DM_INT - pend an interrupt
  145.  * %IA64_IPI_DM_PMI - pend a PMI
  146.  * %IA64_IPI_DM_NMI - pend an NMI
  147.  * %IA64_IPI_DM_INIT - pend an INIT interrupt
  148.  */
  149. void
  150. sn2_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
  151. {
  152. long physid;
  153. physid = cpu_physical_id(cpuid);
  154. sn_send_IPI_phys(physid, vector, delivery_mode);
  155. }
  156. /**
  157.  * init_sn2_smp_config - initialize SN2 smp configuration
  158.  *
  159.  * currently a NOP.
  160.  */
  161. void __init
  162. init_sn2_smp_config(void)
  163. {
  164. }