aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Holt <holt@sgi.com>2009-12-15 19:47:55 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 10:20:13 -0500
commit289750d1f1fd4a715baa2a2c6dd0cec2b8317fd7 (patch)
tree2c525297c460a9ab98b9649eb3021e534a8e77fd
parentfae419f2abd15ab7d1cd1413e6683a276a4e14e2 (diff)
X86: uv: implement a gru_read_gpa kernel function
The BIOS has decided to store a pointer to the partition reserved page in a scratch MMR. The GRU is only able to read an MMR using a vload instruction. The gru_read_gpa() function will implemented. Signed-off-by: Robin Holt <holt@sgi.com> Signed-off-by: Jack Steiner <steiner@sgi.com> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/misc/sgi-gru/gru_instructions.h13
-rw-r--r--drivers/misc/sgi-gru/grukservices.c23
-rw-r--r--drivers/misc/sgi-gru/grukservices.h14
-rw-r--r--drivers/misc/sgi-gru/gruprocfs.c1
-rw-r--r--drivers/misc/sgi-gru/grutables.h1
5 files changed, 52 insertions, 0 deletions
diff --git a/drivers/misc/sgi-gru/gru_instructions.h b/drivers/misc/sgi-gru/gru_instructions.h
index 3c9c06618e6a..e033b6ce4a3f 100644
--- a/drivers/misc/sgi-gru/gru_instructions.h
+++ b/drivers/misc/sgi-gru/gru_instructions.h
@@ -340,6 +340,19 @@ static inline void gru_start_instruction(struct gru_instruction *ins, int op32)
340 * - nelem and stride are in elements 340 * - nelem and stride are in elements
341 * - tri0/tri1 is in bytes for the beginning of the data segment. 341 * - tri0/tri1 is in bytes for the beginning of the data segment.
342 */ 342 */
343static inline void gru_vload_phys(void *cb, unsigned long gpa,
344 unsigned int tri0, int iaa, unsigned long hints)
345{
346 struct gru_instruction *ins = (struct gru_instruction *)cb;
347
348 ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
349 ins->nelem = 1;
350 ins->tri0 = tri0;
351 ins->op1_stride = 1;
352 gru_start_instruction(ins, __opword(OP_VLOAD, 0, XTYPE_DW, iaa, 0,
353 CB_IMA(hints)));
354}
355
343static inline void gru_vload(void *cb, unsigned long mem_addr, 356static inline void gru_vload(void *cb, unsigned long mem_addr,
344 unsigned int tri0, unsigned char xtype, unsigned long nelem, 357 unsigned int tri0, unsigned char xtype, unsigned long nelem,
345 unsigned long stride, unsigned long hints) 358 unsigned long stride, unsigned long hints)
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index 766e21e15574..d2b149facda1 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -858,6 +858,29 @@ EXPORT_SYMBOL_GPL(gru_get_next_message);
858/* ---------------------- GRU DATA COPY FUNCTIONS ---------------------------*/ 858/* ---------------------- GRU DATA COPY FUNCTIONS ---------------------------*/
859 859
860/* 860/*
861 * Load a DW from a global GPA. The GPA can be a memory or MMR address.
862 */
863int gru_read_gpa(unsigned long *value, unsigned long gpa)
864{
865 void *cb;
866 void *dsr;
867 int ret, iaa;
868
869 STAT(read_gpa);
870 if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
871 return MQE_BUG_NO_RESOURCES;
872 iaa = gpa >> 62;
873 gru_vload_phys(cb, gpa, gru_get_tri(dsr), iaa, IMA);
874 ret = gru_wait(cb);
875 if (ret == CBS_IDLE)
876 *value = *(unsigned long *)dsr;
877 gru_free_cpu_resources(cb, dsr);
878 return ret;
879}
880EXPORT_SYMBOL_GPL(gru_read_gpa);
881
882
883/*
861 * Copy a block of data using the GRU resources 884 * Copy a block of data using the GRU resources
862 */ 885 */
863int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa, 886int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
diff --git a/drivers/misc/sgi-gru/grukservices.h b/drivers/misc/sgi-gru/grukservices.h
index d60d34bca44d..02aa94d8484a 100644
--- a/drivers/misc/sgi-gru/grukservices.h
+++ b/drivers/misc/sgi-gru/grukservices.h
@@ -131,6 +131,20 @@ extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
131 131
132 132
133/* 133/*
134 * Read a GRU global GPA. Source can be located in a remote partition.
135 *
136 * Input:
137 * value memory address where MMR value is returned
138 * gpa source numalink physical address of GPA
139 *
140 * Output:
141 * 0 OK
142 * >0 error
143 */
144int gru_read_gpa(unsigned long *value, unsigned long gpa);
145
146
147/*
134 * Copy data using the GRU. Source or destination can be located in a remote 148 * Copy data using the GRU. Source or destination can be located in a remote
135 * partition. 149 * partition.
136 * 150 *
diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c
index 3f2375c5ba5b..cf6b3e3034d6 100644
--- a/drivers/misc/sgi-gru/gruprocfs.c
+++ b/drivers/misc/sgi-gru/gruprocfs.c
@@ -98,6 +98,7 @@ static int statistics_show(struct seq_file *s, void *p)
98 printstat(s, flush_tlb_gru_tgh); 98 printstat(s, flush_tlb_gru_tgh);
99 printstat(s, flush_tlb_gru_zero_asid); 99 printstat(s, flush_tlb_gru_zero_asid);
100 printstat(s, copy_gpa); 100 printstat(s, copy_gpa);
101 printstat(s, read_gpa);
101 printstat(s, mesq_receive); 102 printstat(s, mesq_receive);
102 printstat(s, mesq_receive_none); 103 printstat(s, mesq_receive_none);
103 printstat(s, mesq_send); 104 printstat(s, mesq_send);
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
index 46990bcfa536..f7b553a56ed0 100644
--- a/drivers/misc/sgi-gru/grutables.h
+++ b/drivers/misc/sgi-gru/grutables.h
@@ -224,6 +224,7 @@ struct gru_stats_s {
224 atomic_long_t flush_tlb_gru_zero_asid; 224 atomic_long_t flush_tlb_gru_zero_asid;
225 225
226 atomic_long_t copy_gpa; 226 atomic_long_t copy_gpa;
227 atomic_long_t read_gpa;
227 228
228 atomic_long_t mesq_receive; 229 atomic_long_t mesq_receive;
229 atomic_long_t mesq_receive_none; 230 atomic_long_t mesq_receive_none;