/* * Send a message to a message queue * cb GRU control block to use to send message * mq message queue * mesg message. ust be vaddr within a GSEG * bytes message size (<= 2 CL) */ int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes) { struct message_header *mhdr; void *cb; void *dsr; int istatus, clines, ret; STAT(mesq_send); BUG_ON(bytes < sizeof(int) || bytes > 2 * GRU_CACHE_LINE_BYTES); clines = DIV_ROUND_UP(bytes, GRU_CACHE_LINE_BYTES); if (gru_get_cpu_resources(bytes, &cb, &dsr)) return MQE_BUG_NO_RESOURCES; memcpy(dsr, mesg, bytes); mhdr = dsr; mhdr->present = MQS_FULL; mhdr->lines = clines; if (clines == 2) { mhdr->present2 = get_present2(mhdr); restore_present2(mhdr, MQS_FULL); } do { ret = MQE_OK; gru_mesq(cb, mq, gru_get_tri(mhdr), clines, IMA); istatus = gru_wait(cb); if (istatus != CBS_IDLE) ret = send_message_failure(cb, mq, dsr, clines); } while (ret == MQIE_AGAIN); gru_free_cpu_resources(cb, dsr); if (ret) STAT(mesq_send_failed); return ret; }
/* * Copy a block of data using the GRU resources */ int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa, unsigned int bytes) { void *cb; void *dsr; int ret; STAT(copy_gpa); if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr)) return MQE_BUG_NO_RESOURCES; gru_bcopy(cb, src_gpa, dest_gpa, gru_get_tri(dsr), XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_CL, IMA); ret = gru_wait(cb); gru_free_cpu_resources(cb, dsr); return ret; }
/* * Load a DW from a global GPA. The GPA can be a memory or MMR address. */ int gru_read_gpa(unsigned long *value, unsigned long gpa) { void *cb; void *dsr; int ret, iaa; STAT(read_gpa); if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr)) return MQE_BUG_NO_RESOURCES; iaa = gpa >> 62; gru_vload_phys(cb, gpa, gru_get_tri(dsr), iaa, IMA); ret = gru_wait(cb); if (ret == CBS_IDLE) *value = *(unsigned long *)dsr; gru_free_cpu_resources(cb, dsr); return ret; }
static int quicktest0(unsigned long arg) { unsigned long word0; unsigned long word1; void *cb; void *dsr; unsigned long *p; int ret = -EIO; if (gru_get_cpu_resources(GRU_CACHE_LINE_BYTES, &cb, &dsr)) return MQE_BUG_NO_RESOURCES; p = dsr; word0 = MAGIC; word1 = 0; gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); if (gru_wait(cb) != CBS_IDLE) { ; goto done; } if (*p != MAGIC) { printk(KERN_DEBUG "GRU:%d quicktest0 bad magic 0x%lx\n", smp_processor_id(), *p); goto done; } gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); if (gru_wait(cb) != CBS_IDLE) { ; goto done; } if (word0 != word1 || word1 != MAGIC) { // printk(KERN_DEBUG // "GRU:%d quicktest0 err: found 0x%lx, expected 0x%lx\n", ; goto done; } ret = 0; done: gru_free_cpu_resources(cb, dsr); return ret; }