From 05e548e9ebf97a5f1d278b0fa3e663959ab0f37e Mon Sep 17 00:00:00 2001 From: "Christopher M. Riedl" Date: Wed, 3 May 2017 08:01:45 -0500 Subject: IOTA: Interrupt-Oriented Task Administrator (CME) - experimental replacement for pk on CME to reduce code size Change-Id: Iacff51d23494b28617d27d80fca52288cdd11a0a Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/40009 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert Reviewed-by: CHRISTOPHER M. RIEDL Reviewed-by: Michael S. Floyd Reviewed-by: Jennifer A. Stofer --- import/chips/p9/procedures/ppe/iota/iota.c | 177 ++++++++++++++++ import/chips/p9/procedures/ppe/iota/iota.h | 183 ++++++++++++++++ import/chips/p9/procedures/ppe/iota/iota_ppe42.S | 133 ++++++++++++ import/chips/p9/procedures/ppe/iota/iota_ppe42.h | 129 ++++++++++++ .../p9/procedures/ppe/iota/iota_ppe42_vectors.S | 79 +++++++ import/chips/p9/procedures/ppe/iota/iota_uih.c | 230 +++++++++++++++++++++ import/chips/p9/procedures/ppe/iota/iota_uih.h | 98 +++++++++ import/chips/p9/procedures/ppe/iota/link.ld | 54 +++++ import/chips/p9/procedures/ppe/iota/main.c | 97 +++++++++ import/chips/p9/procedures/ppe/iota/pk.h | 41 ++++ 10 files changed, 1221 insertions(+) create mode 100644 import/chips/p9/procedures/ppe/iota/iota.c create mode 100644 import/chips/p9/procedures/ppe/iota/iota.h create mode 100644 import/chips/p9/procedures/ppe/iota/iota_ppe42.S create mode 100644 import/chips/p9/procedures/ppe/iota/iota_ppe42.h create mode 100644 import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S create mode 100644 import/chips/p9/procedures/ppe/iota/iota_uih.c create mode 100644 import/chips/p9/procedures/ppe/iota/iota_uih.h create mode 100644 import/chips/p9/procedures/ppe/iota/link.ld create mode 100644 import/chips/p9/procedures/ppe/iota/main.c create mode 100644 import/chips/p9/procedures/ppe/iota/pk.h (limited to 'import/chips/p9/procedures/ppe') diff --git a/import/chips/p9/procedures/ppe/iota/iota.c b/import/chips/p9/procedures/ppe/iota/iota.c new file mode 100644 index 00000000..5068912a --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/iota.c @@ -0,0 +1,177 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/iota.c $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include "iota.h" +#include "iota_uih.h" +#include "iota_ppe42.h" + +iotaMachineState g_iota_machine_state_stack[(IOTA_MAX_NESTED_INTERRUPTS)] __attribute__((aligned(8))) = +{ + [ 0 ... (IOTA_MAX_NESTED_INTERRUPTS - 1) ] = IOTA_MACHINE_STATE_INIT +}; +uint64_t g_iota_execution_stack[(IOTA_EXECUTION_STACK_SIZE / 8)] __attribute__((aligned(8))) = +{ + [ 0 ... ((IOTA_EXECUTION_STACK_SIZE / 8) - 1) ] = IOTA_STACK_PATTERN +}; +iotaMachineState* g_iota_curr_machine_state_ptr = g_iota_machine_state_stack; + +iotaTimerFuncPtr g_iota_dec_handler = IOTA_TIMER_HANDLER(__iota_halt); +iotaTimerFuncPtr g_iota_fit_handler = IOTA_TIMER_HANDLER(__iota_halt); + +void _iota_evaluate_idle_tasks() +{ + // Iterate over all idle tasks + uint32_t idle_task_idx = 0; + + for(; idle_task_idx < g_iota_idle_task_list_size; ++idle_task_idx) + { + // Enabled tasks get executed + if(g_iota_idle_task_list[idle_task_idx].state >= IOTA_IDLE_ENABLED) + { + if(g_iota_idle_task_list[idle_task_idx].function == IOTA_NO_TASK) + { + // Tried to execute a NULLPTR task + iota_halt(); + } + + g_iota_idle_task_list[idle_task_idx].function(idle_task_idx); + +#if IOTA_AUTO_DISABLE_IDLE_TASKS + uint32_t ctx = mfmsr(); + wrteei(0); + + g_iota_idle_task_list[idle_task_idx].state = IOTA_IDLE_DISABLED; + + mtmsr(ctx); +#endif + } + } +} + +extern void main(void); + +void _iota_boot() +{ + g_iota_curr_machine_state_ptr = g_iota_machine_state_stack; + main(); +} + +void iota_run() +{ + while(1) + { + // Run any enabled idle tasks + _iota_evaluate_idle_tasks(); + // FIXME / TODO load default MSR here? + uint32_t ctx = mfmsr() | MSR_WE | MSR_EE ; + mtmsr(ctx); + } +} + +void iota_set_idle_task_state(uint32_t state, uint32_t idle_task_idx) +{ + if(idle_task_idx < g_iota_idle_task_list_size) + { + // Ignore any task entries which have no task assigned... + if(g_iota_idle_task_list[idle_task_idx].function != IOTA_NO_TASK) + { + // Setting/changing an idle task enable needs to be done atomically + uint32_t ctx = mfmsr(); + wrteei(0); + + g_iota_idle_task_list[idle_task_idx].state = state; + + mtmsr(ctx); + } + } +} + +void _iota_schedule(uint32_t schedule_reason) +{ + // Increment machine state pointer + if(g_iota_curr_machine_state_ptr < &g_iota_machine_state_stack[IOTA_MAX_NESTED_INTERRUPTS - 1]) + { + g_iota_curr_machine_state_ptr++; + } + else + { + iota_halt(); + } + + // TODO call appropriate interrupt handler here + uint32_t task_idx; + + switch(schedule_reason) + { + case _IOTA_SCHEDULE_REASON_EXT: + task_idx = iota_uih(); + + if(g_iota_task_list[task_idx] != IOTA_NO_TASK) + { + uint32_t ctx = mfmsr(); + wrteei(1); + g_iota_task_list[task_idx](task_idx); + mtmsr(ctx); + } + else + { + iota_halt(); + } + + break; + + case _IOTA_SCHEDULE_REASON_DEC: + g_iota_dec_handler(); + break; + + case _IOTA_SCHEDULE_REASON_FIT: + g_iota_fit_handler(); + break; + } + + // TODO check for idle tasks here + // Rationale: if the g_iota_curr_machine_state_ptr == &g_iota_curr_machine_state_ptr[0], + // then all interrupt tasks must be completed since this is the last + // context about to be restored, which means enabled idle tasks + // can be executed + iotaMachineState* p = g_iota_curr_machine_state_ptr; + + if(--p == g_iota_machine_state_stack) + { + uint32_t ctx = mfmsr(); + wrteei(1); + _iota_evaluate_idle_tasks(); + mtmsr(ctx); + } + + // Decrement machine state pointer + if(g_iota_curr_machine_state_ptr > g_iota_machine_state_stack) + { + g_iota_curr_machine_state_ptr--; + } + else + { + iota_halt(); + } +} diff --git a/import/chips/p9/procedures/ppe/iota/iota.h b/import/chips/p9/procedures/ppe/iota/iota.h new file mode 100644 index 00000000..d2c628ff --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/iota.h @@ -0,0 +1,183 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/iota.h $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __IOTA_H__ +#define __IOTA_H__ + +#include "iota_app_cfg.h" + +#ifndef __ASSEMBLER__ + +#include +#include "iota_ppe42.h" +#include "cme_register_addresses.h" + +/** + * Run the main IOTA kernel loop + * @note does not return + */ +void iota_run() __attribute__((noreturn)); + +#define iota_halt() __iota_halt() + +/** + * Set the state of an idle task + * @param[in] The state + * @param[in[ The task index in the idle task table + */ +void iota_set_idle_task_state(uint32_t state, uint32_t idle_task_idx); + + +/// IOTA --- CONSTANTS +#if !defined(IOTA_STACK_PATTERN) + #define IOTA_STACK_PATTERN 0xfeedfeedfeedfeedull +#endif + +#if !defined(IOTA_64U_ARR_INIT) + #define IOTA_64U_ARR_INIT 0x6666666666666666ull +#endif + +#if !defined(IOTA_32U_ARR_INIT) + #define IOTA_32U_ARR_INIT 0x66666666ul +#endif + +#if !defined(IOTA_08U_ARR_INIT) + #define IOTA_08U_ARR_INIT 0x66u +#endif + +#define IOTA_NO_TASK ((iotaTaskFuncPtr)(IOTA_32U_ARR_INIT)) +#define IOTA_IDLE_DISABLED 0x00000000 +#define IOTA_IDLE_ENABLED 0x00000001 + +#if !defined(IOTA_DEFAULT_MSR) + #define IOTA_DEFAULT_MSR 0x00000000 +#endif + +/// + +/// IOTA -- CONVENIENCE MACROS +// This below macro-fu is an adaptation of a similar macro in the Linux kernel (BUILD_BUG_ON) +// Allows compile time checking of conditions using sizeof() +#define IOTA_TOKEN_PASTE0(a,b) a ## b +#define IOTA_TOKEN_PASTE1(a,b) IOTA_TOKEN_PASTE0(a,b) +#define IOTA_COMPILE_TIME_UNIQUE IOTA_TOKEN_PASTE1(_iota_compile_unique_,__COUNTER__) +#define IOTA_COMPILE_TIME_CHECK(condition) extern int IOTA_COMPILE_TIME_UNIQUE [!!(condition)-1]; + +#define IOTA_TASK(function) ((iotaTaskFuncPtr)function) + +#define IOTA_TIMER_HANDLER(function) ((iotaTimerFuncPtr)function) +#define IOTA_DEC_HANDLER(function) g_iota_dec_handler = IOTA_TIMER_HANDLER(function); +#define IOTA_FIT_HANDLER(function) g_iota_fit_handler = IOTA_TIMER_HANDLER(function); + +#define IOTA_BEGIN_IDLE_TASK_TABLE \ + iotaIdleTask g_iota_idle_task_list[] = { +#define IOTA_END_IDLE_TASK_TABLE \ + }; \ + uint32_t const g_iota_idle_task_list_size = (uint32_t)(sizeof(g_iota_idle_task_list)/sizeof(iotaIdleTask)); + +#define IOTA_BEGIN_TASK_TABLE \ + iotaTaskFuncPtr g_iota_task_list[] = { +#define IOTA_END_TASK_TABLE \ + }; \ + uint32_t const g_iota_task_list_size = (uint32_t)(sizeof(g_iota_task_list)/sizeof(iotaTaskFuncPtr)); \ + IOTA_COMPILE_TIME_CHECK((sizeof(g_iota_task_list)/sizeof(iotaTaskFuncPtr)) == (IOTA_NUM_EXT_IRQ_PRIORITIES)); + +#define IOTA_MACHINE_STATE_INIT { \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT, \ + IOTA_32U_ARR_INIT \ + } +/// + +typedef struct +{ + uint32_t GPR0; + uint32_t GPR1; + uint32_t GPR4; + uint32_t GPR5; + uint32_t GPR6; + uint32_t GPR7; + uint32_t GPR8; + uint32_t GPR9; + uint32_t GPR28; + uint32_t GPR29; + uint32_t GPR30; + uint32_t GPR31; + uint32_t SRR0; + uint32_t SRR1; + uint32_t LR; + uint32_t CR; + uint32_t GPR3; + uint32_t GPR10; + uint32_t CTR; + uint32_t padding; // needs to be 8B aligned +} iotaMachineState; + +typedef void (*iotaTaskFuncPtr )(uint32_t arg); +typedef void (*iotaTimerFuncPtr)(void ); + +typedef struct +{ + uint32_t state; + iotaTaskFuncPtr function; +} iotaIdleTask; + +extern iotaMachineState g_iota_machine_state_stack[]; +extern iotaMachineState* g_iota_curr_machine_state_ptr; +extern iotaTaskFuncPtr g_iota_task_list[]; +extern iotaIdleTask g_iota_idle_task_list[]; +extern uint32_t const g_iota_idle_task_list_size; +extern uint32_t const g_iota_task_list_size; +extern uint64_t g_iota_execution_stack[]; + +void _iota_boot(); +void _iota_schedule(uint32_t schedule_reason); +void _iota_evaluate_idle_tasks(); + +extern void __iota_halt() __attribute__((noreturn)); +extern void iota_uih_irq_vec_restore(); + +extern iotaTimerFuncPtr g_iota_dec_handler; +extern iotaTimerFuncPtr g_iota_fit_handler; + + +#endif // __ASSEMBLER__ + +#endif //__IOTA_H__ diff --git a/import/chips/p9/procedures/ppe/iota/iota_ppe42.S b/import/chips/p9/procedures/ppe/iota/iota_ppe42.S new file mode 100644 index 00000000..e1e4f47f --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/iota_ppe42.S @@ -0,0 +1,133 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/iota_ppe42.S $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include "iota.h" +#include "iota_ppe42.h" + +.global g_iota_execution_stack + +.global __iota_boot +__iota_boot: + # Enable 'trap' to cause a halt + li %r3, 0x0100 + slwi %r3, %r3, 16 + mtdbcr %r3 + + # Mask timer interrupts + li %r3, 0 + mttcr %r3 + + # Load the sda and sda2 pointers to eabi-defined registers + lis %r13, _SDA_BASE_@h + ori %r13, %r13, _SDA_BASE_@l + lis %r2, _SDA2_BASE_@h + ori %r2, %r2, _SDA2_BASE_@l + + # Load the initial stack pointer + lis %r1, g_iota_execution_stack@h + ori %r1, %r1, g_iota_execution_stack@l + addi %r3, 0, IOTA_EXECUTION_STACK_SIZE + add %r1, %r1, %r3 + # 0 to indicate the end of the stack chain + li %r3, 0 + stwu %r3, -8(%r1) + + b _iota_boot + + +# This routine is called for every interrupt/exception which is a "reason" +# for iota to schedule a task. The current machine state is saved. +# A few pre-conditions must be met: +# - original r3 value (yet to be saved!) is at _IOTA_TEMPORARY_R3_STACK_OFFSET(sp) +# - the pointer to location of where to save machine state is in r9 +# - the schedule reason is in r3 +# - d8 is saved +# This routine sets up and calls _zbm_schedule (C-function), upon which's +# return the prior machine state is restored. + +.global g_iota_curr_machine_state_ptr +.global _iota_schedule + +.global __iota_save_interrupt_state_and_schedule +__iota_save_interrupt_state_and_schedule: + # First, save off the original value of r3 + lwz %r8, _IOTA_TEMPORARY_R3_STACK_OFFSET(%r1) + stw %r8, _IOTA_SAVE_R3_OFFSET(%r9) + # Save r10 + stw %r10, _IOTA_SAVE_R10_OFFSET(%r9) + # Save d0, d4, d6, d28, and d31 + stvd %d0, _IOTA_SAVE_D0_OFFSET(%r9) + stvd %d4, _IOTA_SAVE_D4_OFFSET(%r9) + stvd %d6, _IOTA_SAVE_D6_OFFSET(%r9) + stvd %d28, _IOTA_SAVE_D28_OFFSET(%r9) + stvd %d30, _IOTA_SAVE_D30_OFFSET(%r9) + # Piecemeal save srr0+srr1 and lr+cr + mfsrr0 %r4 + mfsrr1 %r5 + stvd %d4, _IOTA_SAVE_SRR0_OFFSET(%r9) + mflr %r4 + mfcr %r5 + stvd %d4, _IOTA_SAVE_LR_OFFSET(%r9) + mfctr %r4 + stw %r4, _IOTA_SAVE_CTR_OFFSET(%r9) + # All state is saved, sp(r1) intact pointing to "Execution Stack" + + # _iota_schedule(uint32_t schedule_reason) + # - schedule_reason is already in r3 + + bl _iota_schedule + + # Task completed, need to restore machine state now + # Get pointer to machine state + lis %r3, g_iota_curr_machine_state_ptr@h + ori %r3, %r3, g_iota_curr_machine_state_ptr@l + lwz %r3, 0(%r3) + # Restore d0 first (need sp in r1) + lvd %d0, _IOTA_SAVE_D0_OFFSET(%r3) + # Save the restore value of r3 to _IOTA_TEMPORARY_R3_STACK_OFFSET(sp) + lwz %r4, _IOTA_SAVE_R3_OFFSET(%r3) + stw %r4, _IOTA_TEMPORARY_R3_STACK_OFFSET(%r1) + # Restore d4, d6, d28, and d30 + lvd %d4, _IOTA_SAVE_D4_OFFSET(%r3) + lvd %d6, _IOTA_SAVE_D6_OFFSET(%r3) + lvd %d28, _IOTA_SAVE_D28_OFFSET(%r3) + lvd %d30, _IOTA_SAVE_D30_OFFSET(%r3) + # Restore r10 + lwz %r10, _IOTA_SAVE_R10_OFFSET(%r3) + # Restore lr and cr + lvd %d8, _IOTA_SAVE_LR_OFFSET(%r3) + mtlr %r8 + mtcr0 %r9 + lwz %r9, _IOTA_SAVE_CTR_OFFSET(%r3) + mtctr %r9 + # Restore d8 + lvd %d8, _IOTA_SAVE_D8_OFFSET(%r3) + # Restore r3 + lwz %r3, _IOTA_TEMPORARY_R3_STACK_OFFSET(%r1) + + rfi + +.global __iota_halt +__iota_halt: + trap diff --git a/import/chips/p9/procedures/ppe/iota/iota_ppe42.h b/import/chips/p9/procedures/ppe/iota/iota_ppe42.h new file mode 100644 index 00000000..8a6f29dd --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/iota_ppe42.h @@ -0,0 +1,129 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/iota_ppe42.h $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __IOTA_PPE42_H__ +#define __IOTA_PPE42_H__ + +#define _IOTA_SAVE_D0_OFFSET 0 +#define _IOTA_SAVE_D4_OFFSET 8 +#define _IOTA_SAVE_D6_OFFSET 16 +#define _IOTA_SAVE_D8_OFFSET 24 +#define _IOTA_SAVE_D28_OFFSET 32 +#define _IOTA_SAVE_D30_OFFSET 40 +#define _IOTA_SAVE_SRR0_OFFSET 48 +#define _IOTA_SAVE_SRR1_OFFSET 52 +#define _IOTA_SAVE_LR_OFFSET 56 +#define _IOTA_SAVE_CR_OFFSET 60 +#define _IOTA_SAVE_R3_OFFSET 64 +#define _IOTA_SAVE_R10_OFFSET 68 +#define _IOTA_SAVE_CTR_OFFSET 72 + +#define _IOTA_TEMPORARY_R3_STACK_OFFSET -4 + +#define _IOTA_SCHEDULE_REASON_FIT 0x0fff +#define _IOTA_SCHEDULE_REASON_DEC 0x0ddd +#define _IOTA_SCHEDULE_REASON_EXT 0x0eee + +#ifdef __ASSEMBLER__ +// *INDENT-OFF* + +# This routine is called on any exception or interrupt and saves some state +# prior to setting up the call to and calling __iota_save_interrupt_state_and_schedule +# Note: must be <=8 instructions! + +.macro __m_iota_interrupt_and_exception_handler, iota_schedule_reason +# temporarily place r3 on the stack, without incrementing sp +stw %r3, _IOTA_TEMPORARY_R3_STACK_OFFSET(%r1) +# load the pointer to the location of where to save machine state +lis %r3, g_iota_curr_machine_state_ptr@h +ori %r3, %r3, g_iota_curr_machine_state_ptr@l +lwz %r3, 0(%r3) +# save d8 +stvd %d8, _IOTA_SAVE_D8_OFFSET(%r3) +mr %r9, %r3 +li %r3, \iota_schedule_reason +b __iota_save_interrupt_state_and_schedule +.endm + +// *INDENT-ON* +#else + +#include "ppe42_msr.h" + +/// 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;}) + +/// 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) \ + ); \ + } + +/// 64-bit MMIO 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 // __ASSEMBLER__ + + +#endif // __IOTA_PPE42_H__ diff --git a/import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S b/import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S new file mode 100644 index 00000000..782f63ad --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S @@ -0,0 +1,79 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include "iota_ppe42.h" + +.section .vectors, "ax", @progbits + +.global __vectors +__vectors: + +.global __machine_check +__machine_check: + trap + +.global __system_reset +.org __vectors + 0x0040 +__system_reset: + b __iota_boot + +.global __data_storage +.org __vectors + 0x0060 +__data_storage: + trap + +.global __instruction_storage +.org __vectors + 0x0080 +__instruction_storage: + trap + +.global __external_interrupt +.org __vectors + 0x00a0 +__external_interrupt: + __m_iota_interrupt_and_exception_handler _IOTA_SCHEDULE_REASON_EXT + +.global __alignment_exception +.org __vectors + 0x00c0 +__alignment_exception: + trap + +.global __program_exception +.org __vectors + 0x00e0 +__program_exception: + trap + +.global __dec_interrupt +.org __vectors + 0x0100 +__dec_interrupt: + __m_iota_interrupt_and_exception_handler _IOTA_SCHEDULE_REASON_DEC + +.global __fit_interrupt +.org __vectors + 0x0120 +__fit_interrupt: + __m_iota_interrupt_and_exception_handler _IOTA_SCHEDULE_REASON_FIT + +.global __watchdog_interrupt +.org __vectors + 0x0140 +__watchdog_interrupt: + b __watchdog_interrupt diff --git a/import/chips/p9/procedures/ppe/iota/iota_uih.c b/import/chips/p9/procedures/ppe/iota/iota_uih.c new file mode 100644 index 00000000..2dd3d1c7 --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/iota_uih.c @@ -0,0 +1,230 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/iota_uih.c $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include "iota.h" +#include "iota_uih.h" + +// Notes: +// The following two lists, +// ext_irq_vectors_cme[][] and IDX_PRTY_LVL_, must match. +// IDX_PRTY_LVL_ is the tasks priority level and serves +// as the index into the ext_irq_vectors_cme[][] table. + +const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = +{ + /* 0: IDX_PRTY_VEC 1: IDX_MASK_VEC */ + { + IRQ_VEC_PRTY0_CME, /* 0: IDX_PRTY_LVL_HIPRTY */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME | + IRQ_VEC_PRTY7_CME | + IRQ_VEC_PRTY6_CME | + IRQ_VEC_PRTY5_CME | + IRQ_VEC_PRTY4_CME | + IRQ_VEC_PRTY3_CME | + IRQ_VEC_PRTY2_CME | + IRQ_VEC_PRTY1_CME | + IRQ_VEC_PRTY0_CME + }, + { + IRQ_VEC_PRTY1_CME, /* 1: IDX_PRTY_LVL_DB3 */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME | + IRQ_VEC_PRTY7_CME | + IRQ_VEC_PRTY6_CME | + IRQ_VEC_PRTY5_CME | + IRQ_VEC_PRTY4_CME | + IRQ_VEC_PRTY3_CME | + IRQ_VEC_PRTY2_CME | + IRQ_VEC_PRTY1_CME + }, + { + IRQ_VEC_PRTY2_CME, /* 2: IDX_PRTY_LVL_DB2 */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME | + IRQ_VEC_PRTY7_CME | + IRQ_VEC_PRTY6_CME | + IRQ_VEC_PRTY5_CME | + IRQ_VEC_PRTY4_CME | + IRQ_VEC_PRTY3_CME | + IRQ_VEC_PRTY2_CME + }, + { + IRQ_VEC_PRTY3_CME, /* 3: IDX_PRTY_LVL_SPWU */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME | + IRQ_VEC_PRTY7_CME | + IRQ_VEC_PRTY6_CME | + IRQ_VEC_PRTY5_CME | + IRQ_VEC_PRTY4_CME | + IRQ_VEC_PRTY3_CME + }, + { + IRQ_VEC_PRTY4_CME, /* 4: IDX_PRTY_LVL_WAKE */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME | + IRQ_VEC_PRTY7_CME | + IRQ_VEC_PRTY6_CME | + IRQ_VEC_PRTY5_CME | + IRQ_VEC_PRTY4_CME + }, + { + IRQ_VEC_PRTY5_CME, /* 5: IDX_PRTY_LVL_STOP */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME | + IRQ_VEC_PRTY7_CME | + IRQ_VEC_PRTY6_CME | + IRQ_VEC_PRTY5_CME + }, + { + IRQ_VEC_PRTY6_CME, /* 6: IDX_PRTY_LVL_DB1 */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME | + IRQ_VEC_PRTY7_CME | + IRQ_VEC_PRTY6_CME + }, + + { + IRQ_VEC_PRTY7_CME, /* 7: IDX_PRTY_LVL_DB0 */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME | + IRQ_VEC_PRTY7_CME + }, + + { + IRQ_VEC_PRTY8_CME, /* 8: IDX_PRTY_LVL_INTERCME_IN0 */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME | + IRQ_VEC_PRTY8_CME + }, + { + IRQ_VEC_PRTY9_CME, /* 9: IDX_PRTY_LVL_PMCR */ + IRQ_VEC_PRTY10_CME | + IRQ_VEC_PRTY9_CME + }, + { + IRQ_VEC_PRTY10_CME, /* 10: IDX_PRTY_LVL_DISABLED */ + IRQ_VEC_PRTY10_CME + } + +}; + +uint8_t g_current_prty_level = IOTA_NUM_EXT_IRQ_PRIORITIES - 1; +uint8_t g_eimr_stack[IOTA_NUM_EXT_IRQ_PRIORITIES]; +int g_eimr_stack_ctr = -1; +uint64_t g_eimr_override_stack[IOTA_NUM_EXT_IRQ_PRIORITIES]; +uint64_t g_eimr_override = 0x0000000000000000; + +// Unified IRQ priority and masking handler. +// - Locates the highest priority IRQ task vector that has at least one of its +// interrupts in the current external PK interrupt vector. +uint32_t iota_uih(void) +{ + uint32_t iPrtyLvl = 0, bFound = 0; + uint64_t ext_irq_vector; + + // 1. Identify the priority level of the interrupt. + ext_irq_vector = in64(CME_LCL_EISTR); + + do + { + if(ext_irq_vectors_cme[iPrtyLvl][IDX_PRTY_VEC] & ext_irq_vector) + { + bFound = 1; + break; + } + } + while(++iPrtyLvl < (IOTA_NUM_EXT_IRQ_PRIORITIES - 1)); //No need to check DISABLED. + + // Only manipulate EIMR masks for task level prty levels. + // Let shared non-task IRQs (iPrtyLvl=0) be processed by + // the PK kernel in usual fashion. + if(bFound) + { + // 2. Save current mask (assume current prty level). + // Note, reading EIMR is NOT safe because overrides may already have + // happened to the EIMR. And we always want to restore + // the EIMR to a known value when we exit our thread. + if(++g_eimr_stack_ctr < IOTA_NUM_EXT_IRQ_PRIORITIES) + { + // Make a note of present prty level and + // then update tracker to new prty level. + g_eimr_stack[g_eimr_stack_ctr] = g_current_prty_level; + g_current_prty_level = iPrtyLvl; // Update prty level tracker. + g_eimr_override_stack[g_eimr_stack_ctr] = g_eimr_override; + } + else + { + asm volatile("mtspr 0x110, %0" : : "r" (0xdead)); + iota_halt(); + } + + // 3. Write the new mask for this priority level. + out64(CME_LCL_EIMR, ext_irq_vectors_cme[iPrtyLvl][IDX_MASK_VEC] | + g_eimr_override); + + } + else + { + asm volatile("mtspr 0x110, %0" : : "r" (0xbeef)); + // Disabled IRQ fired + iota_halt(); + } + + // Return the priority level + return iPrtyLvl; +} + +void iota_uih_irq_vec_restore() +{ + uint32_t ctx = mfmsr(); + wrteei(0); + + if (g_eimr_stack_ctr >= 0) + { + out64(CME_LCL_EIMR, + ext_irq_vectors_cme[g_eimr_stack[g_eimr_stack_ctr]][IDX_MASK_VEC]); + out64(CME_LCL_EIMR_CLR, + g_eimr_override_stack[g_eimr_stack_ctr]); + out64(CME_LCL_EIMR_OR, + g_eimr_override); + // Restore the prty level tracker to the task that was interrupted, if any. + g_current_prty_level = g_eimr_stack[g_eimr_stack_ctr]; + g_eimr_stack_ctr--; + } + else + { + iota_halt(); + } + + mtmsr(ctx); +} diff --git a/import/chips/p9/procedures/ppe/iota/iota_uih.h b/import/chips/p9/procedures/ppe/iota/iota_uih.h new file mode 100644 index 00000000..c3250c2f --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/iota_uih.h @@ -0,0 +1,98 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/iota_uih.h $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +// Notes: +// - The only define names that should be changed/added/removed +// in this file are: +// - IRQ_VEC_PRTY(n>0)_CME(x) +// - IDX_PRTY_LVL_(task_abbr) and reflect in relevant H-code as well +// - All other define names are used in H-codes +// - The variable names and actions in this file must perfectly match associated +// definitions in cme_irq_common.c + +#ifndef __IOTA_UIH_H__ +#define __IOTA_UIH_H__ + +#include "iota.h" + +// Priority Levels +#define IDX_PRTY_LVL_HIPRTY 0 +#define IDX_PRTY_LVL_DB3 1 +#define IDX_PRTY_LVL_DB2 2 +#define IDX_PRTY_LVL_SPWU 3 +#define IDX_PRTY_LVL_WAKE 4 +#define IDX_PRTY_LVL_STOP 5 +#define IDX_PRTY_LVL_DB1 6 +#define IDX_PRTY_LVL_DB0 7 +#define IDX_PRTY_LVL_INTERCME_IN0 8 +#define IDX_PRTY_LVL_PMCR 9 +#define IDX_PRTY_LVL_DISABLED 10 +#define IDX_PRTY_VEC 0 +#define IDX_MASK_VEC 1 +extern const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2]; + +// Group0: Non-task hi-prty IRQs +#define IRQ_VEC_PRTY0_CME (uint64_t)(0xFE00000000000000) +// Group1: DB3 +#define IRQ_VEC_PRTY1_CME (uint64_t)(0x0030000000000000) +// Group2: DB2 +#define IRQ_VEC_PRTY2_CME (uint64_t)(0x0000300000000000) +// Group3: SPWU +#define IRQ_VEC_PRTY3_CME (uint64_t)(0x0003000000000000) +// Group4: WAKE +#define IRQ_VEC_PRTY4_CME (uint64_t)(0x000CC00000000000) +// Group5: STOP +#define IRQ_VEC_PRTY5_CME (uint64_t)(0x00000C0000000000) +// Group6: DB1 +#define IRQ_VEC_PRTY6_CME (uint64_t)(0x0000000000C00000) +// Group7: DB0 +#define IRQ_VEC_PRTY7_CME (uint64_t)(0x000000000C000000) +// Group8: INTERCME_IN0 +#define IRQ_VEC_PRTY8_CME (uint64_t)(0x0100000000000000) +// Group9: PMCR +#define IRQ_VEC_PRTY9_CME (uint64_t)(0x0000000030000000) +// Group10: We should never detect these +#define IRQ_VEC_PRTY10_CME (uint64_t)(0x00C003FFC33FFFFF) + +// This should be 0xFFFFFFFFFFFFFFFF +#define IRQ_VEC_PRTY_CHECK ( IRQ_VEC_PRTY0_CME | \ + IRQ_VEC_PRTY1_CME | \ + IRQ_VEC_PRTY2_CME | \ + IRQ_VEC_PRTY3_CME | \ + IRQ_VEC_PRTY4_CME | \ + IRQ_VEC_PRTY5_CME | \ + IRQ_VEC_PRTY6_CME | \ + IRQ_VEC_PRTY7_CME | \ + IRQ_VEC_PRTY8_CME | \ + IRQ_VEC_PRTY9_CME | \ + IRQ_VEC_PRTY10_CME ) + +extern uint8_t g_current_prty_level; +extern uint8_t g_eimr_stack[IOTA_NUM_EXT_IRQ_PRIORITIES]; +extern int g_eimr_stack_ctr; +extern uint64_t g_eimr_override_stack[IOTA_NUM_EXT_IRQ_PRIORITIES]; +extern uint64_t g_eimr_override; +extern uint32_t iota_uih(void); + +#endif //__IOTA_UIH_H__ diff --git a/import/chips/p9/procedures/ppe/iota/link.ld b/import/chips/p9/procedures/ppe/iota/link.ld new file mode 100644 index 00000000..484c4955 --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/link.ld @@ -0,0 +1,54 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/link.ld $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +OUTPUT_FORMAT(elf32-powerpc) + +MEMORY +{ + sram : ORIGIN = 0xffff8000, LENGTH = 0x8000 +} + +SECTIONS +{ + . = 0xffff8000; + + .vectors : { *(.vectors) } > sram + . = ALIGN(512); + .text . : { *(.text) } > sram + + . = ALIGN(8); + _SDA_BASE_ = . ; + .sdata . : { *(.sdata*) } > sram + .sbss . : { *(.sbss*) } > sram + + . = ALIGN(8); + _SDA2_BASE_ = . ; + .sdata2 . : { *(.sdata2*) } > sram + .sbss2 . : { *(.sbss2*) } > sram + + .data . : { *(.data*) } > sram + .bss . : { *(.bss*) } > sram + + . = ALIGN(8); +} diff --git a/import/chips/p9/procedures/ppe/iota/main.c b/import/chips/p9/procedures/ppe/iota/main.c new file mode 100644 index 00000000..ea978e26 --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/main.c @@ -0,0 +1,97 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/main.c $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include "iota.h" + +/** + * @file main.c + * @brief example main file. Should be overridden + */ +void func0(uint32_t idle_task_idx) +{ + static uint32_t val = 1; + + uint32_t i; + + for(i = 0; i < 10; ++i) + { + asm volatile("mtspr 0x110, %0" : : "r" (val++)); + + iota_set_idle_task_state(IOTA_IDLE_DISABLED, idle_task_idx); + } +} + +__attribute__((weak)) void dec_handler() +{ + asm volatile("mtspr 0x110, %0" : : "r" (0xddddddddul)); +} + +__attribute__((weak)) void fit_handler() +{ + asm volatile("mtspr 0x110, %0" : : "r" (0xfffffffful)); +} + +__attribute__((weak)) void ext_handler(uint32_t task_idx) +{ + asm volatile("mtspr 0x110, %0" : : "r" (0xeeeeeeeeul)); + + iota_set_idle_task_state(IOTA_IDLE_ENABLED, 1); + out64(CME_LCL_EISR_CLR, 0x8000000000000000ull); + + asm("trap"); + + iota_uih_irq_vec_restore(); +} + +IOTA_BEGIN_IDLE_TASK_TABLE +{ IOTA_IDLE_DISABLED, IOTA_NO_TASK }, +{ IOTA_IDLE_DISABLED, IOTA_TASK(func0) } +IOTA_END_IDLE_TASK_TABLE + +IOTA_BEGIN_TASK_TABLE +IOTA_TASK(ext_handler), + IOTA_NO_TASK, + IOTA_NO_TASK, + IOTA_NO_TASK, + IOTA_NO_TASK, + IOTA_NO_TASK, + IOTA_NO_TASK, + IOTA_NO_TASK, + IOTA_NO_TASK, + IOTA_NO_TASK, + IOTA_NO_TASK + IOTA_END_TASK_TABLE; + +__attribute__((weak)) int main() +{ + IOTA_DEC_HANDLER(dec_handler); + IOTA_FIT_HANDLER(func0); + + out64(CME_LCL_EITR_OR, 0x8000000000000000ull); + out64(CME_LCL_EIMR , 0x7fffffffffffffffull); + + iota_run(); + + return 0; +} diff --git a/import/chips/p9/procedures/ppe/iota/pk.h b/import/chips/p9/procedures/ppe/iota/pk.h new file mode 100644 index 00000000..7bebf8be --- /dev/null +++ b/import/chips/p9/procedures/ppe/iota/pk.h @@ -0,0 +1,41 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe/iota/pk.h $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#if !defined(__PK_H__) +#define __PK_H__ + +/** @file pk.h + * @brief Pk defs so that IOTA can use pk parts + */ + +#include "ppe42_asm.h" +#include "iota_ppe42.h" + +#ifndef __ASSEMBLER__ + #include + typedef uint64_t PkTimebase; + extern uint64_t pk_timebase_get(); + +#endif //__ASSEMBLER__ +#endif -- cgit v1.2.1