summaryrefslogtreecommitdiffstats
path: root/pk/kernel/pk_api.h
diff options
context:
space:
mode:
Diffstat (limited to 'pk/kernel/pk_api.h')
-rw-r--r--pk/kernel/pk_api.h1016
1 files changed, 0 insertions, 1016 deletions
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__ */
OpenPOWER on IntegriCloud