| Index: emcore/trunk/util.h |
| — | — | @@ -1,227 +1,227 @@ |
| 2 | | -//
|
| 3 | | -//
|
| 4 | | -// Copyright 2010 TheSeven
|
| 5 | | -//
|
| 6 | | -//
|
| 7 | | -// This file is part of emCORE.
|
| 8 | | -//
|
| 9 | | -// emCORE is free software: you can redistribute it and/or
|
| 10 | | -// modify it under the terms of the GNU General Public License as
|
| 11 | | -// published by the Free Software Foundation, either version 2 of the
|
| 12 | | -// License, or (at your option) any later version.
|
| 13 | | -//
|
| 14 | | -// emCORE is distributed in the hope that it will be useful,
|
| 15 | | -// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 | | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 | | -// See the GNU General Public License for more details.
|
| 18 | | -//
|
| 19 | | -// You should have received a copy of the GNU General Public License along
|
| 20 | | -// with emCORE. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | | -//
|
| 22 | | -//
|
| 23 | | -
|
| 24 | | -
|
| 25 | | -#ifndef __UTIL_H__
|
| 26 | | -#define __UTIL_H__
|
| 27 | | -
|
| 28 | | -
|
| 29 | | -#include "global.h"
|
| 30 | | -
|
| 31 | | -
|
| 32 | | -#ifndef NULL
|
| 33 | | -#define NULL ((void*)0)
|
| 34 | | -#endif
|
| 35 | | -
|
| 36 | | -#ifndef MIN
|
| 37 | | -#define MIN(a, b) (((a)<(b))?(a):(b))
|
| 38 | | -#endif
|
| 39 | | -
|
| 40 | | -#ifndef MAX
|
| 41 | | -#define MAX(a, b) (((a)>(b))?(a):(b))
|
| 42 | | -#endif
|
| 43 | | -
|
| 44 | | -/* return number of elements in array a */
|
| 45 | | -#define ARRAYLEN(a) (sizeof(a)/sizeof((a)[0]))
|
| 46 | | -
|
| 47 | | -/* return p incremented by specified number of bytes */
|
| 48 | | -#define SKIPBYTES(p, count) ((typeof (p))((char *)(p) + (count)))
|
| 49 | | -
|
| 50 | | -#define BIT(x) (1 << (x))
|
| 51 | | -#define BITRANGE(x, y) ((0xfffffffful >> (31 + (x) - (y))) << (x))
|
| 52 | | -
|
| 53 | | -#define ERR_RC(val) (BIT(31) | (val))
|
| 54 | | -#define IS_ERR(val) (val & BIT(31))
|
| 55 | | -#define RET_ERR(val) \
|
| 56 | | -{ \
|
| 57 | | - return ERR_RC(val); \
|
| 58 | | -}
|
| 59 | | -#define RET_ERR_MTX(val, mutex) \
|
| 60 | | -{ \
|
| 61 | | - mutex_unlock(mutex); \
|
| 62 | | - return ERR_RC(val); \
|
| 63 | | -}
|
| 64 | | -#define PASS_RC(expr, bits, val) \
|
| 65 | | -{ \
|
| 66 | | - int PASS_RC_rc = (expr); \
|
| 67 | | - if (IS_ERR(PASS_RC_rc)) \
|
| 68 | | - return ERR_RC((PASS_RC_rc << (bits)) | (val)); \
|
| 69 | | -}
|
| 70 | | -#define PASS_RC_MTX(expr, bits, val, mutex) \
|
| 71 | | -{ \
|
| 72 | | - int PASS_RC_MTX_rc = (expr); \
|
| 73 | | - if (IS_ERR(PASS_RC_MTX_rc)) \
|
| 74 | | - { \
|
| 75 | | - mutex_unlock(mutex); \
|
| 76 | | - return ERR_RC((PASS_RC_MTX_rc << (bits)) | (val)); \
|
| 77 | | - } \
|
| 78 | | -}
|
| 79 | | -
|
| 80 | | -#define P2_M1(p2) ((1 << (p2))-1)
|
| 81 | | -
|
| 82 | | -/* align up or down to nearest 2^p2 */
|
| 83 | | -#define ALIGN_DOWN_P2(n, p2) ((n) & ~P2_M1(p2))
|
| 84 | | -#define ALIGN_UP_P2(n, p2) ALIGN_DOWN_P2((n) + P2_M1(p2),p2)
|
| 85 | | -
|
| 86 | | -/* align up or down to nearest integer multiple of a */
|
| 87 | | -#define ALIGN_DOWN(n, a) ((n)/(a)*(a))
|
| 88 | | -#define ALIGN_UP(n, a) ALIGN_DOWN((n)+((a)-1),a)
|
| 89 | | -
|
| 90 | | -/* align start and end of buffer to nearest integer multiple of a */
|
| 91 | | -#define ALIGN_BUFFER(ptr,len,align) \
|
| 92 | | -{\
|
| 93 | | - uintptr_t tmp_ptr1 = (uintptr_t)ptr; \
|
| 94 | | - uintptr_t tmp_ptr2 = tmp_ptr1 + len;\
|
| 95 | | - tmp_ptr1 = ALIGN_UP(tmp_ptr1,align); \
|
| 96 | | - tmp_ptr2 = ALIGN_DOWN(tmp_ptr2,align); \
|
| 97 | | - len = tmp_ptr2 - tmp_ptr1; \
|
| 98 | | - ptr = (typeof(ptr))tmp_ptr1; \
|
| 99 | | -}
|
| 100 | | -
|
| 101 | | -
|
| 102 | | -/* live endianness conversion */
|
| 103 | | -#ifdef LITTLE_ENDIAN
|
| 104 | | -#define letoh16(x) (x)
|
| 105 | | -#define letoh32(x) (x)
|
| 106 | | -#define htole16(x) (x)
|
| 107 | | -#define htole32(x) (x)
|
| 108 | | -#define betoh16(x) swap16(x)
|
| 109 | | -#define betoh32(x) swap32(x)
|
| 110 | | -#define htobe16(x) swap16(x)
|
| 111 | | -#define htobe32(x) swap32(x)
|
| 112 | | -#define swap_odd_even_be32(x) (x)
|
| 113 | | -#define swap_odd_even_le32(x) swap_odd_even32(x)
|
| 114 | | -#else
|
| 115 | | -#define letoh16(x) swap16(x)
|
| 116 | | -#define letoh32(x) swap32(x)
|
| 117 | | -#define htole16(x) swap16(x)
|
| 118 | | -#define htole32(x) swap32(x)
|
| 119 | | -#define betoh16(x) (x)
|
| 120 | | -#define betoh32(x) (x)
|
| 121 | | -#define htobe16(x) (x)
|
| 122 | | -#define htobe32(x) (x)
|
| 123 | | -#define swap_odd_even_be32(x) swap_odd_even32(x)
|
| 124 | | -#define swap_odd_even_le32(x) (x)
|
| 125 | | -#endif
|
| 126 | | -
|
| 127 | | -
|
| 128 | | -/* static endianness conversion */
|
| 129 | | -#define SWAP_16(x) ((typeof(x))(unsigned short)(((unsigned short)(x) >> 8) | \
|
| 130 | | - ((unsigned short)(x) << 8)))
|
| 131 | | -
|
| 132 | | -#define SWAP_32(x) ((typeof(x))(unsigned long)( ((unsigned long)(x) >> 24) | \
|
| 133 | | - (((unsigned long)(x) & 0xff0000ul) >> 8) | \
|
| 134 | | - (((unsigned long)(x) & 0xff00ul) << 8) | \
|
| 135 | | - ((unsigned long)(x) << 24)))
|
| 136 | | -
|
| 137 | | -#ifdef RLITTLE_ENDIAN
|
| 138 | | -#define LE_TO_H16(x) (x)
|
| 139 | | -#define LE_TO_H32(x) (x)
|
| 140 | | -#define H_TO_LE16(x) (x)
|
| 141 | | -#define H_TO_LE32(x) (x)
|
| 142 | | -#define BE_TO_H16(x) SWAP_16(x)
|
| 143 | | -#define BE_TO_H32(x) SWAP_32(x)
|
| 144 | | -#define H_TO_BE16(x) SWAP_16(x)
|
| 145 | | -#define H_TO_BE32(x) SWAP_32(x)
|
| 146 | | -#else
|
| 147 | | -#define LE_TO_H16(x) SWAP_16(x)
|
| 148 | | -#define LE_TO_H32(x) SWAP_32(x)
|
| 149 | | -#define H_TO_LE16(x) SWAP_16(x)
|
| 150 | | -#define H_TO_LE32(x) SWAP_32(x)
|
| 151 | | -#define BE_TO_H16(x) (x)
|
| 152 | | -#define BE_TO_H32(x) (x)
|
| 153 | | -#define H_TO_BE16(x) (x)
|
| 154 | | -#define H_TO_BE32(x) (x)
|
| 155 | | -#endif
|
| 156 | | -
|
| 157 | | -/* Get the byte offset of a type's member */
|
| 158 | | -#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername)
|
| 159 | | -
|
| 160 | | -/* Get the type pointer from one of its members */
|
| 161 | | -#define TYPE_FROM_MEMBER(type, memberptr, membername) \
|
| 162 | | - ((type *)((intptr_t)(memberptr) - OFFSETOF(type, membername)))
|
| 163 | | -
|
| 164 | | -static inline uint16_t swap16(uint16_t value)
|
| 165 | | - /*
|
| 166 | | - result[15..8] = value[ 7..0];
|
| 167 | | - result[ 7..0] = value[15..8];
|
| 168 | | - */
|
| 169 | | -{
|
| 170 | | - return (value >> 8) | (value << 8);
|
| 171 | | -}
|
| 172 | | -
|
| 173 | | -static inline uint32_t swap32(uint32_t value)
|
| 174 | | - /*
|
| 175 | | - result[31..24] = value[ 7.. 0];
|
| 176 | | - result[23..16] = value[15.. 8];
|
| 177 | | - result[15.. 8] = value[23..16];
|
| 178 | | - result[ 7.. 0] = value[31..24];
|
| 179 | | - */
|
| 180 | | -{
|
| 181 | | - uint32_t hi = swap16(value >> 16);
|
| 182 | | - uint32_t lo = swap16(value & 0xffff);
|
| 183 | | - return (lo << 16) | hi;
|
| 184 | | -}
|
| 185 | | -
|
| 186 | | -static inline uint32_t swap_odd_even32(uint32_t value)
|
| 187 | | -{
|
| 188 | | - /*
|
| 189 | | - result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
|
| 190 | | - result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
|
| 191 | | - */
|
| 192 | | - uint32_t t = value & 0xff00ff00;
|
| 193 | | - return (t >> 8) | ((t ^ value) << 8);
|
| 194 | | -}
|
| 195 | | -
|
| 196 | | -#ifndef BIT_N
|
| 197 | | -#define BIT_N(n) (1U << (n))
|
| 198 | | -#endif
|
| 199 | | -
|
| 200 | | -#ifndef CACHEALIGN_SIZE /* could be elsewhere for a particular reason */
|
| 201 | | -#ifdef CACHEALIGN_BITS
|
| 202 | | -/* 2^CACHEALIGN_BITS = the byte size */
|
| 203 | | -#define CACHEALIGN_SIZE (1u << CACHEALIGN_BITS)
|
| 204 | | -#else
|
| 205 | | -#define CACHEALIGN_SIZE 16 /* FIXME */
|
| 206 | | -#endif
|
| 207 | | -#endif /* CACHEALIGN_SIZE */
|
| 208 | | -
|
| 209 | | -#define CACHEALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE)))
|
| 210 | | -/* Aligns x up to a CACHEALIGN_SIZE boundary */
|
| 211 | | -#define CACHEALIGN_UP(x) \
|
| 212 | | - ((typeof (x))ALIGN_UP_P2((uintptr_t)(x), CACHEALIGN_BITS))
|
| 213 | | -/* Aligns x down to a CACHEALIGN_SIZE boundary */
|
| 214 | | -#define CACHEALIGN_DOWN(x) \
|
| 215 | | - ((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS))
|
| 216 | | -/* Aligns at least to the greater of size x or CACHEALIGN_SIZE */
|
| 217 | | -#define CACHEALIGN_AT_LEAST_ATTR(x) \
|
| 218 | | - __attribute__((aligned(CACHEALIGN_UP(x))))
|
| 219 | | -/* Aligns a buffer pointer and size to proper boundaries */
|
| 220 | | -#define CACHEALIGN_BUFFER(start, size) \
|
| 221 | | - ALIGN_BUFFER((start), (size), CACHEALIGN_SIZE)
|
| 222 | | -
|
| 223 | | -/* Double-cast to avoid 'dereferencing type-punned pointer will
|
| 224 | | - * break strict aliasing rules' B.S. */
|
| 225 | | -#define PUN_PTR(type, p) ((type)(intptr_t)(p))
|
| 226 | | -
|
| 227 | | -
|
| 228 | | -#endif
|
| | 2 | +// |
| | 3 | +// |
| | 4 | +// Copyright 2010 TheSeven |
| | 5 | +// |
| | 6 | +// |
| | 7 | +// This file is part of emCORE. |
| | 8 | +// |
| | 9 | +// emCORE is free software: you can redistribute it and/or |
| | 10 | +// modify it under the terms of the GNU General Public License as |
| | 11 | +// published by the Free Software Foundation, either version 2 of the |
| | 12 | +// License, or (at your option) any later version. |
| | 13 | +// |
| | 14 | +// emCORE is distributed in the hope that it will be useful, |
| | 15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| | 16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| | 17 | +// See the GNU General Public License for more details. |
| | 18 | +// |
| | 19 | +// You should have received a copy of the GNU General Public License along |
| | 20 | +// with emCORE. If not, see <http://www.gnu.org/licenses/>. |
| | 21 | +// |
| | 22 | +// |
| | 23 | + |
| | 24 | + |
| | 25 | +#ifndef __UTIL_H__ |
| | 26 | +#define __UTIL_H__ |
| | 27 | + |
| | 28 | + |
| | 29 | +#include "global.h" |
| | 30 | + |
| | 31 | + |
| | 32 | +#ifndef NULL |
| | 33 | +#define NULL ((void*)0) |
| | 34 | +#endif |
| | 35 | + |
| | 36 | +#ifndef MIN |
| | 37 | +#define MIN(a, b) (((a)<(b))?(a):(b)) |
| | 38 | +#endif |
| | 39 | + |
| | 40 | +#ifndef MAX |
| | 41 | +#define MAX(a, b) (((a)>(b))?(a):(b)) |
| | 42 | +#endif |
| | 43 | + |
| | 44 | +/* return number of elements in array a */ |
| | 45 | +#define ARRAYLEN(a) (sizeof(a)/sizeof((a)[0])) |
| | 46 | + |
| | 47 | +/* return p incremented by specified number of bytes */ |
| | 48 | +#define SKIPBYTES(p, count) ((typeof (p))((char *)(p) + (count))) |
| | 49 | + |
| | 50 | +#define BIT(x) (1 << (x)) |
| | 51 | +#define BITRANGE(x, y) ((0xfffffffful >> (31 + (x) - (y))) << (x)) |
| | 52 | + |
| | 53 | +#define ERR_RC(val) (BIT(31) | (val)) |
| | 54 | +#define IS_ERR(val) (val & BIT(31)) |
| | 55 | +#define RET_ERR(val) \ |
| | 56 | +{ \ |
| | 57 | + return ERR_RC(val); \ |
| | 58 | +} |
| | 59 | +#define RET_ERR_MTX(val, mutex) \ |
| | 60 | +{ \ |
| | 61 | + mutex_unlock(mutex); \ |
| | 62 | + return ERR_RC(val); \ |
| | 63 | +} |
| | 64 | +#define PASS_RC(expr, bits, val) \ |
| | 65 | +{ \ |
| | 66 | + int PASS_RC_rc = (expr); \ |
| | 67 | + if (IS_ERR(PASS_RC_rc)) \ |
| | 68 | + return ERR_RC((PASS_RC_rc << (bits)) | (val)); \ |
| | 69 | +} |
| | 70 | +#define PASS_RC_MTX(expr, bits, val, mutex) \ |
| | 71 | +{ \ |
| | 72 | + int PASS_RC_MTX_rc = (expr); \ |
| | 73 | + if (IS_ERR(PASS_RC_MTX_rc)) \ |
| | 74 | + { \ |
| | 75 | + mutex_unlock(mutex); \ |
| | 76 | + return ERR_RC((PASS_RC_MTX_rc << (bits)) | (val)); \ |
| | 77 | + } \ |
| | 78 | +} |
| | 79 | + |
| | 80 | +#define P2_M1(p2) ((1 << (p2))-1) |
| | 81 | + |
| | 82 | +/* align up or down to nearest 2^p2 */ |
| | 83 | +#define ALIGN_DOWN_P2(n, p2) ((n) & ~P2_M1(p2)) |
| | 84 | +#define ALIGN_UP_P2(n, p2) ALIGN_DOWN_P2((n) + P2_M1(p2),p2) |
| | 85 | + |
| | 86 | +/* align up or down to nearest integer multiple of a */ |
| | 87 | +#define ALIGN_DOWN(n, a) ((n)/(a)*(a)) |
| | 88 | +#define ALIGN_UP(n, a) ALIGN_DOWN((n)+((a)-1),a) |
| | 89 | + |
| | 90 | +/* align start and end of buffer to nearest integer multiple of a */ |
| | 91 | +#define ALIGN_BUFFER(ptr,len,align) \ |
| | 92 | +{\ |
| | 93 | + uintptr_t tmp_ptr1 = (uintptr_t)ptr; \ |
| | 94 | + uintptr_t tmp_ptr2 = tmp_ptr1 + len;\ |
| | 95 | + tmp_ptr1 = ALIGN_UP(tmp_ptr1,align); \ |
| | 96 | + tmp_ptr2 = ALIGN_DOWN(tmp_ptr2,align); \ |
| | 97 | + len = tmp_ptr2 - tmp_ptr1; \ |
| | 98 | + ptr = (typeof(ptr))tmp_ptr1; \ |
| | 99 | +} |
| | 100 | + |
| | 101 | + |
| | 102 | +/* live endianness conversion */ |
| | 103 | +#ifdef LITTLE_ENDIAN |
| | 104 | +#define letoh16(x) (x) |
| | 105 | +#define letoh32(x) (x) |
| | 106 | +#define htole16(x) (x) |
| | 107 | +#define htole32(x) (x) |
| | 108 | +#define betoh16(x) swap16(x) |
| | 109 | +#define betoh32(x) swap32(x) |
| | 110 | +#define htobe16(x) swap16(x) |
| | 111 | +#define htobe32(x) swap32(x) |
| | 112 | +#define swap_odd_even_be32(x) (x) |
| | 113 | +#define swap_odd_even_le32(x) swap_odd_even32(x) |
| | 114 | +#else |
| | 115 | +#define letoh16(x) swap16(x) |
| | 116 | +#define letoh32(x) swap32(x) |
| | 117 | +#define htole16(x) swap16(x) |
| | 118 | +#define htole32(x) swap32(x) |
| | 119 | +#define betoh16(x) (x) |
| | 120 | +#define betoh32(x) (x) |
| | 121 | +#define htobe16(x) (x) |
| | 122 | +#define htobe32(x) (x) |
| | 123 | +#define swap_odd_even_be32(x) swap_odd_even32(x) |
| | 124 | +#define swap_odd_even_le32(x) (x) |
| | 125 | +#endif |
| | 126 | + |
| | 127 | + |
| | 128 | +/* static endianness conversion */ |
| | 129 | +#define SWAP_16(x) ((typeof(x))(unsigned short)(((unsigned short)(x) >> 8) | \ |
| | 130 | + ((unsigned short)(x) << 8))) |
| | 131 | + |
| | 132 | +#define SWAP_32(x) ((typeof(x))(unsigned long)( ((unsigned long)(x) >> 24) | \ |
| | 133 | + (((unsigned long)(x) & 0xff0000ul) >> 8) | \ |
| | 134 | + (((unsigned long)(x) & 0xff00ul) << 8) | \ |
| | 135 | + ((unsigned long)(x) << 24))) |
| | 136 | + |
| | 137 | +#ifdef RLITTLE_ENDIAN |
| | 138 | +#define LE_TO_H16(x) (x) |
| | 139 | +#define LE_TO_H32(x) (x) |
| | 140 | +#define H_TO_LE16(x) (x) |
| | 141 | +#define H_TO_LE32(x) (x) |
| | 142 | +#define BE_TO_H16(x) SWAP_16(x) |
| | 143 | +#define BE_TO_H32(x) SWAP_32(x) |
| | 144 | +#define H_TO_BE16(x) SWAP_16(x) |
| | 145 | +#define H_TO_BE32(x) SWAP_32(x) |
| | 146 | +#else |
| | 147 | +#define LE_TO_H16(x) SWAP_16(x) |
| | 148 | +#define LE_TO_H32(x) SWAP_32(x) |
| | 149 | +#define H_TO_LE16(x) SWAP_16(x) |
| | 150 | +#define H_TO_LE32(x) SWAP_32(x) |
| | 151 | +#define BE_TO_H16(x) (x) |
| | 152 | +#define BE_TO_H32(x) (x) |
| | 153 | +#define H_TO_BE16(x) (x) |
| | 154 | +#define H_TO_BE32(x) (x) |
| | 155 | +#endif |
| | 156 | + |
| | 157 | +/* Get the byte offset of a type's member */ |
| | 158 | +#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername) |
| | 159 | + |
| | 160 | +/* Get the type pointer from one of its members */ |
| | 161 | +#define TYPE_FROM_MEMBER(type, memberptr, membername) \ |
| | 162 | + ((type *)((intptr_t)(memberptr) - OFFSETOF(type, membername))) |
| | 163 | + |
| | 164 | +static inline uint16_t swap16(uint16_t value) |
| | 165 | + /* |
| | 166 | + result[15..8] = value[ 7..0]; |
| | 167 | + result[ 7..0] = value[15..8]; |
| | 168 | + */ |
| | 169 | +{ |
| | 170 | + return (value >> 8) | (value << 8); |
| | 171 | +} |
| | 172 | + |
| | 173 | +static inline uint32_t swap32(uint32_t value) |
| | 174 | + /* |
| | 175 | + result[31..24] = value[ 7.. 0]; |
| | 176 | + result[23..16] = value[15.. 8]; |
| | 177 | + result[15.. 8] = value[23..16]; |
| | 178 | + result[ 7.. 0] = value[31..24]; |
| | 179 | + */ |
| | 180 | +{ |
| | 181 | + uint32_t hi = swap16(value >> 16); |
| | 182 | + uint32_t lo = swap16(value & 0xffff); |
| | 183 | + return (lo << 16) | hi; |
| | 184 | +} |
| | 185 | + |
| | 186 | +static inline uint32_t swap_odd_even32(uint32_t value) |
| | 187 | +{ |
| | 188 | + /* |
| | 189 | + result[31..24],[15.. 8] = value[23..16],[ 7.. 0] |
| | 190 | + result[23..16],[ 7.. 0] = value[31..24],[15.. 8] |
| | 191 | + */ |
| | 192 | + uint32_t t = value & 0xff00ff00; |
| | 193 | + return (t >> 8) | ((t ^ value) << 8); |
| | 194 | +} |
| | 195 | + |
| | 196 | +#ifndef BIT_N |
| | 197 | +#define BIT_N(n) (1U << (n)) |
| | 198 | +#endif |
| | 199 | + |
| | 200 | +#ifndef CACHEALIGN_SIZE /* could be elsewhere for a particular reason */ |
| | 201 | +#ifdef CACHEALIGN_BITS |
| | 202 | +/* 2^CACHEALIGN_BITS = the byte size */ |
| | 203 | +#define CACHEALIGN_SIZE (1u << CACHEALIGN_BITS) |
| | 204 | +#else |
| | 205 | +#define CACHEALIGN_SIZE 16 /* FIXME */ |
| | 206 | +#endif |
| | 207 | +#endif /* CACHEALIGN_SIZE */ |
| | 208 | + |
| | 209 | +#define CACHEALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE))) |
| | 210 | +/* Aligns x up to a CACHEALIGN_SIZE boundary */ |
| | 211 | +#define CACHEALIGN_UP(x) \ |
| | 212 | + ((typeof (x))ALIGN_UP_P2((uintptr_t)(x), CACHEALIGN_BITS)) |
| | 213 | +/* Aligns x down to a CACHEALIGN_SIZE boundary */ |
| | 214 | +#define CACHEALIGN_DOWN(x) \ |
| | 215 | + ((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS)) |
| | 216 | +/* Aligns at least to the greater of size x or CACHEALIGN_SIZE */ |
| | 217 | +#define CACHEALIGN_AT_LEAST_ATTR(x) \ |
| | 218 | + __attribute__((aligned(CACHEALIGN_UP(x)))) |
| | 219 | +/* Aligns a buffer pointer and size to proper boundaries */ |
| | 220 | +#define CACHEALIGN_BUFFER(start, size) \ |
| | 221 | + ALIGN_BUFFER((start), (size), CACHEALIGN_SIZE) |
| | 222 | + |
| | 223 | +/* Double-cast to avoid 'dereferencing type-punned pointer will |
| | 224 | + * break strict aliasing rules' B.S. */ |
| | 225 | +#define PUN_PTR(type, p) ((type)(intptr_t)(p)) |
| | 226 | + |
| | 227 | + |
| | 228 | +#endif |
| Index: emcore/trunk/target/ipodclassic/storage_ata.c |
| — | — | @@ -977,24 +977,24 @@ |
| 978 | 978 | |
| 979 | 979 | void ata_sleep(void) |
| 980 | 980 | { |
| 981 | | - mutex_lock(&ata_mutex, TIMEOUT_BLOCK); |
| 982 | | - ata_power_down(); |
| 983 | | - mutex_unlock(&ata_mutex); |
| | 981 | + ata_last_activity_value = USEC_TIMER - ata_sleep_timeout + 200000; |
| 984 | 982 | } |
| 985 | 983 | |
| 986 | 984 | void ata_sleepnow(void) |
| 987 | 985 | { |
| 988 | | - ata_sleep(); |
| | 986 | + mutex_lock(&ata_mutex, TIMEOUT_BLOCK); |
| | 987 | + ata_power_down(); |
| | 988 | + mutex_unlock(&ata_mutex); |
| 989 | 989 | } |
| 990 | 990 | |
| 991 | 991 | void ata_close(void) |
| 992 | 992 | { |
| 993 | | - ata_sleep(); |
| | 993 | + ata_sleepnow(); |
| 994 | 994 | } |
| 995 | 995 | |
| 996 | 996 | void ata_spin(void) |
| 997 | 997 | { |
| 998 | | - ata_power_up(); |
| | 998 | + ata_set_active(); |
| 999 | 999 | } |
| 1000 | 1000 | |
| 1001 | 1001 | void ata_get_info(IF_MD2(int drive,) struct storage_info *info) |
| Index: emcore/trunk/timer.h |
| — | — | @@ -1,54 +1,54 @@ |
| 2 | | -//
|
| 3 | | -//
|
| 4 | | -// Copyright 2010 TheSeven
|
| 5 | | -//
|
| 6 | | -//
|
| 7 | | -// This file is part of emCORE.
|
| 8 | | -//
|
| 9 | | -// emCORE is free software: you can redistribute it and/or
|
| 10 | | -// modify it under the terms of the GNU General Public License as
|
| 11 | | -// published by the Free Software Foundation, either version 2 of the
|
| 12 | | -// License, or (at your option) any later version.
|
| 13 | | -//
|
| 14 | | -// emCORE is distributed in the hope that it will be useful,
|
| 15 | | -// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 | | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 | | -// See the GNU General Public License for more details.
|
| 18 | | -//
|
| 19 | | -// You should have received a copy of the GNU General Public License along
|
| 20 | | -// with emCORE. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | | -//
|
| 22 | | -//
|
| 23 | | -
|
| 24 | | -
|
| 25 | | -#ifndef __TIMER_H__
|
| 26 | | -#define __TIMER_H__
|
| 27 | | -
|
| 28 | | -#include "global.h"
|
| 29 | | -
|
| 30 | | -
|
| 31 | | -#define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0)
|
| 32 | | -#define TIME_BEFORE(a,b) TIME_AFTER(b,a)
|
| 33 | | -#define TIMEOUT_EXPIRED(a,b) TIME_AFTER(USEC_TIMER,a + b)
|
| 34 | | -
|
| 35 | | -
|
| 36 | | -uint64_t read_native_timer();
|
| 37 | | -#define NATIVE_TIMER (read_native_timer())
|
| 38 | | -uint32_t read_usec_timer();
|
| 39 | | -#define USEC_TIMER (read_usec_timer())
|
| 40 | | -
|
| 41 | | -
|
| 42 | | -#define udelay(duration) \
|
| 43 | | -{ \
|
| 44 | | - long timestamp = USEC_TIMER; \
|
| 45 | | - while (!TIMEOUT_EXPIRED(timestamp, (long)(duration))); \
|
| 46 | | -}
|
| 47 | | -
|
| 48 | | -
|
| 49 | | -void timer_init() INITCODE_ATTR;
|
| 50 | | -void timer_schedule_wakeup(uint32_t usecs) ICODE_ATTR;
|
| 51 | | -void timer_kill_wakeup() ICODE_ATTR;
|
| 52 | | -void INT_TIMERB() ICODE_ATTR;
|
| 53 | | -
|
| 54 | | -
|
| 55 | | -#endif
|
| | 2 | +// |
| | 3 | +// |
| | 4 | +// Copyright 2010 TheSeven |
| | 5 | +// |
| | 6 | +// |
| | 7 | +// This file is part of emCORE. |
| | 8 | +// |
| | 9 | +// emCORE is free software: you can redistribute it and/or |
| | 10 | +// modify it under the terms of the GNU General Public License as |
| | 11 | +// published by the Free Software Foundation, either version 2 of the |
| | 12 | +// License, or (at your option) any later version. |
| | 13 | +// |
| | 14 | +// emCORE is distributed in the hope that it will be useful, |
| | 15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| | 16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| | 17 | +// See the GNU General Public License for more details. |
| | 18 | +// |
| | 19 | +// You should have received a copy of the GNU General Public License along |
| | 20 | +// with emCORE. If not, see <http://www.gnu.org/licenses/>. |
| | 21 | +// |
| | 22 | +// |
| | 23 | + |
| | 24 | + |
| | 25 | +#ifndef __TIMER_H__ |
| | 26 | +#define __TIMER_H__ |
| | 27 | + |
| | 28 | +#include "global.h" |
| | 29 | + |
| | 30 | + |
| | 31 | +#define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0) |
| | 32 | +#define TIME_BEFORE(a,b) TIME_AFTER(b,a) |
| | 33 | +#define TIMEOUT_EXPIRED(a,b) TIME_AFTER(USEC_TIMER,a + b) |
| | 34 | + |
| | 35 | + |
| | 36 | +uint64_t read_native_timer(); |
| | 37 | +#define NATIVE_TIMER (read_native_timer()) |
| | 38 | +uint32_t read_usec_timer(); |
| | 39 | +#define USEC_TIMER (read_usec_timer()) |
| | 40 | + |
| | 41 | + |
| | 42 | +#define udelay(duration) \ |
| | 43 | +{ \ |
| | 44 | + long timestamp = USEC_TIMER; \ |
| | 45 | + while (!TIMEOUT_EXPIRED(timestamp, (long)(duration))); \ |
| | 46 | +} |
| | 47 | + |
| | 48 | + |
| | 49 | +void timer_init() INITCODE_ATTR; |
| | 50 | +void timer_schedule_wakeup(uint32_t usecs) ICODE_ATTR; |
| | 51 | +void timer_kill_wakeup() ICODE_ATTR; |
| | 52 | +void INT_TIMERB() ICODE_ATTR; |
| | 53 | + |
| | 54 | + |
| | 55 | +#endif |