1// 2// clock.S - assembly language clock routines 3// 4// $Id: //depot/rel/Foxhill/dot.8/Xtensa/OS/hal/clock.S#1 $ 5 6// Copyright (c) 2003-2010 Tensilica Inc. 7// 8// Permission is hereby granted, free of charge, to any person obtaining 9// a copy of this software and associated documentation files (the 10// "Software"), to deal in the Software without restriction, including 11// without limitation the rights to use, copy, modify, merge, publish, 12// distribute, sublicense, and/or sell copies of the Software, and to 13// permit persons to whom the Software is furnished to do so, subject to 14// the following conditions: 15// 16// The above copyright notice and this permission notice shall be included 17// in all copies or substantial portions of the Software. 18// 19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 27#include <xtensa/coreasm.h> 28 29 30// A useful looping macro: 31// 'iterate' invokes 'what' (an instruction, pseudo-op or other macro) 32// multiple times, passing it a numbered parameter from 'from' to 'to' 33// inclusively. Does not invoke 'what' at all if from > to. 34// Maximum difference between 'from' and 'to' is 99 minus nesting depth 35// (GNU 'as' doesn't allow nesting deeper than 100). 36// 37 .macro iterate from, to, what 38 .ifeq ((\to-\from) & ~0xFFF) 39 \what \from 40 iterate "(\from+1)", \to, \what 41 .endif 42 .endm // iterate 43 44 45//---------------------------------------------------------------------- 46// Read CCOUNT register 47//---------------------------------------------------------------------- 48 49// unsigned xthal_get_ccount(void) 50// 51 .global xthal_get_ccount 52 .type xthal_get_ccount,@function 53 .align 4 54xthal_get_ccount: 55 abi_entry 56#if XCHAL_HAVE_CCOUNT 57 rsr.ccount a2 58/* 59 * The following alternative (in absence of CCOUNT) doesn't work well, 60 * because ICOUNT is often used for debugging. (And when it isn't, 61 * one would have to ensure that ICOUNTLEVEL is high enough and that 62 * ICOUNT is incremented to zero in the debug exception handler upon 63 * ICOUNT exceptions.) 64 * 65 * #elif XCHAL_HAVE_DEBUG 66 * rsr.icount a2 // no CCOUNT, return ICOUNT if available 67 */ 68#else 69 movi a2, 0 // else no counter at all, just return zero 70#endif 71 abi_return 72 .size xthal_get_ccount, . - xthal_get_ccount 73 74 75//---------------------------------------------------------------------- 76// Access CCOMPAREn registers 77//---------------------------------------------------------------------- 78 79// void xthal_set_ccompare(int, unsigned) 80// 81 .global xthal_set_ccompare 82 .type xthal_set_ccompare,@function 83 .align 4 84xthal_set_ccompare: 85 abi_entry 86#if XCHAL_NUM_TIMERS > 0 87 bnez a2, 1f 88 wsr.ccompare0 a3 89 rsync 90 abi_return 91#endif 921: 93#if XCHAL_NUM_TIMERS > 1 94 bnei a2, 1, 2f 95 wsr.ccompare1 a3 96 rsync 97 abi_return 98#endif 992: 100#if XCHAL_NUM_TIMERS > 2 101 bnei a2, 2, 3f 102 wsr.ccompare2 a3 103 rsync 104#endif 1053: 106 abi_return 107 .size xthal_set_ccompare, . - xthal_set_ccompare 108 109 110// unsigned xthal_get_ccompare(int) 111// 112 .global xthal_get_ccompare 113 .type xthal_get_ccompare,@function 114 .align 4 115xthal_get_ccompare: 116 abi_entry 117#if XCHAL_NUM_TIMERS > 0 118 bnez a2, 1f 119 rsr.ccompare0 a2 120 abi_return 121#endif 1221: 123#if XCHAL_NUM_TIMERS > 1 124 bnei a2, 1, 2f 125 rsr.ccompare1 a2 126 abi_return 127#endif 1282: 129#if XCHAL_NUM_TIMERS > 2 130 bnei a2, 2, 3f 131 rsr.ccompare2 a2 132 abi_return 133#endif 1343: 135 movi a2, 0 136 abi_return 137 .size xthal_get_ccompare, . - xthal_get_ccompare 138 139