xref: /aosp_15_r20/external/coreboot/payloads/libpayload/include/libpayload.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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 
div_round_up(u32 n,u32 d)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 */
popcnt(u32 x)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 */
clz(u32 x)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 */
log2(u32 x)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 */
__ffs(u32 x)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 */
__fls(u32 x)441 static inline int __fls(u32 x) { return log2(x); }
442 
popcnt64(u64 x)443 static inline int popcnt64(u64 x) { return __builtin_popcountll(x); }
clz64(u64 x)444 static inline int clz64(u64 x)
445 {
446 	return x ? __builtin_clzll(x) : sizeof(x) * 8;
447 }
448 
log2_64(u64 x)449 static inline int log2_64(u64 x) { return sizeof(x) * 8 - clz64(x) - 1; }
__ffs64(u64 x)450 static inline int __ffs64(u64 x) { return log2_64(x & (u64)(-(s64)x)); }
__fls64(u64 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);
buffer_to_fifo32(const void * buffer,size_t size,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
544