[FOSS_TLK][task] Add support for event callbacks
Aaron Gamble [Tue, 16 Dec 2014 21:32:14 +0000 (13:32 -0800)]
Add OTE_IOCTL_REGISTER_TA_EVENT enabling tasks to request event
callbacks.

Change-Id: Ib654764cb11de234676ce5e66e95f44d23ad786e
Reviewed-on: http://git-master/r/715774
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Tested-by: Varun Wadekar <vwadekar@nvidia.com>

include/kernel/task.h
include/lib/ote/ote_protocol.h
kernel/syscall.c
kernel/task.c

index 3c55815..383f552 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved
+ * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
@@ -147,6 +147,9 @@ typedef struct task
        unsigned char task_private_data[OTE_TASK_PRIVATE_DATA_LENGTH];
        uint32_t task_size;
        struct list_node node;
+
+       /* bitfield of events task has registered for.  */
+       uint32_t ta_events_mask;
 } task_t;
 
 void task_init();
@@ -228,5 +231,11 @@ u_int task_get_active_count(void);
 /*! return the number of registered tasks since boot */
 u_int task_get_count(void);
 
+/*! set the requested callbacks for ta events */
+status_t task_register_ta_events(task_t *task, uint32_t events_mask);
+
+/*! schedule tasks that have requested callbacks for event.  */
+status_t task_signal_ta_event(enum ta_event_id event, void *arg);
+
 #endif /* ASSEMBLY */
 #endif /* __KERNEL_TASK_H */
index df22de0..2b44b12 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved
+ * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
@@ -33,6 +33,7 @@
 #include "ote_types.h"
 #include <common/ote_common.h>
 #include <common/ote_error.h>
+#include <common/ote_nv_uuid.h>
 #include <service/ote_service.h>
 #include <service/ote_manifest.h>
 #include <ext_nv/ote_ext_nv.h>
index ca578d3..feb9f43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved
+ * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
@@ -300,6 +300,28 @@ static int platform_ioctl_handler(u_int cmd, void *cmdbuf)
 
                        return task_request_handler (args);
                }
+
+               case OTE_IOCTL_REGISTER_TA_EVENT:
+               {
+                       status_t ret;
+
+                       ret = task_register_ta_events(taskp, (uint32_t)cmdbuf);
+                       switch (ret) {
+                       case NO_ERROR:
+                               return NO_ERROR;
+
+                       case ERR_INVALID_ARGS:
+                               return -EINVAL;
+
+                       default:
+                               /* Should never hit this case.  */
+                               dprintf(CRITICAL, "%s: Unknown error "
+                                       "from task_set_power_callbacks %d\n",
+                                       __func__, ret);
+                               return ret;
+                       }
+               }
+
                default:
                {
                        dprintf(SPEW, "%s: invalid ioctl: cmd=0x%x\n",
index 2496160..d1c51cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved
+ * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
@@ -37,7 +37,7 @@
 #include <platform.h>
 #include <platform/platform_p.h>
 #include <kernel/task_load.h>
-#include <common/ote_nv_uuid.h>
+#include <lib/ote/ote_protocol.h>
 
 /*! page aligned area for storing static task headers before heap is initialized */
 #define TASK_LIST_CARVEOUT_PAGES 1
@@ -1171,3 +1171,58 @@ const struct list_node *task_get_task_list()
 {
        return &task_list;
 }
+
+status_t task_register_ta_events(task_t *task, uint32_t events_mask)
+{
+       if (task == NULL)
+               return ERR_INVALID_ARGS;
+
+       if ((events_mask & TA_EVENT_MASK) != events_mask) {
+               dprintf(INFO, "%s: bad events_mask: %d\n", __func__,
+                               events_mask);
+               return ERR_INVALID_ARGS;
+       }
+
+       task->ta_events_mask = events_mask;
+
+       return NO_ERROR;
+}
+
+/*
+ * Signal all tasks that have requested the supplied event.
+ * void *arg is supplied by the caller and is the struct te_command
+ * message to send to the task when it is scheduled.
+ */
+status_t task_signal_ta_event(enum ta_event_id event, void *arg)
+{
+       task_t *tmp;
+       task_t *task;
+       thread_t *thread;
+
+       list_for_every_entry_safe(&task_list, task, tmp, task_t, node) {
+               /* Only schedule tasks that have requested callbacks.  */
+               if ((task->ta_events_mask & (1 << event)) == 0)
+                       continue;
+
+               thread = list_peek_head_type(&task->thread_node,
+                               thread_t, task_node);
+
+               if (thread->state != THREAD_BLOCKED) {
+                       dprintf(CRITICAL,
+                               "%s:%d thread in bad state (%d) for event\n",
+                               __func__, __LINE__, thread->state);
+                       continue;
+               }
+
+               enter_critical_section();
+
+               thread->arg = arg;
+
+               /* kickoff thread */
+               thread_unblock_from_wait_queue(thread, false, NO_ERROR);
+               thread_yield();
+               exit_critical_section();
+       }
+
+       return NO_ERROR;
+}