libpayload.h
1 /* 2 * 3 * Copyright (C) 2008 Advanced Micro Devices, Inc. 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 /** 30 * @mainpage 31 * 32 * @section intro Introduction 33 * libpayload is a small BSD-licensed static library (a lightweight 34 * implementation of common and useful functions) intended to be used 35 * as a basis for coreboot payloads. 36 * 37 * @section example Example 38 * Here is an example of a very simple payload: 39 * @include sample/hello.c 40 */ 41 42 #ifndef _LIBPAYLOAD_H 43 #define _LIBPAYLOAD_H 44 45 #include <stdbool.h> 46 #include <libpayload-config.h> 47 #include <cbgfx.h> 48 #if CONFIG(LP_GPL) 49 #include <commonlib/helpers.h> 50 #else 51 #include <commonlib/bsd/helpers.h> 52 #endif 53 #include <commonlib/bsd/elog.h> 54 #include <commonlib/bsd/fmap_serialized.h> 55 #include <commonlib/bsd/ipchksum.h> 56 #include <commonlib/bsd/mem_chip_info.h> 57 #include <ctype.h> 58 #include <die.h> 59 #include <endian.h> 60 #include <fmap.h> 61 #include <kconfig.h> 62 #include <stddef.h> 63 #include <stdio.h> 64 #include <stdarg.h> 65 #include <stdlib.h> 66 #include <string.h> 67 #include <time.h> 68 #include <sys/types.h> 69 #include <arch/types.h> 70 #include <arch/io.h> 71 #include <arch/virtual.h> 72 #include <sysinfo.h> 73 #include <pci.h> 74 #include <archive.h> 75 #include <delay.h> 76 77 #define BIT(x) (1ul << (x)) 78 79 static inline u32 div_round_up(u32 n, u32 d) { return (n + d - 1) / d; } 80 81 #define LITTLE_ENDIAN 1234 82 #define BIG_ENDIAN 4321 83 84 #define EXIT_SUCCESS 0 85 #define EXIT_FAILURE 1 86 87 #define RAND_MAX 0x7fffffff 88 89 #define MAX_ARGC_COUNT 32 90 91 /** 92 * @defgroup nvram NVRAM and RTC functions 93 * @{ 94 */ 95 96 #define NVRAM_RTC_SECONDS 0 /**< RTC Seconds offset in CMOS */ 97 #define NVRAM_RTC_MINUTES 2 /**< RTC Minutes offset in CMOS */ 98 #define NVRAM_RTC_HOURS 4 /**< RTC Hours offset in CMOS */ 99 #define NVRAM_RTC_DAY 7 /**< RTC Days offset in CMOS */ 100 #define NVRAM_RTC_MONTH 8 /**< RTC Month offset in CMOS */ 101 #define NVRAM_RTC_YEAR 9 /**< RTC Year offset in CMOS */ 102 #define NVRAM_RTC_FREQ_SELECT 10 /**< RTC Update Status Register */ 103 #define NVRAM_RTC_UIP 0x80 104 #define NVRAM_RTC_STATUSB 11 /**< RTC Status Register B */ 105 #define NVRAM_RTC_FORMAT_24HOUR 0x02 106 #define NVRAM_RTC_FORMAT_BINARY 0x04 107 108 /** Broken down time structure */ 109 struct tm { 110 int tm_sec; /**< Number of seconds after the minute */ 111 int tm_min; /**< Number of minutes after the hour */ 112 int tm_hour; /**< Number of hours past midnight */ 113 int tm_mday; /**< The day of the month */ 114 int tm_mon; /**< The month of the year */ 115 int tm_year; /**< The number of years since 1900 */ 116 int tm_wday; /**< The day of the week */ 117 int tm_yday; /**< The number of days since January 1 */ 118 int tm_isdst; /**< A flag indicating daylight savings time */ 119 }; 120 121 u8 nvram_read(u8 addr); 122 void nvram_write(u8 val, u8 addr); 123 int nvram_updating(void); 124 void rtc_read_clock(struct tm *tm); 125 void rtc_write_clock(const struct tm *tm); 126 /** @} */ 127 128 /** 129 * @defgroup storage driver functions 130 * @{ 131 */ 132 void storage_initialize(void); 133 /** @} */ 134 135 /** 136 * @defgroup usb USB functions 137 * @{ 138 */ 139 int usb_initialize(void); 140 int usb_exit (void); 141 int usbhid_havechar(void); 142 int usbhid_getchar(void); 143 int usbhid_getmodifiers(void); 144 /** @} */ 145 146 /** 147 * @defgroup input Device functions 148 * @{ @} 149 */ 150 151 extern void (*reset_handler)(void); 152 int add_reset_handler(void (*new_handler)(void)); 153 154 /** 155 * @defgroup keyboard Keyboard functions 156 * @ingroup input 157 * @{ 158 */ 159 void keyboard_init(void); 160 void keyboard_disconnect(void); 161 bool keyboard_havechar(void); 162 unsigned char keyboard_get_scancode(void); 163 int keyboard_getchar(void); 164 int keyboard_set_layout(char *country); 165 int keyboard_getmodifier(void); 166 void initialize_keyboard_media_key_mapping_callback(int (*media_key_mapper)(char)); 167 168 enum KEYBOARD_MODIFIERS { 169 KB_MOD_SHIFT = (1 << 0), 170 KB_MOD_ALT = (1 << 1), 171 KB_MOD_CTRL = (1 << 2), 172 KB_MOD_CAPSLOCK = (1 << 3), 173 }; 174 /** @} */ 175 176 /** 177 * @defgroup mouse Mouse cursor functions 178 * @ingroup input 179 * @{ 180 */ 181 void mouse_cursor_poll(void); 182 void mouse_cursor_get_rel(int *x, int *y, int *z); 183 u32 mouse_cursor_get_buttons(void); 184 void mouse_cursor_set_speed(u32 val); 185 u32 mouse_cursor_get_speed(void); 186 void mouse_cursor_set_acceleration(u8 val); 187 u8 mouse_cursor_get_acceleration(void); 188 /** @} */ 189 190 /** 191 * @defgroup i8042 controller functions 192 * @ingroup input 193 * @{ 194 */ 195 size_t i8042_has_ps2(void); 196 size_t i8042_has_aux(void); 197 198 u8 i8042_probe(void); 199 void i8042_close(void); 200 201 int i8042_cmd(u8 cmd); 202 void i8042_write_data(u8 data); 203 204 u8 i8042_data_ready_ps2(void); 205 u8 i8042_data_ready_aux(void); 206 207 u8 i8042_read_data_ps2(void); 208 u8 i8042_peek_data_ps2(void); 209 u8 i8042_read_data_aux(void); 210 211 int i8042_wait_read_ps2(void); 212 int i8042_wait_read_aux(void); 213 214 int i8042_get_kbd_translation(void); 215 int i8042_set_kbd_translation(bool xlate); 216 217 /** @} */ 218 219 /** 220 * @defgroup i8042 PS2 Mouse functions 221 * @ingroup input 222 * @{ 223 */ 224 void i8042_mouse_init(void); 225 void i8042_mouse_disconnect(void); 226 /** @} */ 227 228 /** 229 * @defgroup serial Serial functions 230 * @ingroup input 231 * @{ 232 */ 233 void serial_init(void); 234 void serial_console_init(void); 235 void serial_putchar(unsigned int c); 236 int serial_havechar(void); 237 int serial_getchar(void); 238 void serial_clear(void); 239 void serial_start_bold(void); 240 void serial_end_bold(void); 241 void serial_start_reverse(void); 242 void serial_end_reverse(void); 243 void serial_start_altcharset(void); 244 void serial_end_altcharset(void); 245 void serial_set_color(short fg, short bg); 246 void serial_cursor_enable(int state); 247 void serial_set_cursor(int y, int x); 248 /** @} */ 249 250 /** 251 * @defgroup speaker Speaker functions 252 * @ingroup input 253 * @{ 254 */ 255 void speaker_enable(u16 freq); 256 void speaker_disable(void); 257 void speaker_tone(u16 freq, unsigned int duration); 258 /** @} */ 259 260 /** 261 * @defgroup video Video functions 262 * @ingroup input 263 * @{ 264 */ 265 int video_init(void); 266 int video_console_init(void); 267 void video_get_rows_cols(unsigned int *rows, unsigned int *cols); 268 void video_console_putchar(unsigned int ch); 269 void video_console_putc(u8 row, u8 col, unsigned int ch); 270 void video_console_clear(void); 271 void video_console_cursor_enable(int state); 272 void video_console_get_cursor(unsigned int *x, unsigned int *y, unsigned int *en); 273 void video_console_set_cursor(unsigned int cursorx, unsigned int cursory); 274 void video_console_move_cursor(int x, int y); 275 /* 276 * print characters on video console with colors. note that there is a size 277 * restriction for the internal buffer. so, output string can be truncated. 278 */ 279 enum video_printf_align { 280 VIDEO_PRINTF_ALIGN_KEEP = 0, 281 VIDEO_PRINTF_ALIGN_LEFT, 282 VIDEO_PRINTF_ALIGN_CENTER, 283 VIDEO_PRINTF_ALIGN_RIGHT, 284 }; 285 void video_printf(int foreground, int background, enum video_printf_align align, 286 const char *fmt, ...); 287 /** @} */ 288 289 /** 290 * @defgroup cbmem_console CBMEM memory console. 291 * @ingroup input 292 * @{ 293 */ 294 void cbmem_console_init(void); 295 void cbmem_console_write(const void *buffer, size_t count); 296 /** 297 * Take a snapshot of the CBMEM memory console. This function will allocate a 298 * range of memory. Callers must free the returned buffer by themselves. 299 * 300 * @return The allocated buffer on success, NULL on failure. 301 */ 302 char *cbmem_console_snapshot(void); 303 /** @} */ 304 305 /* drivers/option.c */ 306 struct nvram_accessor { 307 u8 (*read)(u8 reg); 308 void (*write)(u8 val, u8 reg); 309 }; 310 311 extern u8 *mem_accessor_base; 312 extern struct nvram_accessor *use_nvram, *use_mem; 313 314 struct cb_cmos_option_table *get_system_option_table(void); 315 int options_checksum_valid(const struct nvram_accessor *nvram); 316 void fix_options_checksum_with(const struct nvram_accessor *nvram); 317 void fix_options_checksum(void); 318 319 struct cb_cmos_entries *first_cmos_entry(struct cb_cmos_option_table *option_table); 320 struct cb_cmos_entries *next_cmos_entry(struct cb_cmos_entries *cur); 321 322 struct cb_cmos_enums *first_cmos_enum(struct cb_cmos_option_table *option_table); 323 struct cb_cmos_enums *next_cmos_enum(struct cb_cmos_enums *cmos_enum); 324 struct cb_cmos_enums *first_cmos_enum_of_id(struct cb_cmos_option_table *option_table, int id); 325 struct cb_cmos_enums *next_cmos_enum_of_id(struct cb_cmos_enums *cmos_enum, int id); 326 327 int get_option_with(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, void *dest, const char *name); 328 int get_option_from(struct cb_cmos_option_table *option_table, void *dest, const char *name); 329 int get_option(void *dest, const char *name); 330 int set_option_with(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, const void *value, const char *name); 331 int set_option(const void *value, const char *name); 332 int get_option_as_string(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, char **dest, const char *name); 333 int set_option_from_string(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, const char *value, const char *name); 334 335 /** 336 * @defgroup console Console functions 337 * @{ 338 */ 339 typedef enum { 340 CONSOLE_INPUT_TYPE_UNKNOWN = 0, 341 CONSOLE_INPUT_TYPE_USB, 342 CONSOLE_INPUT_TYPE_EC, 343 CONSOLE_INPUT_TYPE_UART, 344 CONSOLE_INPUT_TYPE_GPIO, 345 } console_input_type; 346 347 void console_init(void); 348 void console_write(const void *buffer, size_t count); 349 int putchar(unsigned int c); 350 int puts(const char *s); 351 int havekey(void); 352 int getchar(void); 353 int getchar_timeout(int *ms); 354 console_input_type last_key_input_type(void); 355 356 extern int last_putchar; 357 358 struct console_input_driver; 359 struct console_input_driver { 360 struct console_input_driver *next; 361 int (*havekey) (void); 362 int (*getchar) (void); 363 console_input_type input_type; 364 }; 365 366 struct console_output_driver; 367 struct console_output_driver { 368 struct console_output_driver *next; 369 void (*putchar) (unsigned int); 370 void (*write) (const void *, size_t); 371 }; 372 373 void console_add_output_driver(struct console_output_driver *out); 374 void console_add_input_driver(struct console_input_driver *in); 375 int console_remove_output_driver(void *function); 376 377 #define havechar havekey 378 /** @} */ 379 380 /** 381 * @defgroup mouse_cursor Mouse cursor functions 382 * @{ 383 */ 384 typedef enum { 385 CURSOR_INPUT_TYPE_UNKNOWN = 0, 386 CURSOR_INPUT_TYPE_USB, 387 CURSOR_INPUT_TYPE_PS2, 388 } cursor_input_type; 389 390 void mouse_cursor_init(void); 391 392 struct mouse_cursor_input_driver; 393 struct mouse_cursor_input_driver { 394 struct mouse_cursor_input_driver *next; 395 /* X,Y,Z axis and buttons */ 396 void (*get_state)(int *, int *, int *, u32 *); 397 cursor_input_type input_type; 398 }; 399 400 void mouse_cursor_add_input_driver(struct mouse_cursor_input_driver *in); 401 402 /** @} */ 403 404 /** 405 * @defgroup exec Execution functions 406 * @{ 407 */ 408 int exec(long addr, int argc, char **argv); 409 410 /* 411 * reboot() handles reboot requests made by libpayload. It has weak implementation 412 * which should be overridden by payload. 413 */ 414 void __noreturn reboot(void); 415 416 /** @} */ 417 418 /** 419 * @defgroup misc Misc functions 420 * @{ 421 */ 422 int bcd2dec(int b); 423 int dec2bcd(int d); 424 u8 bin2hex(u8 b); 425 u8 hex2bin(u8 h); 426 void hexdump(const void *memory, size_t length); 427 void fatal(const char *msg) __attribute__((noreturn)); 428 429 /* Population Count: number of bits that are one */ 430 static inline int popcnt(u32 x) { return __builtin_popcount(x); } 431 /* Count Leading Zeroes: clz(0) == 32, clz(0xf) == 28, clz(1 << 31) == 0 */ 432 static inline int clz(u32 x) 433 { 434 return x ? __builtin_clz(x) : (int)sizeof(x) * 8; 435 } 436 /* Integer binary logarithm (rounding down): log2(0) == -1, log2(5) == 2 */ 437 static inline int log2(u32 x) { return (int)sizeof(x) * 8 - clz(x) - 1; } 438 /* Find First Set: __ffs(0xf) == 0, __ffs(0) == -1, __ffs(1 << 31) == 31 */ 439 static inline int __ffs(u32 x) { return log2(x & (u32)(-(s32)x)); } 440 /* Find Last Set: __fls(1) == 0, __fls(5) == 2, __fls(1 << 31) == 31 */ 441 static inline int __fls(u32 x) { return log2(x); } 442 443 static inline int popcnt64(u64 x) { return __builtin_popcountll(x); } 444 static inline int clz64(u64 x) 445 { 446 return x ? __builtin_clzll(x) : sizeof(x) * 8; 447 } 448 449 static inline int log2_64(u64 x) { return sizeof(x) * 8 - clz64(x) - 1; } 450 static inline int __ffs64(u64 x) { return log2_64(x & (u64)(-(s64)x)); } 451 static inline int __fls64(u64 x) { return log2_64(x); } 452 /** @} */ 453 454 /** 455 * @defgroup mmio MMIO helper functions 456 * @{ 457 */ 458 void buffer_from_fifo32(void *buffer, size_t size, void *fifo, 459 int fifo_stride, int fifo_width); 460 void buffer_to_fifo32_prefix(const void *buffer, u32 prefix, int prefsz, size_t size, 461 void *fifo, int fifo_stride, int fifo_width); 462 static inline void buffer_to_fifo32(const void *buffer, size_t size, void *fifo, 463 int fifo_stride, int fifo_width) 464 { 465 buffer_to_fifo32_prefix(buffer, 0, 0, size, fifo, 466 fifo_stride, fifo_width); 467 } 468 /** @} */ 469 470 /** 471 * @defgroup hash Hashing functions 472 * @{ 473 */ 474 #define SHA1_BLOCK_LENGTH 64 475 #define SHA1_DIGEST_LENGTH 20 476 typedef struct { 477 u32 state[5]; 478 u64 count; 479 u8 buffer[SHA1_BLOCK_LENGTH]; 480 } SHA1_CTX; 481 void SHA1Init(SHA1_CTX *context); 482 void SHA1Transform(u32 state[5], const u8 buffer[SHA1_BLOCK_LENGTH]); 483 void SHA1Update(SHA1_CTX *context, const u8 *data, size_t len); 484 void SHA1Pad(SHA1_CTX *context); 485 void SHA1Final(u8 digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context); 486 u8 *sha1(const u8 *data, size_t len, u8 *buf); 487 /** @} */ 488 489 /** 490 * @defgroup info System information functions 491 * This module contains functions that return information about the system 492 * @{ 493 */ 494 495 int sysinfo_have_multiboot(unsigned long *addr); 496 /** @} */ 497 498 /** 499 * @defgroup arch Architecture specific functions 500 * This module contains global architecture specific functions. 501 * All architectures are expected to define these functions. 502 * @{ 503 */ 504 int get_coreboot_info(struct sysinfo_t *info); 505 int get_multiboot_info(struct sysinfo_t *info); 506 void *get_cb_header_ptr(void); 507 508 int lib_get_sysinfo(void); 509 void lib_sysinfo_get_memranges(struct memrange **ranges, 510 uint64_t *nranges); 511 512 /* Timer functions. */ 513 /* Defined by each architecture. */ 514 uint64_t timer_hz(void); 515 uint64_t timer_raw_value(void); 516 uint64_t timer_us(uint64_t base); 517 /* Generic. */ 518 519 /** 520 * @defgroup readline Readline functions 521 * This interface provides a simple implementation of the standard readline() 522 * and getline() functions. They read a line of input from the console. 523 * @{ 524 */ 525 char *readline(const char *prompt); 526 int getline(char *buffer, int len); 527 /** @} */ 528 529 /* Defined in arch/${ARCH}/selfboot.c */ 530 void selfboot(void *entry); 531 532 /* Enter remote GDB mode. Will initialize connection if not already up. */ 533 void gdb_enter(void); 534 /* Disconnect existing GDB connection if one exists. */ 535 void gdb_exit(s8 exit_status); 536 537 void __noreturn halt(void); 538 #if CONFIG(LP_REMOTEGDB) 539 /* Override abort()/halt() to trap into GDB if it is enabled. */ 540 #define halt() do { gdb_enter(); halt(); } while (0) 541 #endif 542 543 #endif