| 1 | /* | 
|---|
| 2 | * boot_utils.h - TSAR bootloader utilities definition. | 
|---|
| 3 | * | 
|---|
| 4 | * Authors :   Alain Greiner / Vu Son  (2016) | 
|---|
| 5 | * | 
|---|
| 6 | * Copyright (c) UPMC Sorbonne Universites | 
|---|
| 7 | * | 
|---|
| 8 | * This file is part of ALMOS-MKH. | 
|---|
| 9 | * | 
|---|
| 10 | * ALMOS-MKH is free software; you can redistribute it and/or modify it | 
|---|
| 11 | * under the terms of the GNU General Public License as published by | 
|---|
| 12 | * the Free Software Foundation; version 2.0 of the License. | 
|---|
| 13 | * | 
|---|
| 14 | * ALMOS-MKH is distributed in the hope that it will be useful, but | 
|---|
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|---|
| 17 | * General Public License for more details. | 
|---|
| 18 | * | 
|---|
| 19 | * You should have received a copy of the GNU General Public License | 
|---|
| 20 | * along with ALMOS-MKH; if not, write to the Free Software Foundation, | 
|---|
| 21 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 
|---|
| 22 | */ | 
|---|
| 23 |  | 
|---|
| 24 | /**************************************************************************** | 
|---|
| 25 | * This file defines various utility functions for the boot code.           * | 
|---|
| 26 | *                                                                          * | 
|---|
| 27 | * These functions are classified as follows:                               * | 
|---|
| 28 | *  - Remote accesses,                                                      * | 
|---|
| 29 | *  - Atomic operations,                                                    * | 
|---|
| 30 | *  - Memory functions,                                                     * | 
|---|
| 31 | *  - String functions,                                                     * | 
|---|
| 32 | *  - Display functions,                                                    * | 
|---|
| 33 | *  - Miscellaneous functions,                                              * | 
|---|
| 34 | *                                                                          * | 
|---|
| 35 | * Note that <stdint.h> and <stdarg.h> headers only contain macros, defined * | 
|---|
| 36 | * by the compiler itself, thus are accepted in the boot-loader, in         * | 
|---|
| 37 | * constrast to other headers in the C standard library.                    * | 
|---|
| 38 | ****************************************************************************/ | 
|---|
| 39 |  | 
|---|
| 40 | #ifndef _BOOT_UTILS_H | 
|---|
| 41 | #define _BOOT_UTILS_H | 
|---|
| 42 |  | 
|---|
| 43 | #include <hal_types.h> | 
|---|
| 44 | #include <hard_config.h> | 
|---|
| 45 |  | 
|---|
| 46 | /**************************************************************************** | 
|---|
| 47 | *                             Remote accesses.                             * | 
|---|
| 48 | ****************************************************************************/ | 
|---|
| 49 |  | 
|---|
| 50 | /**************************************************************************** | 
|---|
| 51 | * This function reads an aligned 32-bit word from a remote cluster. | 
|---|
| 52 | * @ xp     : extended pointer to the distant memory location. | 
|---|
| 53 | * @ returns the value read. | 
|---|
| 54 | ****************************************************************************/ | 
|---|
| 55 | uint32_t boot_remote_lw(xptr_t xp); | 
|---|
| 56 |  | 
|---|
| 57 | /**************************************************************************** | 
|---|
| 58 | * This function writes an aligned 32-bit word to a remote cluster. | 
|---|
| 59 | * @ xp     : extended pointer to the distant memory location. | 
|---|
| 60 | * @ data   : data value to be written. | 
|---|
| 61 | ****************************************************************************/ | 
|---|
| 62 | void boot_remote_sw(xptr_t xp, uint32_t data); | 
|---|
| 63 |  | 
|---|
| 64 | /**************************************************************************** | 
|---|
| 65 | * This function atomically adds a value 'val' to the current value stored | 
|---|
| 66 | * in a remote cluster. | 
|---|
| 67 | * @ xp     : extended pointer to the distant memory location. | 
|---|
| 68 | * @ val    : signed value to be added. | 
|---|
| 69 | * @ returns the value stored BEFORE the atomic operation. | 
|---|
| 70 | ****************************************************************************/ | 
|---|
| 71 | int32_t boot_remote_atomic_add(xptr_t xp, int32_t val); | 
|---|
| 72 |  | 
|---|
| 73 | /**************************************************************************** | 
|---|
| 74 | * This function copies 'size' bytes from the buffer pointed to by 'src' | 
|---|
| 75 | * to the buffer pointed to by 'dest'. These 2 addresses may be in any | 
|---|
| 76 | * different memory address spaces. | 
|---|
| 77 | * @ dest   : extended pointer to the destination buffer. | 
|---|
| 78 | * @ src    : extended pointer to the source buffer. | 
|---|
| 79 | * @ size   : size of memory block to be copied (in bytes). | 
|---|
| 80 | ****************************************************************************/ | 
|---|
| 81 | void boot_remote_memcpy(xptr_t dest, xptr_t src, uint32_t size); | 
|---|
| 82 |  | 
|---|
| 83 | /**************************************************************************** | 
|---|
| 84 | *                            Atomic operations.                            * | 
|---|
| 85 | ****************************************************************************/ | 
|---|
| 86 |  | 
|---|
| 87 | /**************************************************************************** | 
|---|
| 88 | * This function atomically adds an value 'val' to the current variable | 
|---|
| 89 | * pointed to by 'ptr'. It only returns when the atomic operation is | 
|---|
| 90 | * successful. | 
|---|
| 91 | * @ ptr    : pointer to the variable to be modified. | 
|---|
| 92 | * @ val    : signed value to be added. | 
|---|
| 93 | * @ returns the value of the variable BEFORE the atomic operation. | 
|---|
| 94 | ****************************************************************************/ | 
|---|
| 95 | int32_t boot_atomic_add(int32_t* ptr, int32_t val); | 
|---|
| 96 |  | 
|---|
| 97 | /**************************************************************************** | 
|---|
| 98 | *                            Memory functions.                             * | 
|---|
| 99 | ****************************************************************************/ | 
|---|
| 100 |  | 
|---|
| 101 | /**************************************************************************** | 
|---|
| 102 | * This function performs a local memory copy (destination and source | 
|---|
| 103 | * addresses are in the same memory space) of 'size' bytes from 'src' | 
|---|
| 104 | * address to 'dest' address. | 
|---|
| 105 | * @ dest   : destination physical address, | 
|---|
| 106 | * @ src    : source physical address, | 
|---|
| 107 | * @ size   : size of memory block to be copied in bytes. | 
|---|
| 108 | ****************************************************************************/ | 
|---|
| 109 | void boot_memcpy(void* dest, void* src, uint32_t size); | 
|---|
| 110 |  | 
|---|
| 111 | /**************************************************************************** | 
|---|
| 112 | * This function fills the first 'size' bytes of the local memory area, | 
|---|
| 113 | * pointed to by 'base' with a constant value 'val'. | 
|---|
| 114 | * @ base   : base address of the memory area to be initialized, | 
|---|
| 115 | * @ val    : value of the constant byte to initialize the area, | 
|---|
| 116 | * @ size   : size of memory block to be filled in bytes. | 
|---|
| 117 | ****************************************************************************/ | 
|---|
| 118 | void boot_memset(void* base, int val,   uint32_t size); | 
|---|
| 119 |  | 
|---|
| 120 | /**************************************************************************** | 
|---|
| 121 | *                            String functions                              * | 
|---|
| 122 | ****************************************************************************/ | 
|---|
| 123 |  | 
|---|
| 124 | /**************************************************************************** | 
|---|
| 125 | * This function converts the letter 'c' to lower case, if possible. | 
|---|
| 126 | * @ c  : letter to be converted. | 
|---|
| 127 | * @ returns the converted letter, or 'c' if conversion not possible. | 
|---|
| 128 | ****************************************************************************/ | 
|---|
| 129 | static inline unsigned char boot_to_lower(unsigned char c) | 
|---|
| 130 | { | 
|---|
| 131 | return ((c >= 'A') && (c <= 'Z')) ? (c | 0x20) : c; | 
|---|
| 132 |  | 
|---|
| 133 | } // boot_to_lower() | 
|---|
| 134 |  | 
|---|
| 135 | /**************************************************************************** | 
|---|
| 136 | * This function converts the letter 'c' to upper case, if possible. | 
|---|
| 137 | * @ c  : letter to be converted. | 
|---|
| 138 | * @ returns the converted letter, or 'c' if conversion not possible. | 
|---|
| 139 | ****************************************************************************/ | 
|---|
| 140 | static inline unsigned char boot_to_upper(unsigned char c) | 
|---|
| 141 | { | 
|---|
| 142 | return ((c >= 'a') && (c <= 'z')) ? (c & ~(0x20)) : c; | 
|---|
| 143 |  | 
|---|
| 144 | } // boot_to_upper() | 
|---|
| 145 |  | 
|---|
| 146 | /**************************************************************************** | 
|---|
| 147 | * This function copies the string pointed to by 'src' (the terminating | 
|---|
| 148 | * null byte '\0' NOT included) to the buffer pointed to by 'dest'. | 
|---|
| 149 | * @ src    : pointer to the string to be copied. | 
|---|
| 150 | * @ dest   : pointer to the destination string. | 
|---|
| 151 | ****************************************************************************/ | 
|---|
| 152 | void boot_strcpy(char* dest, char* src); | 
|---|
| 153 |  | 
|---|
| 154 | /**************************************************************************** | 
|---|
| 155 | * This function calculates the length of the string pointed to by 's', | 
|---|
| 156 | * excluding the terminating null byte '\0'. | 
|---|
| 157 | * @ s  : pointer to the string whose length is to be computed. | 
|---|
| 158 | * @ returns the number of bytes in the string. | 
|---|
| 159 | ****************************************************************************/ | 
|---|
| 160 | uint32_t boot_strlen(char* s); | 
|---|
| 161 |  | 
|---|
| 162 | /**************************************************************************** | 
|---|
| 163 | * This function compares the 2 strings pointed to by 's1' and 's2'. | 
|---|
| 164 | * @ s1 : pointer to the first string to be compared. | 
|---|
| 165 | * @ s2 : pointer to the second string to be compared. | 
|---|
| 166 | * @ returns 0 if these 2 strings match, 1 otherwise. | 
|---|
| 167 | ****************************************************************************/ | 
|---|
| 168 | int boot_strcmp(char* s1, char* s2); | 
|---|
| 169 |  | 
|---|
| 170 | /**************************************************************************** | 
|---|
| 171 | *                            Display functions                             * | 
|---|
| 172 | ****************************************************************************/ | 
|---|
| 173 |  | 
|---|
| 174 | /**************************************************************************** | 
|---|
| 175 | * This function writes the NUL terminated string pointed to by 'str' | 
|---|
| 176 | * to the boot TTY terminal. | 
|---|
| 177 | * @ str    : pointer to the string to be printed on the boot TTY terminal. | 
|---|
| 178 | ****************************************************************************/ | 
|---|
| 179 | void boot_puts(char* str); | 
|---|
| 180 |  | 
|---|
| 181 | /**************************************************************************** | 
|---|
| 182 | * This function produces output, according to the 'format' format, to the | 
|---|
| 183 | * boot TTY terminal. | 
|---|
| 184 | * @ format : the string defining the format of the output. It is composed | 
|---|
| 185 | *            of 0 or more directives: | 
|---|
| 186 | *            - ordinary characters (not %), which are copied unchanged to | 
|---|
| 187 | *              the boot TTY terminal. | 
|---|
| 188 | *            - conversion specifications (introduced by the character %, | 
|---|
| 189 | *              ended by a conversion specifier), each of which results in | 
|---|
| 190 | *              fetching 0 or more subsequent arguments. The arguments must | 
|---|
| 191 | *              correspond properly (after type promotion) with the | 
|---|
| 192 | *              conversion specifier. | 
|---|
| 193 | * | 
|---|
| 194 | * Conversion specifiers: | 
|---|
| 195 | *  - %d : 32-bit signed decimal notation of an integer, | 
|---|
| 196 | *  - %u : 32-bit unsigned decimal notation of an integer, | 
|---|
| 197 | *  - %x : 32-bit unsigned hexadecimal notation of an integer, | 
|---|
| 198 | *  - %l : 64-bit unsigned hexadecimal notation of an integer, | 
|---|
| 199 | *  - %c : character, | 
|---|
| 200 | *  - %s : NUL terminated string. | 
|---|
| 201 | ****************************************************************************/ | 
|---|
| 202 | void boot_printf(char* format, ...); | 
|---|
| 203 |  | 
|---|
| 204 | /**************************************************************************** | 
|---|
| 205 | *                            Misc. functions.                              * | 
|---|
| 206 | ****************************************************************************/ | 
|---|
| 207 |  | 
|---|
| 208 | /**************************************************************************** | 
|---|
| 209 | * This function causes a termination during the boot procedure once the | 
|---|
| 210 | * boot code detects an error. | 
|---|
| 211 | ****************************************************************************/ | 
|---|
| 212 | void boot_exit() __attribute__((noreturn)); | 
|---|
| 213 |  | 
|---|
| 214 | /**************************************************************************** | 
|---|
| 215 | * This function returns the cycle count stored in the CP0_COUNT register | 
|---|
| 216 | * of the currently running processor. | 
|---|
| 217 | * @ returns the processor cycle count. | 
|---|
| 218 | ****************************************************************************/ | 
|---|
| 219 | uint32_t boot_get_proctime(); | 
|---|
| 220 |  | 
|---|
| 221 | /**************************************************************************** | 
|---|
| 222 | * This function returns the global hardware identifier gid stored in the | 
|---|
| 223 | * CP0_PROCID register of the currently running processor. | 
|---|
| 224 | * @ returns the processor gid | 
|---|
| 225 | ****************************************************************************/ | 
|---|
| 226 | uint32_t boot_get_procid(); | 
|---|
| 227 |  | 
|---|
| 228 | /**************************************************************************** | 
|---|
| 229 | * This structure defines a toggling barrier, that can be used to | 
|---|
| 230 | * synchronize a group of cores, whether or not they are in a same cluster, | 
|---|
| 231 | * without any specific initialization. | 
|---|
| 232 | ****************************************************************************/ | 
|---|
| 233 | typedef struct boot_remote_barrier_s | 
|---|
| 234 | { | 
|---|
| 235 | uint32_t current;                      // Number of arrived cores | 
|---|
| 236 | uint32_t sense;                        // Toggle barrier state | 
|---|
| 237 | uint32_t pad[(CACHE_LINE_SIZE>>2)-2];  // Padding | 
|---|
| 238 | } | 
|---|
| 239 | boot_remote_barrier_t; | 
|---|
| 240 |  | 
|---|
| 241 | /**************************************************************************** | 
|---|
| 242 | * This function blocks all processors arriving at the barrier pointed to | 
|---|
| 243 | * by the extend pointer 'xp_barrier' and only returns when all 'count' | 
|---|
| 244 | * expected processors reach the barrier. | 
|---|
| 245 | * @ xp_barrier : extended pointer to a toggling barrier. | 
|---|
| 246 | * @ count      : number of expected processors. | 
|---|
| 247 | ****************************************************************************/ | 
|---|
| 248 | void boot_remote_barrier( xptr_t   xp_barrier, | 
|---|
| 249 | uint32_t count ); | 
|---|
| 250 |  | 
|---|
| 251 | /**************************************************************************** | 
|---|
| 252 | * This structure defines a remote queuing spinlock, that can be used to | 
|---|
| 253 | * synchronize a group of cores, whether or not they are in a same cluster, | 
|---|
| 254 | * without any specific initialization. | 
|---|
| 255 | ****************************************************************************/ | 
|---|
| 256 | typedef struct boot_remote_spinlock_s | 
|---|
| 257 | { | 
|---|
| 258 | uint32_t     ticket;                       // next free ticket index | 
|---|
| 259 | uint32_t     current;                      // current owner index | 
|---|
| 260 | uint32_t     pad[(CACHE_LINE_SIZE>>2)-2];  // Padding | 
|---|
| 261 | } | 
|---|
| 262 | boot_remote_spinlock_t; | 
|---|
| 263 |  | 
|---|
| 264 | /**************************************************************************** | 
|---|
| 265 | * This blocking function returns only when the lock is successfully taken. | 
|---|
| 266 | * @ lock_xp    : extended pointer on lock. | 
|---|
| 267 | ****************************************************************************/ | 
|---|
| 268 | void boot_remote_lock( xptr_t  lock_xp ); | 
|---|
| 269 |  | 
|---|
| 270 | /**************************************************************************** | 
|---|
| 271 | * This function release the lock. | 
|---|
| 272 | * @ lock_xp    : extended pointer on lock. | 
|---|
| 273 | ****************************************************************************/ | 
|---|
| 274 | void boot_remote_unlock( xptr_t  lock_xp ); | 
|---|
| 275 |  | 
|---|
| 276 |  | 
|---|
| 277 | #endif // _BOOT_UTILS_H | 
|---|