summaryrefslogtreecommitdiffstats
path: root/src/lib/ppc405lib
diff options
context:
space:
mode:
authorWilliam Bryan <wilbryan@us.ibm.com>2016-06-20 12:22:09 -0500
committerWilliam A. Bryan <wilbryan@us.ibm.com>2016-06-20 16:00:22 -0400
commitbe72a02c54979ecee2a57649c6f9dd49ca5f2525 (patch)
tree8f37b9a6d44375ea0907155c1f05a16d80ab18e1 /src/lib/ppc405lib
parenta12f5be3e904bf5bb7aabb978f5e4d0cf1e8b969 (diff)
downloadtalos-occ-be72a02c54979ecee2a57649c6f9dd49ca5f2525.tar.gz
talos-occ-be72a02c54979ecee2a57649c6f9dd49ca5f2525.zip
Remove non product code files
Change-Id: Ib42630c94b0e0fbed2bd8c5939fde026af87a212 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/26055 Tested-by: FSP CI Jenkins Reviewed-by: Wael El-Essawy <welessa@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/lib/ppc405lib')
-rw-r--r--src/lib/ppc405lib/byte_pool.c1442
-rw-r--r--src/lib/ppc405lib/byte_pool.h166
-rw-r--r--src/lib/ppc405lib/initcall.c70
-rw-r--r--src/lib/ppc405lib/initcall.h116
-rw-r--r--src/lib/ppc405lib/lfsr.c50
-rw-r--r--src/lib/ppc405lib/lfsr.h46
-rw-r--r--src/lib/ppc405lib/libppc405files.mk10
-rw-r--r--src/lib/ppc405lib/mutex.c129
-rw-r--r--src/lib/ppc405lib/mutex.h164
-rw-r--r--src/lib/ppc405lib/periodic_semaphore.c114
-rw-r--r--src/lib/ppc405lib/periodic_semaphore.h152
-rw-r--r--src/lib/ppc405lib/progress.c743
-rw-r--r--src/lib/ppc405lib/progress.h177
-rw-r--r--src/lib/ppc405lib/rtx_stdio.c149
-rw-r--r--src/lib/ppc405lib/rtx_stdio.h74
-rw-r--r--src/lib/ppc405lib/rtx_stdio_addresses.h55
-rw-r--r--src/lib/ppc405lib/sxlock.c494
-rw-r--r--src/lib/ppc405lib/sxlock.h108
18 files changed, 1 insertions, 4258 deletions
diff --git a/src/lib/ppc405lib/byte_pool.c b/src/lib/ppc405lib/byte_pool.c
deleted file mode 100644
index d382abc..0000000
--- a/src/lib/ppc405lib/byte_pool.c
+++ /dev/null
@@ -1,1442 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/byte_pool.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 */
-// $Id$
-
-/// \file byte_pool.c
-/// \brief An implementation of a constant-time malloc() algorithm.
-///
-/// The 'byte-pool' API defined in this file is similar to ThreadX' byte-pool
-/// operations, with the major difference that here there is no concept of a
-/// thread blocking on memory allocation. This is a concept that is difficult
-/// to implement correctly and efficiently, and several semantic options
-/// exist for how allocation and freeing memory should work in the presence of
-/// blocked threads. The application is always free to implement a blocking
-/// API using these APIs and SSX synchronization primitives.
-///
-/// For convenience this implementation also provides malloc() and calloc()
-/// calls. These APIs depend on the application creating a byte pool and
-/// assigning it to the library variable \a _malloc_byte_pool.
-///
-/// \todo Consider separating the idea of creating a byte pool with a specific
-/// maximum-sized block, from the idea of adding memory to a byte pool. The
-/// idea is to allow pieces of memory required during initialization of the
-/// application to be added back to the pool at run time. We could also
-/// simply add an API to allow memory to be added to a previously created
-/// pool, with the special case that if the block were 'too big' that it would
-/// be split into smaller chunks.
-///
-/// \todo Consider
-/// adding an option to store a pointer to the originating byte pool in the
-/// block header. This would allow deallocation of any block with free()
-/// regardless of which pool it was allocated from, at a cost of 1 pointer per
-/// block. This would simplify some of our validation test cases. We could
-/// also accomplish this by having each pool register ranges of addresses that
-/// it allocates from, but that would require a search every time we freed a
-/// block.
-
-#include "ssx.h"
-#include "byte_pool.h"
-
-// This is an implementation of the TLSF (Two-Level Segregate Fit) algorithm
-// described by M. Masmano, I. Ripoll and A Crespol,
-// http:/rtportal.upv.es/rtmalloc. A couple of their papers and presentations
-// are archived in /lib/doc/tlsf. This is a 'clean-room' implementation of
-// their published ideas based solely on their papers and presentations. No
-// part of their GPL implementation was used to create the byte-pool facility
-// implemented here. The algorithm as implemented here should port without
-// problem to either 32-bit or 64-bit implementations.
-//
-// TLSF has the nice property that it is a constant-time algorithm, both for
-// allocation and freeing allocated blocks. This property is guaranteed by
-// always trading space for speed in the algorithm. This means that we can
-// (and do) run the allocation and freeing in a critical section. With all
-// error checking and statistics, a worst-case byte_bool_alloc() was
-// timed at 318 PowerPC instructions in the PgP OCC (PPC405) Simics
-// simulation. A worst-case byte_pool_free() was timed at 368 PowerPC
-// instructions. These times are expected to equate to ~3us in OCC, a
-// reasonable value for a critical section. [The above times include all
-// error checking].
-//
-// An allocation unit requires two pointers of overhead - a pointer to the
-// previous block and a pointer to the next block (both in terms of linear
-// addresses). The minimum block size also includes the requirement for two
-// extra pointers used to link free blocks into their free lists. The final
-// size of the block (including user data) is simply computed as (next - self)
-// in terms of linear addresses.
-//
-// An allocated block is marked by setting the low-order bit of the 'previous'
-// pointer, which bit is otherwise guaranteed to be 0 due to alignment
-// restrictions. Whenever a block is freed it is immediately merged with the
-// previous and next blocks, if possible. Several places in the block
-// splitting and merging code take advantage of this invariant, and assume
-// that if a block is not already merged with its 'next' partner, then the
-// 'next' partner must be allocated. Sentinel blocks are allocated at either
-// end of the managed area to avoid special checks for the first and last
-// memory blocks during merging.
-//
-// The 'Two-Level' in TLSF refers to the fact that there are multiple free
-// lists arranged in a 2-dimensional array. Each free lists contains blocks
-// that fall into a particular size range. The free list pointers and other
-// data structures described below are carved out of the initial free area
-// when a byte pool is initialized.
-//
-// The first dimension of the free list array is simply the floor(log2(size))
-// of the block. For the second dimension, a tuning parameter selects how many
-// columns each row in the table will contain. The number of columns must be
-// an even power-of-2. Each column represents a fixed power-of-2 size
-// increment of block sizes. Given a block size, it is easy to compute the
-// row and column indices of a free list containing blocks of that size with
-// shifting and masking operation.
-//
-// It is assumed that the C type 'unsigned long' is the same size as a
-// pointer. Therefore the number of rows in the table is less than or equal
-// to the number of bits in an unsigned long. The number of columns is also
-// restricted to being in the range (1, 2, 4, ... number of bits in unsigned
-// long).
-//
-// The above restrictions make it very fast (and constant time) to find a free
-// list that contains a block that will satisfy the allocation request. The
-// byte pool structure maintains a 'row status' word that indicates whether
-// there are any blocks free in any of the free lists of the row. Each row
-// also has an associated 'column status' word that indicates which free lists
-// have blocks free. A row status bit is set if and only if at least one bit
-// in the column status for that row is set.
-//
-// Note that although the 32-bit PowerPC implementation conceptually contains
-// a 32x32 array of free list pointers, only the free list pointers actually
-// required to hold the representable blocks are allocated.
-//
-// The algorithm uses the GCC __builtin_clzl() function to count leading zeros
-// in the status words to find rows/columns that contain free blocks. This
-// generates the 'cntlzw' instruction on 32-bit PowerPC and a similar
-// instruction on X86. So the algorithm is also portable across machines -
-// which simplifies testing.
-//
-// A couple of final facts: When the application requests memory, the block
-// header overhead is added to the request and we look for a free list
-// guaranteed to contain blocks of the requested size. That means that the
-// request size must be rounded up to the next free list size, to avoid having
-// to search a list that might not contain a block of the proper size. This
-// leads to cases where allocation will fail, even though the requested memory
-// is actually available. That's just the price we have to pay for a
-// constant-time guarantee.
-//
-// This memory allocator will never be used in mission-mode for hard-real-time
-// applications, so the statistics are always kept up-to-date. This adds some
-// overhead, but does not effect the constant-time behavior.
-//
-// Given the above description, hopefuly the brief comments with the
-// implementation will make sense.
-
-
-/// The byte pool for use by malloc() and calloc().
-///
-/// The application must define a byte pool and assign it to _malloc_byte_pool
-/// in order for malloc() and calloc() to work.
-
-BytePool *_malloc_byte_pool = 0;
-
-
-// The byte pool memory block header.
-//
-// Each memory block requires 2 pointers of overhead - the pointers to the
-// previous and next (in terms of linear addresses) blocks. The low-order bit
-// of the \a previous pointer is used as the \e allocated flag, and is set
-// when a block is allocated. The size of a block is computed simply as the
-// \a next - \a self. This header layout makes it very simple to merge blocks
-// when they are deallocated.
-
-typedef struct ByteBlock {
-
- // Pointer to the previous (in terms of linear address) block.
- //
- // The low-order bit of the pointer is set to indicate a block that has
- // been allocated.
- struct ByteBlock *previous;
-
- // Pointer to the next (in terms of linear address) block.
- //
- // The size of the block is computed simply as \a next - \a self.
- struct ByteBlock *next;
-
-} ByteBlock;
-
-
-// A free byte-pool memory block
-//
-// Blocks stored in free lists require an additional 2 pointers of
-// overhead. The blocks are doubly-linked in the free lists to make deletion
-// a constant-time operation. Note that the previous pointer is a pointer to
-// a pointer to a ByteBlock - it may be pointing to the free list
-// header. Since all blocks must be freeable, this structure defines the
-// minimum block size.
-
-typedef struct FreeByteBlock {
-
- // The base object
- ByteBlock block;
-
- // Pointer to the next block in the free list
- struct FreeByteBlock *next;
-
- // Pointer to the \a next pointer of the previous element in the free
- // list, or a pointer to the free list header.
- struct FreeByteBlock **previous;
-
-} FreeByteBlock;
-
-
-// All blocks will be aligned to this size, so this size also defines the
-// minimum quantum of memory allocation. The coice of 8 should give
-// good results for both 32-bit and 64-bit implementations.
-//
-// NB : This implmentation assumes that the ByteBlock and FreeByteBLock are
-// aligned to this alignment - if this constant is ever changed from 8 then
-// the ByteBlock and FreeByteBlock may need to be padded to meet the alignment
-// assumptions, and the \a minimum_block_size may need to be adjusted.
-
-#define ALIGNMENT 8
-
-
-// An unsigned long, big-endian bit mask
-
-#define UL_BE_MASK(i) \
- ((unsigned long)1 << (BITS_PER_UNSIGNED_LONG - (i) - 1))
-
-
-// Align a value to the alignment. The direction is either positive or
-// negative to indicate alignment up or down.
-
-static inline unsigned long
-align(unsigned long x, int direction)
-{
- if (x % ALIGNMENT) {
- if (direction > 0) {
- return x + (ALIGNMENT - (x % ALIGNMENT));
- } else {
- return x - (x % ALIGNMENT);
- }
- } else {
- return x;
- }
-}
-
-
-// Compute the floor(log2(x)) of x. This is used to compute the row indices
-// of blocks based on the block size.
-
-static inline int
-floor_log2(unsigned long x)
-{
- return BITS_PER_UNSIGNED_LONG - 1 - __builtin_clzl(x);
-}
-
-
-// In theory the tuning parameters might vary based on the amount of memory
-// being managed, but for now we simply use constants.
-//
-// The minimum block size includes both the size of the header, as well as the
-// requirement that the number of columns be <= the mimumum block size to make
-// the addressing uniform. For example, on PPC405 the minimum block size is 16
-// bytes (4 pointers) -- unless the number of columns is 32, in which case it
-// has to grow to 32 bytes.
-//
-// Note that no matter what, we may allocate free list pointers in the
-// lower-numbered rows that will never be populated due to alignment
-// constraints.
-
-#ifndef BYTE_POOL_TLSF_COLUMNS
-#define BYTE_POOL_TLSF_COLUMNS 8 /* 1,2,4, ... BITS_PER_UNSIGNED_LONG */
-#endif
-
-static void
-compute_tuning(BytePool *pool, size_t size, int columns)
-{
- int log2_min_size;
-
- pool->columns = columns;
- pool->log2_columns = floor_log2(pool->columns);
- pool->column_mask = (1 << pool->log2_columns) - 1;
-
- log2_min_size = MAX(pool->log2_columns, floor_log2(sizeof(FreeByteBlock)));
- pool->minimum_block_size = align(1 << log2_min_size, 1);
-}
-
-
-// Compute the size of a block
-
-static inline size_t
-block_size(ByteBlock *block)
-{
- return (unsigned long)(block->next) - (unsigned long)block;
-}
-
-
-/// Return implementation information for a block
-///
-/// \param memory The memory block to query. This pointer must have been
-/// returned by one of the byte_pool functions or derivitives, or may also be
-/// 0.
-///
-/// \param actual_address : Returned as the address of the block header.
-///
-/// \param actual_size Returned as the size of the complete block, including
-/// the header.
-///
-/// \param useful_size : Returned as the actual amount of space available from
-/// \a memory to the end of the block. The \a useful_size may be useful to
-/// applications that allocate big blocks then carve them up into smaller
-/// structures.
-///
-/// Note that any of \a actual_address, \a actual_size and \a useful_size may
-/// be passed in as 0 if the caller does not require the information.
-
-void
-byte_pool_block_info(void* memory,
- void** actual_address, size_t* actual_size,
- size_t* useful_size)
-{
- ByteBlock* block;
-
- if (memory == 0) {
-
- if (actual_address) *actual_address = 0;
- if (actual_size) *actual_size = 0;
- if (useful_size) *useful_size = 0;
-
- } else {
-
- // This implementation uses the convention that if the \a next pointer
- // of the putative ByteBlock == 1, then this is actually an aligned
- // allocation and the actual ByteBlock is located at the address
- // contained in the \a previous field of the dummy header.
-
- block = (ByteBlock *)(((unsigned long)memory) - sizeof(ByteBlock));
- if ((int)(block->next) == 1) {
- block = block->previous;
- }
-
- if (actual_address) *actual_address = block;
- if (actual_size) *actual_size = block_size(block);
- if (useful_size)
- *useful_size =
- (unsigned long)(block->next) - (unsigned long)memory;
- }
-}
-
-
-// Mark a block as allocated by setting the low-order bit of the \a previous
-// pointer.
-
-static inline ByteBlock *
-allocated(ByteBlock *p)
-{
- return (ByteBlock *)((unsigned long)p | 1ul);
-}
-
-
-static void
-mark_allocated(BytePool *pool, ByteBlock *block)
-{
- size_t bytes = block_size(block);
-
- pool->bytes_allocated += bytes;
- pool->bytes_free -= bytes;
- pool->blocks_allocated += 1;
- pool->blocks_free -= 1;
-
- block->previous = allocated(block->previous);
-}
-
-
-// Mark a block as free by clearing the low-order bit of the \a previous
-// pointer.
-
-static inline ByteBlock *
-deallocated(ByteBlock *p)
-{
- return (ByteBlock *)((unsigned long)p & ~1ul);
-}
-
-
-static void
-mark_free(BytePool *pool, ByteBlock *block)
-{
- size_t bytes = block_size(block);
-
- pool->bytes_allocated -= bytes;
- pool->bytes_free += bytes;
- pool->blocks_allocated -= 1;
- pool->blocks_free += 1;
-
- block->previous = deallocated(block->previous);
-}
-
-
-// Check for a block being free
-
-static inline int
-block_is_free(ByteBlock *block)
-{
- return (((unsigned long)(block->previous)) & 1ul) == 0;
-}
-
-
-// Normalize a 'previous' pointer
-
-static inline ByteBlock *
-normalize_previous(ByteBlock *previous)
-{
- return (ByteBlock *)((unsigned long)previous & ~1ul);
-}
-
-
-// Check for correct linkage. This is such a critical check for application
-// memory corruption that it is always done.
-
-static int
-check_linkage(ByteBlock *block)
-{
- if (normalize_previous(block->next->previous) != block) {
- printk("byte_pool: Forward linkage error\n"
- " block : %p\n"
- " block->next : %p\n"
- " block->next->previous : %p\n",
- block,
- block->next,
- block->next->previous);
- SSX_ERROR(BYTE_POOL_REVERSE_LINKAGE);
- } else if (normalize_previous(block->previous)->next != block) {
- printk("byte_pool: linkage error\n"
- " block->previous : %p\n"
- " block->pevious->next : %p\n"
- " block : %p\n",
- block->previous,
- block->previous->next,
- block);
- SSX_ERROR(BYTE_POOL_FORWARD_LINKAGE);
- }
- return 0;
-}
-
-
-// Mark a free list as empty
-
-static inline void
-mark_empty(BytePool *pool, int row, int column)
-{
- pool->column_status[row] &= ~UL_BE_MASK(column);
- if (pool->column_status[row] == 0) {
- pool->row_status &= ~UL_BE_MASK(row);
- }
-}
-
-
-// Mark a free list as non-empty
-
-static inline void
-mark_non_empty(BytePool *pool, int row, int column)
-{
- pool->column_status[row] |= UL_BE_MASK(column);
- pool->row_status |= UL_BE_MASK(row);
-}
-
-
-// Convert a size into row and column indices
-
-static inline void
-size2rc(BytePool *pool, size_t size, int *row, int *column)
-{
- *row = floor_log2(size);
- *column = (size >> (*row - pool->log2_columns)) & pool->column_mask;
-}
-
-
-// Given a block size, find the free list that contains blocks of that size
-// (or greater, up to the next free list). When called during block freeing,
-// the block size is known to be valid. When called during allocation, the
-// block size may be invalid (too big), in which case 0 is returned.
-
-static FreeByteBlock **
-find_free_list(BytePool *pool, size_t size, int *row, int *column)
-{
- size2rc(pool, size, row, column);
- if (*row > pool->last_row) {
- return 0;
- }
- return &((pool->free[*row])[*column]);
-}
-
-
-// Remove an arbitrary block from its free list due to a merging operation.
-
-static void
-unlink_free_block(BytePool *pool, ByteBlock *block)
-{
- FreeByteBlock **free_list;
- FreeByteBlock *free_block;
- int row, column;
-
- free_list = find_free_list(pool, block_size(block), &row, &column);
-
- if (SSX_ERROR_CHECK_KERNEL) {
- if (free_list == 0) {
- SSX_PANIC(BYTE_POOL_NULL_FREE_LIST);
- }
- }
-
- // Unlink the block from the free list
-
- free_block = (FreeByteBlock *)block;
- *(free_block->previous) = free_block->next;
- if (free_block->next) {
- free_block->next->previous = free_block->previous;
- }
-
- // If the free list is now 0, mark the free list as empty.
-
- if (*free_list == 0) {
- mark_empty(pool, row, column);
- }
-}
-
-
-// Link a block into the head of its free list due to freeing memory
-
-static void
-link_free_block(BytePool *pool, ByteBlock *block)
-{
- FreeByteBlock **free_list;
- FreeByteBlock *free_block;
- int row, column;
-
- free_list = find_free_list(pool, block_size(block), &row, &column);
-
- if (SSX_ERROR_CHECK_KERNEL) {
- if (free_list == 0) {
- SSX_PANIC(BYTE_POOL_NULL_FREE_LIST);
- }
- }
-
- // Link the block into the free list, and mark the free list as
- // non-empty.
-
- free_block = (FreeByteBlock *)block;
-
- free_block->next = *free_list;
- if (*free_list) {
- (*free_list)->previous = &(free_block->next);
- }
- *free_list = free_block;
- free_block->previous = free_list;
-
- mark_non_empty(pool, row, column);
-}
-
-
-// Round up the block size (if required) to the next column. Note that the
-// block_size input here is aligned, and remains aligned even after rounding.
-
-static size_t
-round_up_size(BytePool *pool, size_t block_size)
-{
- size_t residue, column_span, column_mask;
- int row = floor_log2(block_size);
-
- column_span = 1 << (row - pool->log2_columns);
- column_mask = column_span - 1;
- residue = block_size & column_mask;
-
- if (residue == 0) {
- return block_size;
- } else {
- return block_size + (column_span - residue);
- }
-}
-
-
-// The implemenation of freeing a block of memory. When freed, a block is
-// immediately merged with its neighbors if possible, and the final merged
-// block is inserted into the proper free list.
-//
-// The linkage check is done here so that it can also protect internal uses of
-// this API (but only if SSX errors lead to panics, the expected default).
-
-static int
-byte_pool_free_block(BytePool *pool, ByteBlock *block)
-{
- int rc;
- SsxMachineContext ctx;
-
- rc = check_linkage(block);
- if (rc) return rc;
-
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- pool->free_calls++;
-
- mark_free(pool, block);
-
- if (block_is_free(block->next)) {
-
- // Merge next block into current block
-
- unlink_free_block(pool, block->next);
-
- block->next = (ByteBlock *)((unsigned long)(block->next) +
- block_size(block->next));
- block->next->previous = allocated(block);
-
- pool->blocks_free--;
- }
-
- if (block_is_free(block->previous)) {
-
- // Merge current block into previous block
-
- unlink_free_block(pool, block->previous);
-
- block->previous->next =
- (ByteBlock *)((unsigned long)(block->previous->next) +
- block_size(block));
- block = block->previous;
- block->next->previous = allocated(block);
-
- pool->blocks_free--;
- }
-
- // Finally, insert the block into the proper free list.
-
- link_free_block(pool, block);
-
- ssx_critical_section_exit(&ctx);
-
- return 0;
-}
-
-
-/// Free a block of memory back to a byte pool
-///
-/// \param pool A pointer to the BytePool structure that allocated the memory.
-///
-/// \param memory A pointer to memory returned by byte_pool_alloc() or
-/// byte_pool_alloc_aligned() for the pool. This pointer may be NULL (0), in
-/// which case the byte_pool_free() request succeeds immediately.
-///
-/// The part of this API that manipulates the \a pool runs as an
-/// SSX_NONCRITICAL critical section. byte_pool_free() uses a constant-time
-/// algorithm.
-///
-/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
-///
-/// \retval 0 Success
-///
-/// \retval -BYTE_POOL_INVALID_OBJECT The \a pool argument was NULL (0).
-///
-/// \retval -BYTE_POOL_INVALID_ARGUMENT The block is not marked as being
-/// allocated, or does not appear to have been allocated from this byte_pool.
-///
-/// \retval -BYTE_POOL_LINKAGE_ERROR The block being freed is not linked
-/// correctly with the other blocks managed by the pool, most likely
-/// indicating that the memory being freed was not allocated by
-/// byte_pool_alloc(), or that memory corruption has occured.
-
-// This implementation uses the convention that if the \a next pointer of the
-// putative ByteBlock == 1, then this is actually an aligned allocation and
-// the actual ByteBlock is located at the address contained in the \a previous
-// field of the dummy header.
-
-int
-byte_pool_free(BytePool *pool, void *memory)
-{
- ByteBlock *block;
-
- if (memory == 0) {
- return 0;
- }
-
- block = (ByteBlock *)(((unsigned long)memory) - sizeof(ByteBlock));
- if ((int)(block->next) == 1) {
- if (0) {
- printk("byte_pool_free(%p, %p) [%p] : Aligned\n",
- pool, memory, block);
- }
- block = block->previous;
- }
-
- if (0) {
- printk("byte_pool_free(%p, %p) [%p] : %d %d %d\n",
- pool, memory, block,
- block_is_free(block),
- block < pool->first_block,
- block > pool->last_block);
- }
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(pool == 0, BYTE_POOL_INVALID_OBJECT);
- SSX_ERROR_IF(block_is_free(block) ||
- (block < pool->first_block) ||
- (block > pool->last_block),
- BYTE_POOL_INVALID_ARGUMENT);
- }
-
- return byte_pool_free_block(pool, block);
-}
-
-
-/// Create a BytePool with explicit specification of tuning parameters
-///
-/// This routine is the real body of byte_pool_create(), however this
-/// underlying interface is provided for testing and experimentation and allows
-/// the specification of non-default tuning parameters.
-///
-/// There is actually only one tuning parameter for TLSF - the number of
-/// columns. The number of columns must be an even power of two no larger
-/// than the number of bits in an unsigned long.
-///
-/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
-///
-/// \retval -BYTE_POOL_INVALID_OBJECT The \a pool pointer was NULL (0).
-///
-/// \retval -BYTE_POOL_INVALID_ARGUMENT Either the \a memory pointer was NULL
-/// (0), the amount of memory was insufficient for the management overhead, or
-/// the parameterization was invalid.
-
-int
-byte_pool_create_tuned(BytePool *pool, void *memory, size_t size,
- int columns)
-{
- size_t overhead, free_list_overhead;
- unsigned long memory_ul, aligned_memory;
- int i;
- FreeByteBlock **free;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(pool == 0, BYTE_POOL_INVALID_OBJECT);
- SSX_ERROR_IF((memory == 0) ||
- (columns < 1) ||
- ((columns & (columns - 1)) != 0) ||
- (floor_log2(columns) > floor_log2(BITS_PER_UNSIGNED_LONG)),
- BYTE_POOL_INVALID_ARGUMENT);
- }
-
- // Compute tuning parameters
-
- compute_tuning(pool, size, columns);
-
- // Clear free list vector pointers and column status
-
- for (i = 0; i < BITS_PER_UNSIGNED_LONG; i++) {
- pool->free[i] = 0;
- pool->column_status[i] = 0;
- }
-
- // Determine the first and last allocated rows.
-
- pool->first_row = floor_log2(pool->minimum_block_size);
- pool->last_row = floor_log2(size);
-
- // The dynamic overhead consists of aligment overhead, 2 sentinel nodes,
- // the vectors of pointers to free lists, plus 2 alignments. There must
- // also be enough room for at least 1 block to allocate.
-
- memory_ul = (unsigned long)memory;
- aligned_memory = align(memory_ul, 1);
-
- free_list_overhead =
- (((pool->last_row - pool->first_row + 1) * pool->columns) *
- sizeof(FreeByteBlock *));
-
- overhead =
- (aligned_memory - memory_ul) +
- (2 * sizeof(ByteBlock)) +
- free_list_overhead +
- (2 * ALIGNMENT) +
- pool->minimum_block_size;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(overhead >= size, BYTE_POOL_INVALID_ARGUMENT);
- }
-
- // Allocate the overhead items. The free list vectors and column status
- // arrays are carved out and zeroed. For good measure we re-align after
- // each of these operations. The sentinel blocks are carved off of either
- // end of the remaining free space and marked allocated. The remaining
- // initial "big block" is also initialized (as if it were allocated).
-
- size = size - (aligned_memory - memory_ul);
- size = align(size, -1);
-
- pool->row_status = 0;
-
- free = (FreeByteBlock **)aligned_memory;
- memset((void *)free, 0, free_list_overhead);
-
- aligned_memory += free_list_overhead;
- size -= free_list_overhead;
- aligned_memory = align(aligned_memory, 1);
- size = align(size, -1);
-
- for (i = pool->first_row; i <= pool->last_row; i++) {
- pool->free[i] = free;
- free += pool->columns;
- }
-
- pool->first_block = (ByteBlock *)aligned_memory;
- aligned_memory += sizeof(ByteBlock);
- size -= sizeof(ByteBlock);
-
- pool->big_block = (ByteBlock *)aligned_memory;
-
- pool->last_block =
- (ByteBlock *)(aligned_memory + size - sizeof(ByteBlock));
- size -= sizeof(ByteBlock);
-
- pool->first_block->next = pool->big_block;
- pool->first_block->previous = 0;
- mark_allocated(pool, pool->first_block);
-
- pool->last_block->next = 0;
- pool->last_block->previous = pool->big_block;
- mark_allocated(pool, pool->last_block);
-
- pool->big_block->previous = pool->first_block;
- pool->big_block->next = pool->last_block;
-
- // Initialize statistics
-
- pool->bytes_allocated = 0;
- pool->bytes_free = block_size(pool->big_block);
- pool->initial_allocation = pool->bytes_free;
- pool->blocks_allocated = 0;
- pool->blocks_free = 1;
- pool->alloc_calls = 0;
- pool->free_calls = 0;
-
- // Free the big block and we're ready to go.
-
- mark_allocated(pool, pool->big_block);
- byte_pool_free_block(pool, pool->big_block);
-
- return 0;
-}
-
-
-/// Create a BytePool
-///
-/// \param pool A pointer to an uninitialized BytePool structure
-///
-/// \param memory A pointer to the memory to be managed by the BytePool
-///
-/// \param size The size of the managed area in bytes
-///
-/// byte_pool_create() sets up the \a memory area to be used as a memory pool
-/// for malloc()-style allocation using byte_pool_alloc() and
-/// byte_pool_free(). Note that the actual memory area available for
-/// allocation will be smaller than \a size due to alignment, and reservation
-/// of a portion of the area for management overhead.
-///
-/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
-///
-/// \retval -BYTE_POOL_INVALID_OBJECT The \a pool pointer was NULL (0).
-///
-/// \retval -BYTE_POOL_INVALID_ARGUMENT Either the \a memory pointer was NULL
-/// (0), the amount of memory was insufficient for the management overhead, or
-/// the parameterization was invalid.
-
-int
-byte_pool_create(BytePool *pool, void *memory, size_t size)
-{
- return byte_pool_create_tuned(pool, memory, size, BYTE_POOL_TLSF_COLUMNS);
-}
-
-
-/// Allocate memory from a byte pool
-///
-/// \param pool A pointer to an initialized BytePool
-///
-/// \param memory An address to recieve a pointer to the allocated memory.
-/// This address will be set to NULL (0) if the allocation request can not be
-/// satisfied (or the \a size is 0).
-///
-/// \param size The number of bytes to allocate.
-///
-/// The part of this API that manipulates the \a pool runs as an
-/// SSX_NONCRITICAL critical section. byte_pool_alloc() uses a constant-time
-/// algorithm.
-///
-/// Return values other than 0 are not necessarily errors; see \ref
-/// ssx_errors.
-///
-/// The following return codes are not considered errors:
-///
-/// \retval 0 Success
-///
-/// \retval -BYTE_POOL_NO_MEMORY The allocation request could not be
-/// satisfied. The memory pointer will also be NULL (0) in this case.
-///
-/// The following return codes are considered errors:
-///
-/// \retval -BYTE_POOL_INVALID_OBJECT The \a pool argument was NULL (0).
-///
-/// \retval -BYTE_POOL_INVALID_ARGUMENT The \a memory argument is NULL (0).
-
-int
-byte_pool_alloc(BytePool *pool, void **memory, size_t size)
-{
- SsxMachineContext ctx;
- size_t request_size, actual_size;
- int found, row, column;
- unsigned long row_status, column_status;
- FreeByteBlock **free_list;
- FreeByteBlock *free_block;
- ByteBlock *block;
- ByteBlock *residue_block;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(pool == 0, BYTE_POOL_INVALID_OBJECT);
- SSX_ERROR_IF(memory == 0, BYTE_POOL_INVALID_ARGUMENT);
- }
-
- // Quickly dispense with NULL requests
-
- if (size == 0) {
- *memory = 0;
- return 0;
- }
-
- // Compute the requested block size (which includes the header). If the
- // size went down we overflowed due to a huge request (which can't be
- // filled). Otherwise if the request is small it is boosted up to the
- // (aligned) minimum size. To guarantee fast search, the requested size
- // must then be rounded up to a size that is represented in the 2-D array
- // of free list pointers.
-
- request_size = align(size + sizeof(ByteBlock), 1);
- if (request_size < size) {
- *memory = 0;
- return -BYTE_POOL_NO_MEMORY;
- }
-
- if (request_size < pool->minimum_block_size) {
- request_size = pool->minimum_block_size;
- }
-
- request_size = round_up_size(pool, request_size);
-
- // Up to this point, all accesses of the memory pool object have been to
- // read only constants. Now we get serious.
-
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- pool->alloc_calls++;
-
- // See if a block of the correct or larger size exists in the row. The
- // search is first via a single bit in the row_status. If that hits then
- // we check for columns >= the target column.
-
- found = 0;
- size2rc(pool, request_size, &row, &column);
-
- if (pool->row_status & UL_BE_MASK(row)) {
-
- column_status = pool->column_status[row] &
- ((UL_BE_MASK(column) << 1) - 1);
-
- if (column_status != 0) {
- column = __builtin_clzl(column_status);
- found = 1;
- }
- }
-
- // If the block was not found in the 'optimum' row, look in all rows of
- // larger size and take the first block that fits.
-
- if (!found) {
-
- row_status = pool->row_status & (UL_BE_MASK(row) - 1);
-
- if (row_status != 0) {
- row = __builtin_clzl(row_status);
- column = __builtin_clzl(pool->column_status[row]);
- found = 1;
- }
- }
-
- // Another out of memory case.
-
- if (!found) {
- ssx_critical_section_exit(&ctx);
- *memory = 0;
- return -BYTE_POOL_NO_MEMORY;
- }
-
- // Now we can get the pointer to the free list and take the block.
-
- free_list = &((pool->free[row])[column]);
-
- if (SSX_ERROR_CHECK_KERNEL) {
- if ((free_list == 0) || (*free_list == 0)) {
- SSX_PANIC(BYTE_POOL_INVALID_FREE_LIST);
- }
- }
-
- free_block = *free_list;
- *free_list = free_block->next;
- if (free_block->next) {
- free_block->next->previous = free_list;
- } else {
- mark_empty(pool, row, column);
- }
-
- // Mark the block as allocated
-
- block = (ByteBlock *)free_block;
- mark_allocated(pool, block);
-
- // If there is enough residue, split the excess memory off of the end of
- // the block. This is a kind of dummy transaction for our statistical
- // purposes.
-
- actual_size = block_size(block);
- if ((actual_size - request_size) >= pool->minimum_block_size) {
-
- residue_block = (ByteBlock *)((unsigned long)block + request_size);
-
- residue_block->next = block->next;
- residue_block->previous = block;
- residue_block->previous->next = residue_block;
- residue_block->next->previous = allocated(residue_block);
-
- pool->blocks_allocated++;
- byte_pool_free_block(pool, residue_block);
- pool->free_calls--;
- }
-
- // Set the memory pointer to the area to be used by the application and
- // return.
-
- *memory = (void *)((unsigned long)block + sizeof(ByteBlock));
-
- ssx_critical_section_exit(&ctx);
-
- if (0) {
- ByteBlock* block =
- (ByteBlock*)((unsigned long)*memory - sizeof(ByteBlock));
-
- printk("byte_pool_alloc(%p, -> %p, %zu)\n"
- " request_size = %u, Previous = %p, Next = %p\n",
- pool, *memory, size,
- request_size, block->previous, block->next);
- }
-
- return 0;
-}
-
-
-/// Allocate memory from a byte pool and clear
-///
-/// byte_pool_calloc() allocates memory using byte_pool_alloc() then clears
-/// the memory area using memset(). The arguments conform to the POSIX
-/// standard for calloc(). See byte_pool_alloc() for return codes and usage
-/// notes.
-
-int
-byte_pool_calloc(BytePool *pool, void **memory, size_t nmemb, size_t size)
-{
- int rc;
-
- rc = byte_pool_alloc(pool, memory, nmemb * size);
- if (rc || (*memory == 0)) {
- return rc;
- }
-
- memset(*memory, 0, nmemb * size);
-
- return 0;
-}
-
-
-/// Allocate an aligned memory area
-///
-/// \param pool A pointer to an initialized BytePool
-///
-/// \param memory An address to recieve a pointer to the allocated memory.
-/// This address will be set to NULL (0) if the allocation request can not be
-/// satisfied (or the \a size is 0).
-///
-/// \param size The size of the memory area required (in bytes). This can be
-/// any size - it \e does \e not have to be a multiple of the aligned size (as
-/// is required by other common aligned memory allocators).
-///
-/// \param alignment The alignment constraint, specified as the base 2
-/// logarithm of the alignment. For example, to align on a 128-byte boundary
-/// the \a alignment would be specified as 7.
-///
-/// byte_pool_alloc_aligned() is a convenience interface for allocating memory
-/// with a guaranteed alignment. The BytePool APIs do not normally do aligned
-/// allocation. byte_pool_alloc_aligned() first uses byte_pool_alloc() to
-/// allocate a block of memory large enough to satisfy the request and
-/// guarantee that a subset of the memory allocation will satisfy the
-/// alignment constraint plus the overhead of a dummy block header. Note that
-/// it is space-inefficient to allocate many small aligned areas. If possble
-/// it would be better to allocate a single aligned area and then have the
-/// application partition the memory as required.
-///
-/// Memory areas allocated by byte_pool_alloc_aligned() can be freed with
-/// byte_pool_free(), just like any other dynamic memory allocation.
-///
-/// The part of this API that manipulates the \a pool runs as an
-/// SSX_NONCRITICAL critical section. The underlying call of byte_pool_alloc()
-/// uses a constant-time algorithm.
-///
-/// Return values other than 0 are not necessarily errors; see \ref
-/// ssx_errors.
-///
-/// The following return codes are not considered errors:
-///
-/// \retval 0 Success
-///
-/// \retval -BYTE_POOL_NO_MEMORY The allocation request could not be
-/// satisfied. The memory pointer will also be NULL (0) in this case.
-///
-/// The following return codes are considered errors:
-///
-/// \retval -BYTE_POOL_INVALID_OBJECT The \a pool argument was NULL (0).
-///
-/// \retval -BYTE_POOL_INVALID_ARGUMENT The \a memory argument is NULL (0), or
-/// the \a alignment argument is invalid.
-
-// The allocation must be big enough for the size requested + the alignment
-// amount (to guarantee alignment) + room for a dummy ByteBlock. The dummy
-// ByteBlock is marked by setting the \a next pointer to 1 to indicate that
-// this is an aligned allocation. In this case the \a previous pointer of the
-// dummy ByteBlock points to the ByteBlock of the original allocation.
-
-int
-byte_pool_alloc_aligned(BytePool *pool, void **memory, size_t size,
- int alignment)
-{
- int rc;
- unsigned long pow2_alignment, mask, aligned;
- void *unaligned_memory;
- ByteBlock *dummy_block, *unaligned_block;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF((alignment < 1) || (alignment >= BITS_PER_UNSIGNED_LONG),
- BYTE_POOL_INVALID_ARGUMENT);
- }
-
- pow2_alignment = (unsigned long)1 << (unsigned long)alignment;
- mask = pow2_alignment - 1;
-
- rc = byte_pool_alloc(pool, &unaligned_memory,
- size + pow2_alignment + sizeof(ByteBlock));
-
- if (rc || (unaligned_memory == 0)) {
- *memory = 0;
- return rc;
- }
- unaligned_block = (ByteBlock *)(((unsigned long)unaligned_memory) -
- sizeof(ByteBlock));
-
- aligned = (unsigned long)unaligned_memory + sizeof(ByteBlock);
- if (aligned & mask) {
- aligned += (pow2_alignment - (aligned & mask));
- }
- *memory = (void *)aligned;
-
- dummy_block = (ByteBlock *)(aligned - sizeof(ByteBlock));
- dummy_block->previous = unaligned_block;
- dummy_block->next = (ByteBlock*)1;
-
- if (0) {
- printk("byte_pool_alloc_aligned(%p, -> %p, %zu, %d)\n",
- pool, *memory, size, alignment);
- }
-
- return 0;
-}
-
-
-/// Allocate aligned memory from a byte pool and clear
-///
-/// byte_pool_calloc_alligned() allocates memory using
-/// byte_pool_alloc_aligned() then clears the memory area using memset(). The
-/// arguments conform to the POSIX standard for calloc(). See
-/// byte_pool_alloc_aligned() for return codes and usage notes. In particular
-/// note that this memory must be freed with byte_pool_free_aligned().
-
-int
-byte_pool_calloc_aligned(BytePool *pool, void **memory,
- size_t nmemb, size_t size, int alignment)
-{
- int rc;
-
- rc = byte_pool_alloc_aligned(pool, memory, nmemb * size, alignment);
- if (rc || (*memory == 0)) return rc;
-
- memset(*memory, 0, nmemb * size);
-
- return 0;
-}
-
-
-/// malloc() allocates \a size bytes and returns a pointer to the allocated
-/// memory. The memory is not cleared. The value returned is a pointer to the
-/// allocated memory, which is suitably aligned for any kind of variable, or
-/// NULL if the requested \a size is 0 or the request fails.
-///
-/// NB: The aplication must create and assign a BytePool object to the
-/// library variable _malloc_byte_pool in order for malloc() to work.
-
-void *
-malloc(size_t size)
-{
- void *memory;
-
- if (byte_pool_alloc(_malloc_byte_pool, &memory, size)) {
- memory = 0;
- }
- return memory;
-}
-
-
-/// calloc() allocates memory for an array of \a nmemb elements of \a size
-/// bytes each and returns a pointer to the allocated memory. The memory is
-/// set to zero. The value returned is a pointer to the allocated and cleared
-/// memory, which is suitably aligned for any kind of variable, or NULL if the
-/// requested \a size is 0 or the request fails.
-///
-/// NB: The aplication must create and assign a BytePool object to the
-/// library variable _malloc_byte_pool in order for calloc() to work.
-
-void *
-calloc(size_t nmemb, size_t size)
-{
- void *memory;
-
- if (byte_pool_calloc(_malloc_byte_pool, &memory, nmemb, size)) {
- return 0;
- }
- return memory;
-}
-
-
-/// free() frees the memory space pointed to by \a ptr, which must have been
-/// returned by a previous call to malloc(), posix_memalign, calloc() or
-/// realloc(). Otherwise, or if free(ptr) has already been called before,
-/// undefined behavior occurs. If \a ptr is NULL, no operation is performed.
-///
-/// NB: The aplication must create and assign a BytePool object to the
-/// library variable _malloc_byte_pool in order for free() to work.
-
-void
-free(void *ptr)
-{
- byte_pool_free(_malloc_byte_pool, ptr);
-}
-
-
-/// realloc() changes the size of the memory block pointed to by \a ptr to \a
-/// size bytes. The contents will be unchanged to the minimum of the old and
-/// new sizes; newly allocated memory will be uninitialized. If \a ptr is
-/// NULL, the call is equivalent to malloc(size); if \a size is equal to zero,
-/// the call is equivalent to free(ptr). Unless \a ptr is NULL, it must have
-/// been returned by an earlier call to malloc(), calloc() or realloc(). If
-/// the area pointed to was moved, a free(ptr) is done.
-///
-/// realloc() returns a pointer to the newly allocated memory, which is
-/// suitably aligned for any kind of variable and may be different from \a
-/// ptr, or NULL if the request fails. If \a size was equal to 0, either NULL
-/// or a pointer suitable to be passed to free() is returned. If realloc()
-/// fails the original block is left untouched; it is not freed or moved.
-
-void*
-realloc(void *ptr, size_t size)
-{
- void *memory;
- size_t useful_size;
-
- // Handle simple case
-
- if (ptr == 0) {
-
- memory = malloc(size);
-
- } else if (size == 0) {
-
- free(ptr);
- memory = 0;
-
- } else {
-
- // Find out the useful size of the block. If we need more than this we
- // need to allocate a new block and memcpy() the old data to the new
- // block and free the old block. If we need less then this we also
- // need to allocate a new block and move the head of the current
- // data. If the new size is the same as the current size we do nothing.
-
- byte_pool_block_info(ptr, 0, 0, &useful_size);
-
- if (size == useful_size) {
-
- memory = ptr;
-
- } else {
-
- memory = malloc(size);
- if (memory != 0) {
- memcpy(memory, ptr, (size > useful_size) ? useful_size : size);
- free(ptr);
- }
- }
- }
- return memory;
-}
-
-
-/// The posix_memalign() function allocates \a size bytes aligned on a
-/// boundary specified by \a alignment, and returns a pointer to the allocated
-/// memory in \a memptr. The value of \a alignment shall be a multiple of
-/// sizeof(void*), that is also a power of two. Upon successful completion,
-/// the value pointed to by \a memptr will be a multiple of alignment.
-///
-/// Note that memory allocated with posix_memalign() can be freed with
-/// free().
-///
-/// In the event of errors, the contents of \a memptr will be returned as 0.
-///
-/// The following return codes are mandated by POSIX, and are always returned
-/// in the event of the specified condition.
-///
-/// \retval 0 Success
-///
-/// \retval -EINVAL The value of the \a alignment parameter is not a power of
-/// two multiple of sizeof(void*).
-///
-/// \retval -ENOMEM There is insufficient memory available with the requested
-/// alignment.
-///
-/// The following return codes are implementation-specific and may be
-/// configured to cause a kernel panic.
-///
-/// \retval -BYTE_POOL_INVALID_OBJECT The \a _malloc_byte_pool is NULL (0).
-///
-/// \retval -BYTE_POOL_INVALID_ARGUMENT The \a memptr argument is NULL (0).
-
-int
-posix_memalign(void** memptr, size_t alignment, size_t size)
-{
- int rc;
-
- if (((alignment & (alignment - 1)) != 0) ||
- (alignment < sizeof(void*))) {
- rc = -EINVAL;
- } else {
- rc = byte_pool_alloc_aligned(_malloc_byte_pool, memptr, size,
- floor_log2(alignment));
- if (!rc && (*memptr == 0)) {
- rc = -ENOMEM;
- }
- }
- if (rc && memptr) {
- *memptr = 0;
- }
- return rc;
-}
-
-
-/// Print a dump of a byte pool, including the header and allocation report
-///
-/// \param stream The stream to receive the dump
-///
-/// \param pool The BytePool object to dump
-///
-/// \bug This routine is not thread safe.
-
-void
-byte_pool_report(FILE* stream, BytePool* pool)
-{
- ByteBlock* block;
- uint8_t* p8;
- uint32_t* p32;
- int i;
-
- fprintf(stream, ">>> Byte Pool Report for Pool %p <<<\n", pool);
-
- fprintf(stream, ">>> BytePool Object Dump <<<\n");
-
-#define DUMPIT(x, fmt) \
- fprintf(stream, "%20s : " #fmt "\n", #x, pool->x)
-
- DUMPIT(first_row, %d);
- DUMPIT(last_row, %d);
- DUMPIT(columns, %d);
- DUMPIT(log2_columns, %d);
- DUMPIT(column_mask, 0x%08x);
- DUMPIT(minimum_block_size, %d);
- DUMPIT(free, %p);
- DUMPIT(column_status, %p);
- DUMPIT(row_status, %lu);
- DUMPIT(first_block, %p);
- DUMPIT(big_block, %p);
- DUMPIT(last_block, %p);
- DUMPIT(initial_allocation, %d);
- DUMPIT(bytes_allocated, %d);
- DUMPIT(bytes_free, %d);
- DUMPIT(blocks_allocated, %d);
- DUMPIT(blocks_free, %d);
- DUMPIT(alloc_calls, %d);
- DUMPIT(free_calls, %d);
-
- fprintf(stream, ">>> Byte Pool Allocation Report <<<\n");
- fprintf(stream,
- ">>> status : address : size : binary[0:7] : ASCII[0:7] <<<\n");
-
- for (block = pool->first_block->next;
- block != pool->last_block;
- block = block->next) {
-
- fprintf(stream, " %c : %p : %6zu : ",
- (block_is_free(block) ? 'F' : 'A'),
- block, block_size(block));
-
- p8 = (uint8_t*)((unsigned long)block + sizeof(ByteBlock));
- p32 = (uint32_t*)p8;
-
- fprintf(stream, "0x%08x 0x%08x : ", p32[0], p32[1]);
- for (i = 0; i < 8; i++) {
- if (isprint(p8[i])) {
- fputc(p8[i], stream);
- } else {
- fputc('.', stream);
- }
- }
- fputc('\n', stream);
- }
-
- fprintf(stream, ">>> End Report <<<\n");
-}
diff --git a/src/lib/ppc405lib/byte_pool.h b/src/lib/ppc405lib/byte_pool.h
deleted file mode 100644
index 8766745..0000000
--- a/src/lib/ppc405lib/byte_pool.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/byte_pool.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __BYTE_POOL_H__
-#define __BYTE_POOL_H__
-
-// $Id$
-
-#ifndef __ASSEMBLER__
-
-#include "ssx_io.h"
-
-struct ByteBlock;
-struct FreeByteBlock;
-
-// A handy constant
-
-#define BITS_PER_UNSIGNED_LONG (8 * sizeof(unsigned long))
-
-
-/// A control structure for a byte pool. The application will never modify the
-/// structure fields directly, but some applications may be interested in
-/// reading the statistics.
-
-typedef struct {
-
- // The index of the first allocated row of free list pointers
- int first_row;
-
- // The index of the last allocated row of free list pointers
- int last_row;
-
- // The number of columns in each row of free list pointers
- int columns;
-
- // The log2 of the number of columns in each row of free list pointers
- int log2_columns;
-
- // The shifted block size is ANDed with this mask to extract the column
- // number.
- size_t column_mask;
-
- // The minimum block size.
- int minimum_block_size;
-
- // The vectors of free list pointers
- struct FreeByteBlock **free[BITS_PER_UNSIGNED_LONG];
-
- // The array of column status bit masks
- unsigned long column_status[BITS_PER_UNSIGNED_LONG];
-
- // The row status bit mask
- unsigned long row_status;
-
- // A sentinel node - the first allocated block. Kept for error checking
- // purposes.
- struct ByteBlock *first_block;
-
- // The initial memory allocation. Kept here only for debugging purposes.
- struct ByteBlock *big_block;
-
- // A sentinel node - the last allocated block. Kept here for error
- // checking purposes.
- struct ByteBlock *last_block;
-
- // The initial allocation. Kept here for debugging and statistics.
- size_t initial_allocation;
-
- // The total number of bytes currently allocated (excludes overhead)
- size_t bytes_allocated;
-
- // The total number of bytes currently free in the pool
- size_t bytes_free;
-
- // The total number of blocks allocated from the pool
- size_t blocks_allocated;
-
- // The total number of blocks free in the pool
- size_t blocks_free;
-
- // The number of calls to allocate memory
- size_t alloc_calls;
-
- // The number of calls to free memory
- size_t free_calls;
-
-} BytePool;
-
-extern BytePool *_malloc_byte_pool;
-
-int
-byte_pool_create(BytePool *pool, void *memory, size_t size);
-
-int
-byte_pool_create_tuned(BytePool *pool, void *memory, size_t size,
- int columns);
-
-int
-byte_pool_alloc(BytePool *pool, void **memory, size_t size);
-
-int
-byte_pool_calloc(BytePool *pool, void **memory, size_t nmemb, size_t size);
-
-int
-byte_pool_free(BytePool *pool, void *memory);
-
-void
-byte_pool_block_info(void* memory,
- void** actual_address, size_t* actual_size,
- size_t* useful_size);
-
-int
-byte_pool_alloc_aligned(BytePool *pool, void **memory, size_t size,
- int alignment);
-
-void *
-malloc(size_t size);
-
-void *
-calloc(size_t nmemb, size_t size);
-
-void
-free(void *ptr);
-
-int
-posix_memalign(void** memptr, size_t alignment, size_t size);
-
-void
-byte_pool_report(FILE* stream, BytePool* pool);
-
-#endif /* __ASSEMBLER__ */
-
-
-// Error/panic codes
-
-#define BYTE_POOL_INVALID_OBJECT 0x00b98e01
-#define BYTE_POOL_INVALID_ARGUMENT 0x00b98e02
-#define BYTE_POOL_REVERSE_LINKAGE 0x00b98e03
-#define BYTE_POOL_FORWARD_LINKAGE 0x00b98e04
-#define BYTE_POOL_NO_MEMORY 0x00b98e05
-
-#define BYTE_POOL_NULL_FREE_LIST 0x00b98e10
-#define BYTE_POOL_INVALID_FREE_LIST 0x00b98e11
-
-#endif /* __BYTE_POOL_H__ */
diff --git a/src/lib/ppc405lib/initcall.c b/src/lib/ppc405lib/initcall.c
deleted file mode 100644
index 664fb6e..0000000
--- a/src/lib/ppc405lib/initcall.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/initcall.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 */
-// $Id$
-
-/// \file initcall.c
-/// \brief An anonymous early initialization facility for SSX applications
-
-#include "ssx.h"
-#include "initcall.h"
-
-// These linker symbols must be defined if the initcall facility is used. The
-// special ELF section .data.initcall contains an array of Initcall structures
-// for all declared initcalls.
-
-extern InitCall _INITCALL_SECTION_BASE[];
-extern SsxLinkerSymbol _INITCALL_SECTION_SIZE;
-
-void
-_initcall_run(InitCall* initcall)
-{
- void (*f)(void* arg);
-
- f = initcall->initcall;
- if (f) {
- initcall->initcall = 0;
- f(initcall->arg);
- }
-}
-
-
-void
-initcall_run_all()
-{
- InitCall* initcall;
- size_t nCalls;
-
- initcall = _INITCALL_SECTION_BASE;
- nCalls = (size_t)(&_INITCALL_SECTION_SIZE) / sizeof(InitCall);
-
- for (; nCalls--; initcall++) {
- _initcall_run(initcall);
- }
-}
-
-
-
-
-
diff --git a/src/lib/ppc405lib/initcall.h b/src/lib/ppc405lib/initcall.h
deleted file mode 100644
index af8b53c..0000000
--- a/src/lib/ppc405lib/initcall.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/initcall.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __INITCALL_H__
-#define __INITCALL_H__
-
-// $Id$
-
-/// \file initcall.h
-/// \brief An early initialization facility for SSX applications
-///
-/// The C language standard does not define a generic load-time initialization
-/// method, unlike C++ which supports load-time initialization of static
-/// objects. The \e initcall facility implements a simple method for SSX
-/// applications to declare early initialization functions that are executed
-/// prior to or during the invocation of main().
-///
-/// An \e initcall can be any function with the prototype
-///
-/// \code
-///
-/// void (*initcall)(void* arg)
-///
-/// \endcode
-///
-/// Initcalls are declared with the INITCALL() macro. An initcall is
-/// represented by a named structure, and typically an initcall will be
-/// declared static to the compilation unit that implements the initcall:
-///
-/// \code
-///
-/// void (*init_fn)(void* arg);
-/// void* init_data = ...;
-/// static INITCALL(init_var, init_fn, init_data);
-///
-/// \endcode
-///
-/// All INITCALLS loaded in the executable image are executed by the
-/// initcall_run_all() API. An SSX application will typically call
-/// initcall_run_all() in the function declared as the \a ssx_main_hook, or in
-/// the main() routine itself.
-///
-/// Initcalls are run in an arbitrary order. However if initcall \a b is
-/// dependent on initcall \a a, then initcall \a b can execute
-/// initcall_run(&a) to guarantee that initcall \a a runs before \a b.
-/// Regardless, every initcall is run exectly once by the initcall facility,
-/// even if initcall_run() or initcall_run_all() were to be used multiple
-/// times.
-///
-/// Behind the scenes, initcalls are implemented by a special ELF section,
-/// .data.initcall, that records all declared initcalls. The
-/// initcall_run_all() API simply runs all initcalls declared in
-/// .data.initcall.
-
-/// The structure representing an initcall
-
-typedef struct {
-
- /// The initialization function
- ///
- /// Prior to running the initcall, this field is zeroed. This guarantess
- /// that each initcall is run at most 1 time.
- void (*initcall)(void* arg);
-
- /// The argument to the initialization function
- void* arg;
-
-} InitCall;
-
-
-/// Declare an initcall
-///
-/// This macro generates C code and global data so must be placed at file
-/// scope in a C file, not in a header file or inside a C function
-/// body. Unless the initcall needs to be referenced by another initcall (to
-/// guarantee ordering), this declaration will normally be prepended with
-/// 'static'.
-#define INITCALL(_var, _initcall, _arg) \
- InitCall _var __attribute__ ((used, section (".data.initcall"))) = \
- {.initcall = _initcall, .arg = _arg};
-
-
-/// Run the initcall represented by an InitCall structure, assuming it has not
-/// already run.
-///
-/// \param[in] i_initcall The address of the initcall structure to run
-void
-initcall_run(InitCall* i_initcall);
-
-
-/// Run all initcalls
-void
-initcall_run_all();
-
-#endif // __INITCALL_H__
diff --git a/src/lib/ppc405lib/lfsr.c b/src/lib/ppc405lib/lfsr.c
deleted file mode 100644
index 21ddb93..0000000
--- a/src/lib/ppc405lib/lfsr.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/lfsr.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 */
-// $Id$
-
-/// \file lfsr.c
-/// \brief
-
-#include <stdint.h>
-#include "lfsr.h"
-
-// Parity for 4-bit numbers
-static uint8_t S_parity4[16] = {
- 0, 1, 1, 0,
- 1, 0, 0, 1,
- 1, 0, 0, 1,
- 0, 1, 1, 0
-};
-
-// 64, 63, 61, 60 LFSR. The routine is coded with the uint8_t casting to help
-// the compiler generate more efficient code.
-
-void
-_lfsr64(uint64_t* io_seed)
-{
- *io_seed = (*io_seed << 1) |
- S_parity4[(uint8_t)((*io_seed >> 59) & 0x3) |
- (uint8_t)((*io_seed >> 60) & 0xc)];
-}
diff --git a/src/lib/ppc405lib/lfsr.h b/src/lib/ppc405lib/lfsr.h
deleted file mode 100644
index 951ec45..0000000
--- a/src/lib/ppc405lib/lfsr.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/lfsr.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __LFSR_H__
-#define __LFSR_H__
-
-/// \file lfsr.h
-/// \brief Linear-Feedback Shift Register Implementations
-///
-/// The 32- and 64-bit pseudo-random number generators in this library are of
-/// the linear-conguential type. These maximal-length LFSR pseudo-random
-/// sequence generators are also provided.
-
-/// 64-bit LFSR
-///
-/// \param[in,out] io_seed The input seed is converted in one step to the
-/// output seed.
-///
-/// This 64-bit LFSR uses taps 64, 63, 61, and 60. In big-endian numbering
-/// these are bits 0, 1, 3 and 4. This LFSR is also implemented for the PORE
-/// engines in the file pore_rand.pS.
-void
-_lfsr64(uint64_t* io_seed);
-
-#endif // __LFSR_H__
diff --git a/src/lib/ppc405lib/libppc405files.mk b/src/lib/ppc405lib/libppc405files.mk
index 59aa7a0..b042616 100644
--- a/src/lib/ppc405lib/libppc405files.mk
+++ b/src/lib/ppc405lib/libppc405files.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER OnChipController Project
#
-# Contributors Listed Below - COPYRIGHT 2015
+# Contributors Listed Below - COPYRIGHT 2015,2016
# [+] International Business Machines Corp.
#
#
@@ -43,19 +43,12 @@
C-SOURCES = \
assert.c \
- byte_pool.c \
ctype.c \
ctype_table.c \
fgetc.c \
- initcall.c \
- lfsr.c \
- mutex.c \
- periodic_semaphore.c \
polling.c \
printf.c \
- progress.c \
puts.c \
- rtx_stdio.c \
simics_stdio.c \
sprintf.c \
ssx_dump.c \
@@ -66,7 +59,6 @@ C-SOURCES = \
string.c \
string_stream.c \
strtox.c \
- sxlock.c \
time.c
S-SOURCES =
diff --git a/src/lib/ppc405lib/mutex.c b/src/lib/ppc405lib/mutex.c
deleted file mode 100644
index db57f54..0000000
--- a/src/lib/ppc405lib/mutex.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/mutex.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 */
-// $Id$
-
-/// \file mutex.c
-/// \brief A ThreadX-style mutual exclusion object
-
-#include "mutex.h"
-
-int
-mutex_create(Mutex* i_mutex)
-{
- int rc;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(i_mutex == 0, SSX_INVALID_OBJECT);
- }
-
- rc = ssx_semaphore_create(&(i_mutex->sem), 1, 1);
- i_mutex->thread = 0;
- i_mutex->count = 0;
-
- return rc;
-}
-
-
-// If the current thread owns the Mutex we simply increment the count,
-// otherwise pend for the semaphore.
-//
-// Note: It's possible this doesn't need to be done in a critical section. The
-// fact that ssx_semaphore_pend() is atomic may be sufficient since it locks
-// the Mutex.
-
-int
-mutex_pend(Mutex* i_mutex, SsxInterval i_timeout)
-{
- int rc;
- SsxMachineContext ctx;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(i_mutex == 0, SSX_INVALID_OBJECT);
- SSX_ERROR_UNLESS_THREAD_CONTEXT();
- }
-
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- if (i_mutex->thread == ssx_current()) {
-
- i_mutex->count++;
- if (i_mutex->count == 0) {
- rc = MUTEX_OVERFLOW;
- } else {
- rc = 0;
- }
-
- } else {
-
- rc = ssx_semaphore_pend(&(i_mutex->sem), i_timeout);
- if (rc == 0) {
- i_mutex->thread = ssx_current();
- i_mutex->count = 1;
- }
- }
-
- ssx_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-// If the current thread owns the Mutex we decrement the count and free the
-// object when the count goes to 0.
-//
-// Note: It's possible this doesn't need to be done in a critical section. The
-// fact that ssx_semaphore_pend() is atomic may be sufficient since it locks
-// the Mutex.
-
-int
-mutex_post(Mutex* i_mutex)
-{
- int rc;
- SsxMachineContext ctx;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(i_mutex == 0, SSX_INVALID_OBJECT);
- SSX_ERROR_UNLESS_THREAD_CONTEXT();
- }
-
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- SSX_ERROR_IF(i_mutex->thread != ssx_current(), MUTEX_NOT_OWNED);
-
- if (--i_mutex->count == 0) {
- i_mutex->thread = 0;
- rc = ssx_semaphore_post(&(i_mutex->sem));
- } else {
- rc = 0;
- }
-
- ssx_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-
-
diff --git a/src/lib/ppc405lib/mutex.h b/src/lib/ppc405lib/mutex.h
deleted file mode 100644
index 6d3a352..0000000
--- a/src/lib/ppc405lib/mutex.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/mutex.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __MUTEX_H__
-#define __MUTEX_H__
-
-// $Id$
-
-/// \file mutex.h
-/// \brief A ThreadX-style mutual exclusion object
-///
-/// A Mutex is a binary semaphore with the concept of thread ownership. A
-/// thread first obtains the Mutex using the mutex_pend() API, which may block
-/// if the Mutex is currently owned by another thread. Once a thread owns a
-/// Mutex, subsequent calls of mutex_pend() by the same thread simply
-/// increment an internal counter, but do not block. Once a thread has
-/// executed a matching mutex_post() call for every mutex_pend() call, the
-/// Mutex is free for another thread.
-///
-/// This type of mutual exclusion object is useful for example to control
-/// access to data structures that are manipulated by APIs with several common
-/// entry points. Each call of an API in the chain will 'lock' the data
-/// structure using mutex_pend()/mutex_post(). The Mutex semantics allows
-/// multiple "locks" by the same thread, but requires a corresponding "unlock"
-/// for every "lock".
-///
-/// The Mutex usage counter is a 32-bit unsigned integer. If a thread makes
-/// 2^32 calls to mutex_pend() without an intervening call of mutex_post(), an
-/// overflow is signalled. This error should be considered unrecoverable to
-/// the application.
-///
-/// Like the SSX semaphore, no record is kept in the thread of which Mutex
-/// objects are currently owned by the thread. If a thread terminates or is
-/// deleted while holding a Mutex it is likely that the application will
-/// hang. Unlike the SSX semaphore, it is absolutely illegal to call
-/// mutex_pend() and mutex_post() from interrupt contexts. It is also illegal
-/// for a thread to call mutex_post() for a mutex it does not own.
-///
-/// Mutex objects are easily created with the static initialization macro
-/// MUTEX_INITIALIZATION as in the following example.
-///
-/// \code
-///
-/// Mutex G_mutex = MUTEX_INITIALIZATION;
-///
-/// \endcode
-///
-/// The API mutex_create() is also provided for run-time initialization.
-
-#include "ssx.h"
-
-
-// Mutex error/panic codes
-
-#define MUTEX_OVERFLOW 0x00688901
-#define MUTEX_NOT_OWNED 0x00688902
-
-
-#ifndef __ASSEMBLER__
-
-/// Static initialization of a Mutex
-///
-/// For a full description of the Mutex please see the documentation fof the
-/// file mutex.h.
-#define MUTEX_INITIALIZATION {SSX_SEMAPHORE_INITIALIZATION(1, 1), 0, 0}
-
-
-/// The Mutex object
-
-typedef struct {
-
- /// The binary semaphore
- SsxSemaphore sem;
-
- /// A pointer to the owning thread, or NULL (0)
- SsxThread* thread;
-
- /// The count of unmatched mutex_pend() calls made by the owning thread.
- uint32_t count;
-
-} Mutex;
-
-
-/// Create (initialize) a Mutex
-///
-/// \param[in] i_mutex A pointer to the Mutex object to initialize.
-///
-/// For a full description of the Mutex please see the documentation for the
-/// file mutex.h.
-///
-/// \retval 0 Success
-///
-/// \retval 0 -SSX_INVALID_OBJECT The \a i_mutex is NULL (0).
-int
-mutex_create(Mutex* i_mutex);
-
-
-/// Pend on a Mutex with optional timeout
-///
-/// \param[in] i_mutex A pointer to the Mutex
-///
-/// \param[in] i_timeout Either the constant SSX_WAIT_FOREVER, or a timeout
-/// interval specification.
-///
-/// For a full description of the Mutex please see the documentation for the
-/// file mutex.h.
-///
-/// \retval 0 Success
-///
-/// \retval -SSX_INVALID_OBJECT The \a i_mutex is NULL (0).
-///
-/// \retval -SSX_ILLEGAL_CONTEXT The call was not made from a thread context.
-///
-/// \retval -SSX_SEMEPHORE_PEND_TIMED_OUT The thread was not able to obtain
-/// the Mutex before the timeout.
-///
-/// \retval -MUTEX_OVERFLOW The owning thread has made 2^32 unmatched calls of
-/// mutex_pend().
-int
-mutex_pend(Mutex* i_mutex, SsxInterval i_timeout);
-
-
-/// Post to a Mutex
-///
-/// \param[in] i_mutex A pointer to the Mutex
-///
-/// For a full description of the Mutex please see the documentation for the
-/// file mutex.h.
-///
-/// \retval 0 Success
-///
-/// \retval -SSX_INVALID_OBJECT The \a i_mutex is NULL (0).
-///
-/// \retval -SSX_ILLEGAL_CONTEXT The call was not made from a thread context.
-///
-/// \retval -MUTEX_NOT_OWNED The thread calling mutex_post() does not own the
-/// Mutex.
-int
-mutex_post(Mutex* i_mutex);
-
-#endif // __ASSEMBLER__
-
-#endif // __MUTEX_H__
diff --git a/src/lib/ppc405lib/periodic_semaphore.c b/src/lib/ppc405lib/periodic_semaphore.c
deleted file mode 100644
index dec9ea2..0000000
--- a/src/lib/ppc405lib/periodic_semaphore.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/periodic_semaphore.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 */
-// $Id$
-
-/// \file perodic_semaphore.h
-/// \brief Periodic semphores
-
-#include "ssx.h"
-#include "periodic_semaphore.h"
-
-// The timer callback is created nonpreemptible, so noncritical interrupts are
-// disabled at entry.
-
-static void
-_periodic_semaphore_timeout(void* arg)
-{
- PeriodicSemaphore* ps;
-
- ps = (PeriodicSemaphore*)arg;
-
- if (ps->sem.count != 1) {
- ssx_semaphore_post(&(ps->sem));
- }
-}
-
-
-int
-periodic_semaphore_create(PeriodicSemaphore* sem, SsxInterval period)
-{
- int rc;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(sem == 0, SSX_INVALID_OBJECT);
- }
-
- do {
- rc = ssx_semaphore_create(&(sem->sem), 0, 1);
- if (rc) break;
-
- rc = ssx_timer_create_nonpreemptible(&(sem->timer),
- _periodic_semaphore_timeout,
- sem);
- if (rc) break;
-
- rc = ssx_timer_schedule(&(sem->timer),
- period,
- period);
- if (rc) break;
-
- } while (0);
-
- return rc;
-}
-
-
-int
-periodic_semaphore_pend(PeriodicSemaphore* sem)
-{
- int rc;
- SsxMachineContext ctx;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(sem == 0, SSX_INVALID_OBJECT);
- }
-
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- if (sem->sem.count == 0) {
-
- rc = ssx_semaphore_pend(&(sem->sem), SSX_WAIT_FOREVER);
-
- } else {
-
- sem->sem.count = 0;
- rc = -PERIODIC_SEMAPHORE_OVERRUN;
- }
-
- ssx_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-int
-periodic_semaphore_cancel(PeriodicSemaphore* sem)
-{
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(sem == 0, SSX_INVALID_OBJECT);
- }
-
- return ssx_timer_cancel(&(sem->timer));
-}
diff --git a/src/lib/ppc405lib/periodic_semaphore.h b/src/lib/ppc405lib/periodic_semaphore.h
deleted file mode 100644
index c3c2e53..0000000
--- a/src/lib/ppc405lib/periodic_semaphore.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/periodic_semaphore.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __PERIODIC_SEMAPHORE_H__
-#define __PERIODIC_SEMAPHORE_H__
-
-// $Id$
-
-/// \file perodic_semaphore.h
-/// \brief Periodic semphores
-///
-/// The PeriodicSemphore is a simple abstraction introduced to simplify coding
-/// peridic threads. A periodic thread creates the PeriodicSemaphore after
-/// thread initialization, but prior to the entry to the periodic infinite
-/// loop. This creates the periodicSemaphore with a count of 0. Once thread
-/// processing is finished, the thread pends on the PeriodicSemaphore. A
-/// periodic timer posts to the PeriodicSemaphore on a fixed, absolute period
-/// to reschedule the thread.
-///
-/// If the thread pends on the PeriodicSemaphore and the timer has already
-/// posted to the semaphore, the call of periodic_semaphore_pend() clears the
-/// semaphore and terminates immediately with the return code
-/// -PERIODIC_SEMAPHORE_OVERRUN, indicating that the thread has overrun its
-/// period. The thread can choose the appropriate action upon obtaining this
-/// return code.
-///
-/// The PeriodicSemaphore can also be cancelled, which simply cancels the
-/// periodic timer posting to the semaphore. If the thread needs to
-/// re-initialize the PeriodicSemaphore for any reason (e.g, to resynchronize
-/// after an overrun) it must be cancelled first.
-
-// Error/Panic codes
-
-#define PERIODIC_SEMAPHORE_OVERRUN 0x0077e601
-
-
-/// A periodic semaphore
-
-typedef struct {
-
- /// The semaphore
- SsxSemaphore sem;
-
- /// The timer
- SsxTimer timer;
-
-} PeriodicSemaphore;
-
-
-/// Create (initialize) a PeriodicSemaphore
-///
-/// \param sem A pointer to an uninitialized or inactive
-/// PeriodicSemaphore.
-///
-/// \param period The semaphore period
-///
-/// This API creates the embedded semaphore as a binary semaphore with an
-/// initial value of 0, and schedules a periodic timer to post to the
-/// semaphore.
-///
-/// \retval 0 Success
-///
-/// \retval -SSX_INVALID_OBJECT The \a sem was NULL (0) or otherwise invalid.
-///
-/// Other return codes are possible from the embedded calls of SSX APIs.
-int
-periodic_semaphore_create(PeriodicSemaphore* sem, SsxInterval period);
-
-
-/// Pend on a PeriodicSemaphore
-///
-/// \param sem A pointer to an initialized PeriodicSemaphore
-///
-/// Pend on a PeriodicSemaphore. It is considered a non-fatal error if the
-/// semaphore has a non-0 count as this may indicate that a periodic thread
-/// has missed a deadline.
-///
-/// Return values other than SSX_OK (0) are not necessarily errors; see \ref
-/// ssx_errors
-///
-/// The following return codes are non-error codes:
-///
-/// \retval 0 Success. In particular, the semaphore count was 0 at entry.
-///
-/// \retval -PERIODIC_SEMAPHORE_OVERRUN This return code indicates that the
-/// semaphore count was 1 at entry. This code is always returned (never causes
-/// a panic).
-///
-/// The following return codes are error codes:
-///
-/// \retval -SSX_IVALID_OBJECT The \a sem was NULL () or otherwise invalid at
-/// entry.
-///
-/// Other error return codes are possible from embedded calls of SSX APIs.
-int
-periodic_semaphore_pend(PeriodicSemaphore* sem);
-
-
-/// Cancel a periodic semaphore
-///
-/// \param sem A pointer to an initialized PeriodicSemaphore
-///
-/// Cancel the PeriodicSemaphore timeout. This is a required step if the
-/// PeriodicSemaphore is to be reinitialized. This is also required if the
-/// PeriodicSemaphore is created on the thread stack and the thread
-/// terminates. PeriodicSemaphore can be canceled at any time. It is never
-/// an error to call periodic_semaphore_cancel() on a PeriodicSemaphore object
-/// after it is created.
-///
-/// Return values other than SSX_OK (0) are not necessarily errors; see \ref
-/// ssx_errors
-///
-/// The following return codes are non-error codes:
-///
-/// \retval 0 Successful completion
-///
-/// \retval -SSX_TIMER_NOT_ACTIVE The embedded timer is not currently
-/// scheduled, meaning that the PeriodicSemaphore was previosly
-/// cancelled.
-///
-/// The following return codes are error codes:
-///
-/// \retval -SSX_IVALID_OBJECT The \a sem was NULL () or otherwise invalid at
-/// entry.
-///
-/// Other error return codes are possible from embedded calls of SSX APIs.
-int
-periodic_semaphore_cancel(PeriodicSemaphore* sem);
-
-
-#endif // __PERIODIC_SEMAPHORE_H__
diff --git a/src/lib/ppc405lib/progress.c b/src/lib/ppc405lib/progress.c
deleted file mode 100644
index 8d2cd30..0000000
--- a/src/lib/ppc405lib/progress.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/progress.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 */
-// $Id
-
-/// \file progress.c
-/// \brief Programmable progress (hang) checking
-///
-/// This is a simple implementation of a progress (hang) checking
-/// facility. The application provides an array of \e pass \e counts that are
-/// expected to update/count over time. For simplicity and generality all
-/// pass counts are defined to be \c uint64_t types. The
-/// progress_checker_create() API initializes the checker, and as a
-/// convenience clears the pass counts.
-///
-/// The checker can be created with an optional \a callback function, which
-/// has the prototype
-///
-/// \code
-/// typedef int (*ProgressCheckerCallback)(struct ProgressChecker *checker,
-/// void* arg,
-/// size_t failed)
-/// \endcode
-///
-/// The checker callback is called \e every time a check is made by
-/// progress_checker_check(). In addition to a private void* argument, the
-/// parameter list of the callback includes a count of the number of counters
-/// that failed to make progress - this count will be 0 if the check was
-/// successful. The return value of the callback is passed back as the return
-/// value of progress_checker_check(). If the callback is specified as NULL
-/// (0), then a successful check returns 0, and any failure causes a return
-/// code of -PROGRESS_CHECKER_FAILED.
-///
-/// The application can dynamically mark counters as either \e exempt or \e
-/// required. By default all counts are required to have increased
-/// each time a check is made for progress. Counters marked \e exempt when a
-/// progress check is made are not checked for progress.
-///
-/// The application can also use the progress_checker_schedule() API to
-/// schedule either one-shot or periodic checks. The
-/// progress_checker_cancel() API can be used to cancel any scheduled
-/// checks. It is never an error to call this API, even if no checks are
-/// currently scheduled. Note that each call of progress_checker_schedule()
-/// also cancels any outstanding scheduled requests before (re-) scheduling
-/// the checker. If using the built-in timer mechanism, any calls of
-/// progress_checker_check that return a non-0 value will cause a kernel panic.
-///
-/// If failures are detected and caught, the ProgressChecker provides a
-/// primitive iteration facility for the callback or the applicaton to
-/// determine which counters have failed to update. Calling
-/// progress_checker_next_failure() returns either the index of the next
-/// failing counter, or -1 to indicate no more failures. This iteration
-/// facility is reset every time a check is made by progress_checker_check()
-/// (including those made implcitly by the timer-based mechanism). There is no
-/// API to reset the iteration.
-///
-/// The implemetation provides 2 standard callback functions:
-/// progess_checker_printk() and progress_checker_printk_dump(). The former
-/// callback uses printk() to print a simple report of failed counters, and if
-/// there were any failures it then returns its argument as a return code. If
-/// the return code is non-zero then the lack of progress will cause a kernel
-/// panic (test failure). The later callback first calls
-/// progress_checker_printk(). If progress_checker_printk() returns a non-0
-/// value then progress_checker_printk_dump() enters an SSX_CRITICAL crictal
-/// section and prints a full kernel state dump that may be useful to help
-/// diagnose the hang.
-///
-/// \note We do not make the kernel dump the default or only behavior because
-/// it could take 1ms or more to produce the large quantity of formatted
-/// output required, which could be a significant amount of wall time in a
-/// logic simulation environment.
-///
-/// The progress_checker_create() API could be used in a couple of ways as
-/// illustrated below:
-///
-/// \code
-///
-/// ProgressChecker progress;
-/// uint64_t counter;
-///
-/// progress_checker_create(&progress, "progress", counter, 1,
-/// progress_checker_printk,
-/// (void*)-PROGRESS_CHECKER_FAILED);
-///
-/// OR
-///
-/// progress_checker_create(&progress, "progress", counter, 1,
-/// progress_checker_printk, 0);
-///
-/// \endcode
-///
-/// The first usage prints a report and panics the test if lack of progress is
-/// detected. The second form simply prints a report in the event of a lack
-/// or progress. The second form may be useful to report on counters that
-/// only have a statistical probability of making progress, however be aware
-/// that the report is generated in an interrupt context and all thread
-/// activity will be blocked until the formatted I/O is complete.
-///
-/// Notes:
-///
-/// This implementation requires the \c byte_pool facility and malloc() to be
-/// set up as the ProgressChecker allocates dynamic storage during
-/// initialization to store the previous pass counts.
-///
-/// It is probably not a good idea to use a single ProgressChecker for both
-/// manual and timer-based checking, since there is no protection in the
-/// implementation for mutiple accesses to the ProgressChecker.
-
-#include "progress.h"
-#include "ssx_dump.h"
-
-// The built-in timer callback
-
-static void
-progress_callback(void *arg)
-{
- ProgressChecker *checker = (ProgressChecker *)arg;
-
- if (progress_checker_check(checker)){
- if (0) {
- progress_checker_dump(checker);
- }
- SSX_PANIC(PROGRESS_CHECKER_FAILED);
- }
-}
-
-
-// Bit-vector operations manage the array of bits using little-endian
-// protocols
-
-static inline void
-bit_vector_set(uint8_t *vector, size_t bit)
-{
- vector[bit / 8] |= (1 << (bit % 8));
-}
-
-
-static inline void
-bit_vector_clear(uint8_t *vector, size_t bit)
-{
- vector[bit / 8] &= ~(1 << (bit % 8));
-}
-
-
-static inline int
-bit_vector_is_set(uint8_t *vector, size_t bit)
-{
- return ((vector[bit / 8] & (1 << (bit % 8))) != 0);
-}
-
-
-// NB: We don't have a bit-vector object with a size included. For this
-// application we can only call this API if we know that there is at least 1
-// bit set in the vector.
-
-static size_t
-bit_vector_find_first_set(uint8_t *vector)
-{
- size_t byte = 0;
-
- while (vector[byte] == 0) {
- byte++;
- }
-
- return (8 * byte) + __builtin_ffs(vector[byte]) - 1;
-}
-
-
-/// Create a progress checker
-///
-/// \param checker A pointer to an uninitialized or idle ProgressChecker
-///
-/// \param name An optional character string associated with the checker
-///
-/// \param pass_counts An array of pass counters - the array will be cleared
-/// by this API.
-///
-/// \param counters The number of counters in the array
-///
-/// \param callback This function is called \e every time a check is
-/// completed.
-///
-/// \param arg The private argument of the callback function
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c
-///
-/// Return values other than 0 are errors; see \ref ssx_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-///
-/// \retval -PROGRESS_CHECKER_INVALID_ARGUMENT A null (0) pointer was provided
-/// as the \a pass_counts argument, or the number of \a counters can not be
-/// represented as a signed integer.
-///
-/// \retval -PROGRESS_CHECKER_ALLOCATION_FAILED Memory allocation of dynamic
-/// memory failed. This is treated as a fatal error here.
-///
-/// This API may also return or signal other errors from its implementation
-/// APIs.
-
-int
-progress_checker_create(ProgressChecker *checker,
- const char* name,
- uint64_t *pass_counts,
- size_t counters,
- ProgressCheckerCallback callback,
- void *arg)
-{
- int rc, bytes;
- void *memory;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF((checker == 0),
- PROGRESS_CHECKER_INVALID_OBJECT);
- SSX_ERROR_IF((pass_counts == 0) ||
- (counters != (int)counters),
- PROGRESS_CHECKER_INVALID_ARGUMENT);
- }
-
- // Install and clear the counters
-
- checker->pass_counts = pass_counts;
- memset((void *)pass_counts, 0, counters * sizeof(uint64_t));
- checker->counters = counters;
-
- // Allocate and clear dynamic memory
-
- memory = calloc(counters, sizeof(uint64_t));
- checker->saved_counts = (uint64_t *)memory;
-
- bytes = (counters / 8) + (counters % 8 ? 1 : 0);
- checker->bit_vector_bytes = bytes;
-
- memory = calloc(bytes, 1);
- checker->exempt = (uint8_t *)memory;
-
- memory = calloc(bytes, 1);
- checker->failure = (uint8_t *)memory;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF((counters != 0) &&
- ((checker->saved_counts == 0) ||
- (checker->exempt == 0) ||
- (checker->failure == 0)),
- PROGRESS_CHECKER_ALLOCATION_FAILED);
- }
-
- // Initialize other fields
-
- checker->name = name;
- checker->callback = callback;
- checker->arg = arg;
- checker->failed = 0;
- checker->checks = 0;
-
- // Initialize the timer structure.
-
- rc = ssx_timer_create(&(checker->timer),
- progress_callback,
- (void *)checker);
- if (rc) return rc;
-
- return 0;
-}
-
-
-/// Exempt a pass count from progress checking
-///
-/// \param checker A pointer to an initialized ProgressChecker
-///
-/// \param counter The index of the counter to exempt
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c
-///
-/// Return values other than 0 are errors; see \ref ssx_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-///
-/// \retval -PROGRESS_CHECKER_INVALID_ARGUMENT The \a counter argument is not
-/// valid.
-
-int
-progress_checker_exempt(ProgressChecker *checker,
- size_t counter)
-{
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(checker == 0,
- PROGRESS_CHECKER_INVALID_OBJECT);
- SSX_ERROR_IF(counter >= checker->counters,
- PROGRESS_CHECKER_INVALID_ARGUMENT);
- }
-
- bit_vector_set(checker->exempt, counter);
-
- return 0;
-}
-
-
-/// Exempt all pass counts from progress checking
-///
-/// \param checker A pointer to an initialized ProgressChecker
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c
-///
-/// This API is provided to support applications where pass-count-updating
-/// processes are added dynamically. This API coule typically be called
-/// immediately after progress_checker_create(). Them, as each process was
-/// created it would call progress_checker_require() for the pass count.
-///
-/// Return values other than 0 are errors; see \ref ssx_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-int
-progress_checker_exempt_all(ProgressChecker *checker)
-{
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(checker == 0,
- PROGRESS_CHECKER_INVALID_OBJECT);
- }
-
- memset(checker->exempt, -1, checker->bit_vector_bytes);
-
- return 0;
-}
-
-
-/// Require a pass count to update for progress checking
-///
-/// \param checker A pointer to an initialized ProgressChecker
-///
-/// \param counter The index of the counter to require
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c
-///
-/// Return values other than 0 are errors; see \ref ssx_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-///
-/// \retval -PROGRESS_CHECKER_INVALID_ARGUMENT The \a counter argument is not
-/// valid.
-
-int
-progress_checker_require(ProgressChecker *checker,
- size_t counter)
-{
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(checker == 0,
- PROGRESS_CHECKER_INVALID_OBJECT);
- SSX_ERROR_IF(counter >= checker->counters,
- PROGRESS_CHECKER_INVALID_ARGUMENT);
- }
-
- bit_vector_clear(checker->exempt, counter);
-
- return 0;
-}
-
-
-/// Require a pass count to update for progress checking avoiding races
-///
-/// \param checker A pointer to an initialized ProgressChecker
-///
-/// \param counter The index of the counter to require
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c
-///
-/// If a pass counter is marked "exempt" but then later marked "required",
-/// there is a potential race between the update of the pass counter and the
-/// next check, particularly when the checker is scheduled periodically. This
-/// form of the progress_checker_require() marks the progress checker such
-/// that \e all checks are deferred on the next call of
-/// progress_checker_check() targeting the object in order to avoid the race.
-///
-/// Return values other than 0 are errors; see \ref ssx_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-///
-/// \retval -PROGRESS_CHECKER_INVALID_ARGUMENT The \a counter argument is not
-/// valid.
-int
-progress_checker_require_defer(ProgressChecker *checker,
- size_t counter)
-{
- int rc;
- SsxMachineContext ctx;
-
- ssx_critical_section_enter(SSX_CRITICAL, &ctx);
-
- rc = progress_checker_require(checker, counter);
- checker->defer = 1;
-
- ssx_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-/// Check for progress in every required pass counter.
-///
-/// \param checker A pointer to an initialized ProgressChecker
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c
-///
-/// Return values other than 0 are not necessarily errors; see \ref
-/// ssx_errors
-///
-/// \retval various Except for the error listed below,
-/// progress_checker_check() returns the code returned by the callback
-/// function. If no callback was provided when the checker was created, then 0
-/// is returned for success and -PROGRESS_CHECKER_FAILED is returned in the
-/// event of a lack of progress.
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-
-int
-progress_checker_check(ProgressChecker *checker)
-{
- size_t i;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(checker == 0,
- PROGRESS_CHECKER_INVALID_OBJECT);
- }
-
- // Avoid doing this step unless necessary
-
- if (checker->failed != 0) {
- checker->failed = 0;
- memset((void *)checker->failure, 0, checker->bit_vector_bytes);
- }
-
- // Check, unless checking has been deferred for 1 time by
- // progress_checker_require_defer().
-
- if (checker->defer) {
-
- checker->defer = 0;
-
- } else {
-
- SSX_ATOMIC(SSX_CRITICAL, checker->start_check = ssx_timebase_get());
-
- for (i = 0; i < checker->counters; i++) {
-
- if ((checker->pass_counts[i] <= checker->saved_counts[i]) &&
- !(bit_vector_is_set(checker->exempt, i))) {
-
- checker->failed++;
- bit_vector_set(checker->failure, i);
- }
- checker->saved_counts[i] = checker->pass_counts[i];
- }
-
- SSX_ATOMIC(SSX_CRITICAL, checker->end_check = ssx_timebase_get());
- }
-
- checker->checks++;
-
- if (checker->callback) {
- return checker->callback(checker, checker->arg, checker->failed);
- } else if (checker->failed != 0) {
- return -PROGRESS_CHECKER_FAILED;
- } else {
- return 0;
- }
-}
-
-
-/// Schedule progress checks (periodically) in the future.
-///
-/// \param checker A pointer to an initialized ProgressChecker
-///
-/// \param interval The relative time of the (first) check
-///
-/// \param period If non-zero, checks will be made periodically with this
-/// period.
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c. See the SSX documentation for a discussion of
-/// timer scheduling in SSX.
-///
-/// Return values other than 0 errors; see \ref ssx_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-///
-/// This API may also return or signal other errors from its implementation
-/// APIs.
-
-
-int
-progress_checker_schedule(ProgressChecker *checker,
- SsxInterval interval,
- SsxInterval period)
-{
- int rc;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(checker == 0,
- PROGRESS_CHECKER_INVALID_OBJECT);
- }
-
- rc = ssx_timer_cancel(&(checker->timer));
- if (rc != -SSX_TIMER_NOT_ACTIVE) return rc;
-
- rc = ssx_timer_schedule(&(checker->timer), interval, period);
- if (rc) return rc;
-
- return 0;
-}
-
-
-/// Cancel all future (periodic) progress checks
-///
-/// \param checker A pointer to an initialized ProgressChecker
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c. See the SSX documentation for a discussion of
-/// timer scheduling in SSX.
-///
-/// Return values other than 0 errors; see \ref ssx_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-///
-/// This API may also return or signal other errors from its implementation
-/// APIs.
-
-int
-progress_checker_cancel(ProgressChecker *checker)
-{
- int rc;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(checker == 0,
- PROGRESS_CHECKER_INVALID_OBJECT);
- }
-
- rc = ssx_timer_cancel(&(checker->timer));
- if (rc) return rc;
-
- return 0;
-}
-
-
-/// Iterate over progress check failures
-///
-/// \param checker A pointer to an initialized ProgressChecker
-///
-/// \param counter Will return the index of the next failing counter, or -1 to
-/// indicate no more failing counters.
-///
-/// For an overview of the ProgressChecker and its APIs, see the documentation
-/// for the file progress.c.
-///
-/// Return values other than 0 errors; see \ref ssx_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PROGRESS_CHECKER_INVALID_OBJECT A null (0) pointer was provided
-/// as the \a checker argument.
-
-int
-progress_checker_next_failure(ProgressChecker *checker, int *counter)
-{
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(checker == 0,
- PROGRESS_CHECKER_INVALID_OBJECT);
- }
-
- if (checker->failed == 0) {
- *counter = -1;
- return 0;
- }
-
- *counter = bit_vector_find_first_set(checker->failure);
- bit_vector_clear(checker->failure, *counter);
- checker->failed--;
-
- return 0;
-}
-
-
-/// A standard way to print the results of a progress check failure, suitable
-/// for use as a ProgressChecker callback.
-///
-/// \param checker The checker - which may or may not have failed. If the
-/// checker did fail, then a failure report is printed using printk().
-///
-/// \param arg The value to return in case of failure. In case of
-/// success, 0 is returned.
-///
-/// \param failed - The number of failed checks
-
-int
-progress_checker_printk(ProgressChecker *checker,
- void *arg,
- size_t failed)
-{
- int counter;
-
- if (!failed) {
- return 0;
- }
-
- printk("---------------------------------------------------------------\n");
- printk("-- Progress check failed for \"%s\" (%p).\n",
- checker->name, checker);
- printk("-- Check %zu over interval 0x%016llx - 0x%016llx\n",
- checker->checks, checker->start_check, checker->end_check);
- printk("-- %zu failed counter%s listed below\n",
- failed, failed > 1 ? "s are" : " is");
- printk("---------------------------------------------------------------\n");
-
- do {
- progress_checker_next_failure(checker, &counter);
- if (counter < 0) {
- break;
- }
- printk("%4d. 0x%016llx\n", counter, checker->pass_counts[counter]);
- } while (1);
-
- printk("---------------------------------------------------------------\n");
-
- return (int)arg;
-}
-
-
-/// Call progress_checker_printk(), then create a kernel dump on failure
-///
-/// \param checker The checker - which may or may not have failed. If the
-/// checker did fail, then a failure report is printed using
-/// progress_checker_printk().
-///
-/// \param arg The value to return in case of failure. In case of
-/// success, 0 is returned.
-///
-/// \param failed - The number of failed checks
-///
-/// If progress_checker_printk() fails with a non-0 return code then this API
-/// prints a full SSX kernel dump after the progress_checker_printk() report.
-int
-progress_checker_printk_dump(ProgressChecker *checker,
- void *arg,
- size_t failed)
-{
- int rc;
- SsxMachineContext ctx;
-
- rc = progress_checker_printk(checker, arg, failed);
- if (rc != 0) {
- ssx_critical_section_enter(SSX_CRITICAL, &ctx);
- ssx_dump(ssxout, 0);
- ssx_critical_section_exit(&ctx);
- }
-
- return rc;
-}
-
-
-/// Dump a progress checker structure using printk()
-
-void
-progress_checker_dump(ProgressChecker *checker)
-{
- size_t i;
-
- printk("Dump of progress checker \"%s\" (%p)\n"
- " Counters = %zu\n"
- " Checks = %zu\n"
- " Failed = %zu\n"
- " Callback = %p(%p)\n",
- checker->name, checker, checker->counters, checker->checks,
- checker->failed, checker->callback, checker->arg);
-
- printk(" Pass Counts (%p) :\n", checker->pass_counts);
- for (i = 0; i < checker->counters; i++) {
- printk(" %9d%c 0x%016llx\n",
- i,
- bit_vector_is_set(checker->exempt, i) ? '*' : ' ',
- checker->pass_counts[i]);
- }
- printk(" Saved Counts (%p) :\n", checker->saved_counts);
- for (i = 0; i < checker->counters; i++) {
- printk(" %9d 0x%016llx\n",
- i, checker->saved_counts[i]);
- }
-}
-
-
-
-
-
-
-
-
diff --git a/src/lib/ppc405lib/progress.h b/src/lib/ppc405lib/progress.h
deleted file mode 100644
index 3454a0f..0000000
--- a/src/lib/ppc405lib/progress.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/progress.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __PROGRESS_H__
-#define __PROGRESS_H__
-
-// $Id$
-
-/// \file progress.h
-/// \brief Programmable progress (hang) checking
-
-#include <time.h>
-#include "ssx.h"
-#include "byte_pool.h"
-#include "ssx_io.h"
-
-#ifndef __ASSEMBLER__
-
-struct ProgressChecker;
-
-/// ProgressChecker callback type
-///
-/// \param checker The checker that has just been checked
-///
-/// \param arg The private argument provided when the checker was created
-///
-/// \param failed The number of failed pass counts - 0 indicates no failures
-
-typedef int (*ProgressCheckerCallback)(struct ProgressChecker* checker,
- void* arg,
- size_t failed);
-
-
-/// A simple progress (hang) checker. For API details see file progress.c
-
-typedef struct ProgressChecker {
-
- /// The application provided pass-count array
- uint64_t *pass_counts;
-
- /// The number of pass-count counters in the array.
- size_t counters;
-
- /// The (optional) name of the checker for reporting purposes.
- const char *name;
-
- /// The (optional) checker callback.
- ProgressCheckerCallback callback;
-
- /// The checker callback private argument
- void *arg;
-
- /// The dynamically-allocated saved pass counts.
- uint64_t *saved_counts;
-
- /// The dynamically-allocated exemption bit-vector
- ///
- /// \todo Get or implement a generic unlimited-precision bit vector
- uint8_t *exempt;
-
- /// The dynamically-allocated failure bit-vector
- uint8_t *failure;
-
- /// The number of bytes in the bit vector
- size_t bit_vector_bytes;
-
- /// Defer all checking the next time progress_checker_check() is called.
- ///
- /// See progress_checker_require_defer()
- int defer;
-
- /// The number of failures present in the *failure vector
- size_t failed;
-
- /// A timer object to support time-based checking.
- SsxTimer timer;
-
- /// The number of times progress_checker_check() has been called on the
- /// object.
- size_t checks;
-
- /// The time the last check started
- SsxTimebase start_check;
-
- /// The time the last check ended
- SsxTimebase end_check;
-
-} ProgressChecker;
-
-
-int
-progress_checker_create(ProgressChecker *checker,
- const char *name,
- uint64_t *pass_counts,
- size_t counters,
- ProgressCheckerCallback callback,
- void *arg);
-
-int
-progress_checker_exempt(ProgressChecker *checker,
- size_t counter);
-
-int
-progress_checker_exempt_all(ProgressChecker *checker);
-
-int
-progress_checker_require(ProgressChecker *checker,
- size_t counter);
-
-int
-progress_checker_require_defer(ProgressChecker *checker,
- size_t counter);
-
-int
-progress_checker_check(ProgressChecker *checker);
-
-int
-progress_checker_schedule(ProgressChecker *checker,
- SsxInterval interval,
- SsxInterval period);
-
-int
-progress_checker_cancel(ProgressChecker *checker);
-
-int
-progress_checker_next_failure(ProgressChecker *checker, int *counter);
-
-int
-progress_checker_delete(ProgressChecker *checker);
-
-int
-progress_checker_printk(ProgressChecker *checker,
- void *arg,
- size_t failed);
-
-int
-progress_checker_printk_dump(ProgressChecker *checker,
- void *arg,
- size_t failed);
-
-void
-progress_checker_dump(ProgressChecker *checker);
-
-
-#endif /* __ASSEMBLER__ */
-
-// Error/Panic codes
-
-#define PROGRESS_CHECKER_INVALID_OBJECT 0x00776001
-#define PROGRESS_CHECKER_INVALID_ARGUMENT 0x00776002
-#define PROGRESS_CHECKER_FAILED 0x00776003
-#define PROGRESS_CHECKER_CALLBACK_PANIC 0x00776004
-#define PROGRESS_CHECKER_INVARIANT 0x00776005
-#define PROGRESS_CHECKER_ALLOCATION_FAILED 0x00776006
-
-#endif /* __PROGRESS_H__ */
diff --git a/src/lib/ppc405lib/rtx_stdio.c b/src/lib/ppc405lib/rtx_stdio.c
deleted file mode 100644
index 4bb1a18..0000000
--- a/src/lib/ppc405lib/rtx_stdio.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/rtx_stdio.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 */
-// $Id$
-
-/// \file rtx_stdio.c
-/// \brief SSX I/O drivers for RTX stdio streams
-///
-/// The RTX \a stdout and \a stderr components accept 1, 2 and 4-byte
-/// transactions on a 32-bit OCI address and write the data to the RTX
-/// job's \a stdout or \a stderr respectively. The \a stdin device is not yet
-/// implemented.
-
-#include "ssx.h"
-#include "rtx_stdio.h"
-
-RtxStdio rtx_stdin;
-RtxStdio rtx_stdout;
-RtxStdio rtx_stderr;
-
-int
-rtx_stdio_sread(FILE *stream, void *buf, size_t count, size_t *read)
-{
- SSX_PANIC(ENXIO);
- return -ENXIO;
-}
-
-
-int
-rtx_stdio_swrite(FILE *stream, const void *buf,
- size_t count, size_t *written)
-{
- RtxStdio *rtx = (RtxStdio *)stream;
- size_t n;
-
- n = count;
- while (n) {
- if (n >= 4) {
- out32(rtx->address, *((uint32_t *)buf));
- buf += 4;
- n -= 4;
- } else if (n >= 2) {
- out16(rtx->address, *((uint16_t *)buf));
- buf += 2;
- n -= 2;
- } else {
- out8(rtx->address, *((uint8_t *)buf));
- buf++;
- n--;
- }
- }
-
- if (written != 0) {
- *written = count;
- }
-
- return 0;
-}
-
-
-ssize_t
-rtx_stdio_fflush(FILE *stream)
-{
- RtxStdio *rtx = (RtxStdio *)stream;
-
- out8(rtx->flush_address, 0);
- return 0;
-}
-
-
-int
-rtx_stdin_create(RtxStdio *stream)
-{
- FILE *base = (FILE *)stream;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(stream == 0, EBADF);
- }
-
- memset((void *)stream, 0, sizeof(RtxStdio));
- base->sread = rtx_stdio_sread;
-
- stream->address = RTX_STDIN;
-
- return 0;
-}
-
-
-int
-rtx_stdout_create(RtxStdio *stream)
-{
- FILE *base = (FILE *)stream;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(stream == 0, EBADF);
- }
-
- memset((void *)stream, 0, sizeof(RtxStdio));
- base->swrite = rtx_stdio_swrite;
- base->fflush = rtx_stdio_fflush;
-
- stream->address = RTX_STDOUT;
- stream->flush_address = RTX_STDOUT_FLUSH;
-
- return 0;
-}
-
-
-int
-rtx_stderr_create(RtxStdio *stream)
-{
- FILE *base = (FILE *)stream;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(stream == 0, ENXIO);
- }
-
- memset((void *)stream, 0, sizeof(RtxStdio));
- base->swrite = rtx_stdio_swrite;
- base->fflush = rtx_stdio_fflush;
-
- stream->address = RTX_STDERR;
- stream->flush_address = RTX_STDERR_FLUSH;
-
- return 0;
-}
-
-
diff --git a/src/lib/ppc405lib/rtx_stdio.h b/src/lib/ppc405lib/rtx_stdio.h
deleted file mode 100644
index cd2a439..0000000
--- a/src/lib/ppc405lib/rtx_stdio.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/rtx_stdio.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __RTX_STDIO_H__
-#define __RTX_STDIO_H__
-
-// $Id$
-
-/// \file rtx_stdio.h
-/// \brief SSX I/O implementations for RTX stdio streams
-
-#include "ssx_io.h"
-#include "rtx_stdio_addresses.h"
-
-/// A FILE structure for a RTX fake stdio stream
-
-typedef struct {
-
- /// The base class
- FILE stream;
-
- /// The MMIO address of the RTX device for the stream
- SsxAddress address;
-
- /// The MMIO address of the RTX device for flushing the stream;
- SsxAddress flush_address;
-
-} RtxStdio;
-
-extern RtxStdio rtx_stdin;
-extern RtxStdio rtx_stdout;
-extern RtxStdio rtx_stderr;
-
-int
-rtx_stdin_create(RtxStdio *stream);
-
-int
-rtx_stdout_create(RtxStdio *stream);
-
-int
-rtx_stderr_create(RtxStdio *stream);
-
-int
-rtx_stdio_sread(FILE *stream, void *buf, size_t count, size_t *read);
-
-int
-rtx_stdio_swrite(FILE *stream, const void *buf,
- size_t count, size_t *written);
-
-int
-rtx_stdio_sflush(FILE *stream);
-
-#endif /* __RTX_STDIO_H__ */
diff --git a/src/lib/ppc405lib/rtx_stdio_addresses.h b/src/lib/ppc405lib/rtx_stdio_addresses.h
deleted file mode 100644
index 5359f7f..0000000
--- a/src/lib/ppc405lib/rtx_stdio_addresses.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/rtx_stdio_addresses.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __RTX_STDIO_ADDRESSES_H__
-#define __RTX_STDIO_ADDRESSES_H__
-
-// $Id$
-
-/// \file rtx_stdio_addresses.h
-/// \brief MMIO addresses and offsets of the rtx fake stdio model
-///
-/// The RTX stdio module appears as OCI device #7? Reading 1 byte from the
-/// stdin offset returns that byte from stdin. Writing 1, 2 or 4 bytes to the
-/// stdout or stderr offsets causes output on that stream. Writing any single
-/// byte to the 'flush' offsets flush the stdout or stderr streams.
-///
-/// -*- This header is maintained as part of the PMX RTX model. -*-
-/// -*- Do not edit in the SSX library as your edits will be lost. -*-
-
-#define RTX_STDIO_BASE 0x40060000
-
-#define RTX_STDIN_OFFSET 0x00
-#define RTX_STDOUT_OFFSET 0x04
-#define RTX_STDOUT_FLUSH_OFFSET 0x08
-#define RTX_STDERR_OFFSET 0x0c
-#define RTX_STDERR_FLUSH_OFFSET 0x10
-
-#define RTX_STDIN (RTX_STDIO_BASE + RTX_STDIN_OFFSET)
-#define RTX_STDOUT (RTX_STDIO_BASE + RTX_STDOUT_OFFSET)
-#define RTX_STDOUT_FLUSH (RTX_STDIO_BASE + RTX_STDOUT_FLUSH_OFFSET)
-#define RTX_STDERR (RTX_STDIO_BASE + RTX_STDERR_OFFSET)
-#define RTX_STDERR_FLUSH (RTX_STDIO_BASE + RTX_STDERR_FLUSH_OFFSET)
-
-#endif /* __RTX_STDIO_ADDRESSES_H__ */
diff --git a/src/lib/ppc405lib/sxlock.c b/src/lib/ppc405lib/sxlock.c
deleted file mode 100644
index 35f9698..0000000
--- a/src/lib/ppc405lib/sxlock.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/sxlock.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 */
-// $Id$
-
-/// \file sxlock.c
-/// \brief API for the SharedExclusiveLock
-///
-/// The APIs in this file implement a shared-exclusive lock for SSX
-/// applications. This type of lock is also called a readers-writer lock. The
-/// lock is implemented in terms of SSX semaphores, so its use is limited to
-/// threads willing to block for access to a resource.
-///
-/// The SharedExclusiveLock allows multiple threads shared access to a
-/// resource, while limiting exclusive access to a single thread. There are
-/// several ways that this type of lock might be specified. The specification
-/// implemented here is an "exclusive-biasing" lock. As long as the lock is
-/// held or requested in exclusive mode, all new shared-mode requests will
-/// block, and only exclusive accesses will be allowed. If multiple threads
-/// are blocked exclusive the requests are honored in priority order (as
-/// the underlying implementation is an SSX semaphore). Once the exclusive
-/// lock is cleared, any/all threads blocked for shared access are released
-/// simultaneously (using an SSX semaphore as a thread barrier).
-///
-/// The lock is created (initialized) by sxlock_create(), which allows
-/// specification of an initial value of the number of shared or exclusive
-/// accesses outstanding. The lock/unlock APIs are as follows:
-///
-/// - sxlock_lock_shared(SharedExclusiveLock* sxlock, SsxInterval timeout)
-/// - sxlock_unlock_shared(SharedExclusiveLock* sxlock)
-/// - sxlock_lock_exclusive(SharedExclusiveLock* sxlock, SsxInterval timeout)
-/// - sxlock_unlock_exclusive(SharedExclusiveLock* sxlock)
-///
-/// Threads must always issue *_lock() and *_unlock() requests in matched
-/// pairs in order to avoid errors and deadlock. The *_lock() APIs allow
-/// specification of a timeout, which may be SSX_WAIT_FOREVER to indicate no
-/// timeout. The *_lock() APIs will return the code -SXLOCK_TIMED_OUT if the
-/// timeout occurs before the thread acquires the resource. If called from an
-/// interrupt context then the only legal timeout specification is
-/// SSX_NO_WAIT (0).
-///
-/// If a *_lock() request times out then the thread \e has \e not acquired the
-/// resource and \e must \e not call *_unlock(). As with semaphores there is
-/// no record that a thread holds a lock, so if a thread completes or is
-/// deleted while holding a lock it is likely that the application will
-/// deadlock.
-
-#include "ssx.h"
-#include "sxlock.h"
-
-/// Create (initialize) a SharedExclusiveLock
-///
-/// \param sxlock A pointer to the SharedExclusiveLock object to
-/// initialize
-///
-/// \param shared The initial numbers of shared accesses
-///
-/// \param exclusive The initial numbers of exclusive accesses
-///
-/// Create (initialize) a SharedExclusiveLock and optionally specify an
-/// initial state. The initial number of shared or exclusive accesses can be
-/// specified, however at most one of \a nshared and \a exclusive can be
-/// non-0. If \a shared or \a exclusive are non-0 then eventually a
-/// thread(s) will need to issue unmatched *_unlock() call(s) to allow
-/// progress for other threads requiring the resource.
-///
-/// \retval 0 Success
-///
-/// \retval SXLOCK_INVALID_OBJECT The \a sxlock parameter is NULL (0) or
-/// otherwise invalid.
-///
-/// \retval SXLOCK_INVALID_ARGUMENT Both of the \a shared and \a exclusive
-/// parameters are non-0.
-///
-/// \retval others sxlock_create() may also return codes from
-/// ssx_semaphore_create(), which would indicate a serious bug.
-
-int
-sxlock_create(SharedExclusiveLock* sxlock,
- SsxSemaphoreCount shared,
- SsxSemaphoreCount exclusive)
-{
- int rc;
-
- rc = 0;
- do {
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(sxlock == 0,
- SXLOCK_INVALID_OBJECT);
- SSX_ERROR_IF((shared != 0) && (exclusive != 0),
- SXLOCK_INVALID_ARGUMENT);
- }
-
- rc = ssx_semaphore_create(&(sxlock->shared_sem), 0, 0);
- if (rc) break;
-
- rc = ssx_semaphore_create(&(sxlock->exclusive_sem), 0, 0);
- if (rc) break;
-
- sxlock->running_shared = shared;
- sxlock->running_exclusive = exclusive;
-
- } while (0);
-
- return rc;
-}
-
-
-/// Lock a SharedExclusiveLock for shared access
-///
-/// \param sxlock A pointer to the SharedExclusiveLock object to lock
-///
-/// \param timeout The maximum amount of time to wait for access, or the
-/// constant SSX_WAIT_FOREVER to wait forever.
-///
-/// Acquire a SharedExclusiveLock for shared access, potentially blocking
-/// forever or until a specified timeout if access is not immediately
-/// granted. Access will be blocked as long as one or more threads request or
-/// control exclusive acesss to the resource. Once the access is granted, the
-/// thread maintains shared access to the resource until a subsequent call of
-/// sxlock_unlock_shared().
-///
-/// Return values other than SSX_OK (0) are not necessarily errors; see \ref
-/// ssx_errors
-///
-/// The following return codes are non-error codes:
-///
-/// \retval 0 Successful completion
-///
-/// \retval -SXLOCK_TIMED_OUT Shared access was not acquired before the
-/// timeout expired.
-///
-/// The following return codes are error codes:
-///
-/// \retval -SXLOCK_INVALID_OBJECT The \a sxlock parameter was NULL (0) or
-/// otherwise invalid.
-///
-/// \retval -SSX_ILLEGAL_CONTEXT The API was called from a critical
-/// interrupt context.
-///
-/// \retval -SSX_SEMAPHORE_PEND_WOULD_BLOCK The call was made from an
-/// interrupt context (or before threads have been started), shared access was
-/// not immediately available and a non-zero timeout was specified.
-///
-/// \retval others This API may also return codes from SSX semaphore APIs,
-/// which should be considered as non-recoverable errors.
-
-
-int
-sxlock_lock_shared(SharedExclusiveLock* sxlock, SsxInterval timeout)
-{
- SsxMachineContext ctx;
- int rc, pending_exclusive;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(sxlock == 0, SXLOCK_INVALID_OBJECT);
- }
-
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- rc = 0;
- do {
-
- // NB: This is the only way to correctly compute the number of threads
- // pending exclusive, given that threads could be removed from the
- // exclusive_sem by timeout.
-
- rc = ssx_semaphore_info_get(&(sxlock->exclusive_sem),
- 0, &pending_exclusive);
- if (rc) break;
-
- if ((sxlock->running_exclusive == 0) && (pending_exclusive == 0)) {
-
- // If no other thread has or is requesting exclusive access, the
- // current thread gets immediate access.
-
- sxlock->running_shared++;
-
- } else {
-
- // If threads are running or pending exclusive, this thread must
- // pend shared. The thread will be unblocked by an exclusive
- // unlock, which is responsible for adjusting
- // sxlock->running_shared in this case.
-
- rc = ssx_semaphore_pend(&(sxlock->shared_sem), timeout);
- if (rc == -SSX_SEMAPHORE_PEND_TIMED_OUT) {
- rc = -SXLOCK_TIMED_OUT;
- }
- }
-
- } while (0);
-
- ssx_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-/// Relase a SharedExclusiveLock from shared access
-///
-/// \param sxlock A pointer to the SharedExclusiveLock object to unlock
-///
-/// Release a SharedExclusiveLock from shared access, signalling that the
-/// thread no longer requires or expects shared access to the resource. It is
-/// an error for a thread to use this API if it has not previously locked
-/// shared access by a call of sxlock_pend_shared() (or the thread is
-/// unlocking a lock initialized in the shared-locked state).
-///
-/// Return values other than SSX_OK (0) are errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -SSX_ILLEGAL_CONTEXT The API was called from a critical interrupt
-/// context.
-///
-/// \retval -SXLOCK_INVALID_OBJECT The \a sxlock parameter was NULL (0) or
-/// otherwise invalid.
-///
-/// \retval -SXLOCK_SHARED_UNDERFLOW There was apparently no matched call of
-/// sxlock_lock_shared() prior to this call.
-///
-/// \retval others This API may also return codes from SSX semaphore APIs,
-/// which should be considered as non-recoverable errors.
-
-int
-sxlock_unlock_shared(SharedExclusiveLock* sxlock)
-{
- SsxMachineContext ctx;
- int rc, pending_exclusive;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
- SSX_ERROR_IF(sxlock == 0, SXLOCK_INVALID_OBJECT);
- SSX_ERROR_IF(sxlock->running_shared == 0, SXLOCK_SHARED_UNDERFLOW);
- }
-
- if (SSX_ERROR_CHECK_KERNEL) {
- SSX_PANIC_IF(sxlock->running_exclusive != 0,
- SXLOCK_SHARED_EXCLUSIVE_INVARIANT);
- }
-
- rc = 0;
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- do {
-
- // If this is the last shared thread running, and a thread wants
- // exclusive access, grant it. Note that there may be shared requests
- // pending on the shared_sem but we always give preference to
- // exclusive requests.
-
- sxlock->running_shared--;
- if (sxlock->running_shared == 0) {
-
- // Wake any single thread pending exclusive
-
- rc = ssx_semaphore_info_get(&(sxlock->exclusive_sem),
- 0, &pending_exclusive);
- if (rc) break;
-
- if (pending_exclusive != 0) {
-
- sxlock->running_exclusive = 1;
- rc = ssx_semaphore_post(&(sxlock->exclusive_sem));
- if (rc) break;
- }
- }
-
- } while(0);
-
- ssx_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-/// Lock a SharedExclusiveLock for exclusive access
-///
-/// \param sxlock A pointer to the SharedExclusiveLock object to lock
-///
-/// \param timeout The maximum amount of time to wait for access, or the
-/// constant SSX_WAIT_FOREVER to wait forever.
-///
-/// Acquire a SharedExclusiveLock for exclusive access, potentially blocking
-/// forever or until a specified timeout if access is not immediately
-/// granted. Access will be blocked as long as one or more threads control
-/// shared acesss to the resource, however once the thread requests exclusive
-/// access all new shared access requests will block. Once the access is
-/// granted, the thread maintains exclusive access to the resource until a
-/// subsequent call of sxlock_unlock_exclusive().
-///
-/// Return values other than SSX_OK (0) are not necessarily errors; see \ref
-/// ssx_errors
-///
-/// The following return codes are non-error codes:
-///
-/// \retval 0 Successful completion
-///
-/// \retval -SXLOCK_TIMED_OUT Exclusive access was not acquired before the
-/// timeout expired.
-///
-/// The following return codes are error codes:
-///
-/// \retval -SXLOCK_INVALID_OBJECT The \a sxlock parameter was NULL (0) or
-/// otherwise invalid.
-///
-/// \retval -SSX_ILLEGAL_CONTEXT The API was called from a critical
-/// interrupt context.
-///
-/// \retval -SSX_SEMAPHORE_PEND_WOULD_BLOCK The call was made from an
-/// interrupt context (or before threads have been started), exclusive access
-/// was not immediately available and a non-zero timeout was specified.
-///
-/// \retval others This API may also return codes from SSX semaphore APIs,
-/// which shoudl be considered as non-recoverable errors.
-
-
-int
-sxlock_lock_exclusive(SharedExclusiveLock* sxlock, SsxInterval timeout)
-{
- SsxMachineContext ctx;
- int rc, pending_exclusive, pending_shared;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF(sxlock == 0, SXLOCK_INVALID_OBJECT);
- }
-
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- rc = 0;
- do {
-
- if ((sxlock->running_shared == 0) &&
- (sxlock->running_exclusive == 0)) {
-
- // If no other thread has acquired the lock, this thread gets
- // immediate access.
-
- sxlock->running_exclusive = 1;
-
- } else {
-
- // Some other thread has acquired the lock. This thread must pend
- // exclusive. In this case the sxlock->running_exclusive must be
- // set by the *_unlock() operation that unblocks the thread.
-
- rc = ssx_semaphore_pend(&(sxlock->exclusive_sem), timeout);
- if (rc == -SSX_SEMAPHORE_PEND_TIMED_OUT) {
-
- // This exclusive request timed out. Since the request may
- // have blocked shared requests, then if this is the only
- // exclusive request or thread we need to unblock any pending
- // shared requests.
-
- if (sxlock->running_exclusive == 0) {
-
- rc = ssx_semaphore_info_get(&(sxlock->exclusive_sem),
- 0, &pending_exclusive);
- if (rc) break;
-
- if (pending_exclusive == 0) {
-
- rc = ssx_semaphore_info_get(&(sxlock->shared_sem),
- 0, &pending_shared);
- if (rc) break;
-
- if (pending_shared != 0) {
-
- sxlock->running_shared += pending_shared;
- rc = ssx_semaphore_release_all(&(sxlock->shared_sem));
- if (rc) break;
- }
- }
- }
-
- rc = -SXLOCK_TIMED_OUT;
- }
- }
-
- } while (0);
-
- ssx_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-/// Release a SharedExclusiveLock from exclusive access
-///
-/// \param sxlock A pointer to the SharedExclusiveLock object to unlock
-///
-/// Release a SharedExclusiveLock from exclusive access, signalling that the
-/// thread no longer requires or expects exclusive access to the resource. It
-/// is an error for a thread to use this API if it has not previously locked
-/// exclusive access by a call of sxlock_lock_exclusive() (or the thread is
-/// unlocking a lock initialized in the exclusive-locked state).
-///
-/// Return values other than SSX_OK (0) are errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -SSX_ILLEGAL_CONTEXT The API was called from a critical interrupt
-/// context.
-///
-/// \retval -SXLOCK_INVALID_OBJECT The \a sxlock parameter was NULL (0) or
-/// otherwise invalid.
-///
-/// \retval -SXLOCK_EXCLUSIVE_UNDERFLOW There was apparently no matched call of
-/// sxlock_lock_exclusive() prior to this call.
-///
-/// \retval others This API may also return codes from SSX semaphore APIs,
-/// which should be considered as non-recoverable errors.
-
-int
-sxlock_unlock_exclusive(SharedExclusiveLock* sxlock)
-{
- SsxMachineContext ctx;
- int rc, pending_exclusive, pending_shared;
-
- if (SSX_ERROR_CHECK_API) {
- SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
- SSX_ERROR_IF(sxlock == 0, SXLOCK_INVALID_OBJECT);
- SSX_ERROR_IF(sxlock->running_exclusive != 1, SXLOCK_SHARED_UNDERFLOW);
- }
-
- if (SSX_ERROR_CHECK_KERNEL) {
- SSX_PANIC_IF(sxlock->running_shared != 0,
- SXLOCK_SHARED_EXCLUSIVE_INVARIANT);
- }
-
- rc = 0;
- ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
-
- do {
-
- rc = ssx_semaphore_info_get(&(sxlock->exclusive_sem),
- 0, &pending_exclusive);
- if (rc) break;
-
- if (pending_exclusive != 0) {
-
- // If there are other threads pending exclusive, make the
- // highest-priority one of them
- // runnable. sxlock->running_exclusive remains equal to 1.
-
- rc = ssx_semaphore_post(&(sxlock->exclusive_sem));
- if (rc) break;
-
- } else {
-
- // Otherwise unblock any/all threads pending shared
-
- sxlock->running_exclusive = 0;
-
- rc = ssx_semaphore_info_get(&(sxlock->shared_sem),
- 0, &pending_shared);
- if (rc) break;
-
- if (pending_shared != 0) {
-
- sxlock->running_shared = pending_shared;
- rc = ssx_semaphore_release_all(&(sxlock->shared_sem));
- if (rc) break;
- }
- }
- } while (0);
-
- ssx_critical_section_exit(&ctx);
-
- return rc;
-}
diff --git a/src/lib/ppc405lib/sxlock.h b/src/lib/ppc405lib/sxlock.h
deleted file mode 100644
index e0fa196..0000000
--- a/src/lib/ppc405lib/sxlock.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/lib/ppc405lib/sxlock.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] 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 __SXLOCK_H__
-#define __SXLOCK_H__
-
-// $Id$
-
-/// \file sxlock.h
-/// \brief The implementation of a SharedExclusiveLock
-///
-/// The SharedExclusiveLock is documented in the comments for the file
-/// sxlock.c
-
-// Error/panic codes
-
-#define SXLOCK_INVALID_OBJECT 0x00795501
-#define SXLOCK_INVALID_ARGUMENT 0x00795502
-#define SXLOCK_TIMED_OUT 0x00795503
-#define SXLOCK_SHARED_UNDERFLOW 0x00795504
-#define SXLOCK_EXCLUSIVE_UNDERFLOW 0x00795505
-#define SXLOCK_SHARED_EXCLUSIVE_INVARIANT 0x00795506
-
-/// A shared-exclusive lock object (also called a readers-write lock)
-///
-/// This facility is documented in the file sxlock.c
-
-typedef struct {
-
- /// A semaphore for threads requesting shared access
- SsxSemaphore shared_sem;
-
- /// A semaphore for threads requesting exclusive access
- SsxSemaphore exclusive_sem;
-
- /// The number of threads running shared
- SsxSemaphoreCount running_shared;
-
- /// The number of threads running exclusive
- SsxSemaphoreCount running_exclusive;
-
-} SharedExclusiveLock;
-
-
-/// Static initialization of a shared-exclusive lock object
-///
-/// \param[in] shared The number of threads running shared at static
-/// initialization
-///
-/// \param[in] exclusive The number of threads running exclusive at static
-/// initialization.
-///
-/// Note that it is an error to specify both \a shared and \a exclusive as
-/// non-0.
-
-#define SXLOCK_INITIALIZATION(shared, exclusive) \
- { \
- SSX_SEMAPHORE_INITIALIZATION(0, 0), \
- SSX_SEMAPHORE_INITIALIZATION(0, 0), \
- (shared), (exclusive) \
- }
-
-/// Declare and initialize a shared-exclusive lock
-
-#define SXLOCK(sxlock, shared, exclusive) \
- SharedExclusiveLock sxlock = SXLOCK_INITIALIZATION(shared, exclusive)
-
-
-
-int
-sxlock_create(SharedExclusiveLock* sxlock,
- SsxSemaphoreCount shared,
- SsxSemaphoreCount exclusive);
-
-int
-sxlock_lock_shared(SharedExclusiveLock* sxlock, SsxInterval timeout);
-
-int
-sxlock_unlock_shared(SharedExclusiveLock* sxlock);
-
-int
-sxlock_lock_exclusive(SharedExclusiveLock* sxlock, SsxInterval timeout);
-
-int
-sxlock_unlock_exclusive(SharedExclusiveLock* sxlock);
-
-#endif // __SXLOCK_H__
OpenPOWER on IntegriCloud