lib.c
1 /* 2 * 3 * Copyright (C) 2008 Uwe Hermann <uwe@hermann-uwe.de> 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <assert.h> 30 #include <libpayload.h> 31 32 /* 33 * Convert a number in BCD format to decimal. 34 * 35 * @param b The BCD number. 36 * @return The given BCD number in decimal format. 37 */ 38 int bcd2dec(int b) 39 { 40 return ((b >> 4) & 0x0f) * 10 + (b & 0x0f); 41 } 42 43 /* 44 * Convert a number in decimal format into the BCD format. 45 * 46 * @param d The decimal number. 47 * @return The given decimal number in BCD format. 48 */ 49 int dec2bcd(int d) 50 { 51 return ((d / 10) << 4) | (d % 10); 52 } 53 54 /** 55 * Return the absolute value of the specified integer. 56 * 57 * @param j The integer of which we want to know the absolute value. 58 * @return The absolute value of the specified integer. 59 */ 60 int abs(int j) 61 { 62 return (j >= 0 ? j : -j); 63 } 64 65 long int labs(long int j) 66 { 67 return (j >= 0 ? j : -j); 68 } 69 70 long long int llabs(long long int j) 71 { 72 return (j >= 0 ? j : -j); 73 } 74 75 /** 76 * Given a 4-bit value, return the ASCII hex representation of it. 77 * 78 * @param b A 4-bit value which shall be converted to ASCII hex. 79 * @return The ASCII hex representation of the specified 4-bit value. 80 * Returned hex-characters will always be lower-case (a-f, not A-F). 81 */ 82 u8 bin2hex(u8 b) 83 { 84 return (b < 10) ? '0' + b : 'a' + (b - 10); 85 } 86 87 /** 88 * Given an ASCII hex input character, return its integer value. 89 * 90 * For example, the input value '6' will be converted to 6, 'a'/'A' will 91 * be converted to 10, 'f'/'F' will be converted to 15, and so on. 92 * 93 * The return value for invalid input characters is 0. 94 * 95 * @param h The input byte in ASCII hex format. 96 * @return The integer value of the specified ASCII hex byte. 97 */ 98 u8 hex2bin(u8 h) 99 { 100 return (('0' <= h && h <= '9') ? (h - '0') : \ 101 ('A' <= h && h <= 'F') ? (h - 'A' + 10) : \ 102 ('a' <= h && h <= 'f') ? (h - 'a' + 10) : 0); 103 } 104 105 /** 106 * Enters HALT state, after printing msg 107 * 108 * @param msg message to print 109 */ 110 void fatal(const char *msg) 111 { 112 fprintf(stderr, "%s",msg); 113 halt(); 114 } 115 116 void exit(int status) 117 { 118 printf("exited with status %d\n", status); 119 halt(); 120 } 121 122 void __noreturn abort(void) 123 { 124 halt(); 125 } 126 127 int errno; 128 129 char *getenv(const char *name) 130 { 131 return NULL; 132 } 133 134 /* 135 * Reads a transfer buffer from 32-bit FIFO registers. fifo_stride is the 136 * distance in bytes between registers (e.g. pass 4 for a normal array of 32-bit 137 * registers or 0 to read everything from the same register). fifo_width is 138 * the amount of bytes read per register (can be 1 through 4). 139 */ 140 void buffer_from_fifo32(void *buffer, size_t size, void *fifo, 141 int fifo_stride, int fifo_width) 142 { 143 u8 *p = buffer; 144 int i, j; 145 146 assert(fifo_width > 0 && fifo_width <= sizeof(u32) && 147 fifo_stride % sizeof(u32) == 0); 148 149 for (i = 0; i < size; i += fifo_width, fifo += fifo_stride) { 150 u32 val = read32(fifo); 151 for (j = 0; j < MIN(size - i, fifo_width); j++) 152 *p++ = (u8)(val >> (j * 8)); 153 } 154 } 155 156 /* 157 * Version of buffer_to_fifo32() that can prepend a prefix of up to fifo_width 158 * size to the transfer. This is often useful for protocols where a command word 159 * precedes the actual payload data. The prefix must be packed in the low-order 160 * bytes of the 'prefix' u32 parameter and any high-order bytes exceeding prefsz 161 * must be 0. Note that 'size' counts total bytes written, including 'prefsz'. 162 */ 163 void buffer_to_fifo32_prefix(const void *buffer, u32 prefix, int prefsz, size_t size, 164 void *fifo, int fifo_stride, int fifo_width) 165 { 166 const u8 *p = buffer; 167 int i, j = prefsz; 168 169 assert(fifo_width > 0 && fifo_width <= sizeof(u32) && 170 fifo_stride % sizeof(u32) == 0 && prefsz <= fifo_width); 171 172 uint32_t val = prefix; 173 for (i = 0; i < size; i += fifo_width, fifo += fifo_stride) { 174 for (; j < MIN(size - i, fifo_width); j++) 175 val |= *p++ << (j * 8); 176 write32(fifo, val); 177 val = 0; 178 j = 0; 179 } 180 181 } 182 183 __weak void reboot(void) 184 { 185 fatal("Reboot requested but not implemented\n"); 186 }