Skip to content

Commit

Permalink
p9_dd_container: simple generic standalone DD level container
Browse files Browse the repository at this point in the history
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>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/40758
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
Martin Peschke authored and dcrowell77 committed May 23, 2017
1 parent c3ea903 commit 3736d09
Show file tree
Hide file tree
Showing 5 changed files with 385 additions and 0 deletions.
262 changes: 262 additions & 0 deletions src/import/chips/p9/utils/imageProcs/p9_dd_container.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/import/chips/p9/utils/imageProcs/p9_dd_container.c $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - 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;
}
94 changes: 94 additions & 0 deletions src/import/chips/p9/utils/imageProcs/p9_dd_container.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/import/chips/p9/utils/imageProcs/p9_dd_container.h $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - 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
27 changes: 27 additions & 0 deletions src/import/chips/p9/utils/imageProcs/p9_dd_container.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
# $Source: src/import/chips/p9/utils/imageProcs/p9_dd_container.mk $
#
# OpenPOWER HostBoot Project
#
# Contributors Listed Below - 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)

1 change: 1 addition & 0 deletions src/usr/isteps/pm/pm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ include ${HWP_CUST_PATH}/p9_xip_customize.mk
include ${HWP_ACC_PATH}/p9_get_mvpd_ring.mk
include ${HWP_ACC_PATH}/p9_mvpd_ring_funcs.mk
include ${HWP_XIP_PATH}/p9_xip_image.mk
include ${HWP_IMAGEPROCS_PATH}/p9_dd_container.mk
include ${HWP_IMAGEPROCS_PATH}/p9_tor.mk
include ${HWP_IMAGEPROCS_PATH}/p9_ring_identification.mk
include ${HWP_IMAGEPROCS_PATH}/p9_ringId.mk
Expand Down

0 comments on commit 3736d09

Please sign in to comment.