diff options
Diffstat (limited to 'pk/ppe42/ppe42.h')
-rw-r--r-- | pk/ppe42/ppe42.h | 825 |
1 files changed, 0 insertions, 825 deletions
diff --git a/pk/ppe42/ppe42.h b/pk/ppe42/ppe42.h deleted file mode 100644 index 35d57bad..00000000 --- a/pk/ppe42/ppe42.h +++ /dev/null @@ -1,825 +0,0 @@ -#ifndef __PPE42_H__ -#define __PPE42_H__ -//----------------------------------------------------------------------------- -// *! (C) Copyright International Business Machines Corp. 2014 -// *! All Rights Reserved -- Property of IBM -// *! *** IBM Confidential *** -//----------------------------------------------------------------------------- - -/// \file ppe42.h -/// \brief PPE42 port header for PK - -// Macros to define where declared code is actually compiled - -#ifdef __PPE42_C__ -#define IF__PPE42_CORE_C__(x) x -#define UNLESS__PPE42_CORE_C__(x) -#else -#define IF__PPE42_CORE_C__(x) -#define UNLESS__PPE42_CORE_C__(x) x -#endif - -#ifdef __PPE42_IRQ_CORE_C__ -#define IF__PPE42_IRQ_CORE_C__(x) x -#define UNLESS__PPE42_IRQ_CORE_C__(x) -#else -#define IF__PPE42_IRQ_CORE_C__(x) -#define UNLESS__PPE42_IRQ_CORE_C__(x) x -#endif - -#ifdef HWMACRO_GPE -#include "gpe.h" -#elif defined(HWMACRO_STD) -#include "std.h" -#elif defined(HWMACRO_PPE) -#include "ppe.h" -#else -#error "Macro Type not specified. Are you building from the correct directory?" -#endif - - -#include "ppe42_asm.h" -#include "ppe42_gcc.h" -#include "ppe42_spr.h" -#include "ppe42_msr.h" - - -///start - -/// The synchronization macros defined here all create a compiler -/// memory barrier that will cause GCC to flush/invalidate all memory data -/// held in registers before the macro. This is consistent with other systems, -/// e.g., the PowerPC Linux kernel, and is the safest way to define these -/// macros. - - -// Condition register fields - -#define CR_LT(n) (0x80000000u >> (4 * (n))) -#define CR_GT(n) (0x40000000u >> (4 * (n))) -#define CR_EQ(n) (0x20000000u >> (4 * (n))) -#define CR_SO(n) (0x10000000u >> (4 * (n))) - - -#ifndef __ASSEMBLER__ - -#include "stdint.h" - -/// ssize_t is defined explictly rather than bringing in all of <unistd.h> -#ifndef __ssize_t_defined -#define __ssize_t_defined -typedef int ssize_t; -#endif - -/// A memory barrier -#define barrier() asm volatile ("" : : : "memory") - -/// Ensure In-order Execution of Input/Output -#define eieio() asm volatile ("sync" : : : "memory") - -/// Memory barrier -#define sync() asm volatile ("sync" : : : "memory") - -/// Instruction barrier -#define isync() asm volatile ("sync" : : : "memory") - -/// CouNT Leading Zeros Word -#define cntlzw(x) \ -({uint32_t __x = (x); \ - uint32_t __lzw; \ - asm volatile ("cntlzw %0, %1" : "=r" (__lzw) : "r" (__x)); \ - __lzw;}) - -/// CouNT Leading Zeros : uint32_t -static inline int -cntlz32(uint32_t x) { - return cntlzw(x); -} - -/// CouNT Leading Zeros : uint64_t -static inline int -cntlz64(uint64_t x) { - if (x > 0xffffffff) { - return cntlz32(x >> 32); - } else { - return 32 + cntlz32(x); - } -} - - -/// 32-bit population count -static inline int -popcount32(uint32_t x) -{ - return __builtin_popcount(x); -} - - -/// 64-bit population count -static inline int -popcount64(uint64_t x) -{ - return __builtin_popcountll(x); -} - - -// NB: Normally we wouldn't like to force coercion inside a macro because it -// can mask programming errors, but for the MMIO macros the addresses are -// typically manifest constants or 32-bit unsigned integer expressions so we -// embed the coercion to avoid warnings. - -/// 8-bit MMIO Write -#define out8(addr, data) \ -do {*(volatile uint8_t *)(addr) = (data);} while(0) - -/// 8-bit MMIO Read -#define in8(addr) \ -({uint8_t __data = *(volatile uint8_t *)(addr); __data;}) - -/// 16-bit MMIO Write -#define out16(addr, data) \ -do {*(volatile uint16_t *)(addr) = (data);} while(0) - -/// 16-bit MMIO Read -#define in16(addr) \ -({uint16_t __data = *(volatile uint16_t *)(addr); __data;}) - -/// 32-bit MMIO Write -#define out32(addr, data) \ -do {*(volatile uint32_t *)(addr) = (data);} while(0) - -/// 32-bit MMIO Read -#define in32(addr) \ -({uint32_t __data = *(volatile uint32_t *)(addr); __data;}) - -#ifdef HWMACRO_GPE - -/// 64-bit MMIO Write -#define out64(addr, data) \ - do { \ - uint64_t __data = (data); \ - volatile uint32_t *__addr_hi = (uint32_t *)(addr); \ - volatile uint32_t *__addr_lo = __addr_hi + 1; \ - *__addr_hi = (__data >> 32); \ - *__addr_lo = (__data & 0xffffffff); \ - } while(0) - -#else /* standard PPE's require a 64 bit write */ - -/// 64-bit MMIO Write -#define out64(addr, data) \ -{\ - uint64_t __d = (data); \ - uint32_t* __a = (uint32_t*)(addr); \ - asm volatile \ - (\ - "stvd %1, %0 \n" \ - : "=o"(*__a) \ - : "r"(__d) \ - ); \ -} - -#endif /* HWMACRO_GPE */ - -#ifdef HWMACRO_GPE -/// 64-bit MMIO Read -#define in64(addr) \ - ({ \ - uint64_t __data; \ - volatile uint32_t *__addr_hi = (uint32_t *)(addr); \ - volatile uint32_t *__addr_lo = __addr_hi + 1; \ - __data = *__addr_hi; \ - __data = (__data << 32) | *__addr_lo; \ - __data;}) - -#else /* Standard PPE's require a 64 bit read */ - -#define in64(addr) \ -({\ - uint64_t __d; \ - uint32_t* __a = (uint32_t*)(addr); \ - asm volatile \ - (\ - "lvd %0, %1 \n" \ - :"=r"(__d) \ - :"o"(*__a) \ - ); \ - __d; \ -}) - -#endif /* HWMACRO_GPE */ - -#endif /* __ASSEMBLER__ */ - -#include "ppe42_irq.h" - -#ifndef __ASSEMBLER__ - -/// Store revision information as a (global) string constant -#define REVISION_STRING(symbol, rev) const char* symbol = rev; - -#else // __ASSEMBLER__ - -/// Store revision information as a global string constant - .macro .revision_string, symbol:req, rev:req - .pushsection .rodata - .balign 4 - .global \symbol -\symbol\(): - .asciz "\rev" - .balign 4 - .popsection - .endm - -#endif // __ASSEMBLER__ - - - -#include "ppe42_context.h" - -// PPE42 stack characteristics for PK. The pre-pattern pattern is selected -// to be easily recognizable yet be an illegal instruction. - -#define PK_STACK_DIRECTION -1 -#define PK_STACK_PRE_DECREMENT 1 -#define PK_STACK_ALIGNMENT 8 -#define PK_STACK_TYPE unsigned int -#define PK_STACK_PATTERN 0x03abcdef - -// Kernel data structure offsets for assembler code - -#define PK_THREAD_OFFSET_SAVED_STACK_POINTER 0 -#define PK_THREAD_OFFSET_STACK_LIMIT 4 -#define PK_THREAD_OFFSET_STACK_BASE 8 - -// PK boot loader panic codes - -#define PPE42_BOOT_VECTORS_NOT_ALIGNED 0x00405001 - -// Interrupt handler panic codes - -#define PPE42_DEFAULT_IRQ_HANDLER 0x00405010 -#define PPE42_DEFAULT_SPECIAL_HANDLER 0x00405011 -#define PPE42_PHANTOM_INTERRUPT 0x00405012 -#define PPE42_PROGRAM_HALT 0x00405013 - - -// Exception handling invariant panic codes - -#define PPE42_IRQ_FULL_EXIT_INVARIANT 0x00405020 -#define PPE42_IRQ_FAST2FULL_INVARIANT 0x00405021 - - -// API error panic codes - - -// Application-overrideable definitions - -/// The default thread machine context has MSR[CE], MSR[EE] and MSR[ME] set, -/// and all other MSR bits cleared. -/// -/// The default definition allows external and machine check exceptions. This -/// definition can be overriden by the application. - -#ifndef PK_THREAD_MACHINE_CONTEXT_DEFAULT -#define PK_THREAD_MACHINE_CONTEXT_DEFAULT \ - (MSR_UIE | MSR_EE | MSR_ME) - -#endif - - -#ifndef __ASSEMBLER__ - -/// The PK kernel default panic sequence for C code -/// -/// By default a kernel panic from C code forces external debug mode then -/// generates a \c trap instruction followed by the error code. The \a code -/// argument must be a compile-time integer immediate. This definition can be -/// overriden by the application. -/// -/// The OCC may be running in internal debug mode for various reasons, and -/// TRAP-ing in internal debug mode would lead to an infinite loop in the -/// default Program Interrupt handler - which itself would be a TRAP (since -/// that's the default implementation of PK_PANIC(). Therefore by default -/// the panic is implemented as a special code sequence that forces the core -/// into external debug mode before issuing a TRAP which will halt the core. -/// To preserve the state we use the special global variables -/// __pk_panic_save_dbcr0 and __pk_panic_save_r3 defined in ppe42_core.c. -/// The original value of DBCR0 is destroyed, but can be recovered from the -/// global. In the end %r3 is reloaded from temporary storage and will be -/// unchanged at the halt. -/// -/// Note that there is a small chance that an interrupt will fire and -/// interrupt this code before the halt - in general there is no way around -/// this. -/// -/// The Simics environment does not model Debug events correctly. It executes -/// the TRAP as an illegal instruction and branches to the Program Interrupt -/// handler, destroying the contents of SRR0 and SRR1. Therefore we always -/// insert a special Simics magic breakpoint (which is an effective NOP) -/// before the hardware trap. The special-form magic instruction is -/// recognized by our Simics support scripts which decode the kernel state and -/// try to help the user interpret what happened based on the TRAP code. - -#ifndef PK_PANIC - -/*#define PK_PANIC(code) \ - do { \ - barrier(); \ - asm volatile ("stw %r3, __pk_panic_save_r3@sda21(0)"); \ - asm volatile ("mfdbcr0 %r3"); \ - asm volatile ("stw %r3, __pk_panic_save_dbcr0@sda21(0)"); \ - asm volatile ("lwz %r3, __pk_panic_dbcr0@sda21(0)"); \ - asm volatile ("mtdbcr0 %r3"); \ - asm volatile ("isync"); \ - asm volatile ("lwz %r3, __pk_panic_save_r3@sda21(0)"); \ - asm volatile ("rlwimi 1,1,0,0,0"); \ - asm volatile ("trap"); \ - asm volatile (".long %0" : : "i" (code)); \ - } while (0) -*/ -#define PK_PANIC(code) \ - do { \ - barrier(); \ - asm volatile ("b ."); \ - } while (0) - -// These variables are used by the PK_PANIC() definition above to save and -// restore state. __pk_panic_dbcr0 is the value loaded into DBCR0 to force -// traps to halt the OCC and freeze the timers. - -//#ifdef __PPE42_CORE_C__ -//uint32_t __pk_panic_save_r3; -//uint32_t __pk_panic_save_dbcr0; -//uint32_t __pk_panic_dbcr0 = DBCR0_EDM | DBCR0_TDE | DBCR0_FT; -//#endif - -#endif // PK_PANIC - -/// This is the Simics 'magic breakpoint' instruction. -/// -/// Note that this form does not include a memory barrier, as doing so might -/// change the semantics of the program. There is an alternative form -/// SIMICS_MAGIC_BREAKPOINT_BARRIER that does include a barrier. - -//#define SIMICS_MAGIC_BREAKPOINT asm volatile ("rlwimi 0,0,0,0,0") - -/// This is the Simics 'magic breakpoint' instruction including a memory -/// barrier. -/// -/// Note that the memory barrier guarantees that all variables held in -/// registers are flushed to memory before the breakpoint, however this might -/// change the semantics of the program. There is an alternative form of -/// SIMICS_MAGIC_BREAKPOINT that does not include a barrier. If the idea is -/// to use the breakpoint for tracing code execution in Simics, the barrier -/// form may be preferred so that variable values will be visible in memory. - -/*#define SIMICS_MAGIC_BREAKPOINT_BARRIER \ - asm volatile ("rlwimi 0,0,0,0,0" : : : "memory") -*/ - -#else // __ASSEMBLER__ - -/// This is the Simics 'magic breakpoint' instruction. An assembler macro -/// form is also provided for use within macros. - -//#define SIMICS_MAGIC_BREAKPOINT rlwimi 0,0,0,0,0 - -// .macro _simics_magic_breakpoint -// rlwimi 0,0,0,0,0 -// .endm - -/// The PK kernel panic default panic sequence for assembler code -/// -/// By default a kernel panic from assembler forces external debug mode then -/// generates a \c trap instruction followed by the error code. The \a code -/// argument must be a compile-time integer immediate. This definition can be -/// overriden by the application. -/// -/// See the comments for the non-ASSEMBLER version for further details. Note -/// that the code space reserved for exception handlers is only 8 -/// instructions, so in the assembler context we don't save DBCR0 as doing so -/// would require 10. - -#ifndef PK_PANIC - -#define PK_PANIC(code) _pk_panic code - - .macro _pk_panic, code - b . - .endm - -#endif // PK_PANIC - -#endif // __ASSEMBLER__ - - -// Application-overridible definitions for the PK boot loader - -/// In order to enable the default kernel panic (a trap) to halt the machine, -/// the Debug Control Register 0 (DBCR0) is initialized in externel debug -/// mode, with the Trap Debug Event enabled so that the trap will not cause a -/// program exception, and the FT bit set so that the timers will freeze. -/// This definition can be overridden by the application. -/// -/// NB: It is expected that a reliable production system will redefine all of -/// the 'panic' macros and the default DBCR0 setup. - -#ifndef PPE42_DBCR_INITIAL -#define PPE42_DBCR_INITIAL DBCR_TRAP -#endif - -/// This is the value of the MSR used during initialization. Once PK threads -/// are started (with \c pk_start_threads()), all machine contexts derive -/// from the default thread context \c -/// PK_THREAD_MACHINE_CONTEXT_DEFAULT. This definition can be overriden by -/// the application. -/// -/// The default is to enable machine checks only. - -#ifndef PPE42_MSR_INITIAL -#define PPE42_MSR_INITIAL MSR_ME -#endif - -/// The \a argc argument passed to \c main(). This definition can be overriden -/// by the application. - -#ifndef PPE42_ARGC_INITIAL -#define PPE42_ARGC_INITIAL 0 -#endif - -/// The \a argv argument passed to \c main(). This definition can be overriden -/// by the application. - -#ifndef PPE42_ARGV_INITIAL -#define PPE42_ARGV_INITIAL 0 -#endif - -/// Optionally trap the reset for the debugger, which means that the PPE42 -/// will simply spin at the symbol \c __reset_trap after a chip reset. Set R0 -/// to a non-zero value in the debugger to continue execution. This definition -/// can be overriden by the application. - -#ifndef PPE42_RESET_TRAP -#define PPE42_RESET_TRAP 0 -#endif - -#ifndef __ASSEMBLER__ - -/// The PPE42 PK machine context is simply the MSR, a 32-bit integer. - -typedef uint32_t PkMachineContext; - -/// Disable interrupts and return the current -/// context. -/// -/// \param context A pointer to an PkMachineContext, this is the context that -/// existed before interrupts were disabled. Typically this -/// context is restored at the end of a critical section. -/// -/// Return values other then PK_OK (0) are errors; see \ref pk_errors -/// -/// \retval 0 Successful completion -/// -/// \retval -PK_INVALID_ARGUMENT_INTERRUPT An illegal priority was specified. - -UNLESS__PPE42_CORE_C__(extern) -inline int -pk_interrupt_disable(PkMachineContext *context) -{ - *context = mfmsr(); - - wrteei(0); - - return PK_OK; -} - -/// Set the machine context. -/// -/// \param context A pointer to an PkMachineContext -/// -/// Return values other then PK_OK (0) are errors; see \ref pk_errors -/// -/// \retval 0 Successful completion -/// -/// \retval -PK_INVALID_ARGUMENT_CONTEXT_SET A null pointer was provided as -/// the \a context argument or an illegal machine context was specified. - -UNLESS__PPE42_CORE_C__(extern) -inline int -pk_machine_context_set(PkMachineContext *context) -{ - if (PK_ERROR_CHECK_API) { - PK_ERROR_IF(context == 0, PK_INVALID_ARGUMENT_CONTEXT_SET); - } - - mtmsr(*context); - - return PK_OK; -} - -/// Get the machine context. -/// -/// \param context A pointer to an PkMachineContext. -/// -/// Return values other then PK_OK (0) are errors; see \ref pk_errors -/// -/// \retval 0 Successful completion -/// -/// \retval -PK_INVALID_ARGUMENT_CONTEXT_GET A null pointer was provided as -/// the \a context argument. - -UNLESS__PPE42_CORE_C__(extern) -inline int -pk_machine_context_get(PkMachineContext *context) -{ - if (PK_ERROR_CHECK_API) { - PK_ERROR_IF(context == 0, PK_INVALID_ARGUMENT_CONTEXT_GET); - } - - *context = mfmsr(); - - return PK_OK; -} - -extern void __ctx_switch(); -/// The PK context switch for the PPE kernel -// There is no protected mode in PPE42 so just call kernel code -#define __pk_switch() __ctx_switch() - - -/// In the PowerPC EABI all initial stack frames require 8 bytes - the 4 bytes -/// at the SP are zeroed to indicate the end of the stack, and the 4 bytes -/// behind the SP are for the initial subroutine's LR. - -static inline void -__pk_stack_create_initial_frame(PkAddress *stack, size_t *size) \ -{ - *stack -= 8; - *size -= 8; - *((PK_STACK_TYPE *)(*stack)) = 0; -} - -/// The PK Kernel Context for PPE42 -/// -/// The PK portable kernel does not define how the kernel keeps track of -/// whether PK is running, interrupt levels, and other debug -/// information. Instead it defines an API that the port must provide to the -/// portable kernel. -/// -/// In the PPE42 port, the kernel context is maintained in SPRG0. This -/// 32-bit value is treated as 6 distinct fields as indicated in the structure -/// definition. -typedef union { - - uint32_t value; - - struct { - - /// A flag indicating that PK is in thread mode after a call of - /// pk_start_threads(). - unsigned thread_mode : 1; - - /// If this field is non-zero then PK is processing an interrupt - /// and the \c irq field will contain the PkIrqId of the interrupt - /// that kicked off interrupt processing. - unsigned processing_interrupt : 1; - - /// The priority of the currently running thread. In an interrupt - /// context, this is the priority of the thread that was interrupted. - unsigned thread_priority : 6; - - /// This bit tracks whether the current context can be discarded or - /// if the context must be saved. If the processor takes an interrupt - /// and this bit is set, then the current context will be discarded. - /// This bit is set at the end of handling an interrupt and prior - /// to entering the wait enabled state. - unsigned discard_ctx : 1; - - /// The PkIrqId of the currently running (or last run) handler. If - /// \c processing_interrupt is set, then this is the - /// PkIrqId of the IRQ that is currently executing. - unsigned irq : 7; - - /// Each PPE application will define (or not) the interpretation of - /// this field. Since SPRG0 is saved and restored during during thread - /// context switches, this field can be used to record the progress of - /// individual threads. The kernel and/or application will provide - /// APIs or macros to read and write this field. - unsigned app_specific : 16; - - } fields; - -} __PkKernelContext; - -// These APIs are provided for applications to get and set the app_specific -// field of the kernel context which is held in sprg0. - -static inline uint16_t ppe42_app_ctx_get(void) -{ - __PkKernelContext __ctx; - __ctx.value = mfspr(SPRN_SPRG0); - return __ctx.fields.app_specific; -} - -static inline void ppe42_app_ctx_set(uint16_t app_ctx) -{ - PkMachineContext mctx; - __PkKernelContext __ctx; - mctx = mfmsr(); - wrteei(0); - __ctx.value = mfspr(SPRN_SPRG0); - __ctx.fields.app_specific = app_ctx; - mtspr(SPRN_SPRG0, __ctx.value); - mtmsr(mctx); -} - -// These APIs are provided to the PK portable kernel by the port. - -/// PK threads have been started by a call of pk_start_threads(). - -#define __pk_kernel_mode_thread() \ - ({ \ - __PkKernelContext __ctx; \ - __ctx.value = mfspr(SPRN_SPRG0); \ - __ctx.fields.thread_mode;}) - - -/// PK is executing in a thread context (not an interrupt handler). - -#define __pk_kernel_context_thread() \ - ({ \ - __PkKernelContext __ctx; \ - __ctx.value = mfspr(SPRN_SPRG0); \ - __ctx.fields.thread_mode && !__ctx.fields.processing_interrupt;}) - - -/// PK is executing an interrupt handler of any priority. - -#define __pk_kernel_context_any_interrupt() \ - ({ \ - __PkKernelContext __ctx; \ - __ctx.value = mfspr(SPRN_SPRG0); \ - __ctx.fields.processing_interrupt;}) - - -// PK requires the port to define the type PkThreadQueue, which is a -// priority queue (where 0 is the highest priority). This queue must be able -// to handle PK_THREADS + 1 priorities (the last for the idle thread) The -// port must also define methods for clearing, insertion, deletion and min -// (with assumed legal priorities). The min operation returns PK_THREADS if -// the queue is empty (or a queue could be initialized with that entry always -// present - PK code never tries to delete the idle thread from a thread -// queue). -// -// These queues are used both for the run queue and the pending queue -// associated with every semaphore. -// -// On PPE42 with 32 threads (implied), this is a job for a uint32_t and -// cntlzw(). - -static inline void -__pk_thread_queue_clear(volatile PkThreadQueue *queue) -{ - *queue = 0; -} - -static inline void -__pk_thread_queue_insert(volatile PkThreadQueue *queue, PkThreadPriority priority) -{ - *queue |= (0x80000000u >> priority); -} - -static inline void -__pk_thread_queue_delete(volatile PkThreadQueue *queue, PkThreadPriority priority) -{ - *queue &= ~(0x80000000u >> priority); -} - -static inline PkThreadPriority -__pk_thread_queue_min(volatile PkThreadQueue *queue) -{ - return cntlzw(*queue); -} - -static inline int -__pk_thread_queue_member(volatile PkThreadQueue *queue, PkThreadPriority priority) -{ - return ((*queue >> (31 - priority)) & 1); -} - -static inline void -__pk_thread_queue_union(volatile PkThreadQueue *queue0, - volatile PkThreadQueue *queue1) -{ - *queue0 |= *queue1; -} - -static inline int -__pk_thread_queue_count(volatile PkThreadQueue* queue) -{ - return __builtin_popcount(*queue); -} - - -/// This macro is used to call __pk_start_threads() using the kernel stack, -/// in a critical section. - -#define __pk_call_pk_start_threads() \ - do { \ - PkMachineContext ctx; \ - pk_critical_section_enter(&ctx); \ - asm volatile ("mr 1, %0; mtlr %1; blrl" : : \ - "r" (__pk_kernel_stack), \ - "r" (__pk_start_threads)); \ - PK_PANIC(PK_START_THREADS_RETURNED); \ - } while (0) - - -#endif /* __ASSEMBLER__ */ - -/// The __PkKernelContext 'thread_mode' bit as a flag - -#define PPE42_THREAD_MODE 0x8000 -#define PPE42_PROC_IRQ 0x4000 -#define PPE42_DISCARD_CTX 0x0080 - -#define PPE42_THREAD_MODE_BIT 0 -#define PPE42_PROC_IRQ_BIT 1 -#define PPE42_DISCARD_CTX_BIT 8 - -#ifndef __ASSEMBLER__ - -/// Code breakpoints for PPE42 -/// -/// This macro inserts a special PPE42-only breakpoint into the object code -/// at the place the macro invocation appears. This facility is designed for -/// VBU/VPO procedure debugging. This type of breakpoint may not be required -/// on real hardware as we will then have the full power of RISCWatch, gdb, -/// etc. Once inserted into the code, code breakpoints can be enabled or -/// disabled by manipulating the global variable _code_breakpoint_enable, -/// which defaults to 1. -/// -/// The code breakpoint is implemented as a setup routine and a teardown -/// routine, executed in an critical section. The actual break -/// will occur at the address of the call of the teardown routine, in the -/// context of the calling code. The setup routine saves the state of DBCR0/1 -/// and IAC4, then programs the DBCR for an external debug mode, IAC4 -/// breakpoint. The IAC4 breakpoint is set for the address of the call of the -/// teardown routine. The teardown routine simply restores the state of the -/// debug registers that existed before the code breakpoint. -/// -/// Once hit, restarting from the break requires clearing IAC4 and restarting -/// instructions: -/// -/// \code -/// -/// putspr pu.occ iac4 0 -/// cipinstruct pu.occ start -/// -/// \endcode -/// -/// The above restart processes is also encapsulated as the p8_tclEcmd -/// procedure 'unbreakOcc'. -/// -/// In code built for the Simics environment (i.e., with the preprocessor -/// macro SIMICS_ENVIRONMENT=1) this macro simply expands into -/// SIMICS_MAGIC_BREAKPOINT, and simulation can be continued from the break as -/// normal. This Simics magic breakpoint is also under the control of -/// _code_breakpoint_enable. In code not built with SIMICS_ENVIROMENT=1, note -/// that the CODE_BREAKPOINT is ignored by the Simics PPE42 model as it does -/// not model debug events. - -//#if defined(SIMICS_ENVIRONMENT) && (SIMICS_ENVIRONMENT != 0) -/*#define CODE_BREAKPOINT \ - do { \ - if (_code_breakpoint_enable) { \ - SIMICS_MAGIC_BREAKPOINT; \ - } \ - } while (0) -#else -#define CODE_BREAKPOINT \ - do { \ - if (_code_breakpoint_enable) { \ - PkMachineContext __ctx; \ - pk_critical_section_enter(&__ctx); \ - _code_breakpoint_prologue(); \ - _code_breakpoint_epilogue(); \ - pk_critical_section_exit(&__ctx); \ - } \ - } while (0) -#endif -*/ - -//void -//_code_breakpoint_prologue(void); - -//void -//_code_breakpoint_epilogue(void); - -//extern uint32_t _code_breakpoint_enable; - -#endif // __ASSEMBLER__ - - -#endif /* __PPE42_H__ */ |