summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Goz <ben.goz@amd.com>2014-12-07 14:50:28 +0200
committerOded Gabbay <oded.gabbay@gmail.com>2015-06-12 23:24:52 +0300
commitdd1947fcff12ad564437fb7c4b3cd1e616cc97e2 (patch)
treee03dc30db01a011c270a68254eb4c90ebcd5a80f
parent992c631933fd3bc81e56323045797669d0792dbd (diff)
Add CZ support to queues module
Signed-off-by: Ben Goz <ben.goz@amd.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
-rw-r--r--src/queues.c146
1 files changed, 140 insertions, 6 deletions
diff --git a/src/queues.c b/src/queues.c
index 1feb9ba..2d7692f 100644
--- a/src/queues.c
+++ b/src/queues.c
@@ -30,15 +30,73 @@
#include <sys/mman.h>
#include <math.h>
#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
/* 1024 doorbells, 4 bytes each doorbell */
#define DOORBELLS_PAGE_SIZE 1024 * 4
+struct device_info
+{
+ uint32_t ctx_save_restore_size;
+ uint32_t eop_buffer_size;
+};
+
+struct device_info kaveri_device_info = {
+ .ctx_save_restore_size = 0,
+ .eop_buffer_size = 0,
+};
+
+struct device_info carrizo_device_info = {
+ .ctx_save_restore_size = 2756608,
+ .eop_buffer_size = 4096,
+};
+
+struct device_id
+{
+ uint16_t dev_id;
+ struct device_info *dev_info;
+};
+
+struct device_id supported_devices[] = {
+ { 0x1304, &kaveri_device_info }, /* Kaveri */
+ { 0x1305, &kaveri_device_info }, /* Kaveri */
+ { 0x1306, &kaveri_device_info }, /* Kaveri */
+ { 0x1307, &kaveri_device_info }, /* Kaveri */
+ { 0x1309, &kaveri_device_info }, /* Kaveri */
+ { 0x130A, &kaveri_device_info }, /* Kaveri */
+ { 0x130B, &kaveri_device_info }, /* Kaveri */
+ { 0x130C, &kaveri_device_info }, /* Kaveri */
+ { 0x130D, &kaveri_device_info }, /* Kaveri */
+ { 0x130E, &kaveri_device_info }, /* Kaveri */
+ { 0x130F, &kaveri_device_info }, /* Kaveri */
+ { 0x1310, &kaveri_device_info }, /* Kaveri */
+ { 0x1311, &kaveri_device_info }, /* Kaveri */
+ { 0x1312, &kaveri_device_info }, /* Kaveri */
+ { 0x1313, &kaveri_device_info }, /* Kaveri */
+ { 0x1315, &kaveri_device_info }, /* Kaveri */
+ { 0x1316, &kaveri_device_info }, /* Kaveri */
+ { 0x1317, &kaveri_device_info }, /* Kaveri */
+ { 0x1318, &kaveri_device_info }, /* Kaveri */
+ { 0x131B, &kaveri_device_info }, /* Kaveri */
+ { 0x131C, &kaveri_device_info }, /* Kaveri */
+ { 0x131D, &kaveri_device_info }, /* Kaveri */
+ { 0x9870, &carrizo_device_info }, /* Carrizo */
+ { 0x9874, &carrizo_device_info }, /* Carrizo */
+ { 0x9875, &carrizo_device_info }, /* Carrizo */
+ { 0x9876, &carrizo_device_info }, /* Carrizo */
+ { 0x9877, &carrizo_device_info }, /* Carrizo */
+ { 0, NULL }
+};
+
struct queue
{
uint32_t queue_id;
uint32_t wptr;
uint32_t rptr;
+ void *eop_buffer;
+ void *ctx_save_restore;
};
struct process_doorbells
@@ -50,6 +108,74 @@ struct process_doorbells
struct process_doorbells doorbells[] = {[0 ... (NUM_OF_SUPPORTED_GPUS-1)] = {.need_mmap = true, .doorbells = NULL, .doorbells_mutex = PTHREAD_MUTEX_INITIALIZER}};
+static struct device_info *get_device_info_by_dev_id(uint16_t dev_id)
+{
+ int i = 0;
+ while (supported_devices[i].dev_id != 0) {
+ if (supported_devices[i].dev_id == dev_id) {
+ return supported_devices[i].dev_info;
+ }
+ i++;
+ }
+
+ return NULL;
+}
+
+static void free_queue(struct queue *q)
+{
+ if (q->eop_buffer)
+ free(q->eop_buffer);
+ if (q->ctx_save_restore)
+ free(q->ctx_save_restore);
+ free(q);
+}
+
+static void* allocate_exec_aligned_memory(uint32_t size, uint32_t align)
+{
+ void *ptr;
+ int retval;
+
+ retval = posix_memalign(&ptr, align, size);
+ if (retval != 0)
+ return NULL;
+
+ retval = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC);
+ if (retval != 0) {
+ free(ptr);
+ return NULL;
+ }
+
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+static int handle_concrete_asic(struct device_info *dev_info, struct queue *q,
+ struct kfd_ioctl_create_queue_args *args)
+{
+ if (dev_info) {
+ if (dev_info->eop_buffer_size > 0) {
+ q->eop_buffer =
+ allocate_exec_aligned_memory(dev_info->eop_buffer_size, PAGE_SIZE);
+ if (q->eop_buffer == NULL) {
+ return HSAKMT_STATUS_NO_MEMORY;
+ }
+ args->eop_buffer_address = (uintptr_t)q->eop_buffer;
+ args->eop_buffer_size = dev_info->eop_buffer_size;
+ }
+ if (dev_info->ctx_save_restore_size > 0) {
+ args->ctx_save_restore_size = dev_info->ctx_save_restore_size;
+ q->ctx_save_restore =
+ allocate_exec_aligned_memory(dev_info->ctx_save_restore_size, PAGE_SIZE);
+ if (q->ctx_save_restore == NULL) {;
+ return HSAKMT_STATUS_NO_MEMORY;
+ }
+ args->ctx_save_restore_address = (uintptr_t)q->ctx_save_restore;
+ }
+ }
+
+ return HSAKMT_STATUS_SUCCESS;
+}
+
HSAKMT_STATUS
HSAKMTAPI
hsaKmtCreateQueue(
@@ -65,6 +191,8 @@ hsaKmtCreateQueue(
{
HSAKMT_STATUS result;
uint32_t gpu_id;
+ uint16_t dev_id;
+ struct device_info *dev_info;
int err;
void* ptr;
CHECK_KFD_OPEN();
@@ -75,23 +203,28 @@ hsaKmtCreateQueue(
struct queue *q = malloc(sizeof(struct queue));
if (q == NULL)
- {
return HSAKMT_STATUS_NO_MEMORY;
- }
-
memset(q, 0, sizeof(*q));
struct kfd_ioctl_create_queue_args args;
memset(&args, 0, sizeof(args));
+ dev_id = get_device_id_by_node(NodeId);
+ dev_info = get_device_info_by_dev_id(dev_id);
args.gpu_id = gpu_id;
+ err = handle_concrete_asic(dev_info, q, &args);
+ if (err != HSAKMT_STATUS_SUCCESS) {
+ free_queue(q);
+ return err;
+ }
+
switch (Type)
{
case HSA_QUEUE_COMPUTE: args.queue_type = KFD_IOC_QUEUE_TYPE_COMPUTE; break;
case HSA_QUEUE_SDMA: free(q); return HSAKMT_STATUS_NOT_IMPLEMENTED;
case HSA_QUEUE_COMPUTE_AQL: args.queue_type = KFD_IOC_QUEUE_TYPE_COMPUTE_AQL; break;
- default: free(q); return HSAKMT_STATUS_INVALID_PARAMETER;
+ default: free_queue(q); return HSAKMT_STATUS_INVALID_PARAMETER;
}
if (Type != HSA_QUEUE_COMPUTE_AQL)
@@ -111,7 +244,7 @@ hsaKmtCreateQueue(
if (err == -1)
{
- free(q);
+ free_queue(q);
return HSAKMT_STATUS_ERROR;
}
@@ -126,6 +259,7 @@ hsaKmtCreateQueue(
if (ptr == MAP_FAILED) {
pthread_mutex_unlock(&doorbells[NodeId].doorbells_mutex);
hsaKmtDestroyQueue(q->queue_id);
+ free_queue(q);
return HSAKMT_STATUS_ERROR;
}
@@ -201,7 +335,7 @@ hsaKmtDestroyQueue(
}
else
{
- free(q);
+ free_queue(q);
return HSAKMT_STATUS_SUCCESS;
}
}