summaryrefslogtreecommitdiffstats
path: root/pk/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'pk/kernel')
-rw-r--r--pk/kernel/.empty0
-rw-r--r--pk/kernel/Makefile26
-rw-r--r--pk/kernel/pk.h125
-rw-r--r--pk/kernel/pk_api.h1016
-rw-r--r--pk/kernel/pk_bh_core.c29
-rw-r--r--pk/kernel/pk_core.c79
-rw-r--r--pk/kernel/pk_debug_ptrs.c53
-rw-r--r--pk/kernel/pk_debug_ptrs.h39
-rw-r--r--pk/kernel/pk_init.c196
-rw-r--r--pk/kernel/pk_kernel.h246
-rw-r--r--pk/kernel/pk_macros.h110
-rw-r--r--pk/kernel/pk_semaphore_core.c318
-rw-r--r--pk/kernel/pk_semaphore_init.c82
-rw-r--r--pk/kernel/pk_stack_init.c85
-rw-r--r--pk/kernel/pk_thread.h56
-rw-r--r--pk/kernel/pk_thread_core.c573
-rw-r--r--pk/kernel/pk_thread_init.c134
-rw-r--r--pk/kernel/pk_thread_util.c291
-rw-r--r--pk/kernel/pk_timer_core.c401
-rw-r--r--pk/kernel/pk_timer_init.c62
-rw-r--r--pk/kernel/pkkernelfiles.mk32
21 files changed, 0 insertions, 3953 deletions
diff --git a/pk/kernel/.empty b/pk/kernel/.empty
deleted file mode 100644
index e69de29b..00000000
--- a/pk/kernel/.empty
+++ /dev/null
diff --git a/pk/kernel/Makefile b/pk/kernel/Makefile
deleted file mode 100644
index 3fad153e..00000000
--- a/pk/kernel/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# This Makefile is designed to be invoked with the -I argument set to
-# the location of the "pk.mk" for the build
-
-include img_defs.mk
-include pkkernelfiles.mk
-
-ifeq "$(PK_TIMER_SUPPORT)" "1"
-PK_OBJECTS += ${PK-TIMER-C-SOURCES:.c=.o}
-endif
-
-ifeq "$(PK_THREAD_SUPPORT)" "1"
-PK_OBJECTS += ${PK-THREAD-C-SOURCES:.c=.o}
-endif
-
-OBJS := $(addprefix $(OBJDIR)/, $(PK_OBJECTS))
-
-all: $(OBJS)
-
-$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
-
-$(OBJDIR):
- mkdir -p $(OBJDIR)
-
-ifneq ($(MAKECMDGOALS),clean)
-include $(OBJS:.o=.d)
-endif
diff --git a/pk/kernel/pk.h b/pk/kernel/pk.h
deleted file mode 100644
index 2efcdf11..00000000
--- a/pk/kernel/pk.h
+++ /dev/null
@@ -1,125 +0,0 @@
-#ifndef __PK_H__
-#define __PK_H__
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk.h
-/// \brief The combined header of the PK kernel.
-///
-/// This header will be included in any C or assembler source file that
-/// requires any of the PK API. All headers defined by PK and co-compiled
-/// code should be protected such that they can be included without error into
-/// assembly.
-
-#ifndef __ASSEMBLER__
-#include <stdint.h>
-#include <stddef.h>
-#endif /* __ASSEMBLER__ */
-
-#ifndef __PK__
-#define __PK__ 1
-#endif
-
-/// The application environment specifies whether or not it will provide an
-/// application configuration file, which must be named "pk_app_cfg.h".
-
-#ifndef USE_PK_APP_CFG_H
-#define USE_PK_APP_CFG_H 0
-#endif
-
-#if USE_PK_APP_CFG_H
-#include "pk_app_cfg.h"
-#endif
-
-#include "pk_macros.h"
-#include "pk_api.h"
-#include "pk_port.h"
-#include "pk_kernel.h"
-//#include "pk_io.h"
-
-#ifndef __ASSEMBLER__
-
-#define MIN(X, Y) \
- ({ \
- typeof (X) __x = (X); \
- typeof (Y) __y = (Y); \
- (__x < __y) ? __x : __y; })
-
-#define MAX(X, Y) \
- ({ \
- typeof (X) __x = (X); \
- typeof (Y) __y = (Y); \
- (__x > __y) ? __x : __y; \
- })
-
-/// \todo These don't require 32/64 bit versions, can always promote 32->64.
-
-#define FLOOR_LOG2_32(x) (32 - 1 - cntlz32(x))
-#define FLOOR_LOG2_64(x) (64 - 1 - cntlz64(x))
-
-#define CEILING_LOG2(x) \
- ({ \
- uint64_t __x = (uint64_t)(x); \
- int __y; \
- __y = FLOOR_LOG2_64(__x); \
- if ((__x & (__x - 1)) != 0) { \
- __y++; \
- } \
- __y;})
-
-
-#define POW2_32(x) ((uint32_t)1 << (x))
-#define POW2_64(x) ((uint64_t)1 << (x))
-
-/// Cast a pointer to another type
-///
-/// This macro is necessary when casting a pointer to a longer integer type.
-/// The pointer is first cast to the equivalent integer type 'unsigned long',
-/// then cast to the final type. You can also use this to cast integers longer
-/// than pointers back to pointers.
-
-#define CAST_POINTER(t, p) ((t)((unsigned long)(p)))
-
-
-/// Create an alignment attribute.
-#define ALIGNED_ATTRIBUTE(alignment) __attribute__ ((aligned (alignment)))
-
-/// Create a specific-section attribute
-///
-/// Note that the section \a s here must be a string. Also note that data
-/// specified to reside in specific sections must always be
-/// initialized. Otherwise it confuses the linker which wants to put
-/// uninitialized data into .bss sections.
-///
-/// \code
-///
-/// int foo SECTION_ATTRIBUTE(".noncacheable") = 0;
-/// int bar[10] SECTION_ATTRIBUTE(".noncacheable") = {0};
-///
-/// \endcode
-#define SECTION_ATTRIBUTE(s) __attribute__ ((section (s)))
-
-/// Create a 'used' attribute
-///
-/// This is required for example to avoid "function unused" warnings when a
-/// function is declared static but only referenced by inline assembler:
-///
-/// \code
-///
-/// static USED_ATTRIBUTE void
-/// _checkstop(void* arg, PkIrqId irq, int priority)
-/// {
-/// PK_PANIC(VALIDATION_CHECKSTOP);
-/// }
-///
-/// PK_IRQ_FAST2FULL(_validationCheckstopHandler, _checkstop);
-///
-/// \endcode
-#define USED_ATTRIBUTE __attribute__ ((used))
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* __PK_H__ */
diff --git a/pk/kernel/pk_api.h b/pk/kernel/pk_api.h
deleted file mode 100644
index 66ed1324..00000000
--- a/pk/kernel/pk_api.h
+++ /dev/null
@@ -1,1016 +0,0 @@
-#ifndef __PK_API_H__
-#define __PK_API_H__
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_api.h
-/// \brief Macros and declarations for the PK API.
-
-// Basic constants
-
-/// Although the number of threads is defined as a manifest constant,
-/// numerous parts of the PK code assume this definition. The number of
-/// supported threads _can not_ be changed simply by changing this constant.
-
-#define PK_THREADS 32
-
-#define PK_IDLE_THREAD_PRIORITY PK_THREADS
-
-// Interrupt API
-
-#define PK_IRQ_POLARITY_ACTIVE_LOW 0
-#define PK_IRQ_POLARITY_ACTIVE_HIGH 1
-
-#define PK_IRQ_TRIGGER_LEVEL_SENSITIVE 0
-#define PK_IRQ_TRIGGER_EDGE_SENSITIVE 1
-
-// API return codes
-
-#define PK_OK 0
-#define PK_ILLEGAL_CONTEXT_THREAD_CONTEXT 0x00779002
-#define PK_ILLEGAL_CONTEXT_INTERRUPT_CONTEXT 0x00779003
-#define PK_ILLEGAL_CONTEXT_THREAD 0x00779004
-#define PK_ILLEGAL_CONTEXT_TIMER 0x00779005
-#define PK_INVALID_THREAD_AT_RESUME1 0x00779007
-#define PK_INVALID_THREAD_AT_RESUME2 0x00779008
-#define PK_INVALID_THREAD_AT_SUSPEND1 0x00779009
-#define PK_INVALID_THREAD_AT_SUSPEND2 0x0077900a
-#define PK_INVALID_THREAD_AT_DELETE 0x0077900b
-#define PK_INVALID_THREAD_AT_INFO 0x0077900c
-#define PK_INVALID_THREAD_AT_CHANGE 0x0077900d
-#define PK_INVALID_THREAD_AT_SWAP1 0x0077900e
-#define PK_INVALID_THREAD_AT_SWAP2 0x0077900f
-#define PK_INVALID_THREAD_AT_CREATE 0x00779010
-#define PK_INVALID_SEMAPHORE_AT_POST 0x00779011
-#define PK_INVALID_SEMAPHORE_AT_PEND 0x00779012
-#define PK_INVALID_SEMAPHORE_AT_RELEASE 0x00779013
-#define PK_INVALID_SEMAPHORE_AT_INFO 0x00779014
-#define PK_INVALID_SEMAPHORE_AT_CREATE 0x00779015
-#define PK_INVALID_TIMER_AT_SCHEDULE 0x00779016
-#define PK_INVALID_TIMER_AT_CANCEL 0x00779017
-#define PK_INVALID_TIMER_AT_INFO 0x00779018
-#define PK_INVALID_TIMER_AT_CREATE 0x00779019
-#define PK_INVALID_ARGUMENT_IRQ_SETUP 0x0077901a
-#define PK_INVALID_ARGUMENT_IRQ_HANDLER 0x0077901b
-#define PK_INVALID_ARGUMENT_INTERRUPT 0x00779024
-#define PK_INVALID_ARGUMENT_CONTEXT_SET 0x00779025
-#define PK_INVALID_ARGUMENT_CONTEXT_GET 0x00779026
-#define PK_INVALID_ARGUMENT_FIT 0x00779027
-#define PK_INVALID_ARGUMENT_WATCHDOG 0x00779028
-#define PK_INVALID_ARGUMENT_INIT 0x00779029
-#define PK_INVALID_ARGUMENT_SEMAPHORE 0x0077902a
-#define PK_INVALID_ARGUMENT_THREAD_CHANGE 0x0077902b
-#define PK_INVALID_ARGUMENT_THREAD_PRIORITY 0x0077902c
-#define PK_INVALID_ARGUMENT_THREAD1 0x0077902d
-#define PK_INVALID_ARGUMENT_THREAD2 0x0077902e
-#define PK_INVALID_ARGUMENT_THREAD3 0x0077902f
-#define PK_STACK_OVERFLOW 0x00779030
-#define PK_TIMER_ACTIVE 0x00779031
-#define PK_TIMER_NOT_ACTIVE 0x00779032
-#define PK_PRIORITY_IN_USE_AT_RESUME 0x00779033
-#define PK_PRIORITY_IN_USE_AT_CHANGE 0x00779034
-#define PK_PRIORITY_IN_USE_AT_SWAP 0x00779035
-#define PK_SEMAPHORE_OVERFLOW 0x00779036
-#define PK_SEMAPHORE_PEND_NO_WAIT 0x00779037
-#define PK_SEMAPHORE_PEND_TIMED_OUT 0x00779038
-#define PK_SEMAPHORE_PEND_WOULD_BLOCK 0x00779039
-#define PK_INVALID_DEQUE_SENTINEL 0x0077903a
-#define PK_INVALID_DEQUE_ELEMENT 0x0077903b
-#define PK_INVALID_OBJECT 0x0077903c
-
-// Kernel panics
-
-#define PK_NO_TIMER_SUPPORT 0x0077903d
-#define PK_START_THREADS_RETURNED 0x0077903e
-#define PK_UNIMPLEMENTED 0x0077903f
-#define PK_SCHEDULING_INVARIANT 0x00779040
-#define PK_TIMER_HANDLER_INVARIANT 0x00779041
-#define PK_THREAD_TIMEOUT_STATE 0x00779045
-
-// Application-level panic offsets
-// (Use these as offsets for your application code panics and keep
-// track of them locally in your application code domain, including
-// sharing the panic defines with other developers making codes
-// for the same engine.)
-
-#define PK_APP_OFFSET_SBE 0x0077a000
-#define PK_APP_OFFSET_GPE0 0x0077b000
-#define PK_APP_OFFSET_GPE1 0x0077c000
-#define PK_APP_OFFSET_GPE2 0x0077d000
-#define PK_APP_OFFSET_GPE3 0x0077e000
-#define PK_APP_OFFSET_CME 0x0077f000
-
-/// \defgroup pk_thread_states PK Thread States
-///
-/// Threads are created in the state PK_THREAD_STATE_SUSPENDED_RUNNABLE.
-/// When the thread is mapped it transitions to state PK_THREAD_STATE_MAPPED.
-/// A mapped thread is runnable if it appears in the run queue; there is no
-/// other flag or status to indicate a runnable thread. If a blocked thread
-/// is suspended it goes into state PK_THREAD_STATE_SUSPENDED_BLOCKED. For
-/// all threads the reason for blockage is detailed in the \a flags field of
-/// the thread; See \ref pk_thread_flags. PK_THREAD_STATE_DELETED and
-/// PK_THREAD_STATE_COMPLETED are effectively equivalent but named
-/// individually for reporting purposes.
-///
-/// \note This separation of the thread \a state and \a flags allows the use
-/// of an PK semaphore as a thread barrier, as it supports a non-iterative
-/// implementation of pk_semaphore_release_all() in which all threads blocked
-/// on the semaphore are simultaneously inserted into the run queue with an
-/// atomic operation, followed by each individual thread readjusting its flags
-/// appropriately once the thread runs again.
-///
-/// @{
-
-#define PK_THREAD_STATE_SUSPENDED_RUNNABLE 1
-#define PK_THREAD_STATE_MAPPED 2
-#define PK_THREAD_STATE_SUSPENDED_BLOCKED 3
-#define PK_THREAD_STATE_COMPLETED 4
-#define PK_THREAD_STATE_DELETED 5
-
-/// @}
-
-
-/// \defgroup pk_thread_flags PK Thread Flags
-///
-/// The \a flag field of the thread extends the information contained in the
-/// \a state field; See \ref pk_thread_states. Blocked threads will show
-/// PK_THREAD_FLAG_SEMAPHORE_PEND, PK_THREAD_FLAG_TIMER_PEND or both (if
-/// blocked on a semaphore with timeout). The flag PK_THREAD_FLAG_TIMED_OUT
-/// indicates that a thread timer timed out before the thread became
-/// runnable. Currently only the semaphore-pend-with-timeout code uses this
-/// flag.
-///
-/// Note that a thread can be mapped and runnable (in the run queue) even
-/// though PK_THREAD_FLAG_SEMAPHORE_PEND and/or PK_THREAD_FLAG_TIMER_PEND
-/// are set. These flags are always cleared by the thread itself, not the code
-/// that unblocks the thread. This allows the implementation of the
-/// pk_semaphore_release_all() as explained in \ref pk_thread_states.
-///
-/// @{
-
-#define PK_THREAD_FLAG_SEMAPHORE_PEND 0x1
-#define PK_THREAD_FLAG_TIMER_PEND 0x2
-#define PK_THREAD_FLAG_TIMED_OUT 0x4
-
-/// @}
-
-
-// Critical Sections
-
-/// Enter a critical section, saving the current machine
-/// context.
-
-#define pk_critical_section_enter(pctx) \
- pk_interrupt_disable(pctx)
-
-/// Exit a critical section by restoring the previous machine context.
-
-#define pk_critical_section_exit(pctx) \
- pk_machine_context_set(pctx)
-
-
-/// Execute a statement atomically
-
-#define PK_ATOMIC(stmt) \
- do { \
- PkMachineContext __ctx; \
- pk_critical_section_enter(&__ctx); \
- stmt; \
- pk_critical_section_exit(&__ctx); \
- } while (0)
-
-
-// Application-overrideable definitions
-
-/// Control whether or not the API functions check for errors.
-///
-/// This definition can be overriden by the application.
-
-#ifndef PK_ERROR_CHECK_API
-#define PK_ERROR_CHECK_API 1
-#endif
-
-/// Control whether API errors cause kernel panics or return negative error
-/// codes.
-///
-/// This selection is only valid if \c PK_ERROR_CHECK_API is defined
-/// non-0. This definition can be overriden by the application.
-
-#ifndef PK_ERROR_PANIC
-#define PK_ERROR_PANIC 1
-#endif
-
-/// Control whether or not the PK kernel checks key invariants.
-///
-/// Violations of kernel invariants always cause kernel panics. This
-/// definition can be overriden by the application.
-
-#ifndef PK_ERROR_CHECK_KERNEL
-#define PK_ERROR_CHECK_KERNEL 1
-#endif
-
-/// Define the time interval type, which must be an unsigned type of a size
-/// less then or equal to the size of \c PkTimebase. This definition can be
-/// overridden by the application.
-
-#ifndef PK_TIME_INTERVAL_TYPE
-#define PK_TIME_INTERVAL_TYPE uint32_t
-#endif
-
-/// Provide support for the PkTimer APIs in addition to the default
-/// initerrupt APIs. This definition can be overridden by the application.
-
-#ifndef PK_TIMER_SUPPORT
-#define PK_TIMER_SUPPORT 1
-#endif
-
-/// Provide support for the all PK APIs. Thread support requires/implies
-/// support for time services and semaphores. This definition can be
-/// overridden by the application.
-
-#ifndef PK_THREAD_SUPPORT
-#define PK_THREAD_SUPPORT 1
-#endif
-
-/// Control the level of stack checking.
-///
-/// This definition can be overriden by the application.
-///
-/// 0 : No stack prepatterning or checking is made for thread and kernel
-/// stacks.
-///
-/// 1 : Kernel interrupt stacks are prepatterned during
-/// \c pk_initialize(). Thread stacks are prepatterned during
-/// \c pk_thread_create().
-///
-/// 2 : (\b Default - Currently Unimplemented) In addition to prepatterning,
-/// stack utilization is computed at the exit of context switches and
-/// interrupt processing. The maximum utilization is stored in
-/// the thread data structure. The kernel will panic if stack overflow is
-/// detected. Stack utilization is not computed for the idle thread.
-
-#ifndef PK_STACK_CHECK
-#define PK_STACK_CHECK 1
-#endif
-
-/// A hook for main()
-///
-/// This hook macro is expanded in the body of __pk_main() prior to the call
-/// of the application main(). The application can redefine this hook macro
-/// in (or in headers referred to in) the application header
-/// pk_app_cfg.h. The PK_MAIN_HOOK will run on the stack of main().
-
-#ifndef PK_MAIN_HOOK
-#define PK_MAIN_HOOK do {} while (0)
-#endif
-
-/// A hook for pk_start_threads()
-///
-/// This hook macro is expanded in the call-tree of pk_start_threads() before
-/// threads are actually started. The application can redefine this hook
-/// macro in (or in headers referred to in) the application header
-/// pk_app_cfg.h.
-///
-/// The PK_START_THREADS_HOOK runs as a pseudo-interrupt handler on the
-/// kernel stack, with external interrupts disabled.
-
-#ifndef PK_START_THREADS_HOOK
-#define PK_START_THREADS_HOOK do {} while (0)
-#endif
-
-/// The maximum value of the \c PkTimebase type.
-
-#define PK_TIMEBASE_MAX ((PkTimebase)-1)
-
-/// A special value that specifies that the timebase will not be reset during
-/// pk_init().
-
-#define PK_TIMEBASE_CONTINUES PK_TIMEBASE_MAX
-
-/// By convention, a timeout value indicating 'no waiting' in a call of \c
-/// pk_semaphore_pend().
-
-#define PK_NO_WAIT 0
-
-/// By convention, a timeout value indicating 'wait forever' in a call of \c
-/// pk_semaphore_pend().
-
-#define PK_WAIT_FOREVER ((PkInterval)-1)
-
-/// The PK timebase frequency in Hz
-///
-/// Earlier version of PK defined the timbase frequency as a preprocessor
-/// macro. Now, the timebase frequency is specified as a parameter of the
-/// pk_initialize() API. The macro remains defined for backwards
-/// compatibility, however all kernel uses of the timebase frequency are now
-/// optimized around the timebase parameter.
-
-#define PK_TIMEBASE_FREQUENCY_HZ __pk_timebase_frequency_hz
-
-/// This is the unscaled timebase frequency in Hz.
-#ifdef APPCFG_USE_EXT_TIMEBASE
-#define PK_BASE_FREQ_HZ (uint32_t)25000000
-#else
-#define PK_BASE_FREQ_HZ (uint32_t)400000000
-#endif /* APPCFG_USE_EXT_TIMEBASE */
-#define PK_BASE_FREQ_KHZ (PK_BASE_FREQ_HZ / 1000)
-#define PK_BASE_FREQ_MHZ (PK_BASE_FREQ_HZ / 1000000)
-
-/// Scale a time interval to be _closer_ to what was actually requested
-/// base on the actual timebase frequency.
-#define PK_INTERVAL_SCALE(interval) ((interval) + ((interval) >> __pk_timebase_rshift))
-
-/// Convert a time in integral seconds to a time interval - overflows are
-/// ignored. The application can redefine this macro.
-
-#ifndef PK_SECONDS
-#define PK_SECONDS(s) ((PkInterval)(PK_BASE_FREQ_HZ * (s)))
-#endif
-
-/// Convert a time in integral milliseconds to a time interval - overflows are
-/// ignored, and a frequency evenly (or closely) divisible by 1000 is
-/// assumed. The application can redefine this macro.
-
-#ifndef PK_MILLISECONDS
-#define PK_MILLISECONDS(m) ( (PkInterval)(PK_BASE_FREQ_KHZ * (m)) )
-#endif
-
-/// Convert a time in integral microseconds to a time interval - overflows are
-/// ignored, and a frequncy evenly (or closely) divisible by 1,000,000 is
-/// assumed. The application can redefine this macro.
-
-#ifndef PK_MICROSECONDS
-#define PK_MICROSECONDS(u) ( (PkInterval)(PK_BASE_FREQ_MHZ * (u)) )
-#endif
-
-/// Convert a time in integral nanoseconds to a time interval - overflows are
-/// ignored, and a frequeyncy evenly (or closely) divisible by 1,000,000 is
-/// assumed. The application can redefine this macro.
-
-#ifndef PK_NANOSECONDS
-#define PK_NANOSECONDS(n) ( (PkInterval)( ( ((PK_BASE_FREQ_MHZ<<10)/1000) * (n) ) >> 10) )
-#endif
-
-
-/// Enable PK application tracing (enabled by default)
-#ifndef PK_TRACE_ENABLE
-#define PK_TRACE_ENABLE 1
-#endif
-
-/// Enable PK kernel tracing (disabled by default)
-#ifndef PK_KERNEL_TRACE_ENABLE
-#define PK_KERNEL_TRACE_ENABLE 0
-#endif
-
-//Application trace macros
-#if !PK_TRACE_ENABLE
-#define PK_TRACE(...)
-#define PK_TRACE_BIN(str, bufp, buf_size)
-#else
-#define PK_TRACE(...) PKTRACE(__VA_ARGS__)
-#define PK_TRACE_BIN(str, bufp, buf_size) PKTRACE_BIN(str, bufp, buf_size)
-#endif
-
-
-//Kernel trace macros
-#if !PK_KERNEL_TRACE_ENABLE
-#define PK_KERN_TRACE(...)
-#define PK_KERN_TRACE_ASM16(...)
-#else
-#define PK_KERN_TRACE(...) PK_TRACE(__VA_ARGS__)
-#define PK_KERN_TRACE_ASM16(...) PK_TRACE_ASM16(__VA_ARGS__)
-#endif /* PK_KERNEL_TRACE_ENABLE */
-
-
-/// Add a string to the trace buffer with an optional register holding a 16bit value
-/// WARNING: This calls a c function which may clobber any of the volatile registers
-#if (PK_TRACE_SUPPORT && PK_TIMER_SUPPORT)
-#define PK_TRACE_ASM16(...) TRACE_ASM_HELPER16(VARG_COUNT(__VA_ARGS__), __VA_ARGS__)
-#else
-#define PK_TRACE_ASM16(...)
-#endif /* PK_TRACE_SUPPORT */
-
-/// The following macros are helper macros for tracing. They should not be called
-/// directly.
-#define VARG_COUNT_HELPER(_0, _1, _2, _3, _4, _5, _6, _7, N, ...) N
-#define VARG_COUNT(...) VARG_COUNT_HELPER(, ##__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
-
-#ifdef __ASSEMBLER__
-#define TRACE_ASM_HELPER16_CALL(count, ...) TINY_TRACE_ASM ## count (__VA_ARGS__)
-#define TRACE_ASM_HELPER16(count, ...) TRACE_ASM_HELPER16_CALL(count, __VA_ARGS__)
-
-#define TINY_TRACE_ASM0() .error "format string required"
-#define TINY_TRACE_ASM1(str) \
- .tiny_trace_asm1 trace_ppe_hash(str, PK_TRACE_HASH_PREFIX)
-#define TINY_TRACE_ASM2(str, reg) \
- .tiny_trace_asm2 trace_ppe_hash(str, PK_TRACE_HASH_PREFIX), reg
-#define TINY_TRACE_ASM3() .error "too many parameters"
-#define TINY_TRACE_ASM4() .error "too many parameters"
-#define TINY_TRACE_ASM5() .error "too many parameters"
-#define TINY_TRACE_ASM6() .error "too many parameters"
-#define TINY_TRACE_ASM7() .error "too many parameters"
-
-//TODO: add support for tracing more than 1 parameter and binary data in assembly
-
- .global pk_trace_tiny
-
- .macro .tiny_trace_asm1 hash16
- lis %r3, \hash16
- bl pk_trace_tiny
- .endm
-
- .macro .tiny_trace_asm2 hash16, parm16
- clrlwi %r3, \parm16, 16
- oris %r3, %r3, \hash16
- bl pk_trace_tiny
- .endm
-
-#endif /*__ASSEMBLER__*/
-
-
-
-#ifndef __ASSEMBLER__
-
-#include <stddef.h>
-#include <stdint.h>
-
-/// The timebase frequency in Hz; A parameter to pk_initialize()
-extern uint32_t __pk_timebase_frequency_hz;
-
-extern uint8_t __pk_timebase_rshift;
-
-/// The timebase frequency in KHz
-extern uint32_t __pk_timebase_frequency_khz;
-
-/// The timebase frequency in Mhz
-extern uint32_t __pk_timebase_frequency_mhz;
-
-
-typedef unsigned long int PkAddress;
-
-typedef uint8_t PkThreadState;
-
-typedef uint8_t PkThreadPriority;
-
-typedef uint8_t PkThreadFlags;
-
-typedef uint32_t PkSemaphoreCount;
-
-typedef uint64_t PkTimebase;
-
-typedef PK_TIME_INTERVAL_TYPE PkInterval;
-
-#include "pk_port_types.h"
-
-typedef struct {
-
- /// A priority queue of threads pending on the semaphore.
- PkThreadQueue pending_threads;
-
- /// The current semaphore count.
- PkSemaphoreCount count;
-
- /// The maximum allowable count - for error checking.
- PkSemaphoreCount max_count;
-
-} PkSemaphore;
-
-
-/// Compile-time initialize a PkSemaphore structure
-///
-/// This low-level macro creates a structure initializatin of an PkSemaphore
-/// structure. This can be used for example to create compile-time initialized
-/// arrays of semaphores.
-#define PK_SEMAPHORE_INITIALIZATION(_initial_count, _max_count) \
- {.pending_threads = 0, \
- .count = (_initial_count), \
- .max_count = (_max_count)}
-
-
-/// Declare and initialize a semaphore
-#define PK_SEMAPHORE(sem, initial_count, max_count) \
- PkSemaphore sem = PK_SEMAPHORE_INITIALIZATION(initial_count, max_count)
-
-
-/// Trace macros for C functions
-#define HASH_ARG_COMBO(str, arg) \
- ((((uint32_t)trace_ppe_hash(str, PK_TRACE_HASH_PREFIX)) << 16) | ((uint32_t)(arg) & 0x0000ffff))
-
-#define PKTRACE0(...) pk_trace_tiny() //will fail at compile time
-
-#define PKTRACE1(str) \
- pk_trace_tiny((trace_ppe_hash(str, PK_TRACE_HASH_PREFIX) << 16))
-
-#define PKTRACE2(str, parm0) \
- ((sizeof(parm0) <= 2)? \
- pk_trace_tiny(HASH_ARG_COMBO(str, parm0)): \
- pk_trace_big(HASH_ARG_COMBO(str, 1), ((uint64_t)parm0) << 32, 0))
-
-#define PKTRACE3(str, parm0, parm1) \
- pk_trace_big(HASH_ARG_COMBO(str, 2), ((((uint64_t)parm0) << 32) | parm1), 0)
-
-#define PKTRACE4(str, parm0, parm1, parm2) \
- pk_trace_big(HASH_ARG_COMBO(str, 3), ((((uint64_t)parm0) << 32) | parm1),\
- ((uint64_t)parm2) << 32 )
-
-#define PKTRACE5(str, parm0, parm1, parm2, parm3) \
- pk_trace_big(HASH_ARG_COMBO(str, 4), ((((uint64_t)parm0) << 32) | parm1),\
- ((((uint64_t)parm2) << 32) | parm3) )
-
-#define PKTRACE6(...) pk_trace_tiny() //will fail at compile time
-#define PKTRACE7(...) pk_trace_tiny() //will fail at compile time
-
-#define PKTRACE_HELPER2(count, ...) PKTRACE ## count (__VA_ARGS__)
-#define PKTRACE_HELPER(count, ...) PKTRACE_HELPER2(count, __VA_ARGS__)
-
-#if (PK_TRACE_SUPPORT && PK_TIMER_SUPPORT)
-#define PKTRACE(...) PKTRACE_HELPER(VARG_COUNT(__VA_ARGS__), __VA_ARGS__)
-#define PKTRACE_BIN(str, bufp, buf_size) \
- pk_trace_binary(((buf_size < 255)? HASH_ARG_COMBO(str, buf_size): HASH_ARG_COMBO(str, 255)), bufp)
-#else
-#define PKTRACE(...)
-#define PKTRACE_BIN(str, bufp, buf_size)
-#endif //PK_TRACE_SUPPORT
-
-
-
-/// A generic doubly-linked list object
-///
-/// This object functions both as a sentinel mode for a deque as well as a
-/// pointer container for elements in deques. The PK API assumes that
-/// queueable structures will be defined with an PkDeque structure as the
-/// initial 'data member' of the structure. This allows a pointer to a queue
-/// element to be cast to a pointer to an PkDeque and vice-versa.
-
-typedef struct PkDeque {
-
- /// Pointer to the head or the next element in a deque.
- ///
- /// When an PkDeque is used as the sentinel node for a queue, \a next
- /// points to the head of the queue, and the condition (next == \<self\>)
- /// indicates an empty PkDeque. By convention the condition (\a next ==
- /// 0) is used to indicate that a queue element is not enqueued.
- struct PkDeque* next;
-
- /// Pointer to the tail or previous element in a deque.
- ///
- /// When a DQueue is used as the sentinel node for a queue, \a previous
- /// points to the tail of the queue.
- struct PkDeque* previous;
-
-} PkDeque;
-
-
-typedef void (*PkTimerCallback)(void *);
-
-#define PK_TIMER_CALLBACK(callback) void callback(void *)
-
-struct PkTimer;
-
-/// The PK timer object
-
-typedef struct PkTimer {
-
- /// The time queue management pointers
- ///
- /// This pointer container is defined as the first element of the
- /// structure to allow the PkTimer to be cast to an PkDeque and
- /// vice-versa.
- PkDeque deque;
-
- /// The absolute timeout of the timer.
- PkTimebase timeout;
-
- /// The timer callback
- ///
- /// For PK thread timers used to implement Sleep and semaphore pend
- /// timeouts this field is initialized to __pk_thread_timeout().
- PkTimerCallback callback;
-
- /// Private data passed to the callback.
- ///
- /// For PK thread timers used to implement Sleep and semaphore pend this
- /// field is initialized to a pointer to the thread.
- void *arg;
-
-} PkTimer;
-
-
-// Threads
-
-typedef void (*PkThreadRoutine)(void *arg);
-
-#define PK_THREAD_ROUTINE(f) void f(void *arg);
-
-typedef struct {
-
- /// Stack pointer saved during context switches. Assembler code expects
- /// this to always be at address offset 0 from the thread pointer.
- PkAddress saved_stack_pointer;
-
- /// This is 1 past the last valid byte address of the thread stack.
- /// Assembler code expects this to always be at address offset (sizeof
- /// PkAddress) from the thread pointer.
- PkAddress stack_limit;
-
- /// This is the original base of the stack.
- /// Assembler code expects this to always be at address offset 2 * (sizeof
- /// PkAddress) from the thread pointer.
- PkAddress stack_base;
-
- /// If the thread is blocked on a semaphore, then this is the semaphore the
- /// thread is blocked on.
- PkSemaphore *semaphore;
-
- /// The thread priority.
- PkThreadPriority priority;
-
- /// The thread state; See \ref pk_thread_states
- PkThreadState state;
-
- /// Thread flags; See \ref pk_thread_flags
- PkThreadFlags flags;
-
- /// The timer structure handles Sleep and blocking on a semaphore with
- /// timeout.
- PkTimer timer;
-
-} PkThread;
-
-
-typedef void (*PkBhHandler)(void *);
-
-#define PK_BH_HANDLER(handler) void handler(void *)
-
-typedef struct {
-
- /// The bottom half queue management pointers
- ///
- /// This pointer container is defined as the first element of the
- /// structure to allow the PkBottomHalf to be cast to a PkDeque and
- /// vice-versa.
- PkDeque deque;
-
- /// The bottom half handler
- PkBhHandler bh_handler;
-
- /// Private data passed to the handler.
- void *arg;
-
-} PkBottomHalf;
-
-
-// Initialization APIs
-
-int
-pk_initialize(PkAddress kernel_stack,
- size_t kernel_stack_size,
- PkTimebase initial_timebase,
- uint32_t timebase_frequency_hz);
-
-
-// Timebase APIs
-
-PkTimebase
-pk_timebase_get(void);
-
-
-// Timer APIs
-
-int
-pk_timer_create(PkTimer *timer,
- PkTimerCallback callback,
- void *arg);
-
-
-int
-pk_timer_schedule(PkTimer *timer,
- PkInterval interval);
-
-int
-pk_timer_cancel(PkTimer *timer);
-
-int
-pk_timer_info_get(PkTimer *timer,
- PkTimebase *timeout,
- int *active);
-
-// Thread APIs
-
-int
-pk_thread_create(PkThread *thread,
- PkThreadRoutine thread_routine,
- void *arg,
- PkAddress stack,
- size_t stack_size,
- PkThreadPriority priority);
-
-int
-pk_start_threads(void);
-
-int
-pk_thread_resume(PkThread *thread);
-
-int
-pk_thread_suspend(PkThread *thread);
-
-int
-pk_thread_delete(PkThread *thread);
-
-int
-pk_complete(void);
-
-int
-pk_sleep(PkInterval interval);
-
-int
-pk_thread_info_get(PkThread *thread,
- PkThreadState *state,
- PkThreadPriority *priority,
- int *runnable);
-
-int
-pk_thread_priority_change(PkThread *thread,
- PkThreadPriority new_priority,
- PkThreadPriority *old_priority);
-
-int
-pk_thread_at_priority(PkThreadPriority priority,
- PkThread **thread);
-
-int
-pk_thread_priority_swap(PkThread* thread_a, PkThread* thread_b);
-
-
-// Semaphore APIs
-
-int
-pk_semaphore_create(PkSemaphore *semaphore,
- PkSemaphoreCount initial_count,
- PkSemaphoreCount max_count);
-
-int
-pk_semaphore_post(PkSemaphore *semaphore);
-
-int
-pk_semaphore_pend(PkSemaphore *semaphore,
- PkInterval timeout);
-
-int
-pk_semaphore_release_all(PkSemaphore *semaphore);
-
-
-int
-pk_semaphore_info_get(PkSemaphore *semaphore,
- PkSemaphoreCount *count,
- int *pending);
-
-void
-pk_semaphore_post_handler(void *arg,
- PkIrqId irq);
-
-// Misc. APIs
-
-void
-pk_halt() __attribute__ ((noreturn));
-
-// Deque APIs
-
-int
-pk_deque_sentinel_create(PkDeque *deque);
-
-#define PK_DEQUE_SENTINEL_INIT(dq_addr) \
-{\
- .next = dq_addr, \
- .previous = dq_addr \
-}
-
-#define PK_DEQUE_SENTINEL_STATIC_CREATE(deque) \
- PkDeque deque = PK_DEQUE_SENTINEL_INIT(&deque)
-
-int
-pk_deque_element_create(PkDeque *element);
-
-#define PK_DEQUE_ELEMENT_INIT() \
-{\
- .next = 0, \
- .previous = 0 \
-}
-
-#define PK_DEQUE_ELEMENT_STATIC_CREATE(deque) \
- PkDeque deque = PK_DEQUE_ELEMENT_INIT()
-
-/// Check for an empty PkDeque
-///
-/// \param deque The sentinel node of a deque
-///
-/// \retval 0 The PkDeque is not empty
-///
-/// \retval 1 The PkDeque is empty
-
-static inline int
-pk_deque_is_empty(PkDeque *deque)
-{
- return (deque == deque->next);
-}
-
-
-/// Check if an PkDeque element is currently enqueued
-///
-/// \param element Typically the PkDeque object of a queable structure
-///
-/// \retval 0 The element is not currently enqueued
-///
-/// \retval 1 The element is currently enqueued
-
-static inline int
-pk_deque_is_queued(PkDeque *element)
-{
- return (element->next != 0);
-}
-
-
-/// Append an element to the tail of a deque (FIFO order)
-///
-/// \param deque The sentinel node of a deque
-///
-/// \param element Typically the PkDeque object of a queable structure
-///
-/// It is an error to call this API on an element that is already enqueued,
-/// but the API does not check for this error.
-
-static inline void
-pk_deque_push_back(PkDeque *deque, PkDeque *element)
-{
- deque->previous->next = element;
- element->previous = deque->previous;
- element->next = deque;
- deque->previous = element;
-}
-
-
-/// Push an element at the head of a deque (LIFO order)
-///
-/// \param deque The sentinel node of a deque
-///
-/// \param element Typically the PkDeque object of a queable structure
-///
-/// It is an error to call this API on an element that is already enqueued,
-/// but the API does not check for this error.
-
-static inline void
-pk_deque_push_front(PkDeque *deque, PkDeque *element)
-{
- deque->next->previous = element;
- element->next = deque->next;
- element->previous = deque;
- deque->next = element;
-}
-
-/// Pop an element from the head of a deque
-///
-/// \param deque The sentinel node of a deque
-///
-/// \retval 0 The PkDeque was empty prior to the call
-///
-/// \retval non-0 A pointer to the previous head of the deque, which has been
-/// removed from the deque and marked as no longer queued.
-
-// The cast of 'head' is used to remove the 'volatile' attribute.
-
-static inline PkDeque *
-pk_deque_pop_front(PkDeque *deque)
-{
- PkDeque *head;
-
- if (pk_deque_is_empty(deque)) {
- return 0;
- } else {
- head = (PkDeque *)(deque->next);
- deque->next = head->next;
- deque->next->previous = deque;
- head->next = 0;
- return head;
- }
-}
-
-
-/// Remove a deque element from any position in the deque
-///
-/// \param element Typically the PkDeque object of a queable structure
-///
-/// It is an error to call this API on an element that is not currently
-/// enqueued, but the API does not check for this error.
-
-static inline void
-pk_deque_delete(PkDeque *element)
-{
- element->previous->next = element->next;
- element->next->previous = element->previous;
- element->next = 0;
-}
-
-// Bottom Half APIs
-
-extern PkDeque _pk_bh_queue;
-
-static inline void
-pk_bh_schedule(PkBottomHalf *bottom_half)
-{
- pk_deque_push_back(&_pk_bh_queue, (PkDeque *)bottom_half);
-}
-
-#define PK_BH_INIT(_handler, _arg) \
-{\
- .deque = PK_DEQUE_ELEMENT_INIT(), \
- .bh_handler = _handler, \
- .arg = _arg \
-}
-
-#define PK_BH_STATIC_CREATE(bh_name, handler, arg) \
-PkBottomHalf bh_name = PK_BH_INIT(handler, arg)
-
-
-//Trace function prototypes
-void pk_trace_tiny(uint32_t i_parm);
-void pk_trace_big(uint32_t i_hash_and_count,
- uint64_t i_parm1, uint64_t i_parm2);
-void pk_trace_binary(uint32_t i_hash_and_size, void* bufp);
-void pk_trace_set_timebase(PkTimebase timebase);
-
-
-/// Cast a pointer to another type, in a way that won't cause warnings
-
-#define PK_CAST_POINTER(t, p) ((t)((PkAddress)(p)))
-
-// Static Assert Macro for Compile time assertions.
-// - This macro can be used both inside and outside of a function.
-// - A value of false will cause the ASSERT to produce this error
-// - This will show up on a compile fail as:
-// <file>:<line> error: size of array '_static_assert' is negative
-// - It would be trivial to use the macro to paste a more descriptive
-// array name for each assert, but we will leave it like this for now.
-#define PK_STATIC_ASSERT(cond) extern uint8_t _static_assert[(cond) ? 1 : -1] __attribute__ ((unused))
-
-/// \page pk_errors PK API and Kernel Error Handling
-///
-/// Error checking in the PK API consumes a significant amount of code space.
-/// Approximately 20% of the object code in the PPC405 port is devoted to
-/// error checking. Presumably a like amount of time overhead is also added to
-/// PK API calls by this checking.
-///
-/// API error checking can be disabled to save space and time in the kernel.
-/// API errors can also be configured to cause kernel panics, allowing
-/// applications to be coded without the overhead of error checking but still
-/// providing an escape in the event of application errors or (unlikely)
-/// hardware failures. The PK default is to check for API errors and kernel
-/// invariants, and panic should errors occur.
-///
-/// PK follows the Unix convention that a successful call of an API returns 0
-/// (PK_OK), but returns a negative code in the event of failure, or to
-/// provide further information. The error codes are all defined as manifest
-/// constants.
-///
-/// Some negative codes returned by PK APIs are not considered errors. These
-/// conditions are always checked, never cause a panic if they occur, and
-/// their interpretation is always left to the application. See the detailed
-/// documentation for each API for lists of error and non-error codes returned
-/// by the API.
-///
-/// There are three configuration options that control error handling in the
-/// PK API and kernel:
-///
-/// \c PK_ERROR_CHECK_API
-///
-/// \arg \b 0 - No PK API error checking. APIs that potentially return error
-/// codes will always return 0 (PK_OK) instead of an error code. Those
-/// APIs that return negative codes that are not errors (see Table 1.5)
-/// always return the negative non-error codes when appropriate.
-///
-/// \arg \b 1 - (Default) All PK API errors are checked. The behavior in
-/// the event of an error is defined by the configuration option
-/// PK_ERROR_PANIC.
-///
-/// \c PK_ERROR_CHECK_KERNEL
-///
-/// \arg \b 0 - No kernel invariant error checking is done.
-///
-/// \arg \b 1 - (Default) Selected kernel invariants are checked. The overhead
-/// for these checks should be minimal.
-///
-/// \c PK_ERROR_PANIC
-///
-/// \arg \b 0 - PK API calls return negative error codes in the event of
-/// errors. Note that PK kernel invariants always cause a panic if
-/// violations occur.
-///
-/// \arg \b 1 - (Default) In the event of errors PK APIs invoke PK_PANIC(code),
-/// where code is a positive error code. Kernel invariant checks always
-/// cause a panic if violations are detected.
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* __PK_API_H__ */
diff --git a/pk/kernel/pk_bh_core.c b/pk/kernel/pk_bh_core.c
deleted file mode 100644
index 8a6181cb..00000000
--- a/pk/kernel/pk_bh_core.c
+++ /dev/null
@@ -1,29 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2015
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_bh_core.c
-/// \brief PK bottom half APIs
-///
-/// The entry points in this file are considered 'core' routines that will
-/// always be present at runtime in any PK application.
-
-#include "pk.h"
-
-/// Statically initialize the bottom half queue
-PK_DEQUE_SENTINEL_STATIC_CREATE(_pk_bh_queue);
-
-void _pk_process_bh(void)
-{
- PkBottomHalf *bh;
- while((bh = (PkBottomHalf*)pk_deque_pop_front(&_pk_bh_queue)) != 0)
- {
- bh->bh_handler(bh->arg);
- }
- return;
-}
-
-
-#undef __PK_THREAD_CORE_C__
diff --git a/pk/kernel/pk_core.c b/pk/kernel/pk_core.c
deleted file mode 100644
index bfa6d6be..00000000
--- a/pk/kernel/pk_core.c
+++ /dev/null
@@ -1,79 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_core.c
-/// \brief Core routines for the PK kernel.
-///
-/// The entry points in this file are routines that are expected to be needed
-/// at runtime by all PK applications. This file also serves as a place for
-/// kernel global variables to be realized.
-
-#define __PK_CORE_C__
-
-#include "pk.h"
-
-#if !PK_TIMER_SUPPORT
-
-/// If there is no timer support, then any call of the timer interrupt handler
-/// is considered a fatal error.
-
-void
-__pk_timer_handler()
-{
- PK_PANIC(PK_NO_TIMER_SUPPORT);
-}
-
-#endif /* PK_TIMER_SUPPORT */
-
-
-/// Initialize an PkDeque sentinel node
-///
-/// \param deque The sentinel node of the deque
-///
-/// PK has no way of knowing whether the \a deque is currently in use, so
-/// this API must only be called on unitialized or otherwise unused sentinel
-/// nodes.
-///
-/// \retval 0 success
-///
-/// \retval -PK_INVALID_DEQUE_SENTINEL The \a deque pointer was null
-
-int
-pk_deque_sentinel_create(PkDeque *deque)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(deque == 0, PK_INVALID_DEQUE_SENTINEL);
- }
-
- deque->next = deque->previous = deque;
- return 0;
-}
-
-
-/// Initialize an PkDeque element
-///
-/// \param element Typically the PkDeque object of a queable structure
-///
-/// PK has no way of knowing whether the \a element is currently in use, so
-/// this API must only be called on unitialized or otherwise unused deque
-/// elements.
-///
-/// \retval 0 success
-///
-/// \retval -PK_INVALID_DEQUE_ELEMENT The \a element pointer was null
-
-int
-pk_deque_element_create(PkDeque *element)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(element == 0, PK_INVALID_DEQUE_ELEMENT);
- }
-
- element->next = 0;
- return 0;
-}
-
-#undef __PK_CORE_C__
diff --git a/pk/kernel/pk_debug_ptrs.c b/pk/kernel/pk_debug_ptrs.c
deleted file mode 100644
index 0ed540f4..00000000
--- a/pk/kernel/pk_debug_ptrs.c
+++ /dev/null
@@ -1,53 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2015
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_debug_ptrs.c
-/// \brief Defines a table of pointers to important kernel debug data.
-///
-/// This table is placed in a special section named .debug_ptrs which can be
-/// placed at a well-known memory location for tools to find.
-///
-
-#include "pk.h"
-#include "pk_trace.h"
-#include "pk_debug_ptrs.h"
-
-extern PkTimebase ppe42_64bit_timebase;
-
-#if PK_TRACE_SUPPORT
-extern PkTraceBuffer g_pk_trace_buf;
-#endif
-
-pk_debug_ptrs_t pk_debug_ptrs SECTION_ATTRIBUTE(".debug_ptrs") =
-{
- .debug_ptrs_size = sizeof(pk_debug_ptrs),
- .debug_ptrs_version = PK_DEBUG_PTRS_VERSION,
-
-#if PK_TRACE_SUPPORT
- .debug_trace_ptr = &g_pk_trace_buf,
- .debug_trace_size = sizeof(g_pk_trace_buf),
-#else
- .debug_trace_ptr = 0,
- .debug_trace_size = 0,
-#endif /* PK_TRACE_SUPPORT */
-
-#if PK_THREAD_SUPPORT
- .debug_thread_table_ptr = &__pk_priority_map,
- .debug_thread_table_size = sizeof(__pk_priority_map),
- .debug_thread_runq_ptr = (void*)&__pk_run_queue,
- .debug_thread_runq_size = sizeof(__pk_run_queue),
-#else
- .debug_thread_table_ptr = 0,
- .debug_thread_table_size = 0,
- .debug_thread_runq_ptr = 0,
- .debug_thread_runq_size = 0,
-#endif /* PK_THREAD_SUPPORT */
-
- .debug_timebase_ptr = &ppe42_64bit_timebase,
- .debug_timebase_size = sizeof(ppe42_64bit_timebase),
-
-};
-
diff --git a/pk/kernel/pk_debug_ptrs.h b/pk/kernel/pk_debug_ptrs.h
deleted file mode 100644
index 62a36839..00000000
--- a/pk/kernel/pk_debug_ptrs.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __PK_DEBUG_PTRS_H__
-#define __PK_DEBUG_PTRS_H__
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2015
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_debug_ptrs.h
-/// \brief Structure for a table of pointers to kernel debug data
-///
-
-#define PK_DEBUG_PTRS_VERSION 1
-
-typedef struct
-{
- // The size and version of this structure
- unsigned short debug_ptrs_size;
- unsigned short debug_ptrs_version;
-
- // Trace buffer location and size
- void* debug_trace_ptr;
- unsigned long debug_trace_size;
-
- // Thread table location and size
- void* debug_thread_table_ptr;
- unsigned long debug_thread_table_size;
-
- // Thread run queue location and size
- void* debug_thread_runq_ptr;
- unsigned long debug_thread_runq_size;
-
- // Emulated timebase location and size
- void* debug_timebase_ptr;
- unsigned long debug_timebase_size;
-
-} pk_debug_ptrs_t;
-
-#endif /*__PK_DEBUG_PTRS_H__*/
diff --git a/pk/kernel/pk_init.c b/pk/kernel/pk_init.c
deleted file mode 100644
index ebd6323a..00000000
--- a/pk/kernel/pk_init.c
+++ /dev/null
@@ -1,196 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_init.c
-/// \brief PK initialization
-///
-/// The entry points in this file are initialization routines - they are never
-/// needed after PK initialization and their code space could be reclaimed by
-/// the application after initialization if required.
-
-#include "pk.h"
-#include "pk_trace.h"
-
-uint32_t __pk_timebase_frequency_hz;
-
-/// The timebase frequency is passed into PK during initialization. It cannot
-/// be set statically because there is a requirement to support a frequency
-/// that can change from one IPL to the next. On the 405, scaling of time
-/// intervals is accomplished by doing a 32x32 bit multiplication which is
-/// supported by the ppc405 instruction set. PPE42 does not support 32x32 bit
-/// multiplication directly and some applications can not afford to use a
-/// function call to emulate the operation. Instead we scale the time
-/// interval by shifting the value X bits to the right and adding it to itself.
-/// This can scale the value by 2, 1.5, 1.25, 1.125, etc.
-///
-/// This is the right shift value.
-/// NOTE: shifting by 0 gives a 2x scale factor, shifting by 32 gives a 1x
-/// scale factor.
-uint8_t __pk_timebase_rshift = 32;
-
-void pk_set_timebase_rshift(uint32_t timebase_freq_hz)
-{
- //Use 1.0 scale if less than halfway between 1.0 and 1.25
- if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 3)))
- {
- __pk_timebase_rshift = 32;
- }
-
- //use 1.25 scale if less than halfway between 1.25 and 1.5
- else if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 3) + (PK_BASE_FREQ_HZ >> 2)))
- {
- __pk_timebase_rshift = 2;
- }
- //use 1.5 scale if less than halfway between 1.5 and 2.0
- else if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 2) + (PK_BASE_FREQ_HZ >> 1)))
- {
- __pk_timebase_rshift = 1;
- }
- //use 2.0 scale if greater than 1.5
- else
- {
- __pk_timebase_rshift = 0;
- }
-}
-
-/// Initialize PK.
-///
-/// \param kernel_stack A stack area for interrupt and bottom-half handlers.
-///
-/// \param kernel_stack_size The size (in bytes) of the stack area for
-/// interrupt and bottom-half handlers.
-///
-/// \param initial_timebase The initial value of the PK timebase.
-/// If the argument is given as the special value \c PK_TIMEBASE_CONTINUES, then the
-/// timebase is not reset.
-///
-/// \param timebase_frequency_hz The frequency of the PK timebase in Hz.
-///
-/// This routine \e must be called before any other PK / routines, and \e
-/// should be called before any interrupts are enabled.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_ARGUMENT_INIT A stack pointer is 0 or is given
-/// a 0 size.
-///
-/// \retval -PK_STACK_OVERFLOW One or both stacks are not large enough to
-/// support a minimum context save in the event of an interrupt.
-
-// Note that PK does not rely on any static initialization of dynamic
-// variables. In debugging sessions using RAM-resident PK images it is
-// assumed that the processor may be reset at any time, so we always need to
-// reset everything at initialization.
-
-int
-pk_initialize(PkAddress kernel_stack,
- size_t kernel_stack_size,
- PkTimebase initial_timebase,
- uint32_t timebase_frequency_hz)
-{
- int rc;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF((kernel_stack == 0) ||
- (kernel_stack_size == 0),
- PK_INVALID_ARGUMENT_INIT);
- }
-
- __pk_timebase_frequency_hz = timebase_frequency_hz;
-
- __pk_thread_machine_context_default = PK_THREAD_MACHINE_CONTEXT_DEFAULT;
-
- rc = __pk_stack_init(&kernel_stack, &kernel_stack_size);
- if (rc) {
- return rc;
- }
-
- __pk_kernel_stack = kernel_stack;
- __pk_kernel_stack_size = kernel_stack_size;
-
-#if PK_TIMER_SUPPORT
-
- // Initialize the time queue sentinel as a circular queue, set the next
- // timeout and clear the cursor.
-
- pk_deque_sentinel_create((PkDeque*)&__pk_time_queue);
- __pk_time_queue.cursor = 0;
- __pk_time_queue.next_timeout = PK_TIMEBASE_MAX;
-
-#if PK_TRACE_SUPPORT
-extern PkTimer g_pk_trace_timer;
-extern PkTraceBuffer g_pk_trace_buf;
-
- //set the trace timebase HZ
- g_pk_trace_buf.hz = timebase_frequency_hz;
-
- //set the shift adjustment to get us closer to the true
- //timebase frequency (versus what was hardcoded)
- pk_set_timebase_rshift(timebase_frequency_hz);
-
- if(initial_timebase != PK_TIMEBASE_CONTINUES)
- {
- //set the timebase ajdustment for trace synchronization
- pk_trace_set_timebase(initial_timebase);
- }
-
- // Schedule the timer that puts a 64bit timestamp in the trace buffer
- // periodically. This allows us to use 32bit timestamps.
- pk_timer_schedule(&g_pk_trace_timer,
- PK_TRACE_TIMER_PERIOD);
-
-#endif /* PK_TRACE_SUPPORT */
-
-#endif /* PK_TIMER_SUPPORT */
-
-#if PK_THREAD_SUPPORT
-
- // Clear the priority map. The final entry [PK_THREADS] is for the idle
- // thread.
-
- int i;
- for (i = 0; i <= PK_THREADS; i++) {
- __pk_priority_map[i] = 0;
- }
-
- // Initialize the thread scheduler
-
- __pk_thread_queue_clear(&__pk_run_queue);
- __pk_current_thread = 0;
- __pk_next_thread = 0;
- __pk_delayed_switch = 0;
-
-#endif /* PK_THREAD_SUPPORT */
-
- return PK_OK;
-}
-
-
-/// Call the application main()
-///
-/// __pk_main() is called from the bootloader. It's only purpose is to
-/// provide a place for the PK_MAIN_HOOK to be called before main() is
-/// called.
-
-void
-__pk_main(int argc, char **argv)
-{
- PK_MAIN_HOOK;
-
- int main(int argc, char **argv);
- main(argc, argv);
-}
-
-
-
-
-
-
-
-
-
diff --git a/pk/kernel/pk_kernel.h b/pk/kernel/pk_kernel.h
deleted file mode 100644
index 85b028a2..00000000
--- a/pk/kernel/pk_kernel.h
+++ /dev/null
@@ -1,246 +0,0 @@
-#ifndef __PK_KERNEL_H__
-#define __PK_KERNEL_H__
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_kernel.h
-/// \brief PK portable kernel (non-API) data and data structures
-///
-/// \todo In theory, as long as the critical section entry/exit macros use GCC
-/// memory barriers, we should be able to eliminate all of the 'volatile'
-/// declarations in PK code. These have been added to the port, so
-/// we should try it.
-
-#ifdef __PK_CORE_C__
-#define IF__PK_CORE_C__(x) x
-#define UNLESS__PK_CORE_C__(x)
-#else
-#define IF__PK_CORE_C__(x)
-#define UNLESS__PK_CORE_C__(x) x
-#endif
-
-#if PK_MINIMIZE_KERNEL_CODE_SPACE
-#define IF_PK_MINIMIZE_KERNEL_CODE_SPACE(x) x
-#define UNLESS_PK_MINIMIZE_KERNEL_CODE_SPACE(x)
-#else
-#define IF_PK_MINIMIZE_KERNEL_CODE_SPACE(x)
-#define UNLESS_PK_MINIMIZE_KERNEL_CODE_SPACE(x) x
-#endif
-
-
-#ifndef __ASSEMBLER__
-
-/// This is the stack pointer saved when switching from a thread context to an
-/// interrupt context.
-
-UNLESS__PK_CORE_C__(extern)
-volatile
-PkAddress __pk_saved_sp;
-
-/// The kernel stack; constant once defined by the call of
-/// pk_initialize().
-
-UNLESS__PK_CORE_C__(extern)
-volatile
-PkAddress __pk_kernel_stack;
-
-/// This is the run queue - the queue of mapped runnable tasks.
-UNLESS__PK_CORE_C__(extern)
-volatile
-PkThreadQueue __pk_run_queue;
-
-/// This flag is set by \c __pk_schedule() if a new highest-priority thread
-/// becomes runnable during an interrupt handler. The context switch will
-/// take place at the end of interrupt processing, and the
-/// interrupt handling code will clear the flag.
-
-UNLESS__PK_CORE_C__(extern)
-volatile
-int __pk_delayed_switch;
-
-/// The currently running thread, or NULL (0) to indicate the idle thread
-///
-/// \a __pk_current_thread holds a pointer to the currently executing
-/// thread. This pointer will be NULL (0) under the following conditions:
-///
-/// - After pk_initialize() but prior to pk_start_threads()
-///
-/// - After pk_start_threads(), when no threads are runnable. In this case
-/// the NULL (0) value indicates that the PK idle thread is 'running'.
-///
-/// - After pk_start_threads(), when the current (non-idle) thread has
-/// completed or been deleted.
-///
-/// If \a __pk_current_thread == 0 then there is no requirement to save any
-/// register state on a context switch, either because the PK idle thread has
-/// no permanent context, or because any thread context on the kernel stack is
-/// associated with a deleted thread.
-///
-/// If \a __pk_current_thread != 0 then \a __pk_current_thread is a pointer
-/// to the currently executing thread. In an interrupt handler \a
-/// pk_current_thread is a pointer to the thread whose context is saved on
-/// the kernel stack.
-UNLESS__PK_CORE_C__(extern)
-volatile
-PkThread* __pk_current_thread;
-
-/// The thread to switch to during the next context switch, or NULL (0).
-///
-/// \a __pk_next_thread is computed by __pk_schedule(). \a
-/// __pk_next_thread holds a pointer to the thread to switch to at the next
-/// context switch. In a thread context the switch happens immediately if \a
-/// __pk_next_thread == 0 or \a __pk_next_thread != \a __pk_current_thread.
-/// In an interrupt context the check happens at the end of processing all
-/// interrupts.
-///
-/// \a __pk_next_thread may be NULL (0) under the following
-/// conditions:
-///
-/// - After pk_initialize() but prior to pk_start_threads(), assuming no
-/// threads have been made runnable.
-///
-/// - After pk_start_threads(), when no threads are runnable. In this case
-/// the NULL (0) value indicates that the PK idle thread is the next thread
-/// to 'run'.
-///
-/// If \a __pk_next_thread == 0 then there is no requirement to restore
-/// any register state on a context switch, because the PK idle thread has
-/// no permanent context.
-///
-/// If \a __pk_next_thread != 0 then \a __pk_next_thread is a pointer
-/// to the thread whose context will be restored at the next context switch.
-UNLESS__PK_CORE_C__(extern)
-volatile
-PkThread* __pk_next_thread;
-
-/// The priority of \a __pk_next_thread
-///
-/// If \a __pk_next_thread == 0, the \a __pk_next_priority == PK_THREADS.
-UNLESS__PK_CORE_C__(extern)
-volatile
-PkThreadPriority __pk_next_priority;
-
-/// This variable holds the default thread machine context for newly created
-/// threads. The idle thread also uses this context. This variable is normally
-/// constant after the call of \c pk_initialize().
-
-UNLESS__PK_CORE_C__(extern)
-volatile
-PkMachineContext __pk_thread_machine_context_default;
-
-
-/// The size of the kernel stack (bytes).
-
-UNLESS__PK_CORE_C__(extern)
-volatile
-size_t __pk_kernel_stack_size;
-
-/// This table maps priorities to threads, and contains PK_THREADS + 1
-/// entries. The final entry is for the idle thread and will always be null
-/// after initizlization.
-
-UNLESS__PK_CORE_C__(extern)
-volatile
-PkThread* __pk_priority_map[PK_THREADS + 1];
-
-/// The PK time queue structure
-///
-/// This structure is defined for use by the kernel, however applications
-/// could also use this structure to define their own time queues.
-
-typedef struct {
-
- /// A sentinel node for the time queue.
- ///
- /// The time queue is an PkDeque managed as a FIFO queue for queue
- /// management purpose, although events time out in time order.
- ///
- /// This pointer container is defined as the first element of the
- /// structure to allow the PkTimeQueue to be cast to an PkDeque.
- PkDeque queue;
-
- /// The next timeout in absolute time.
- PkTimebase next_timeout;
-
- /// A pointer to allow preemption of time queue processing
- ///
- /// If non-0, then this is the next timer in the time queue to handle, or
- /// a pointer to the \a queue object indicating no more timers to handle.
- ///
- /// \a cursor != 0 implies that time queue handler is in the midst of
- /// processing the time queue, but has enabled interrupt preemption for
- /// processing a timer handler. This means that 1) if the timer pointed to
- /// by \a cursor is deleted then the cursor must be assigned to the
- /// next timer in the queue; and 2) if a new timer is scheduled then
- /// activating the next timeout will be handled by the timer handler.
- PkDeque* cursor;
-
-} PkTimeQueue;
-
-UNLESS__PK_CORE_C__(extern)
-PkTimeQueue __pk_time_queue;
-
-/// Return a pointer to the PkThread object of the currently running thread,
-/// or NULL (0) if PK is idle or has not been started.
-///
-/// In this API the current thread is not volatile - it will never change
-/// inside application code - thus the 'volatile' is cast away. The PK kernel
-/// does not (must not) use this API.
-
-UNLESS__PK_CORE_C__(extern)
-inline PkThread *
-pk_current(void)
-{
- return (PkThread *)__pk_current_thread;
-}
-
-/// Schedule the next timeout in a machine-specific way.
-
-void
-__pk_schedule_hardware_timeout(PkTimebase timeout);
-
-/// The thread timeout handler. Portable.
-
-PK_TIMER_CALLBACK(__pk_thread_timeout);
-
-/// Generic stack initialization. Portable.
-
-int
-__pk_stack_init(PkAddress *stack,
- size_t *size);
-
-/// Machine-specific thread context initialization.
-
-void
-__pk_thread_context_initialize(PkThread *thread,
- PkThreadRoutine thread_routine,
- void *arg);
-
-/// Machine specific resumption of __pk_next_thread at __pk_next_priority
-/// without saving the current context.
-void
-__pk_next_thread_resume(void);
-
-/// Schedule a timer in the time queue. Portable.
-void
-__pk_timer_schedule(PkTimer *timer);
-
-/// Remove a timer from the time queue. Portable.
-int
-__pk_timer_cancel(PkTimer *timer);
-
-void
-__pk_schedule(void);
-
-
-// Call the application main(). Portable.
-
-void
-__pk_main(int argc, char **argv);
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* __PK_KERNEL_H__ */
diff --git a/pk/kernel/pk_macros.h b/pk/kernel/pk_macros.h
deleted file mode 100644
index 45bfbac6..00000000
--- a/pk/kernel/pk_macros.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef __PK_MACROS_H__
-#define __PK_MACROS_H__
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_macros.h
-/// \brief Boilerplate macros for PK
-
-/// This macro encapsulates error handling boilerplate for code that uses the
-/// PK API-type error handling, for errors that do not occur in critical
-/// sections.
-
-#define PK_ERROR(code) \
- do { \
- if (PK_ERROR_PANIC) { \
- PK_PANIC(code); \
- } else { \
- return -(code); \
- } \
- } while (0)
-
-
-/// This macro encapsulates error handling boilerplate in the PK API
-/// functions, for errors that do not occur in critical sections.
-
-#define PK_ERROR_IF(condition, code) \
- do { \
- if (condition) { \
- PK_ERROR(code); \
- } \
- } while (0)
-
-
-/// This macro encapsulates error handling boilerplate in the PK API
-/// functions, for errors that do not occur in critical sections and always
-/// force a kernel panic, indicating a kernel or API bug.
-
-#define PK_PANIC_IF(condition, code) \
- do { \
- if (condition) { \
- PK_PANIC(code); \
- } \
- } while (0)
-
-
-/// This macro encapsulates error handling boilerplate in the PK API
-/// functions, for errors that do not occur in critical sections.
-/// The error handling will only be enabled when PK_ERROR_CHECK_API
-/// is enabled.
-
-#define PK_ERROR_IF_CHECK_API(condition, code) \
- do { \
- if (PK_ERROR_CHECK_API) { \
- PK_ERROR_IF(condition, code); \
- } \
- } while (0)
-
-/// This macro encapsulates error handling boilerplate in the PK API
-/// functions, for errors that occur in critical sections.
-
-#define PK_ERROR_IF_CRITICAL(condition, code, context) \
- do { \
- if (condition) { \
- if (PK_ERROR_PANIC) { \
- PK_PANIC(code); \
- pk_critical_section_exit(context); \
- } else { \
- pk_critical_section_exit(context); \
- return -(code); \
- } \
- } \
- } while (0)
-
-
-/// This is a general macro for errors that require cleanup before returning
-/// the error code.
-
-#define PK_ERROR_IF_CLEANUP(condition, code, cleanup) \
- do { \
- if (condition) { \
- if (PK_ERROR_PANIC) { \
- PK_PANIC(code); \
- cleanup; \
- } else { \
- cleanup; \
- return -(code); \
- } \
- } \
- } while (0)
-
-
-
-/// Some PK APIs can only be called from thread contexts - these are APIs
-/// that threads call on 'themselves'.
-
-#define PK_ERROR_UNLESS_THREAD_CONTEXT() \
- PK_ERROR_IF(!__pk_kernel_context_thread(), \
- PK_ILLEGAL_CONTEXT_THREAD_CONTEXT)
-
-
-/// Some PK APIs must be called from an interrupt context only.
-
-#define PK_ERROR_UNLESS_ANY_INTERRUPT_CONTEXT() \
- PK_ERROR_IF(!__pk_kernel_context_any_interrupt(), \
- PK_ILLEGAL_CONTEXT_INTERRUPT_CONTEXT)
-
-#endif /* __PK_MACROS_H__ */
diff --git a/pk/kernel/pk_semaphore_core.c b/pk/kernel/pk_semaphore_core.c
deleted file mode 100644
index 0e1e34d4..00000000
--- a/pk/kernel/pk_semaphore_core.c
+++ /dev/null
@@ -1,318 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_semaphore_core.c
-/// \brief PK semaphore APIs
-///
-/// The entry points in this file are considered 'core' routines that will
-/// always be present at runtime in any PK application that enables
-/// semaphores.
-
-#include "pk.h"
-
-/// Post a count to a semaphore
-///
-/// \param semaphore A pointer to the semaphore
-///
-/// If any thread is pending on the semaphore, the highest priority thread
-/// will be made runnable and the internal count will remain 0.
-///
-/// If no thread is pending on the semaphore then the internal count will be
-/// incremented by 1, with overflow wrapping the internal count through 0. If
-/// the \a max_count argument supplied when the semaphore was created is
-/// non-zero and the new internal count is greater than the \a max_count, an
-/// overflow error will be signalled.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_POST The \a semaphore is a null (0) pointer.
-///
-/// \retval -PK_SEMAPHORE_OVERFLOW The \a max_count argument supplied when
-/// the semaphore was created is non-zero and the new internal count is
-/// greater than the \a max_count.
-
-int
-pk_semaphore_post(PkSemaphore *semaphore)
-{
- PkMachineContext ctx;
- PkThreadPriority priority;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_POST);
- }
-
- pk_critical_section_enter(&ctx);
-
- priority = __pk_thread_queue_min(&(semaphore->pending_threads));
-
- if (priority != PK_IDLE_THREAD_PRIORITY) {
-
- __pk_thread_queue_delete(&(semaphore->pending_threads), priority);
- __pk_thread_queue_insert(&__pk_run_queue, priority);
-
- PK_KERN_TRACE("THREAD_SEMAPHORE_POST(%d)", priority);
-
- __pk_schedule();
-
- } else {
-
- semaphore->count++;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF((semaphore->max_count > 0) &&
- (semaphore->count > semaphore->max_count),
- PK_SEMAPHORE_OVERFLOW);
- }
- }
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-
-/// Pend on a semaphore with timeout
-///
-/// \param semaphore A pointer to the semaphore
-///
-/// \param timeout A relative timeout in PK timebase ticks, including the
-/// special values PK_NO_WAIT and PK_WAIT_FOREVER
-///
-/// This API is normally called from threads, and can only be successfully
-/// called from interupt handlers under special conditions.
-///
-/// If the internal count of the \a semaphore is non-zero, the internal count
-/// is decremented by one and execution of the caller continues.
-///
-/// If the internal count of the \a semaphore is zero and the \a timeout is
-/// PK_NO_WAIT (0) then the call returns immediately with the informational
-/// code -PK_SEMAPHORE_PEND_NO_WAIT.
-///
-/// If the internal count of the \a semaphore is zero and the \a timeout is
-/// non-zero then a thread will block until either a semaphore count is
-/// acquired or the relative timeout expires. If this condition occurs in a
-/// call from an interrupt context or before threads have been started then
-/// the call will fail with the error \c -PK_SEMAPHORE_PEND_WOULD_BLOCK.
-///
-/// Once timed out the thread is removed from the semaphore pending queue and
-/// made runnable, and the pk_semaphore_pend() operation will fail, even if
-/// the semaphore count becomes available before the thread runs again. The
-/// pk_semaphore_pend() API returns the informational code
-/// -PK_SEMAPHORE_PEND_TIMED_OUT in this case.
-///
-/// By convention, a timeout interval equal to the maximum possible value of
-/// the \c PkInterval type is taken to mean "wait forever". A thread blocked
-/// on a semaphore in this mode will never time out. PK provides this
-/// constant as \c PK_WAIT_FOREVER.
-///
-/// Return values other than PK_OK (0) are not necessarily errors; see \ref
-/// pk_errors
-///
-/// The following return codes are non-error codes:
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_SEMAPHORE_PEND_NO_WAIT timeout is set to PK_NO_WAIT
-///
-/// \retval -PK_SEMAPHORE_PEND_TIMED_OUT The semaphore was not acquired
-/// before the timeout expired.
-///
-/// The following return codes are error codes:
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_PEND The \a semaphore is a null (0)
-/// pointer.
-///
-/// \retval -PK_SEMAPHORE_PEND_WOULD_BLOCK The call was made from an
-/// interrupt context (or before threads have been started), the semaphore
-/// internal count was 0 and a non-zero timeout was specified.
-
-// Note: Casting __pk_current_thread removes the 'volatile' attribute.
-
-int
-pk_semaphore_pend(PkSemaphore *semaphore,
- PkInterval timeout)
-{
- PkMachineContext ctx;
- PkThreadPriority priority;
- PkThread *thread;
- PkTimer *timer = 0;
- PkInterval scaled_timeout = PK_INTERVAL_SCALE(timeout);
-
- int rc = PK_OK;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_PEND);
- }
-
- pk_critical_section_enter(&ctx);
-
- if (semaphore->count != 0) {
-
- semaphore->count--;
-
- } else if (timeout == PK_NO_WAIT) {
-
- rc = -PK_SEMAPHORE_PEND_NO_WAIT;
-
- } else {
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF_CRITICAL(!__pk_kernel_context_thread(),
- PK_SEMAPHORE_PEND_WOULD_BLOCK,
- &ctx);
- }
-
- thread = (PkThread *)__pk_current_thread;
- priority = thread->priority;
-
- __pk_thread_queue_insert(&(semaphore->pending_threads), priority);
-
- thread->semaphore = semaphore;
- thread->flags |= PK_THREAD_FLAG_SEMAPHORE_PEND;
-
- PK_KERN_TRACE("THREAD_SEMAPHORE_PEND(%d)", priority);
-
- if (timeout != PK_WAIT_FOREVER) {
- timer = &(thread->timer);
- timer->timeout = pk_timebase_get() + scaled_timeout;
- __pk_timer_schedule(timer);
- thread->flags |= PK_THREAD_FLAG_TIMER_PEND;
- }
-
- __pk_thread_queue_delete(&__pk_run_queue, priority);
- __pk_schedule();
-
- thread->flags &= ~PK_THREAD_FLAG_SEMAPHORE_PEND;
-
- if (thread->flags & PK_THREAD_FLAG_TIMER_PEND) {
- if (thread->flags & PK_THREAD_FLAG_TIMED_OUT) {
- rc = -PK_SEMAPHORE_PEND_TIMED_OUT;
- __pk_thread_queue_delete(&(semaphore->pending_threads), thread->priority);
- } else {
- __pk_timer_cancel(timer);
- }
- thread->flags &=
- ~(PK_THREAD_FLAG_TIMER_PEND | PK_THREAD_FLAG_TIMED_OUT);
- }
- }
-
- pk_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-/// Release all threads blocked on a semaphore
-///
-/// \param semaphore A pointer to a semaphore
-///
-/// This API is provided to allow an PK semaphore to be used as a thread
-/// barrier. pk_semaphore_release_all() simultaneously unblocks all threads
-/// (if any) currently pending on a semaphore. A semaphore to be used as a
-/// thread barrier will typically be initialized with
-/// pk_semaphore_create(\a sem, 0, 0), and sxx_semaphore_post() would never be
-/// called on the \a sem.
-///
-/// This API never modifies the \a count field of the semaphore; If any
-/// threads are blocked on a semaphore the semaphore count is 0 by definition.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_RELEASE The \a semaphore is a null (0)
-/// pointer.
-
-int
-pk_semaphore_release_all(PkSemaphore* semaphore)
-{
- PkMachineContext ctx;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_RELEASE);
- }
-
- pk_critical_section_enter(&ctx);
-
- __pk_thread_queue_union(&__pk_run_queue, &(semaphore->pending_threads));
- __pk_thread_queue_clear(&(semaphore->pending_threads));
- __pk_schedule();
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-
-/// Get information about a semaphore.
-///
-/// \param semaphore A pointer to the PkSemaphore to query
-///
-/// \param count The value returned through this pointer is the current count
-/// of the semaphore. The caller can set this parameter to the null pointer
-/// (0) if this information is not required.
-///
-/// \param pending The value returned through this pointer is the current
-/// number of threads pending on the semaphore. The caller can set this
-/// parameter to the null pointer (0) if this information is not required.
-///
-/// The information returned by this API can only be guaranteed consistent if
-/// the API is called from a critical section.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_INFO The \a semaphore is a null (0)
-/// pointer.
-
-int
-pk_semaphore_info_get(PkSemaphore* semaphore,
- PkSemaphoreCount* count,
- int* pending)
-
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_INFO);
- }
-
- if (count) {
- *count = semaphore->count;
- }
- if (pending) {
- *pending = __pk_thread_queue_count(&(semaphore->pending_threads));
- }
-
- return PK_OK;
-}
-
-
-/// An simple interrupt handler that posts to a semaphore.
-///
-/// To implement basic event-driven blocking of a thread, install
-/// pk_semaphore_post_handler() as the handler for an interrupt
-/// and provide a pointer to the semaphore as the \a arg argument in
-/// pk_irq_handler_set(). The semaphore should be initialized with
-/// pk_semaphore_create(&sem, 0, 1). This handler simply disables (masks)
-/// the interrupt, clears the status and calls pk_semaphore_post() on the
-/// semaphore.
-///
-/// Note that clearing the status in the interrupt controller as done here is
-/// effectively a no-op for level-sensitive interrupts. In the level-sensitive
-/// case any thread pending on the semaphore must reset the interrupt
-/// condition in the device before re-enabling the interrupt.
-#if 0
-void
-pk_semaphore_post_handler(void *arg, PkIrqId irq, int priority)
-{
- pk_irq_disable(irq);
- pk_irq_status_clear(irq);
- pk_semaphore_post((PkSemaphore *)arg);
-}
-
-#endif
diff --git a/pk/kernel/pk_semaphore_init.c b/pk/kernel/pk_semaphore_init.c
deleted file mode 100644
index bed029da..00000000
--- a/pk/kernel/pk_semaphore_init.c
+++ /dev/null
@@ -1,82 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_semaphore_init.c
-/// \brief PK semaphore API initialization routines
-///
-/// The entry points in this file are routines that are typically used during
-/// initialization, and their code space could be deallocated and recovered if
-/// no longer needed by the application after initialization.
-
-#include "pk.h"
-
-/// Create (initialize) a semaphore
-///
-/// \param semaphore A pointer to an PkSemaphore structure to initialize
-///
-/// \param initial_count The initial count of the semaphore
-///
-/// \param max_count The maximum count allowed in the semaphore, for error
-/// checking
-///
-/// Semaphores are created (initialized) by a call of \c
-/// pk_semaphore_create(), using an application-provided instance of an \c
-/// PkSemaphore structure. This structure \e is the semaphore, so the
-/// application must never modify the structure if the semaphore is in use.
-/// PK has no way to know if an \c PkSemaphore structure provided to
-/// \c pk_semaphore_create() is safe to use as a semaphore, and will silently
-/// modify whatever memory is provided.
-///
-/// PK provides two simple overflow semantics based on the value of max_count
-/// in the call of \c pk_semaphore_create().
-///
-/// If \a max_count = 0, then posting to the semaphore first increments the
-/// internal count by 1. Overflows are ignored and will wrap the internal
-/// count through 0.
-///
-/// If \a max_count != 0, then posting to the semaphore first increments the
-/// internal count by 1, wrapping through 0 in the event of overflow. If the
-/// resulting count is greater than max_count, \c pk_semaphore_post() will
-/// return the error \c -PK_SEMAPHORE_POST_OVERFLOW to the caller.
-///
-/// In most applications it is probably best to use the \a max_count != 0
-/// semantics to trap programming errors, unless there is a specific
-/// application where overflow is expected and ignorable. As a fine point of
-/// the specification, a \a max_count of 0 is equivalent to a max_count of
-/// 0xFFFFFFFF.
-///
-/// Return values other then PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_CREATE The \a semaphore is a null (0)
-/// pointer.
-///
-/// \retval -PK_INVALID_ARGUMENT_SEMAPHORE The \a max_count is non-zero
-/// and less than the \a initial_count.
-
-int
-pk_semaphore_create(PkSemaphore *semaphore,
- PkSemaphoreCount initial_count,
- PkSemaphoreCount max_count)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_CREATE);
- PK_ERROR_IF((max_count != 0) && (initial_count > max_count),
- PK_INVALID_ARGUMENT_SEMAPHORE);
- }
-
- __pk_thread_queue_clear(&(semaphore->pending_threads));
- semaphore->count = initial_count;
- semaphore->max_count = max_count;
-
- return PK_OK;
-}
-
-
-
-
-
diff --git a/pk/kernel/pk_stack_init.c b/pk/kernel/pk_stack_init.c
deleted file mode 100644
index c3ddc90a..00000000
--- a/pk/kernel/pk_stack_init.c
+++ /dev/null
@@ -1,85 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_stack_init.c
-/// \brief PK stack initialization
-///
-/// The entry points in this file are initialization routines - they are never
-/// needed after PK initialization and their code space could be reclaimed by
-/// the application after initialization if required.
-///
-/// This code was split out from "pk_init.c" because it may be needed in a
-/// thread configuration if threads are being created dynamically. in an
-/// interrupt-only configuration it is not needed after \c pk_initialize().
-
-#include "pk.h"
-
-/// Initialize a stack area.
-///
-/// \param stack A pointer to the smallest legal address of the stack. The
-/// stack address is modified as the stack is aligned and initialized.
-///
-/// \param size A pointer to the size of the stack (in bytes). The size is
-/// modified as the stack is aligned and initialized. At exit this is the
-/// final usable stack area size aligned to the size of the PK_STACK_TYPE.
-///
-/// PK makes no assumptions about size or alignment of the area provided as a
-/// stack, and carefully aligns and initializes the stack. Regardless of how
-/// the stack grows, the \a stack parameter is considered to be the lowest
-/// legal address of the stack.
-
-int
-__pk_stack_init(PkAddress *stack,
- size_t *size)
-{
- PkAddress mask;
- size_t excess, i, count;
- PK_STACK_TYPE *p;
-
- if (PK_STACK_DIRECTION < 0) {
-
- // Stacks grow down. The initial stack pointer is set to just above
- // the last allocated stack address. This is legal for pre-decrement
- // stacks, otherwise the initial address is first brought into range
- // before alignment. The stack is aligned downward, then the size is
- // adjusted to a multiple of the stack type. Stacks are optionally
- // prepatterned. Alignment is assumed to be a power of 2.
-
- *stack += *size;
-
- if (!PK_STACK_PRE_DECREMENT) {
- *stack -= sizeof(PK_STACK_TYPE);
- *size -= sizeof(PK_STACK_TYPE);
- }
-
- mask = PK_STACK_ALIGNMENT - 1;
- excess = *stack & mask;
- *stack -= excess;
- *size -= excess;
- *size = (*size / sizeof(PK_STACK_TYPE)) * sizeof(PK_STACK_TYPE);
-
- if (PK_STACK_CHECK) {
- p = (PK_STACK_TYPE *)(*stack);
- count = *size / sizeof(PK_STACK_TYPE);
- for (i = 0; i < count; i++) {
- if (PK_STACK_PRE_DECREMENT) {
- *(--p) = PK_STACK_PATTERN;
- } else {
- *(p--) = PK_STACK_PATTERN;
- }
- }
- }
-
- __pk_stack_create_initial_frame(stack, size);
-
- } else {
-
- PK_PANIC(PK_UNIMPLEMENTED);
- }
-
- return PK_OK;
-}
-
diff --git a/pk/kernel/pk_thread.h b/pk/kernel/pk_thread.h
deleted file mode 100644
index acc32525..00000000
--- a/pk/kernel/pk_thread.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __PK_THREAD_H__
-#define __PK_THREAD_H__
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2015
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_thread.h
-/// \brief Contains private declarations and definitions needed for threads
-///
-
-void
-__pk_thread_map(PkThread* thread);
-
-void
-__pk_thread_unmap(PkThread *thread);
-
-
-// Interrupts must be disabled at entry.
-
-static inline int
-__pk_thread_is_active(PkThread *thread)
-{
- return ((thread->state != PK_THREAD_STATE_COMPLETED) &&
- (thread->state != PK_THREAD_STATE_DELETED));
-}
-
-
-// Interrupts must be disabled at entry.
-
-static inline int
-__pk_thread_is_mapped(PkThread *thread)
-{
- return (thread->state == PK_THREAD_STATE_MAPPED);
-}
-
-
-// Interrupts must be disabled at entry. This is only called on mapped threads.
-
-static inline int
-__pk_thread_is_runnable(PkThread *thread)
-{
- return __pk_thread_queue_member(&__pk_run_queue, thread->priority);
-}
-
-
-// Interrupts must be disabled at entry.
-
-static inline PkThread*
-__pk_thread_at_priority(PkThreadPriority priority)
-{
- return (PkThread*)__pk_priority_map[priority];
-}
-
-#endif /* __PK_THREAD_H__ */
diff --git a/pk/kernel/pk_thread_core.c b/pk/kernel/pk_thread_core.c
deleted file mode 100644
index 2966eb9b..00000000
--- a/pk/kernel/pk_thread_core.c
+++ /dev/null
@@ -1,573 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_thread_core.c
-/// \brief PK thread APIs
-///
-/// The entry points in this file are considered 'core' routines that will
-/// always be present at runtime in any PK application that enables threads.
-
-#include "pk.h"
-#include "pk_thread.h"
-
-#define __PK_THREAD_CORE_C__
-
-
-// This routine is only used locally. Interrupts must be disabled
-// at entry. The caller must also have checked that the priority is free.
-// This routine is only called on threads known to be in a suspended state,
-// either PK_THREAD_STATE_SUSPENDED_RUNNABLE or
-// PK_THREAD_STATE_SUSPENDED_BLOCKED. Mapping a runnable thread adds it to
-// the run queue. Mapping a thread pending on a semaphore either takes the
-// count and becomes runnable or adds the thread to the pending queue for the
-// semaphore. Mapping a sleeping thread requires no further action
-// here. Scheduling after the map must be handled by the caller.
-
-void
-__pk_thread_map(PkThread* thread)
-{
- PkThreadPriority priority;
-
- priority = thread->priority;
- __pk_priority_map[priority] = thread;
-
- if (thread->state == PK_THREAD_STATE_SUSPENDED_RUNNABLE) {
-
- __pk_thread_queue_insert(&__pk_run_queue, priority);
-
- } else if (thread->flags & PK_THREAD_FLAG_SEMAPHORE_PEND) {
-
- if (thread->semaphore->count) {
-
- thread->semaphore->count--;
- __pk_thread_queue_insert(&__pk_run_queue, priority);
-
- } else {
-
- __pk_thread_queue_insert(&(thread->semaphore->pending_threads),
- priority);
- }
- }
-
- thread->state = PK_THREAD_STATE_MAPPED;
-
- if (PK_KERNEL_TRACE_ENABLE) {
- if (__pk_thread_is_runnable(thread)) {
- PK_KERN_TRACE("THREAD_MAPPED_RUNNABLE(%d)", priority);
- } else if (thread->flags & PK_THREAD_FLAG_SEMAPHORE_PEND) {
- PK_KERN_TRACE("THREAD_MAPPED_SEMAPHORE_PEND(%d)", priority);
- } else {
- PK_KERN_TRACE("THREAD_MAPPED_SLEEPING(%d)", priority);
- }
- }
-}
-
-
-// This routine is only used locally. Interrupts must be disabled
-// at entry. This routine is only ever called on threads in the
-// PK_THREAD_STATE_MAPPED. Unmapping a thread removes it from the priority
-// map, the run queue and any semaphore pend, but does not cancel any
-// timers. Scheduling must be handled by the code calling
-// __pk_thread_unmap().
-
-void
-__pk_thread_unmap(PkThread *thread)
-{
- PkThreadPriority priority;
-
- priority = thread->priority;
- __pk_priority_map[priority] = 0;
-
- if (__pk_thread_is_runnable(thread)) {
-
- thread->state = PK_THREAD_STATE_SUSPENDED_RUNNABLE;
- __pk_thread_queue_delete(&__pk_run_queue, priority);
-
- } else {
-
- thread->state = PK_THREAD_STATE_SUSPENDED_BLOCKED;
- if (thread->flags & PK_THREAD_FLAG_SEMAPHORE_PEND) {
- __pk_thread_queue_delete(&(thread->semaphore->pending_threads),
- priority);
- }
- }
-}
-
-
-// Schedule and run the highest-priority mapped runnable thread.
-//
-// The priority of the next thread to run is first computed. This may be
-// PK_THREADS, indicating that the only thread to run is the idle thread.
-// This will always cause (or defer) a 'context switch' to the idle thread.
-// Otherwise, if the new thread is not equal to the current thread this will
-// also cause (or defer) a context switch. Note that scheduling is defined in
-// terms of priorities but actually implemented in terms of PkThread pointers.
-//
-// If we are not yet in thread mode we're done - threads will be started by
-// pk_start_threads() later. If we're in thread context a context switch
-// happens immediately. In an interrupt context the switch is deferred to the
-// end of interrupt processing.
-
-void
-__pk_schedule(void)
-{
- __pk_next_priority = __pk_thread_queue_min(&__pk_run_queue);
- __pk_next_thread = __pk_priority_map[__pk_next_priority];
-
- if ((__pk_next_thread == 0) ||
- (__pk_next_thread != __pk_current_thread)) {
-
- if (__pk_kernel_mode_thread()) {
- if (__pk_kernel_context_thread()) {
- if (__pk_current_thread != 0) {
- __pk_switch();
- } else {
- __pk_next_thread_resume();
- }
- } else {
- __pk_delayed_switch = 1;
- }
- }
- }
-}
-
-
-// This routine is only used locally.
-//
-// Completion and deletion are pretty much the same thing. Completion is
-// simply self-deletion of the current thread (which is mapped by
-// definition.) The complete/delete APIs have slightly different error
-// conditions but are otherwise the same.
-//
-// Deleting a mapped thread first unmaps (suspends) the thread, which takes
-// care of removing the thread from any semaphores it may be pending on. Then
-// any outstanding timer is also cancelled.
-//
-// If the current thread is being deleted we install the idle thread as
-// __pk_current_thread, so scheduling is forced and no context is saved on
-// the context switch.
-//
-// Note that we do not create trace events for unmapped threads since the trace
-// tag only encodes the priority, which may be in use by a mapped thread.
-
-void
-__pk_thread_delete(PkThread *thread, PkThreadState final_state)
-{
- PkMachineContext ctx;
- int mapped;
-
- pk_critical_section_enter(&ctx);
-
- mapped = __pk_thread_is_mapped(thread);
-
- if (mapped) {
- __pk_thread_unmap(thread);
- }
-
- __pk_timer_cancel(&(thread->timer));
- thread->state = final_state;
-
- if (mapped) {
-
- if (PK_KERNEL_TRACE_ENABLE) {
- if (final_state == PK_THREAD_STATE_DELETED) {
- PK_KERN_TRACE("THREAD_DELETED(%d)", thread->priority);
- } else {
- PK_KERN_TRACE("THREAD_COMPLETED(%d)", thread->priority);
- }
- }
-
- if (thread == __pk_current_thread) {
- __pk_current_thread = 0;
- }
- __pk_schedule();
- }
-
- pk_critical_section_exit(&ctx);
-}
-
-
-// Generic thread timeout
-//
-// This routine is called as a timer callback either because a sleeping thread
-// has timed out or a thread pending on a semaphore has timed out. If the
-// thread is not already runnable then the the timeout flag is set, and if the
-// thread is mapped it is scheduled.
-//
-// This implementation allows that a thread blocked on a timer may have been
-// made runnable by some other mechanism, such as acquiring a semaphore. In
-// order to provide an iteration-free implementation of
-// pk_semaphore_release_all(), cancelling any semaphore timeouts is deferred
-// until the thread runs again.
-//
-// Note that we do not create trace events for unmapped threads since the trace
-// tag only encodes the priority, which may be in use by a mapped thread.
-
-void
-__pk_thread_timeout(void *arg)
-{
- PkMachineContext ctx;
- PkThread *thread = (PkThread *)arg;
-
- pk_critical_section_enter(&ctx);
-
- switch (thread->state) {
-
- case PK_THREAD_STATE_MAPPED:
- if (!__pk_thread_is_runnable(thread)) {
- thread->flags |= PK_THREAD_FLAG_TIMED_OUT;
- __pk_thread_queue_insert(&__pk_run_queue, thread->priority);
- __pk_schedule();
- }
- break;
-
- case PK_THREAD_STATE_SUSPENDED_RUNNABLE:
- break;
-
- case PK_THREAD_STATE_SUSPENDED_BLOCKED:
- thread->flags |= PK_THREAD_FLAG_TIMED_OUT;
- thread->state = PK_THREAD_STATE_SUSPENDED_RUNNABLE;
- break;
-
- default:
- PK_PANIC(PK_THREAD_TIMEOUT_STATE);
- }
-
- pk_critical_section_exit(&ctx);
-}
-
-
-// This routine serves as a container for the PK_START_THREADS_HOOK and
-// actually starts threads. The helper routine __pk_call_pk_start_threads()
-// arranges this routine to be called with interrupts disabled while running
-// on the kernel stack.
-//
-// The reason for this roundabout is that we want to be able to run a hook
-// routine (transparent to the application) that can hand over every last byte
-// of free memory to "malloc()" - including the stack of main(). Since we
-// always need to run on some stack, we chose to run the hook on the kernel
-// stack. However to do this safely we need to make sure
-// that no interrupts will happen during this time. When __pk_thread_resume()
-// is finally called all stack-based context is lost but it doesn't matter at
-// that point - it's a one-way street into thread execution.
-//
-// This is considered part of pk_start_threads() and so is also considered a
-// 'core' routine.
-
-void
-__pk_start_threads(void)
-{
- PK_START_THREADS_HOOK;
-
- __pk_next_thread_resume();
-
- PK_PANIC(PK_START_THREADS_RETURNED);
-}
-
-
-/// Start PK threads
-///
-/// This routine starts the PK thread scheduler infrastructure. This routine
-/// must be called after a call of \c pk_initialize(). This routine never
-/// returns. Interrupt (+ timer) only configurations of PK need not call this
-/// routine.
-///
-/// Note: This tiny routine is considered a 'core' routine so that the
-/// initialziation code can safely recover all 'init' code space before
-/// starting threads.
-///
-/// This routine typically does not return - any return value indicates an
-/// error; see \ref pk_errors
-///
-/// \retval -PK_ILLEGAL_CONTEXT_THREAD The API was called twice.
-
-int
-pk_start_threads(void)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(__pk_kernel_mode_thread(), PK_ILLEGAL_CONTEXT_THREAD);
- }
-
- __pk_call_pk_start_threads();
-
- return 0;
-}
-
-
-/// Resume a suspended thread
-///
-/// \param thread The thread to resume
-///
-/// PK only allows one thread at a time to run at a given priority, and
-/// implements the notion of a thread \e claiming a priority. A suspended
-/// thread claims a priority when it is mapped by a call of
-/// pk_thread_resume(). This API will succeed only if no other active thread
-/// is currently mapped at the priority assigned to the thread. PK provides
-/// the pk_thread_at_priority() API which allows an application-level
-/// scheduler to correctly manage multiple threads running at the same
-/// priority.
-///
-/// If the thread was sleeping while suspended it remains asleep. However if
-/// the sleep timer timed out while the thread was suspended it will be
-/// resumed runnable.
-///
-/// If the thread was blocked on a semaphore when it was suspended, then when
-/// the thread is resumed it will attempt to reacquire the semaphore.
-/// However, if the thread was blocked on a semaphore with timeout while
-/// suspended and the timeout interval has passed, the thread will be resumed
-/// runnable and see that the semaphore pend timed out.
-///
-/// It is not an error to call pk_thread_resume() on a mapped
-/// thread. However it is an error to call pk_thread_resume() on a completed
-/// or deleted thread.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion, including calls on a \a thread that is
-/// already mapped.
-///
-/// \retval -PK_INVALID_THREAD_AT_RESUME1 The \a thread is a null (0) pointer.
-///
-/// \retval -PK_INVALID_THREAD_AT_RESUME2 The \a thread is not active,
-/// i.e. has completed or been deleted.
-///
-/// \retval -PK_PRIORITY_IN_USE_AT_RESUME Another thread is already mapped at
-/// the priority of the \a thread.
-
-int
-pk_thread_resume(PkThread *thread)
-{
- PkMachineContext ctx;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_RESUME1);
- }
-
- pk_critical_section_enter(&ctx);
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF_CRITICAL(!__pk_thread_is_active(thread),
- PK_INVALID_THREAD_AT_RESUME2,
- &ctx);
- }
-
- if (!__pk_thread_is_mapped(thread)) {
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF_CRITICAL(__pk_priority_map[thread->priority] != 0,
- PK_PRIORITY_IN_USE_AT_RESUME,
- &ctx);
- }
- __pk_thread_map(thread);
- __pk_schedule();
- }
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-
-/// Suspend a thread
-///
-/// Any active thread can be suspended. A suspended thread 1) remains active
-/// but will not be scheduled; 2) relinquishes its priority assignment,
-/// allowing another thread to be resumed at the suspended thread's priority;
-/// and 3) disassociates from any semaphore mutual exclusion it may have been
-/// participating in.
-///
-/// If a sleeping thread is suspended, the sleep timer remains active but a
-/// timeout of the timer simply marks the thread as runnable, but does not
-/// resume the thread.
-///
-/// If a thread blocked on a semaphore is suspended, the thread no longer
-/// participates in the semaphore mutual exclusion. If the thread is later
-/// resumed it will attempt to acquire the semaphore again the next time it
-/// runs (unless it was blocked with a timeout and the timeout has expired).
-///
-/// If a thread blocked on a semaphore with timeout is suspended, the
-/// semaphore timeout timer continues to run. If the timer times out while the
-/// thread is suspended the thread is simply marked runnable. If the thread is
-/// later resumed, the suspended call of \c pk_semaphore_pend() will return the
-/// timeout code -PK_SEMAPHORE_PEND_TIMED_OUT.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion, including calls on a \a thread that is
-/// already suspended.
-///
-/// \retval -PK_INVALID_THREAD_AT_SUSPEND1 The \a thread is a null (0) pointer
-///
-/// \retval -PK_INVALID_THREAD_AT_SUSPEND2 The \a thread is not active,
-/// i.e. has completed or been deleted.
-
-int
-pk_thread_suspend(PkThread *thread)
-{
- PkMachineContext ctx;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF((thread == 0), PK_INVALID_THREAD_AT_SUSPEND1);
- }
-
- pk_critical_section_enter(&ctx);
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF_CRITICAL(!__pk_thread_is_active(thread),
- PK_INVALID_THREAD_AT_SUSPEND2,
- &ctx);
- }
-
- if (__pk_thread_is_mapped(thread)) {
-
- PK_KERN_TRACE("THREAD_SUSPENDED(%d)", thread->priority);
- __pk_thread_unmap(thread);
- __pk_schedule();
- }
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-
-/// Delete a thread
-///
-/// Any active thread can be deleted. If a thread is deleted it is removed
-/// from the run queue, deleted from the timer queue (if sleeping or blocked
-/// on a semaphore with timeout), and deleted from the semaphore mutual
-/// exclusion if blocked on a semaphore. The thread control block is then
-/// marked as deleted.
-///
-/// Once a thread has completed or been deleted the thread structure and
-/// thread stack areas can be used for other purposes.
-///
-/// \param thread The thread to delete
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors. If a
-/// thread deletes itself this API does not return at all.
-///
-/// \retval 0 Successful completion, including calls on a \a thread that has
-/// completed or had already been deleted.
-///
-///
-/// \retval -PK_INVALID_THREAD_AT_DELETE The \a thread is a null (0) pointer.
-
-int
-pk_thread_delete(PkThread *thread)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_DELETE);
- }
-
- __pk_thread_delete(thread, PK_THREAD_STATE_DELETED);
-
- return PK_OK;
-}
-
-
-/// Complete a thread
-///
-/// If a thread ever returns from the subroutine defining the thread entry
-/// point, the thread is removed from all PK kernel data structures and
-/// marked completed. The thread routine can also use the API pk_complete()
-/// to make this more explicit if desired. PK makes no distinction between
-/// completed and deleted threads, but provides these indications for
-/// the benefit of the application.
-///
-/// Note that this API is only available from the current thread to mark its
-/// own completion.
-///
-/// Once a thread has completed or been deleted the thread structure and
-/// thread stack areas can be used for other purposes.
-///
-/// Any return value indicates an error; see \ref pk_errors. In the event of
-/// a successful completion this API does not return to the caller, which is
-/// always the thread context being completed.
-///
-/// \retval -PK_ILLEGAL_CONTEXT_THREAD The API was not called from a thread
-/// context.
-
-// Note: Casting __pk_current_thread removes the 'volatile' attribute.
-
-int
-pk_complete(void)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_UNLESS_THREAD_CONTEXT();
- }
-
- __pk_thread_delete((PkThread *)__pk_current_thread,
- PK_THREAD_STATE_COMPLETED);
-
- return PK_OK;
-}
-
-/// Sleep a thread for an interval relative to the current time.
-///
-/// \param interval A time interval relative to the current timebase.
-///
-/// Threads can use this API to sleep for a time relative to the current
-/// timebase. The absolute timeout is \c pk_timebase_get() + \a interval.
-///
-/// Sleeping threads are not scheduled, although they maintain their
-/// priorities. This differs from thread suspension, where the suspended
-/// thread relinquishes its priority. When the sleep timer times out the
-/// thread becomes runnable again, and will run as soon as it becomes the
-/// highest-priority mapped runnable thread.
-///
-/// Sleeping threads may also be later suspended. In this case the Sleep timer
-/// continues to run, and if it times out before the thread is resumed the
-/// thread will be immediately runnable when it is resumed.
-///
-/// See the PK specification for a full discussion of how PK handles
-/// scheduling events at absolute times "in the past". Briefly stated, if the
-/// \a interval is 0 or is so small that the absolute time becomes a "past"
-/// time before the Sleep is actually scheduled, the thread will Sleep for the
-/// briefest possible period supported by the hardware.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion.
-///
-/// \retval -PK_ILLEGAL_CONTEXT_THREAD The API was not called from a thread
-/// context.
-
-int
-pk_sleep(PkInterval interval)
-{
- PkTimebase time;
- PkMachineContext ctx;
- PkThread *current;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_UNLESS_THREAD_CONTEXT();
- }
-
- time = pk_timebase_get() + PK_INTERVAL_SCALE(interval);
-
- pk_critical_section_enter(&ctx);
-
- current = (PkThread *)__pk_current_thread;
-
- current->timer.timeout = time;
- __pk_timer_schedule(&(current->timer));
-
- current->flags |= PK_THREAD_FLAG_TIMER_PEND;
-
- PK_KERN_TRACE("THREAD_SLEEP(%d)", current->priority);
-
- __pk_thread_queue_delete(&__pk_run_queue, current->priority);
- __pk_schedule();
-
- current->flags &= ~(PK_THREAD_FLAG_TIMER_PEND | PK_THREAD_FLAG_TIMED_OUT);
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-#undef __PK_THREAD_CORE_C__
diff --git a/pk/kernel/pk_thread_init.c b/pk/kernel/pk_thread_init.c
deleted file mode 100644
index 97bce4c4..00000000
--- a/pk/kernel/pk_thread_init.c
+++ /dev/null
@@ -1,134 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_thread_init.c
-/// \brief PK thread API initialization routines
-///
-/// The entry points in this file are routines that are typically used during
-/// initialization, and their code space could be deallocated and recovered if
-/// no longer needed by the application after initialization.
-
-#include "pk.h"
-
-/// Create (initialize) a thread
-///
-/// \param thread A pointer to an PkThread structure to initialize
-///
-/// \param thread_routine The subroutine that implements the thread
-///
-/// \param arg Private data to be passed as the argument to the thread
-/// routine when it begins execution
-///
-/// \param stack The stack space of the thread
-///
-/// \param stack_size The size of the stack in bytes
-///
-/// \param priority The initial priority of the thread
-///
-/// The \a thread argument must be a pointer to an uninitialized or completed
-/// or deleted thread. This \c PkThread structure \em is the thread, so this
-/// memory area must not be modified by the application until the thread
-/// completes or is deleted. PK can not tell if an PkThread structure is
-/// currently in use as a thread control block.pk_thread_create() will
-/// silently overwrite an PkThread structure that is currently in use.
-///
-/// The stack area must be large enough to hold the dynamic stack requirements
-/// of the entry point routine, and all subroutines and functions that might
-/// be invoked on any path from the entry point. The stack must also always
-/// be able to hold the thread context in the event the thread is preempted,
-/// plus other critical context. PK aligns stack areas in machine-specific
-/// ways, so that the actual stack area may reduced in size slightly if it is
-/// not already aligned.
-///
-/// Threads are created runnable but unmapped. A newly created thread will
-/// not be eligible to run until a call of pk_thread_resume() targets the
-/// thread.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_THREAD_AT_CREATE The \a thread is a null (0) pointer.
-///
-/// \retval -PK_INVALID_ARGUMENT_THREAD1 the \a thread_routine is null (0)
-///
-/// \retval -PK_INVALID_ARGUMENT_THREAD2 the \a priority is invalid,
-///
-/// \retval -PK_INVALID_ARGUMENT_THREAD3 the stack area wraps around
-/// the end of memory.
-///
-/// \retval -PK_STACK_OVERFLOW The stack area at thread creation is smaller
-/// than the minimum safe size.
-
-int
-pk_thread_create(PkThread *thread,
- PkThreadRoutine thread_routine,
- void *arg,
- PkAddress stack,
- size_t stack_size,
- PkThreadPriority priority)
-{
- int rc;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_CREATE);
- PK_ERROR_IF((thread_routine == 0) ||
- (priority >= PK_THREADS),
- PK_INVALID_ARGUMENT_THREAD1);
- }
-
- rc = __pk_stack_init(&stack, &stack_size);
- if (rc) {
- return rc;
- }
-
- thread->saved_stack_pointer = stack;
- thread->stack_base = stack;
-
- if (PK_STACK_DIRECTION < 0) {
-
- thread->stack_limit = stack - stack_size;
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(thread->stack_limit > thread->stack_base,
- PK_INVALID_ARGUMENT_THREAD2);
- }
-
- } else {
-
- thread->stack_limit = stack + stack_size;
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(thread->stack_limit < thread->stack_base,
- PK_INVALID_ARGUMENT_THREAD3);
- }
- }
-
- thread->semaphore = 0;
- thread->priority = priority;
- thread->state = PK_THREAD_STATE_SUSPENDED_RUNNABLE;
- thread->flags = 0;
-
- pk_timer_create(&(thread->timer),
- __pk_thread_timeout,
- (void *)thread);
-
- __pk_thread_context_initialize(thread, thread_routine, arg);
-
- return rc;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pk/kernel/pk_thread_util.c b/pk/kernel/pk_thread_util.c
deleted file mode 100644
index bf2e21b7..00000000
--- a/pk/kernel/pk_thread_util.c
+++ /dev/null
@@ -1,291 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_thread_util.c
-/// \brief PK thread utility APIs
-///
-/// The entry points in this file are considered extra routines that will
-/// only be included in a PK application that enables threads and uses at
-/// least one of these interfaces.
-
-#include "pk.h"
-#include "pk_thread.h"
-
-/// Get information about a thread.
-///
-/// \param thread A pointer to the PkThread to query
-///
-/// \param state The value returned through this pointer is the current state
-/// of the thread; See \ref pk_thread_states. The caller can set this
-/// parameter to the null pointer (0) if this information is not required.
-///
-/// \param priority The value returned through this pointer is the current
-/// priority of the thread. The caller can set this parameter to the null
-/// pointer (0) if this information is not required.
-///
-/// \param runnable The value returned through this pointer is 1 if the thread
-/// is in state PK_THREAD_STATE_MAPPED and is currently in the run queue
-/// (i.e., neither blocked on a semaphore nor sleeping), otherwise 0. The
-/// caller can set this parameter to the null pointer (0) if this information
-/// is not required.
-///
-/// The information returned by this API can only be guaranteed consistent if
-/// the API is called from a critical section.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_THREAD_AT_INFO The \a thread is a null (0) pointer.
-
-int
-pk_thread_info_get(PkThread *thread,
- PkThreadState *state,
- PkThreadPriority *priority,
- int *runnable)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_INFO);
- }
-
- if (state) {
- *state = thread->state;
- }
- if (priority) {
- *priority = thread->priority;
- }
- if (runnable) {
- *runnable = ((thread->state == PK_THREAD_STATE_MAPPED) &&
- __pk_thread_queue_member(&__pk_run_queue,
- thread->priority));
- }
- return PK_OK;
-}
-
-
-/// Change the priority of a thread.
-///
-/// \param thread The thread whose priority will be changed
-///
-/// \param new_priority The new priority of the thread
-///
-/// \param old_priority The value returned through this pointer is the
-/// old priority of the thread prior to the change. The caller can set
-/// this parameter to the null pointer (0) if this information is not
-/// required.
-///
-/// Thread priorities can be changed by the \c pk_thread_priority_change()
-/// API. This call will fail if the thread pointer is invalid or if the thread
-/// is mapped and the new priority is currently in use. The call will succeed
-/// even if the \a thread is suspended, completed or deleted. The
-/// application-level scheduling algorithm is completely responsible for the
-/// correctness of the application in the event of suspended, completed or
-/// deleted threads.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion, including the redundant case of
-/// attempting to change the priority of the thread to its current priority.
-///
-/// \retval -PK_INVALID_THREAD_AT_CHANGE The \a thread is null (0) or
-/// otherwise invalid.
-///
-/// \retval -PK_INVALID_ARGUMENT_THREAD_CHANGE The \a new_priority is invalid.
-///
-/// \retval -PK_PRIORITY_IN_USE_AT_CHANGE The \a thread is mapped and the \a
-/// new_priority is currently in use by another thread.
-
-int
-pk_thread_priority_change(PkThread *thread,
- PkThreadPriority new_priority,
- PkThreadPriority *old_priority)
-{
- PkMachineContext ctx;
- PkThreadPriority priority;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_CHANGE);
- PK_ERROR_IF(new_priority > PK_THREADS,
- PK_INVALID_ARGUMENT_THREAD_CHANGE);
- }
-
- pk_critical_section_enter(&ctx);
-
- priority = thread->priority;
-
- if (priority != new_priority) {
-
- if (!__pk_thread_is_mapped(thread)) {
-
- thread->priority = new_priority;
-
- } else {
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF_CRITICAL(__pk_priority_map[new_priority] != 0,
- PK_PRIORITY_IN_USE_AT_CHANGE,
- &ctx);
- }
-
- __pk_thread_unmap(thread);
- thread->priority = new_priority;
- __pk_thread_map(thread);
- __pk_schedule();
- }
- }
-
- if (old_priority) {
- *old_priority = priority;
- }
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-
-/// Return a pointer to the thread (if any) mapped at a given priority.
-///
-/// \param priority The thread priority of interest
-///
-/// \param thread The value returned through this pointer is a pointer to the
-/// thread currently mapped at the given priority level. If no thread is
-/// mapped, or if the \a priority is the priority of the idle thread, the
-/// pointer returned will be null (0).
-///
-/// The information returned by this API can only be guaranteed consistent if
-/// the API is called from a critical section.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion.
-///
-/// \retval -PK_INVALID_ARGUMENT_THREAD_PRIORITY The \a priority is invalid
-/// or the \a thread parameter is null (0).
-
-int
-pk_thread_at_priority(PkThreadPriority priority,
- PkThread **thread)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF((priority > PK_THREADS) || (thread == 0),
- PK_INVALID_ARGUMENT_THREAD_PRIORITY);
- }
-
- *thread = __pk_thread_at_priority(priority);
-
- return PK_OK;
-}
-
-
-/// Swap thread priorities
-///
-/// \param thread_a A pointer to an initialized PkThread
-///
-/// \param thread_b A pointer to an initialized PkThread
-///
-/// This API swaps the priorities of \a thread_a and \a thread_b. The API is
-/// provided to support general and efficient application-directed scheduling
-/// algorithms. The requirements on the \a thread_a and \a thread_b arguments
-/// are that they are valid pointers to initialized PkThread structures, that
-/// the current thread priorities of both threads are legal, and that if a
-/// thread is currently mapped, that the new thread priority is not otherwise
-/// in use.
-///
-/// The API does not require either thread to be mapped, or even to be active.
-/// It is legal for one or both of the swap partners to be suspended, deleted
-/// or completed threads. The application is completely responsible for the
-/// correctness of scheduling algorithms that might operate on inactive or
-/// suspended threads.
-///
-/// The API does not change the mapped status of a thread. A thread will be
-/// mapped after the call of pk_thread_priority_swap() if and only if it was
-/// mapped prior to the call. If the new priority of a mapped thread is
-/// currently in use (by a thread other than the swap partner), then the
-/// PK_PRIORITY_IN_USE_AT_SWAP error is signalled and the swap does not take
-/// place. This could only happen if the swap partner is not currently mapped.
-///
-/// It is legal for a thread to swap its own priority with another thread. The
-/// degenerate case that \a thread_a and \a thread_b are equal is also legal -
-/// but has no effect.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion, including the redundant cases that do not
-/// actually change priorities, or the cases that assign new priorities to
-/// suspended, completed or deleted threads.
-///
-/// \retval -PK_INVALID_THREAD_AT_SWAP1 One or both of \a thread_a and
-/// \a thread_b is null (0) or otherwise invalid,
-///
-/// \retval -PK_INVALID_THREAD_AT_SWAP2 the priorities of One or both of
-/// \a thread_a and \a thread_b are invalid.
-///
-/// \retval -PK_INVALID_ARGUMENT One or both of the priorities
-/// of \a thread_a and \a thread_b is invalid.
-///
-/// \retval -PK_PRIORITY_IN_USE_AT_SWAP Returned if a thread is mapped and the
-/// new thread priority is currently in use by another thread (other than the
-/// swap partner).
-
-int
-pk_thread_priority_swap(PkThread* thread_a, PkThread* thread_b)
-{
- PkMachineContext ctx;
- PkThreadPriority priority_a, priority_b;
- int mapped_a, mapped_b;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF((thread_a == 0) || (thread_b == 0),
- PK_INVALID_THREAD_AT_SWAP1);
- }
-
- pk_critical_section_enter(&ctx);
-
- if (thread_a != thread_b) {
-
- mapped_a = __pk_thread_is_mapped(thread_a);
- mapped_b = __pk_thread_is_mapped(thread_b);
- priority_a = thread_a->priority;
- priority_b = thread_b->priority;
-
- if (PK_ERROR_CHECK_API) {
- int priority_in_use;
- PK_ERROR_IF_CRITICAL((priority_a > PK_THREADS) ||
- (priority_b > PK_THREADS),
- PK_INVALID_THREAD_AT_SWAP2,
- &ctx);
- priority_in_use =
- (mapped_a && !mapped_b &&
- (__pk_thread_at_priority(priority_b) != 0)) ||
- (!mapped_a && mapped_b &&
- (__pk_thread_at_priority(priority_a) != 0));
- PK_ERROR_IF_CRITICAL(priority_in_use,
- PK_PRIORITY_IN_USE_AT_SWAP, &ctx);
- }
-
- if (mapped_a) {
- __pk_thread_unmap(thread_a);
- }
- if (mapped_b) {
- __pk_thread_unmap(thread_b);
- }
- thread_a->priority = priority_b;
- thread_b->priority = priority_a;
- if (mapped_a) {
- __pk_thread_map(thread_a);
- }
- if (mapped_b) {
- __pk_thread_map(thread_b);
- }
- __pk_schedule();
- }
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
diff --git a/pk/kernel/pk_timer_core.c b/pk/kernel/pk_timer_core.c
deleted file mode 100644
index 59b9d628..00000000
--- a/pk/kernel/pk_timer_core.c
+++ /dev/null
@@ -1,401 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_timer_core.c
-/// \brief PK portable kernel timer handler
-///
-/// This file contains core routines that would be needed by any application
-/// that requires PK timer support at runtime.
-///
-/// PK implements a 'tickless' kernel - all events are scheduled at absolute
-/// times of the PK timebase. This approach gives the application full
-/// control over granularity of event scheduling. Scheduling in absolute time
-/// opens up the possibility of scheduling events "in the past". PK
-/// uniformly handles this case by scheduling "past" events to occur 1
-/// timebase tick in the future, so that timer callbacks are always run in the
-/// expected interrupt context.
-///
-/// PK implements the time queue as a simple unordered list of events, plus a
-/// dedicated variable that holds the earliest timeout of any event in the
-/// list. This is thought to be an appropriate data structure for the
-/// following reasons:
-///
-/// - PK applications will be small and will not schedule a large number of
-/// events. Therefore the cost of scanning the list each time an event times
-/// out is balanced against the cost of maintaining the list as a sorted data
-/// structure each time an event is added or removed from the event queue.
-///
-/// - PK applications may schedule and cancel many, many more events (safety
-/// timeouts) than are ever allowed to expire. Events can be added and deleted
-/// from the simple DEQUE very quickly since there is no sorting
-/// overhead.
-///
-/// Events are added to the queue simply by placing them at the end of the
-/// queue. If the new event times out earlier than the previous earliest
-/// event, the hardware timeout is rescheduled for the new event time. Events
-/// are deleted from the queue (cancelled) simply by deleting them. Deletion
-/// does not affect the hardware timeout, even if the deleted event would have
-/// been the next to time out. It is not an error for the timer handler to
-/// take a timer interrupt and find no events pending. Pending events can
-/// also be rescheduled in place.
-///
-/// When a timeout occurs the event list is scanned from the beginning, and
-/// any event that has timed out has its callback processed.
-/// Since event and callback processing take
-/// time, the list is potentially scanned multiple times until there are no
-/// more timed-out events in the list.
-///
-/// Note that callbacks are not necessarily processed in time-order. In this
-/// sense the PK time queue is like a traditional tick-based time queue in
-/// that events are effectively lumped into groups of events that time out
-/// together. In a tick-based kernel the 'lump' is the tick interval; here
-/// the 'lump' is a variable interval that corresponds to the time it takes to
-/// process the entire event list.
-///
-/// Timer callbacks are typically run with interrupt preemption enabled.
-/// Special callbacks may run without preemption. This is the only part of
-/// the PK kernel where data structures of indeterminate size are processed.
-/// During processing of the event list by the timer interrupt handler, the
-/// consideration of each event always includes a window of preemptability.
-
-#define __PK_TIMER_CORE_C__
-
-#include "pk.h"
-
-// Declare the timer bottom half handler
-static PK_BH_HANDLER(__pk_timer_bh_handler);
-
-// Define the timer bottom half handler that the interrupt handler will
-// schedule
-PK_BH_STATIC_CREATE(pk_timer_bh, __pk_timer_bh_handler, 0);
-
-
-// This routine is only used in this file, and will always be called in a
-// critical section.
-
-static inline int
-timer_active(PkTimer* timer)
-{
- return pk_deque_is_queued((PkDeque*)timer);
-}
-
-
-// This is the kernel version of pk_timer_cancel().
-//
-// This routine is used here and by thread and semaphore routines.
-// External interrupts must be disabled at entry.
-//
-// If the timer is active, then there is a special case if we are going to
-// delete the 'cursor' - that is the timer that __pk_timer_handler() is going
-// to handle next. In this case we need to move the cursor to the next timer
-// in the queue.
-//
-// Note that cancelling a timer does not cause a re-evaluation of the next
-// timeout. This will happen naturally when the current timeout expires.
-
-int
-__pk_timer_cancel(PkTimer *timer)
-{
- int rc;
- PkDeque* timer_deque = (PkDeque*)timer;
- PkTimeQueue* tq = &__pk_time_queue;
-
- if (!timer_active(timer)) {
-
- rc = -PK_TIMER_NOT_ACTIVE;
-
- } else {
-
- if (timer_deque == tq->cursor) {
- tq->cursor = tq->cursor->next;
- }
- pk_deque_delete(timer_deque);
- rc = 0;
- }
- return rc;
-}
-
-
-// This is the kernel version of pk_timer_schedule().
-//
-// This routine is used here and by thread and semaphore routines.
-// interrupts must be disabled at entry.
-//
-// Unless the timer is already active it is enqueued in the doubly-linked
-// timer list by inserting the timer at the end of the queue. Then the
-// hardware timeout is scheduled if necessary. If the time queue 'cursor' != 0
-// we are in the midst of processing the time queue, and the end of time queue
-// processing will schedule the next hardware timemout.
-
-void
-__pk_timer_schedule(PkTimer* timer)
-{
- PkTimeQueue* tq = &__pk_time_queue;
-
- if (!timer_active(timer)) {
- pk_deque_push_back((PkDeque*)tq, (PkDeque*)timer);
- }
-
- if (timer->timeout < tq->next_timeout) {
- tq->next_timeout = timer->timeout;
- if (tq->cursor == 0) {
- __pk_schedule_hardware_timeout(tq->next_timeout);
- }
- }
-}
-
-
-// The tickless timer mechanism has timed out. Note that due to timer
-// deletions and other factors, there may not actually be a timer in the queue
-// that has timed out - but it doesn't matter (other than for efficiency).
-//
-// This routine must not be entered reentrantly.
-//
-// First, time out any timers that have expired. Timers in the queue are
-// unordered, so we have to check every one. Since passing through the
-// loop takes time, we may have to make multiple passes until we know
-// that there are no timers in the queue that have already timed
-// out. Note that it would also work to only go through the loop once and
-// let the hardware scheduler take care of looping, but that would imply
-// more overhead than the current implementation.
-//
-// On each pass through the loop tq->next_timeout computes the minimum timeout
-// of events remaining in the queue. This is the only part of the kernel that
-// searches a list of indefinite length. Kernel interrupt latency is mitigated
-// by running this function as a bottom half. As such, interrupts are only
-// disabled when explicitly requested.
-//
-// Because interrupt preemption is enabled during processing, and preempting
-// handlers may invoke time queue operations, we need to establish a pointer
-// to the next entry to be examined (tq->cursor) before enabling interupts.
-// It's possible that this pointer will be changed by other interrupt handlers
-// that cancel the timer pointed to by tq->cursor.
-//
-// The main loop iterates on the PkDeque form of the time queue, casting each
-// element back up to the PkTimer as it is processed.
-
-static void
-__pk_timer_bh_handler(void* arg)
-{
- PkMachineContext ctx;
- PkTimeQueue* tq;
- PkTimebase now;
- PkTimer* timer;
- PkDeque* timer_deque;
- PkTimerCallback callback;
-
- tq = &__pk_time_queue;
-
- // Check if we entered the function while it was running in another context.
- if (PK_ERROR_CHECK_KERNEL) {
- if (tq->cursor != 0) {
- PK_PANIC(PK_TIMER_HANDLER_INVARIANT);
- }
- }
-
- pk_critical_section_enter(&ctx);
-
- while ((now = pk_timebase_get()) >= tq->next_timeout) {
- tq->next_timeout = PK_TIMEBASE_MAX;
- timer_deque = ((PkDeque*)tq)->next;
-
- // Iterate through the entire timer list, calling the callback of
- // timed-out elements and finding the timer that will timeout next,
- // which is stored in tq->next_timeout.
- while (timer_deque != (PkDeque*)tq) {
-
- timer = (PkTimer*)timer_deque;
-
- // Setting this to a non-zero value indicates we are in the middle
- // of processing the time queue.
- tq->cursor = timer_deque->next;
-
- if (timer->timeout <= now) {
-
- // The timer timed out. It is removed from the queue.
- //
- // The callback may be made with interrupt preemption enabled
- // or disabled. However to mitigate kernel interrupt latency
- // we go ahead and open up to interrupts after the callback if
- // the callback itself was not preemptible.
-
- pk_deque_delete(timer_deque);
-
- pk_critical_section_exit(&ctx);
-
- callback = timer->callback;
- if (callback) {
- callback(timer->arg);
- }
-
- } else {
-
- // This timer has not timed out. Its timeout will simply
- // participate in the computation of the next timeout.
- tq->next_timeout = MIN(timer->timeout, tq->next_timeout);
- pk_critical_section_exit(&ctx);
- }
-
- timer_deque = tq->cursor;
- pk_critical_section_enter(&ctx);
- }
-
- // Time has passed since we checked the time. Loop back
- // to check the time again and see if enough time has passed
- // that the next timer has timed out too.
- }
-
- pk_critical_section_exit(&ctx);
-
- // This marks that we are no longer processing the time queue
- tq->cursor = 0;
-
- // Finally, reschedule the next timeout
- __pk_schedule_hardware_timeout(tq->next_timeout);
-}
-
-
-void
-__pk_timer_handler(void)
-{
- //schedule the timer bottom half handler which
- //is preemptible.
- pk_bh_schedule(&pk_timer_bh);
-}
-
-
-/// Schedule a timer for an interval relative to the current time.
-///
-/// \param timer The PkTimer to schedule.
-///
-/// \param interval The timer will be scheduled to time out at the current
-/// time (pk_timebase_get()) plus this \a interval.
-///
-/// Once created with pk_timer_create() a timer can be \e scheduled, which
-/// queues the timer in the kernel time queue. It is not an error to call \c
-/// pk_timer_schedule() on a timer that is already scheduled in the time
-/// queue - the timer is simply rescheduled with the new characteristics.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_TIMER_AT_SCHEDULE A a null (0) pointer was provided as
-/// the \a timer argument.
-///
-
-int
-pk_timer_schedule(PkTimer *timer,
- PkInterval interval)
-{
- PkMachineContext ctx;
- PkTimebase timeout = pk_timebase_get() + PK_INTERVAL_SCALE(interval);
-
- pk_critical_section_enter(&ctx);
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(timer == 0, PK_INVALID_TIMER_AT_SCHEDULE);
- }
-
- timer->timeout = timeout;
- __pk_timer_schedule(timer);
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-
-/// Cancel (dequeue) a timer.
-///
-/// \param timer The PkTimer to cancel.
-///
-/// Timers can be canceled at any time. It is never an error to call
-/// pk_timer_cancel() on an PkTimer object after it is created. Memory used
-/// by an PkTimer can be safely reused for another purpose after a successful
-/// call ofpk_timer_cancel().
-///
-/// Return values other than PK_OK (0) are not necessarily errors; see \ref
-/// pk_errors
-///
-/// The following return codes are non-error codes:
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_TIMER_NOT_ACTIVE The \a timer is not currently scheduled,
-/// i.e. it was never scheduled or has timed out. This code is returned for
-/// information only and is not considered an error.
-///
-/// The following return codes are error codes:
-///
-/// \retval -PK_INVALID_TIMER_AT_CANCEL The \a timer is a null (0) pointer.
-///
-
-int
-pk_timer_cancel(PkTimer *timer)
-{
- PkMachineContext ctx;
- int rc = PK_OK;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(timer == 0, PK_INVALID_TIMER_AT_CANCEL);
- }
-
- pk_critical_section_enter(&ctx);
-
- rc = __pk_timer_cancel(timer);
-
- pk_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-/// Get information about a timer.
-///
-/// \param timer The PkTimer to query
-///
-/// \param timeout The API returns the absolute timeout of the timer through
-/// this pointer. If the timer is active, this is the current timeout. If
-/// the timer has timed out then this is the previous absolute timeout. If
-/// the timer was never scheduled this will be 0. The caller can set this
-/// parameter to the null pointer (0) if this information is not required.
-///
-/// \param active If the value returned through this pointer is 1 then the
-/// timer is active (currently scheduled), otherwise the value will be 0
-/// indicating an inactive timer. The caller can set this parameter to the
-/// null pointer (0) if this information is not required.
-///
-/// The information returned by this API can only be guaranteed consistent if
-/// the API is called from a critical section.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_TIMER_AT_INFO The \a timer is a null (0) pointer.
-
-int
-pk_timer_info_get(PkTimer *timer,
- PkTimebase *timeout,
- int *active)
-
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(timer == 0, PK_INVALID_TIMER_AT_INFO);
- }
-
- if (timeout) {
- *timeout = timer->timeout;
- }
- if (active) {
- *active = timer_active(timer);
- }
-
- return PK_OK;
-}
-
-#undef __PK_TIMER_CORE_C__
diff --git a/pk/kernel/pk_timer_init.c b/pk/kernel/pk_timer_init.c
deleted file mode 100644
index 457f78c4..00000000
--- a/pk/kernel/pk_timer_init.c
+++ /dev/null
@@ -1,62 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_timer_init.c
-/// \brief PK timer initialization
-///
-/// The entry points in this file might only be used during initialization of
-/// the application. In this case the code space for these routines could be
-/// recovered and reused after initialization.
-
-#include "pk.h"
-
-
-/// Create (initialize) a timer.
-///
-/// \param timer The PkTimer to initialize.
-///
-/// \param callback The timer callback
-///
-/// \param arg Private data provided to the callback.
-///
-/// Once created with pk_timer_create() a timer can be scheduled with
-/// pk_timer_schedule() or pk_timer_schedule_absolute(), which queues the
-/// timer in the kernel time queue. Timers can be cancelled by a call of
-/// pk_timer_cancel().
-///
-/// Timers created with pk_timer_create() are always run as
-/// bottom-half handlers with interrupt preemption enabled. Timer callbacks are
-/// free to enter critical sections if required, but must
-/// always exit with interrupts enabled.
-///
-/// Caution: PK has no way to know if an PkTimer structure provided to
-/// pk_timer_create() is safe to use as a timer, and will silently modify
-/// whatever memory is provided.
-///
-/// Return values other then PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_TIMER_AT_CREATE The \a timer is a null (0) pointer.
-
-int
-pk_timer_create(PkTimer *timer,
- PkTimerCallback callback,
- void *arg)
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF((timer == 0), PK_INVALID_TIMER_AT_CREATE);
- }
-
- pk_deque_element_create((PkDeque*)timer);
- timer->timeout = 0;
- timer->callback = callback;
- timer->arg = arg;
-
- return PK_OK;
-}
-
-
diff --git a/pk/kernel/pkkernelfiles.mk b/pk/kernel/pkkernelfiles.mk
deleted file mode 100644
index df7872bd..00000000
--- a/pk/kernel/pkkernelfiles.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# @file pkkernelfiles.mk
-#
-# @brief mk for including architecture independent pk object files
-#
-# @page ChangeLogs Change Logs
-# @section pkkernelfiles.mk
-# @verbatim
-#
-#
-# Change Log ******************************************************************
-# Flag Defect/Feature User Date Description
-# ------ -------------- ---------- ------------ -----------
-#
-# @endverbatim
-#
-##########################################################################
-# Include
-##########################################################################
-
-
-##########################################################################
-# Object Files
-##########################################################################
-PK-C-SOURCES = pk_core.c pk_init.c pk_stack_init.c pk_bh_core.c pk_debug_ptrs.c
-
-PK-TIMER-C-SOURCES += pk_timer_core.c pk_timer_init.c
-
-PK-THREAD-C-SOURCES += pk_thread_init.c pk_thread_core.c pk_thread_util.c \
- pk_semaphore_init.c pk_semaphore_core.c
-
-PK_OBJECTS += $(PK-C-SOURCES:.c=.o)
-
OpenPOWER on IntegriCloud