1 /* 2 (C) Copyright IBM Corp. 2008 3 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 9 * Redistributions of source code must retain the above copyright notice, 10 this list of conditions and the following disclaimer. 11 * Redistributions in binary form must reproduce the above copyright 12 notice, this list of conditions and the following disclaimer in the 13 documentation and/or other materials provided with the distribution. 14 * Neither the name of IBM nor the names of its contributors may be 15 used to endorse or promote products derived from this software without 16 specific prior written permission. 17 18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* Internal definitions for SPU timer library. */ 32 #ifndef _SPU_TIMER_INTERNAL_H_ 33 #define _SPU_TIMER_INTERNAL_H_ 34 35 #include <spu_intrinsics.h> 36 #include <spu_mfcio.h> 37 #include <limits.h> 38 #include <stdlib.h> 39 40 #ifdef SPU_TIMER_DEBUG 41 #include <stdio.h> 42 #include <assert.h> 43 #endif 44 45 /* The timer state tells which list its on. */ 46 typedef enum spu_timer_state 47 { 48 SPU_TIMER_FREE = 0, 49 SPU_TIMER_ACTIVE = 1, 50 SPU_TIMER_HANDLED = 2, 51 SPU_TIMER_STOPPED = 3 52 } spu_timer_state_t; 53 54 typedef struct spu_timer 55 { 56 int tmout __attribute__ ((__aligned__ (16))); /* Time until expiration (tb). */ 57 int intvl __attribute__ ((__aligned__ (16))); /* Interval. */ 58 int id __attribute__ ((__aligned__ (16))); 59 spu_timer_state_t state __attribute__ ((__aligned__ (16))); 60 void (*func) (int) __attribute__ ((__aligned__ (16))); /* Handler. */ 61 struct spu_timer *next __attribute__ ((__aligned__ (16))); 62 } spu_timer_t; 63 64 65 /* Max decrementer value. */ 66 #define DECR_MAX 0xFFFFFFFFU 67 68 /* Arbitrary non-triggering value. */ 69 #define CLOCK_START_VALUE 0x7FFFFFFF 70 71 #define MIN_INTVL 1 72 #define MAX_INTVL INT_MAX 73 74 /* Timers within 15 tics will expire together. */ 75 #define TIMER_INTERVAL_WINDOW 15 76 77 /* Disables the decrementer and returns the saved event mask for a subsequent 78 call to __enable_spu_decr. The decrementer interrupt is acknowledged in the 79 flih when the event is received, but is required also as part of the 80 procedure to stop the decrementer. */ 81 static inline unsigned __disable_spu_decr(void)82 __disable_spu_decr (void) 83 { 84 unsigned mask = spu_readch (SPU_RdEventMask); 85 spu_writech (SPU_WrEventMask, mask & ~MFC_DECREMENTER_EVENT); 86 spu_writech (SPU_WrEventAck, MFC_DECREMENTER_EVENT); 87 spu_sync_c (); 88 return mask; 89 } 90 91 /* Writes and enables the decrementer, along with the given event mask. */ 92 static inline void __enable_spu_decr(int val,unsigned mask)93 __enable_spu_decr (int val, unsigned mask) 94 { 95 spu_writech (SPU_WrDec, (val)); 96 spu_writech (SPU_WrEventMask, mask | MFC_DECREMENTER_EVENT); 97 spu_sync_c (); 98 } 99 100 /* These are shared between modules but are not inlined, to save space. */ 101 extern void __spu_timer_start (int id, int reset); 102 extern void __reset_spu_decr (int val); 103 104 /* The timers. */ 105 extern spu_timer_t __spu_timers[]; 106 107 /* Active timer list. */ 108 extern spu_timer_t *__spu_timers_active; 109 110 /* Stopped (allocated) timer list. */ 111 extern spu_timer_t *__spu_timers_stopped; 112 113 /* List of timers being handled. */ 114 extern spu_timer_t *__spu_timers_handled; 115 116 /* Bitmask of available timers. */ 117 extern unsigned __spu_timers_avail; 118 119 /* The software managed timebase value. */ 120 extern volatile uint64_t __spu_tb_val; 121 122 /* Timeout value of the current interval. */ 123 extern volatile int __spu_tb_timeout; 124 125 /* Clock start count (clock is running if >0). */ 126 extern volatile unsigned __spu_clock_startcnt; 127 128 /* Saved interrupt state from clock_start. */ 129 extern volatile unsigned __spu_clock_state_was_enabled; 130 131 #define __likely(_c) __builtin_expect((_c), 1) 132 #define __unlikely(_c) __builtin_expect((_c), 0) 133 134 #define ABORT() \ 135 {\ 136 fprintf(stderr, "Internal error, aborting: %s:%d\n", __FILE__, __LINE__);\ 137 assert(0);\ 138 } 139 140 #endif 141