summaryrefslogtreecommitdiffstats
path: root/import/chips/p9/utils
diff options
context:
space:
mode:
authorMartin Peschke <mpeschke@de.ibm.com>2017-04-08 19:02:59 +0200
committerJoshua Hunsberger <jahunsbe@us.ibm.com>2017-10-23 17:35:36 -0500
commitcf1e2b9514b8f04a3efd4cb9f0ad0246cfdba91f (patch)
treede2eab08bf71e4b5fa029721dc167b5cc7f70389 /import/chips/p9/utils
parent514f6623a16a3f3f1cc713385601bca116baa858 (diff)
downloadtalos-hcode-cf1e2b9514b8f04a3efd4cb9f0ad0246cfdba91f.tar.gz
talos-hcode-cf1e2b9514b8f04a3efd4cb9f0ad0246cfdba91f.zip
p9_dd_container: simple generic standalone DD level container
Change-Id: I4c9d8cb28d4ae6a8b21c87ebaad07c1fd7163b85 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/39588 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Claus M. Olsen <cmolsen@us.ibm.com> Reviewed-by: Sumit Kumar <sumit_kumar@in.ibm.com> Reviewed-by: Martin Peschke <mpeschke@de.ibm.com>
Diffstat (limited to 'import/chips/p9/utils')
-rw-r--r--import/chips/p9/utils/imageProcs/p9_dd_container.c262
-rw-r--r--import/chips/p9/utils/imageProcs/p9_dd_container.h94
-rw-r--r--import/chips/p9/utils/imageProcs/p9_dd_container.mk26
-rw-r--r--import/chips/p9/utils/imageProcs/p9_dd_container_tool.c356
-rw-r--r--import/chips/p9/utils/imageProcs/p9_dd_container_tool.mk29
5 files changed, 767 insertions, 0 deletions
diff --git a/import/chips/p9/utils/imageProcs/p9_dd_container.c b/import/chips/p9/utils/imageProcs/p9_dd_container.c
new file mode 100644
index 00000000..340de207
--- /dev/null
+++ b/import/chips/p9/utils/imageProcs/p9_dd_container.c
@@ -0,0 +1,262 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/utils/imageProcs/p9_dd_container.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <endian.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "p9_dd_container.h"
+
+int p9_dd_validate(struct p9_dd_cont* i_cont)
+{
+ if (!i_cont)
+ {
+ return P9_DD_FAILURE_DOES_NOT_EXIST;
+ }
+
+ if (be32toh(i_cont->iv_magic) != P9_DD_CONTAINER_MAGIC)
+ {
+ return P9_DD_FAILURE_BROKEN;
+ }
+
+ // may want to check here for holes or overlap as to stored blocks
+
+ return P9_DD_SUCCESS;
+}
+
+// iterates through all dd level blocks
+struct p9_dd_block* p9_dd_next(struct p9_dd_iter* io_iter)
+{
+ struct p9_dd_block* block;
+
+ if (!io_iter ||
+ !io_iter->iv_cont ||
+ io_iter->iv_idx >= io_iter->iv_cont->iv_num)
+ {
+ return NULL;
+ }
+
+ block = &(io_iter->iv_cont->iv_blocks)[io_iter->iv_idx];
+ io_iter->iv_idx++;
+
+ return block;
+}
+
+uint8_t* p9_dd_addr(struct p9_dd_cont* i_cont, uint32_t i_offset)
+{
+ return (uint8_t*)i_cont + i_offset;
+}
+
+void p9_dd_betoh(struct p9_dd_block* i_block_be,
+ struct p9_dd_block* io_block_he)
+{
+ io_block_he->iv_offset = be32toh(i_block_be->iv_offset);
+ io_block_he->iv_size = be32toh(i_block_be->iv_size);
+ io_block_he->iv_dd = i_block_be->iv_dd;
+}
+
+// returns address of dd level content (without meta data)
+int p9_dd_get(uint8_t* i_cont, uint8_t i_dd, uint8_t** o_buf, uint32_t* o_size)
+{
+ struct p9_dd_cont* cont = (struct p9_dd_cont*)i_cont;
+ struct p9_dd_iter iter = P9_DD_ITER_INIT(cont);
+ struct p9_dd_block* block;
+ struct p9_dd_block block_he;
+ int rc;
+
+ rc = p9_dd_validate(cont);
+
+ if (rc != P9_DD_SUCCESS)
+ {
+ return rc;
+ }
+
+ while ((block = p9_dd_next(&iter)))
+ {
+ if (block->iv_dd == i_dd)
+ {
+ p9_dd_betoh(block, &block_he);
+ *o_buf = p9_dd_addr(cont, block_he.iv_offset);
+ *o_size = block_he.iv_size;
+ return P9_DD_SUCCESS;
+ }
+ }
+
+ return P9_DD_FAILURE_NOT_FOUND;
+}
+
+uint32_t p9_dd_size_meta(struct p9_dd_cont* i_cont)
+{
+ return (i_cont ?
+ (sizeof(struct p9_dd_cont) +
+ sizeof(struct p9_dd_block) * i_cont->iv_num) :
+ 0);
+}
+
+// assumes only API (p9_dd_add()) used to create container,
+// that is, last block header points to block with biggest offset
+uint32_t p9_dd_size(struct p9_dd_cont* i_cont)
+{
+ struct p9_dd_block* last;
+
+ if (!i_cont)
+ {
+ return 0;
+ }
+
+ if (!i_cont->iv_num)
+ {
+ return p9_dd_size_meta(i_cont);
+ }
+
+ last = &(i_cont->iv_blocks)[i_cont->iv_num - 1];
+
+ return be32toh(last->iv_offset) + be32toh(last->iv_size);
+}
+
+struct p9_dd_cont* p9_dd_create(void)
+{
+ struct p9_dd_cont* cont;
+
+ cont = malloc(sizeof(struct p9_dd_cont));
+
+ if (!cont)
+ {
+ return cont;
+ }
+
+ cont->iv_magic = htobe32(P9_DD_CONTAINER_MAGIC);
+ cont->iv_num = 0;
+
+ return cont;
+}
+
+// enlarges (reallocates) container and copies dd level block into container
+int p9_dd_add(
+ uint8_t** io_cont, uint32_t* o_cont_size, uint8_t i_dd,
+ uint8_t* i_buf, uint32_t i_buf_size)
+{
+ struct p9_dd_cont* cont = (struct p9_dd_cont*)*io_cont;
+
+ uint8_t* dupl_buf;
+ uint32_t dupl_size;
+
+ uint32_t enlarged;
+
+ int rc;
+
+ uint8_t* others_addr_new;
+ uint8_t* others_addr_old;
+ uint32_t others_size;
+ struct p9_dd_block* others_block;
+
+ uint8_t* this_addr;
+ uint32_t this_offs;
+ struct p9_dd_block* this_block;
+
+ struct p9_dd_iter iter = P9_DD_ITER_INIT(NULL);
+
+ // handle duplicates and initial setup of empty container
+ rc = p9_dd_get(*io_cont, i_dd, &dupl_buf, &dupl_size);
+
+ switch (rc)
+ {
+ case P9_DD_FAILURE_NOT_FOUND :
+ break;
+
+ case P9_DD_FAILURE_DOES_NOT_EXIST :
+ cont = p9_dd_create();
+
+ if (!cont)
+ {
+ return P9_DD_FAILURE_NOMEM;
+ }
+
+ break;
+
+ case P9_DD_SUCCESS :
+ return P9_DD_FAILURE_DUPLICATE;
+
+ default :
+ return rc;
+ }
+
+ // size of enlarged container
+ enlarged = p9_dd_size(cont) + sizeof(struct p9_dd_block) + i_buf_size;
+
+ // re-allocate to enlarge container (content is retained and consistent)
+ cont = realloc(cont, enlarged);
+
+ if (!cont)
+ {
+ return P9_DD_FAILURE_NOMEM;
+ }
+
+ // offsets and size of existing bufs
+ others_addr_old = p9_dd_addr(cont, p9_dd_size_meta(cont));
+ others_addr_new = others_addr_old + sizeof(struct p9_dd_block);
+ others_size = p9_dd_size(cont) - p9_dd_size_meta(cont);
+
+ // meta data, offset and address of new buf
+ this_block = (struct p9_dd_block*)others_addr_old;
+ this_offs = p9_dd_size(cont) + sizeof(struct p9_dd_block);
+ this_addr = p9_dd_addr(cont, this_offs);
+
+ // fix offsets of existing bufs
+ iter.iv_cont = cont;
+
+ while ((others_block = p9_dd_next(&iter)))
+ {
+ others_block->iv_offset =
+ htobe32(be32toh(others_block->iv_offset) +
+ sizeof(struct p9_dd_block));
+ }
+
+ // move existing bufs
+ memmove(others_addr_new, others_addr_old, others_size);
+
+ // copy new buf into container
+ memcpy(this_addr, i_buf, i_buf_size);
+
+ // fill in meta data for new buf
+ memset(this_block, sizeof(struct p9_dd_block), 0);
+ this_block->iv_offset = htobe32(this_offs);
+ this_block->iv_size = htobe32(i_buf_size);
+ this_block->iv_dd = i_dd;
+ this_block->iv_reserved[0] = 0;
+ this_block->iv_reserved[1] = 0;
+ this_block->iv_reserved[2] = 0;
+
+ // increase number off DD level blocks in container
+ (cont)->iv_num++;
+
+ *io_cont = (uint8_t*)cont;
+ *o_cont_size = enlarged;
+
+ return P9_DD_SUCCESS;
+}
diff --git a/import/chips/p9/utils/imageProcs/p9_dd_container.h b/import/chips/p9/utils/imageProcs/p9_dd_container.h
new file mode 100644
index 00000000..6a373587
--- /dev/null
+++ b/import/chips/p9/utils/imageProcs/p9_dd_container.h
@@ -0,0 +1,94 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/utils/imageProcs/p9_dd_container.h $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef _P9_DD_CONTAINER_H_
+#define _P9_DD_CONTAINER_H_
+
+#include <stdint.h>
+
+#define P9_DD_CONTAINER_MAGIC 0x4444434F // "DDCO"
+
+#define P9_DD_SUCCESS 0
+#define P9_DD_FAILURE_BROKEN 1
+#define P9_DD_FAILURE_NOMEM 2
+#define P9_DD_FAILURE_NOT_FOUND 3
+#define P9_DD_FAILURE_DOES_NOT_EXIST 4
+#define P9_DD_FAILURE_DUPLICATE 5
+
+// header for each dd level block inside container
+struct p9_dd_block
+{
+ uint32_t iv_offset;
+ uint32_t iv_size;
+ uint8_t iv_dd;
+ uint8_t iv_reserved[3];
+};
+
+// container header
+struct p9_dd_cont
+{
+ uint32_t iv_magic;
+ uint8_t iv_num;
+ uint8_t iv_reserved[3];
+ struct p9_dd_block iv_blocks[0];
+};
+
+// iterator that can be used to iterate through all dd level blocks
+struct p9_dd_iter
+{
+ struct p9_dd_cont* iv_cont;
+ uint8_t iv_idx;
+};
+
+// initialisation of iterator
+#define P9_DD_ITER_INIT(dd_cont) { .iv_cont = (dd_cont), .iv_idx = 0 }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// validates container
+int p9_dd_validate(struct p9_dd_cont* i_cont);
+
+void p9_dd_betoh(struct p9_dd_block* i_block_be,
+ struct p9_dd_block* io_block_he);
+
+// iterates through all dd level blocks
+struct p9_dd_block* p9_dd_next(struct p9_dd_iter* io_iter);
+
+// returns address of dd level content (without meta data)
+int p9_dd_get(
+ uint8_t* i_cont, uint8_t i_dd, uint8_t** o_buf, uint32_t* o_size);
+
+// enlarges (reallocates) container and copies dd level block into container
+int p9_dd_add(
+ uint8_t** io_cont, uint32_t* o_cont_size, uint8_t i_dd,
+ uint8_t* i_buf, uint32_t i_buf_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/import/chips/p9/utils/imageProcs/p9_dd_container.mk b/import/chips/p9/utils/imageProcs/p9_dd_container.mk
new file mode 100644
index 00000000..f08211ca
--- /dev/null
+++ b/import/chips/p9/utils/imageProcs/p9_dd_container.mk
@@ -0,0 +1,26 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: import/chips/p9/utils/imageProcs/p9_dd_container.mk $
+#
+# OpenPOWER HCODE Project
+#
+# COPYRIGHT 2016,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+PROCEDURE=p9_dd_container
+$(call BUILD_PROCEDURE)
diff --git a/import/chips/p9/utils/imageProcs/p9_dd_container_tool.c b/import/chips/p9/utils/imageProcs/p9_dd_container_tool.c
new file mode 100644
index 00000000..016796e4
--- /dev/null
+++ b/import/chips/p9/utils/imageProcs/p9_dd_container_tool.c
@@ -0,0 +1,356 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: import/chips/p9/utils/imageProcs/p9_dd_container_tool.c $ */
+/* */
+/* OpenPOWER HCODE Project */
+/* */
+/* COPYRIGHT 2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "p9_dd_container.h"
+
+bool debug = false;
+
+#define DEBUG(_fmt_, _args_...) \
+ if (debug) \
+ { \
+ printf(_fmt_, ##_args_); \
+ }
+
+enum commands
+{
+ COMMAND_UNDEF,
+ COMMAND_ADD,
+ COMMAND_GET,
+ COMMAND_LIST
+};
+
+const char* usage =
+ "adds DD level block to container, and creates container, if needed\n"
+ "\n"
+ "Usage:\n"
+ " p9_dd_container_tool [options]\n"
+ " --command add|get|list\n"
+ " --dd <num> DD level number (hexadecimal)\n"
+ " --block <file name> DD level block to be added\n"
+ " --cont <file name> DD level block container to be enlarged/shown\n"
+ " --help this information\n"
+ " --debug enable debug output\n"
+ "\n"
+ "Examples:\n"
+ " p9_dd_container_tool\n"
+ " --command add\n"
+ " --dd 0x10\n"
+ " --block output/images/cme/p9n/dd10/cme.bin\n"
+ " --cont output/images/cme/hcode.bin\n"
+ " p9_dd_container_tool\n"
+ " --command get\n"
+ " --cont output/images/cme/hcode.bin\n"
+ " --dd 0x10\n"
+ " p9_dd_container_tool\n"
+ " --command list\n"
+ " --cont output/images/cme/hcode.bin\n"
+ "\n"
+ "If the DD level container file already exists, the tool attempts\n"
+ "to add the new DD level block. Otherwise a new DD level container\n"
+ "is created and a new output file is written.\n"
+ "\n"
+ "The tool checks for duplicates. That means, a DD level block\n"
+ "is to be added is rejected if another block for the same DD\n"
+ "level number already exists.\n";
+
+static const struct option options[] =
+{
+ {"command", required_argument, NULL, 'c'},
+ {"dd", required_argument, NULL, 'n'},
+ {"block", required_argument, NULL, 'b'},
+ {"cont", required_argument, NULL, 'o'},
+ {"help", no_argument, NULL, 'h'},
+ {"debug", no_argument, NULL, 'd'},
+};
+
+static const char* optionstr = "c:nbo:h:d";
+
+int p9_dd_tool_read(uint8_t** buf, uint32_t* size, char* fn, int mandatory)
+{
+ FILE* fp;
+ uint32_t read;
+
+ fp = fopen(fn, "r");
+
+ if (!fp)
+ {
+ if (mandatory)
+ {
+ printf("failed to open %s for reading\n", fn);
+ exit(-1);
+ }
+
+ *buf = NULL;
+ *size = 0;
+ return *size;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ *size = ftell(fp);
+
+ if (*size)
+ {
+ fseek(fp, 0, SEEK_SET);
+ *buf = malloc(*size);
+
+ if (!*buf)
+ {
+ printf("failed to allocate buffer\n");
+ fclose(fp);
+ exit(-1);
+ }
+
+ read = fread(*buf, 1, *size, fp);
+
+ if (read != *size)
+ {
+ printf("failed to read %s\n", fn);
+ exit(-1);
+ }
+ }
+
+ fclose(fp);
+
+ return *size;
+}
+
+int p9_dd_tool_write(uint8_t* buf, uint32_t size, char* fn)
+{
+ FILE* fp;
+ uint32_t written;
+
+ fp = fopen(fn, "w+");
+
+ if (!fp)
+ {
+ printf("failed to open %s for writing\n", fn);
+ exit(-1);
+ }
+
+ written = fwrite(buf, 1, size, fp);
+
+ if (written != size)
+ {
+ printf("failed to write to %s\n", fn);
+ exit(-1);
+ }
+
+ fclose(fp);
+ return size;
+}
+
+int p9_dd_tool_add(int dd, char* fn_block, char* fn_cont)
+{
+ uint32_t block_size;
+ uint32_t cont_size;
+ uint8_t* block;
+ uint8_t* cont;
+ int rc = 0;
+
+ p9_dd_tool_read(&block, &block_size, fn_block, 1);
+ p9_dd_tool_read(&cont, &cont_size, fn_cont, 0);
+
+ if (block || block_size)
+ {
+ rc = p9_dd_add(&cont, &cont_size, dd, block, block_size);
+
+ if (rc == P9_DD_SUCCESS)
+ {
+ rc = p9_dd_tool_write(cont, cont_size, fn_cont);
+ }
+ else
+ {
+ printf("failed, p9_dd_add returned %d\n", rc);
+ }
+ }
+
+ free(block);
+ free(cont);
+
+ return rc;
+}
+
+int p9_dd_tool_get(int dd, char* fn_block, char* fn_cont)
+{
+ uint32_t block_size;
+ uint32_t cont_size;
+ uint8_t* block;
+ uint8_t* cont;
+ int rc = 0;
+
+ p9_dd_tool_read(&cont, &cont_size, fn_cont, 1);
+
+ rc = p9_dd_get(cont, dd, &block, &block_size);
+
+ if (rc == P9_DD_SUCCESS)
+ {
+ rc = p9_dd_tool_write(block, block_size, fn_block);
+ }
+ else
+ {
+ printf("failed, p9_dd_get returned %d\n", rc);
+ }
+
+ free(cont);
+
+ return rc;
+}
+
+int p9_dd_tool_list(char* fn_cont)
+{
+ uint32_t cont_size;
+ uint8_t* cont;
+ struct p9_dd_iter iter = P9_DD_ITER_INIT(NULL);
+ struct p9_dd_block* block;
+ struct p9_dd_block block_he;
+
+ p9_dd_tool_read(&cont, &cont_size, fn_cont, 1);
+ iter.iv_cont = (struct p9_dd_cont*)cont;
+
+ while ((block = p9_dd_next(&iter)))
+ {
+ p9_dd_betoh(block, &block_he);
+ printf("block: dd=0x%x size=%d\n", block_he.iv_dd, block_he.iv_size);
+ }
+
+ free(cont);
+
+ return 0;
+}
+
+int main(int argc, char* argv[])
+{
+ char* fn_block = NULL;
+ char* fn_cont = NULL;
+ int dd = 0;
+ int command = COMMAND_UNDEF;
+ int option = -1;
+
+ if (argc == 1)
+ {
+ printf("%s", usage);
+ exit(-1);
+ }
+
+ while (-1 != (option = getopt_long(argc, argv, optionstr, options, NULL)))
+ {
+ switch (option)
+ {
+ case 'c' :
+ if (!strcmp(optarg, "add"))
+ {
+ command = COMMAND_ADD;
+ }
+ else if (!strcmp(optarg, "get"))
+ {
+ command = COMMAND_GET;
+ }
+ else if (!strcmp(optarg, "list"))
+ {
+ command = COMMAND_LIST;
+ }
+
+ break;
+
+ case 'n' :
+ if (sscanf(optarg, "0x%x", &dd) != 1)
+ {
+ printf("%s", usage);
+ exit(-1);
+ }
+
+ break;
+
+ case 'b' :
+ fn_block = strdup(optarg);
+ break;
+
+ case 'o' :
+ if (fn_cont)
+ {
+ printf("%s", usage);
+ exit(-1);
+ }
+
+ fn_cont = strdup(optarg);
+ break;
+
+ case 'd' :
+ debug = true;
+ break;
+
+ case 'h' :
+ printf("%s", usage);
+ exit(0);
+
+ default :
+ printf("%s", usage);
+ exit(-1);
+ }
+
+ switch (command)
+ {
+ case COMMAND_LIST :
+ if (fn_cont)
+ {
+ return p9_dd_tool_list(fn_cont);
+ }
+
+ break;
+
+ case COMMAND_ADD :
+ if (fn_cont && fn_block && dd)
+ {
+ p9_dd_tool_add(dd, fn_block, fn_cont);
+ dd = 0;
+ free(fn_block);
+ fn_block = NULL;
+ }
+
+ break;
+
+ case COMMAND_GET :
+ if (fn_cont && fn_block && dd)
+ {
+ p9_dd_tool_get(dd, fn_block, fn_cont);
+ dd = 0;
+ free(fn_block);
+ fn_block = NULL;
+ }
+
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/import/chips/p9/utils/imageProcs/p9_dd_container_tool.mk b/import/chips/p9/utils/imageProcs/p9_dd_container_tool.mk
new file mode 100644
index 00000000..063aee50
--- /dev/null
+++ b/import/chips/p9/utils/imageProcs/p9_dd_container_tool.mk
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: import/chips/p9/utils/imageProcs/p9_dd_container_tool.mk $
+#
+# OpenPOWER HCODE Project
+#
+# COPYRIGHT 2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+EXE = p9_dd_container_tool
+OBJS += $(EXE).o
+$(EXE)_DEPLIBS += p9_dd_container
+$(call BUILD_EXE)
OpenPOWER on IntegriCloud