1 /* timer.h: System timer definitions for sun5. 2 * 3 * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net) 4 */ 5 6 #ifndef _SPARC64_TIMER_H 7 #define _SPARC64_TIMER_H 8 9 #include <linux/types.h> 10 #include <linux/init.h> 11 12 /* The most frequently accessed fields should be first, 13 * to fit into the same cacheline. 14 */ 15 struct sparc64_tick_ops { 16 unsigned long ticks_per_nsec_quotient; 17 unsigned long offset; 18 unsigned long long (*get_tick)(void); 19 int (*add_compare)(unsigned long); 20 unsigned long softint_mask; 21 void (*disable_irq)(void); 22 23 void (*init_tick)(void); 24 unsigned long (*add_tick)(unsigned long); 25 unsigned long (*get_frequency)(void); 26 unsigned long frequency; 27 28 char *name; 29 }; 30 31 extern struct sparc64_tick_ops *tick_ops; 32 33 unsigned long sparc64_get_clock_tick(unsigned int cpu); 34 void setup_sparc64_timer(void); 35 void __init time_init(void); 36 37 #define TICK_PRIV_BIT BIT(63) 38 #define TICKCMP_IRQ_BIT BIT(63) 39 40 #define HBIRD_STICKCMP_ADDR 0x1fe0000f060UL 41 #define HBIRD_STICK_ADDR 0x1fe0000f070UL 42 43 #define GET_TICK_NINSTR 13 44 struct get_tick_patch { 45 unsigned int addr; 46 unsigned int tick[GET_TICK_NINSTR]; 47 unsigned int stick[GET_TICK_NINSTR]; 48 }; 49 50 extern struct get_tick_patch __get_tick_patch; 51 extern struct get_tick_patch __get_tick_patch_end; 52 53 static inline unsigned long get_tick(void) 54 { 55 unsigned long tick, tmp1, tmp2; 56 57 __asm__ __volatile__( 58 /* read hbtick 13 instructions */ 59 "661:\n" 60 " mov 0x1fe, %1\n" 61 " sllx %1, 0x20, %1\n" 62 " sethi %%hi(0xf000), %2\n" 63 " or %2, 0x70, %2\n" 64 " or %1, %2, %1\n" /* %1 = HBIRD_STICK_ADDR */ 65 " add %1, 8, %2\n" 66 " ldxa [%2]%3, %0\n" 67 " ldxa [%1]%3, %1\n" 68 " ldxa [%2]%3, %2\n" 69 " sub %2, %0, %0\n" /* don't modify %xcc */ 70 " brnz,pn %0, 661b\n" /* restart to save one register */ 71 " sllx %2, 32, %2\n" 72 " or %2, %1, %0\n" 73 /* Common/not patched code */ 74 " sllx %0, 1, %0\n" 75 " srlx %0, 1, %0\n" /* Clear TICK_PRIV_BIT */ 76 /* Beginning of patch section */ 77 " .section .get_tick_patch, \"ax\"\n" 78 " .word 661b\n" 79 /* read tick 2 instructions and 11 skipped */ 80 " ba 1f\n" 81 " rd %%tick, %0\n" 82 " .skip 4 * (%4 - 2)\n" 83 "1:\n" 84 /* read stick 2 instructions and 11 skipped */ 85 " ba 1f\n" 86 " rd %%asr24, %0\n" 87 " .skip 4 * (%4 - 2)\n" 88 "1:\n" 89 /* End of patch section */ 90 " .previous\n" 91 : "=&r" (tick), "=&r" (tmp1), "=&r" (tmp2) 92 : "i" (ASI_PHYS_BYPASS_EC_E), "i" (GET_TICK_NINSTR)); 93 94 return tick; 95 } 96 97 #endif /* _SPARC64_TIMER_H */ 98