23 #include <linux/kernel.h>
24 #include <linux/errno.h>
25 #include <linux/slab.h>
28 #include <linux/device.h>
34 #include <linux/export.h>
41 #include <asm/uv/uv_hub.h>
99 #define ASYNC_HAN_TO_BID(h) ((h) - 1)
100 #define ASYNC_BID_TO_HAN(b) ((b) + 1)
101 #define ASYNC_HAN_TO_BS(h) gru_base[ASYNC_HAN_TO_BID(h)]
103 #define GRU_NUM_KERNEL_CBR 1
104 #define GRU_NUM_KERNEL_DSR_BYTES 256
105 #define GRU_NUM_KERNEL_DSR_CL (GRU_NUM_KERNEL_DSR_BYTES / \
106 GRU_CACHE_LINE_BYTES)
109 #define IMA IMA_CB_DELAY
112 #define __gru_cacheline_aligned__ \
113 __attribute__((__aligned__(GRU_CACHE_LINE_BYTES)))
115 #define MAGIC 0x1234567887654321UL
118 #define EXCEPTION_RETRY_LIMIT 3
146 #define HSTATUS(mq, h) ((mq) + offsetof(struct message_queue, hstatus[h]))
152 static void gru_load_kernel_context(
struct gru_blade_state *bs,
int blade_id)
164 bs->
bs_kgts->ts_user_blade_id = blade_id;
169 STAT(load_kernel_context);
170 ncpus = uv_blade_nr_possible_cpus(blade_id);
184 bs->
kernel_cb = get_gseg_base_address_cb(vaddr, ctxnum, 0);
185 bs->
kernel_dsr = get_gseg_base_address_ds(vaddr, ctxnum, 0);
194 static int gru_free_kernel_contexts(
void)
228 STAT(lock_kernel_context);
230 bid = blade_id < 0 ? uv_numa_blade_id() : blade_id;
235 if (blade_id < 0 && bid != uv_numa_blade_id()) {
240 gru_load_kernel_context(bs, bid);
249 static void gru_unlock_kernel_context(
int blade_id)
255 STAT(unlock_kernel_context);
262 static int gru_get_cpu_resources(
int dsr_bytes,
void **
cb,
void **dsr)
269 bs = gru_lock_kernel_context(-1);
270 lcpu = uv_blade_processor_id();
279 static void gru_free_cpu_resources(
void *
cb,
void *dsr)
281 gru_unlock_kernel_context(uv_numa_blade_id());
372 gru_lock_kernel_context(blade_id);
373 ncpus = uv_blade_nr_possible_cpus(blade_id);
390 gru_unlock_kernel_context(blade_id);
407 for_each_possible_blade(bid) {
411 if (!kgts || !kgts->
ts_gru)
413 off = cb - kgts->
ts_gru->gs_gru_base_vaddr;
420 cbe = get_cbe(
GRUBASE(cb), cbrnum);
421 gru_flush_cache(cbe);
428 gru_flush_cache(cbe);
441 "GRU:%d exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
446 snprintf(buf, size,
"No exception");
460 static int gru_retry_exception(
void *cb)
467 if (gru_wait_idle_or_exception(gen) ==
CBS_IDLE)
469 if (gru_get_cb_message_queue_substatus(cb))
478 gru_flush_cache(gen);
490 ret = gru_retry_exception(cb);
501 ret = gru_wait_idle_or_exception(gen);
503 ret = gru_retry_exception(cb);
512 panic(
"GRU FATAL ERROR: %s - %s\n", str,
529 #define MQIE_AGAIN -1
536 static inline int get_present2(
void *
p)
542 static inline void restore_present2(
void *
p,
int val)
560 mq->
start = &mq->data;
562 mq->next = &mq->data;
567 mq->head = gru_mesq_head(2, qlines / 2 + 1);
598 gru_mesq(cb, mqd->
mq_gpa, gru_get_tri(mhdr), 1,
IMA);
602 substatus = gru_get_cb_message_queue_substatus(cb);
605 STAT(mesq_noop_unexpected_error);
609 STAT(mesq_noop_lb_overflow);
613 STAT(mesq_noop_qlimit_reached);
617 STAT(mesq_noop_amo_nacked);
621 STAT(mesq_noop_put_nacked);
622 m = mqd->
mq_gpa + (gru_get_amo_value_head(cb) << 6);
623 gru_vstore(cb, m, gru_get_tri(mesg),
XTYPE_CL, 1, 1,
631 STAT(mesq_noop_page_overflow);
645 void *mesg,
int lines)
649 unsigned long avalue;
653 avalue = gru_get_amo_value(cb);
654 head = gru_get_amo_value_head(cb);
655 limit = gru_get_amo_value_limit(cb);
658 half = (limit != qlines);
661 mqh = gru_mesq_head(qlines / 2 + 1, qlines);
663 mqh = gru_mesq_head(2, qlines / 2 + 1);
669 if (!gru_get_amo_value(cb)) {
670 STAT(mesq_qf_locked);
676 if (send_noop_message(cb, mqd, mesg)) {
681 STAT(mesq_qf_noop_not_full);
694 if (gru_get_amo_value(cb) != avalue) {
695 STAT(mesq_qf_switch_head_failed);
703 STAT(mesq_qf_unexpected_error);
714 void *mesg,
int lines)
716 unsigned long m, *
val = mesg, gpa, save;
719 m = mqd->
mq_gpa + (gru_get_amo_value_head(cb) << 6);
725 gru_vstore(cb, m, gru_get_tri(mesg),
XTYPE_CL, lines, 1,
IMA);
756 void *mesg,
int lines)
758 int substatus, ret = 0;
760 substatus = gru_get_cb_message_queue_substatus(cb);
763 STAT(mesq_send_unexpected_error);
767 STAT(mesq_send_lb_overflow);
771 STAT(mesq_send_qlimit_reached);
772 ret = send_message_queue_full(cb, mqd, mesg, lines);
775 STAT(mesq_send_amo_nacked);
779 STAT(mesq_send_put_nacked);
780 ret = send_message_put_nacked(cb, mqd, mesg, lines);
783 STAT(mesq_page_overflow);
803 int istatus, clines,
ret;
809 if (gru_get_cpu_resources(bytes, &cb, &dsr))
814 mhdr->
lines = clines;
816 mhdr->
present2 = get_present2(mhdr);
822 gru_mesq(cb, mqd->
mq_gpa, gru_get_tri(mhdr), clines,
IMA);
823 istatus = gru_wait(cb);
825 ret = send_message_failure(cb, mqd, dsr, clines);
827 gru_free_cpu_resources(cb, dsr);
830 STAT(mesq_send_failed);
844 int lines = mhdr->
lines;
852 if (next == mq->
limit) {
855 }
else if (pnext < mq->start2 && next >= mq->
start2) {
889 STAT(mesq_receive_none);
893 if (mhdr->
lines == 2)
894 restore_present2(mhdr, mhdr->
present2);
916 gru_vload_phys(cb, gpa, gru_get_tri(dsr), iaa,
IMA);
919 *value = *(
unsigned long *)dsr;
920 gru_free_cpu_resources(cb, dsr);
939 gru_bcopy(cb, src_gpa, dest_gpa, gru_get_tri(dsr),
942 gru_free_cpu_resources(cb, dsr);
950 static int quicktest0(
unsigned long arg)
965 gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr),
XTYPE_DW, 1, 1,
IMA);
975 gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr),
XTYPE_DW, 1, 1,
IMA);
981 if (word0 != word1 || word1 !=
MAGIC) {
983 "GRU:%d quicktest0 err: found 0x%lx, expected 0x%lx\n",
990 gru_free_cpu_resources(cb, dsr);
994 #define ALIGNUP(p, q) ((void *)(((unsigned long)(p) + (q) - 1) & ~(q - 1)))
996 static int quicktest1(
unsigned long arg)
1009 memset(mes, 0xee,
sizeof(mes));
1013 for (i = 0; i < 6; i++) {
1027 for (i = 0; i < 6; i++) {
1029 if (!m || m[8] != i)
1045 static int quicktest2(
unsigned long arg)
1057 bytes = numcb * 4 * 8;
1068 memset(buf, 0xee, bytes);
1069 for (i = 0; i < numcb; i++)
1077 for (i = 0; i < numcb; i++) {
1079 istatus = gru_check_status(cb);
1088 }
else if (buf[4 * i] || buf[4 * i + 1] || buf[4 * i + 2] ||
1090 printk(
KERN_DEBUG "GRU:%d quicktest2:cb %d, buf 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
1091 smp_processor_id(), i, buf[4 * i], buf[4 * i + 1], buf[4 * i + 2], buf[4 * i + 3]);
1108 static int quicktest3(
unsigned long arg)
1113 memset(buf2, 0,
sizeof(buf2));
1131 switch (arg & 0xff) {
1133 ret = quicktest0(arg);
1136 ret = quicktest1(arg);
1139 ret = quicktest2(arg);
1142 ret = quicktest3(arg);
1145 ret = gru_free_kernel_contexts();
1159 if (gru_free_kernel_contexts())