diff options
author | Robin Holt <holt@sgi.com> | 2009-12-15 19:47:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 10:20:13 -0500 |
commit | 289750d1f1fd4a715baa2a2c6dd0cec2b8317fd7 (patch) | |
tree | 2c525297c460a9ab98b9649eb3021e534a8e77fd | |
parent | fae419f2abd15ab7d1cd1413e6683a276a4e14e2 (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.h | 13 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grukservices.c | 23 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grukservices.h | 14 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/gruprocfs.c | 1 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grutables.h | 1 |
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 | */ |
343 | static 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 | |||
343 | static inline void gru_vload(void *cb, unsigned long mem_addr, | 356 | static 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 | */ | ||
863 | int 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 | } | ||
880 | EXPORT_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 | */ |
863 | int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa, | 886 | int 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 | */ | ||
144 | int 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; |