@@ -87,6 +87,66 @@ found:
opal_call(OPAL_GET_VARIABLE, opal_get_variable, 4);
+static int64_t opal_set_variable(uint64_t k_varname, uint64_t k_vardata, uint64_t varsize, uint64_t section)
+{
+ char *varname = (char*) k_varname;
+ char *vardata = (char*) k_vardata;
+
+ struct keystore_variable *var = NULL;
+
+ struct list_head *bank;
+
+ CHECK_KEYSTORE_READY;
+
+ bank = GET_BANK(section);
+
+ list_for_each(bank, var, link) {
+ if (!strcmp(varname, var->name)) {
+ goto found;
+ }
+ }
+
+ var = (struct keystore_variable *) malloc(sizeof(struct keystore_variable));
+ if (!var) {
+ prlog(PR_ERR, "Failed to allocate new variable\n");
+ return OPAL_NO_MEM;
+ }
+
+ var->name_size = strlen(varname) + 1;
+ var->name = malloc(var->name_size);
+ var->name[var->name_size] = '\0'; // Ensure print-friendly NULL terminator
+ if (!var->name) {
+ prlog(PR_ERR, "Failed to allocate new variable's name\n");
+ return OPAL_NO_MEM;
+ }
+
+ memcpy(var->name, varname, var->name_size);
+ var->data = NULL;
+
+ // Add to the list before moving to the shared behavior portion
+ list_add_tail(bank, &var->link);
+
+found:
+ // Clear old data if this is not a new variable.
+ if (var->data)
+ free(var->data);
+
+ var->data_size = varsize;
+ var->data = malloc(var->data_size);
+ if (!var->data) {
+ prlog(PR_ERR, "Failed to allocate new variable's data\n");
+ // TODO: we should probably clean up the linked list node if there is an error
+ // maybe we should try allocating data before freeing the old?
+ return OPAL_NO_MEM;
+ }
+
+ memcpy(var->data, vardata, var->data_size);
+
+ return OPAL_SUCCESS;
+}
+opal_call(OPAL_SET_VARIABLE, opal_set_variable, 4);
+
+
int keystore_init(void)
{
int rc;
The opal_set_variable runtime service operates the same way for the active bank and update queue; it updates an existing variable name's associated data with the supplied data blob if the requested name exists. If the requested name does not exist, it appends a new entry in the list. NOTE: This runtime service does not do any size checks, and is the likely candidate to do some form of size checking. Since we are holding the keys in a sparse structure in memory, this service should probably either use a routine to calculate the current total size, or a total size value should be maintained either in the list head or globally. Signed-off-by: Eric Richter <erichte@linux.ibm.com> --- libstb/keystore.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)