2008-03-20 00:56:58 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the libpayload project.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2008-09-01 00:10:35 +02:00
|
|
|
/**
|
|
|
|
* @mainpage
|
|
|
|
*
|
2008-08-28 18:53:24 +02:00
|
|
|
* @section intro Introduction
|
|
|
|
* libpayload is a small BSD-licensed static library (a lightweight
|
|
|
|
* implementation of common and useful functions) intended to be used
|
|
|
|
* as a basis for coreboot payloads.
|
|
|
|
*
|
|
|
|
* @section example Example
|
|
|
|
* Here is an example of a very simple payload:
|
|
|
|
* @include sample/hello.c
|
|
|
|
*/
|
|
|
|
|
2008-04-11 20:01:50 +02:00
|
|
|
#ifndef _LIBPAYLOAD_H
|
|
|
|
#define _LIBPAYLOAD_H
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2010-03-25 23:15:19 +01:00
|
|
|
#include <libpayload-config.h>
|
2017-07-13 02:20:27 +02:00
|
|
|
#include <compiler.h>
|
2015-07-30 01:03:52 +02:00
|
|
|
#include <cbgfx.h>
|
Attached patch moves functions out of the huge libpayload.h into headers
according to libc/posix traditions, to simplify porting applications to
payloads.
It also adds a couple of functions:
strcasecmp, strncasecmp, strcat, strtol, strspn, strcspn, strtok_r,
strtok, perror, exit, getpagesize
Signed-off-by: Patrick Georgi <patrick.georgi@coresystems.de>
Acked-by: Stefan Reinauer <stepan@coresystems.de>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5643 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2010-06-24 13:16:10 +02:00
|
|
|
#include <ctype.h>
|
2013-11-23 09:38:49 +01:00
|
|
|
#include <die.h>
|
2014-07-17 19:43:15 +02:00
|
|
|
#include <endian.h>
|
2015-07-09 13:57:00 +02:00
|
|
|
#include <fmap_serialized.h>
|
2012-08-29 01:31:09 +02:00
|
|
|
#include <ipchksum.h>
|
2015-06-29 22:33:34 +02:00
|
|
|
#include <kconfig.h>
|
2008-03-20 00:56:58 +01:00
|
|
|
#include <stddef.h>
|
Attached patch moves functions out of the huge libpayload.h into headers
according to libc/posix traditions, to simplify porting applications to
payloads.
It also adds a couple of functions:
strcasecmp, strncasecmp, strcat, strtol, strspn, strcspn, strtok_r,
strtok, perror, exit, getpagesize
Signed-off-by: Patrick Georgi <patrick.georgi@coresystems.de>
Acked-by: Stefan Reinauer <stepan@coresystems.de>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5643 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2010-06-24 13:16:10 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2016-04-20 15:22:00 +02:00
|
|
|
#include <time.h>
|
2018-12-10 15:10:58 +01:00
|
|
|
#include <sys/types.h>
|
2008-03-20 00:56:58 +01:00
|
|
|
#include <arch/types.h>
|
|
|
|
#include <arch/io.h>
|
2008-08-19 19:49:53 +02:00
|
|
|
#include <arch/virtual.h>
|
2008-03-20 02:53:30 +01:00
|
|
|
#include <sysinfo.h>
|
2008-08-04 23:00:49 +02:00
|
|
|
#include <pci.h>
|
2015-11-05 19:05:38 +01:00
|
|
|
#include <archive.h>
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2015-05-23 03:09:48 +02:00
|
|
|
/* Double-evaluation unsafe min/max, for bitfields and outside of functions */
|
|
|
|
#define __CMP_UNSAFE(a, b, op) ((a) op (b) ? (a) : (b))
|
|
|
|
#define MIN_UNSAFE(a, b) __CMP_UNSAFE(a, b, <)
|
|
|
|
#define MAX_UNSAFE(a, b) __CMP_UNSAFE(a, b, >)
|
|
|
|
|
|
|
|
#define __CMP_SAFE(a, b, op, var_a, var_b) ({ \
|
|
|
|
__TYPEOF_UNLESS_CONST(a, b) var_a = (a); \
|
|
|
|
__TYPEOF_UNLESS_CONST(b, a) var_b = (b); \
|
|
|
|
var_a op var_b ? var_a : var_b; \
|
|
|
|
})
|
|
|
|
|
|
|
|
#define __CMP(a, b, op) __builtin_choose_expr( \
|
|
|
|
__builtin_constant_p(a) && __builtin_constant_p(b), \
|
|
|
|
__CMP_UNSAFE(a, b, op), __CMP_SAFE(a, b, op, __TMPNAME, __TMPNAME))
|
|
|
|
|
|
|
|
#define MIN(a, b) __CMP(a, b, <)
|
|
|
|
#define MAX(a, b) __CMP(a, b, >)
|
|
|
|
|
2008-03-20 00:56:58 +01:00
|
|
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
|
|
|
|
2015-05-23 03:09:48 +02:00
|
|
|
#define DIV_ROUND_UP(x, y) ({ \
|
|
|
|
typeof(x) _div_local_x = (x); \
|
|
|
|
typeof(y) _div_local_y = (y); \
|
|
|
|
(_div_local_x + _div_local_y - 1) / _div_local_y; \
|
|
|
|
})
|
|
|
|
|
2015-07-10 00:47:07 +02:00
|
|
|
static inline u32 div_round_up(u32 n, u32 d) { return (n + d - 1) / d; }
|
2015-05-23 03:18:46 +02:00
|
|
|
|
2008-04-04 01:01:23 +02:00
|
|
|
#define LITTLE_ENDIAN 1234
|
|
|
|
#define BIG_ENDIAN 4321
|
|
|
|
|
2008-04-11 22:16:24 +02:00
|
|
|
#define EXIT_SUCCESS 0
|
|
|
|
#define EXIT_FAILURE 1
|
|
|
|
|
2008-04-08 01:33:50 +02:00
|
|
|
#define RAND_MAX 0x7fffffff
|
|
|
|
|
2016-11-18 13:40:32 +01:00
|
|
|
#define MAX_ARGC_COUNT 32
|
2008-10-20 18:51:43 +02:00
|
|
|
|
2008-09-01 00:10:35 +02:00
|
|
|
/*
|
|
|
|
* Payload information parameters - these are used to pass information
|
|
|
|
* to the entity loading the payload.
|
|
|
|
* Usage: PAYLOAD_INFO(key, value)
|
|
|
|
* Example: PAYLOAD_INFO(name, "CoreInfo!")
|
2008-05-27 22:06:54 +02:00
|
|
|
*/
|
|
|
|
#define _pstruct(key) __pinfo_ ##key
|
|
|
|
#define PAYLOAD_INFO(key, value) \
|
|
|
|
static const char _pstruct(key)[] \
|
|
|
|
__attribute__((__used__)) \
|
|
|
|
__attribute__((section(".note.pinfo"),unused)) = #key "=" value
|
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
|
|
|
* @defgroup nvram NVRAM and RTC functions
|
|
|
|
* @{
|
|
|
|
*/
|
2008-08-29 01:10:55 +02:00
|
|
|
|
|
|
|
#define NVRAM_RTC_SECONDS 0 /**< RTC Seconds offset in CMOS */
|
|
|
|
#define NVRAM_RTC_MINUTES 2 /**< RTC Minutes offset in CMOS */
|
|
|
|
#define NVRAM_RTC_HOURS 4 /**< RTC Hours offset in CMOS */
|
|
|
|
#define NVRAM_RTC_DAY 7 /**< RTC Days offset in CMOS */
|
|
|
|
#define NVRAM_RTC_MONTH 8 /**< RTC Month offset in CMOS */
|
|
|
|
#define NVRAM_RTC_YEAR 9 /**< RTC Year offset in CMOS */
|
|
|
|
#define NVRAM_RTC_FREQ_SELECT 10 /**< RTC Update Status Register */
|
|
|
|
#define NVRAM_RTC_UIP 0x80
|
|
|
|
|
2008-09-01 00:10:35 +02:00
|
|
|
/** Broken down time structure */
|
2008-04-26 01:11:02 +02:00
|
|
|
struct tm {
|
2008-08-29 01:10:55 +02:00
|
|
|
int tm_sec; /**< Number of seconds after the minute */
|
|
|
|
int tm_min; /**< Number of minutes after the hour */
|
|
|
|
int tm_hour; /**< Number of hours past midnight */
|
|
|
|
int tm_mday; /**< The day of the month */
|
|
|
|
int tm_mon; /**< The month of the year */
|
|
|
|
int tm_year; /**< The number of years since 1900 */
|
|
|
|
int tm_wday; /**< The day of the week */
|
|
|
|
int tm_yday; /**< The number of days since January 1 */
|
|
|
|
int tm_isdst; /**< A flag indicating daylight savings time */
|
2008-04-26 01:11:02 +02:00
|
|
|
};
|
2008-03-28 00:26:40 +01:00
|
|
|
|
2008-03-31 17:17:39 +02:00
|
|
|
u8 nvram_read(u8 addr);
|
|
|
|
void nvram_write(u8 val, u8 addr);
|
2008-04-26 01:11:02 +02:00
|
|
|
int nvram_updating(void);
|
|
|
|
void rtc_read_clock(struct tm *tm);
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
|
|
|
|
2012-08-30 15:36:57 +02:00
|
|
|
/**
|
|
|
|
* @defgroup storage driver functions
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
void storage_initialize(void);
|
|
|
|
/** @} */
|
|
|
|
|
2008-09-26 20:42:40 +02:00
|
|
|
/**
|
|
|
|
* @defgroup usb USB functions
|
|
|
|
* @{
|
|
|
|
*/
|
2010-04-27 08:56:47 +02:00
|
|
|
int usb_initialize(void);
|
2011-11-04 12:06:06 +01:00
|
|
|
int usb_exit (void);
|
2008-10-16 21:20:51 +02:00
|
|
|
int usbhid_havechar(void);
|
|
|
|
int usbhid_getchar(void);
|
2017-03-06 18:37:00 +01:00
|
|
|
int usbhid_getmodifiers(void);
|
2008-09-26 20:42:40 +02:00
|
|
|
/** @} */
|
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
|
|
|
* @defgroup input Device functions
|
|
|
|
* @{ @}
|
|
|
|
*/
|
2008-03-28 00:26:40 +01:00
|
|
|
|
2010-03-25 19:52:24 +01:00
|
|
|
extern void (*reset_handler)(void);
|
|
|
|
int add_reset_handler(void (*new_handler)(void));
|
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
|
|
|
* @defgroup keyboard Keyboard functions
|
|
|
|
* @ingroup input
|
|
|
|
* @{
|
|
|
|
*/
|
2008-04-26 01:09:39 +02:00
|
|
|
void keyboard_init(void);
|
2013-07-27 00:31:21 +02:00
|
|
|
void keyboard_disconnect(void);
|
2008-03-20 02:53:30 +01:00
|
|
|
int keyboard_havechar(void);
|
|
|
|
unsigned char keyboard_get_scancode(void);
|
|
|
|
int keyboard_getchar(void);
|
2008-09-26 20:37:26 +02:00
|
|
|
int keyboard_set_layout(char *country);
|
2017-03-05 17:29:18 +01:00
|
|
|
int keyboard_getmodifier(void);
|
|
|
|
|
|
|
|
enum KEYBOARD_MODIFIERS {
|
|
|
|
KB_MOD_SHIFT = (1 << 0),
|
|
|
|
KB_MOD_ALT = (1 << 1),
|
|
|
|
KB_MOD_CTRL = (1 << 2),
|
|
|
|
KB_MOD_CAPSLOCK = (1 << 3),
|
|
|
|
};
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2017-02-06 15:02:25 +01:00
|
|
|
/**
|
|
|
|
* @defgroup mouse Mouse cursor functions
|
|
|
|
* @ingroup input
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
void mouse_cursor_poll(void);
|
|
|
|
void mouse_cursor_get_rel(int *x, int *y, int *z);
|
|
|
|
u32 mouse_cursor_get_buttons(void);
|
|
|
|
void mouse_cursor_set_speed(u32 val);
|
|
|
|
u32 mouse_cursor_get_speed(void);
|
|
|
|
void mouse_cursor_set_acceleration(u8 val);
|
|
|
|
u8 mouse_cursor_get_acceleration(void);
|
|
|
|
/** @} */
|
|
|
|
|
2017-03-01 19:07:37 +01:00
|
|
|
/**
|
|
|
|
* @defgroup i8042 controller functions
|
|
|
|
* @ingroup input
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
size_t i8042_has_ps2(void);
|
|
|
|
size_t i8042_has_aux(void);
|
|
|
|
|
|
|
|
u8 i8042_probe(void);
|
|
|
|
void i8042_close(void);
|
|
|
|
|
|
|
|
int i8042_cmd(u8 cmd);
|
|
|
|
void i8042_write_data(u8 data);
|
|
|
|
|
|
|
|
u8 i8042_data_ready_ps2(void);
|
|
|
|
u8 i8042_data_ready_aux(void);
|
|
|
|
|
|
|
|
u8 i8042_read_data_ps2(void);
|
|
|
|
u8 i8042_read_data_aux(void);
|
|
|
|
|
|
|
|
int i8042_wait_read_ps2(void);
|
|
|
|
int i8042_wait_read_aux(void);
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
2017-02-06 15:26:58 +01:00
|
|
|
/**
|
|
|
|
* @defgroup i8042 PS2 Mouse functions
|
|
|
|
* @ingroup input
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
void i8042_mouse_init(void);
|
|
|
|
void i8042_mouse_disconnect(void);
|
|
|
|
/** @} */
|
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
|
|
|
* @defgroup serial Serial functions
|
|
|
|
* @ingroup input
|
|
|
|
* @{
|
|
|
|
*/
|
2008-03-20 02:53:30 +01:00
|
|
|
void serial_init(void);
|
2013-12-04 06:25:35 +01:00
|
|
|
void serial_console_init(void);
|
2008-10-21 17:08:18 +02:00
|
|
|
void serial_putchar(unsigned int c);
|
2008-03-20 02:53:30 +01:00
|
|
|
int serial_havechar(void);
|
|
|
|
int serial_getchar(void);
|
2008-06-20 02:01:42 +02:00
|
|
|
void serial_clear(void);
|
|
|
|
void serial_start_bold(void);
|
|
|
|
void serial_end_bold(void);
|
2008-09-26 20:36:26 +02:00
|
|
|
void serial_start_reverse(void);
|
|
|
|
void serial_end_reverse(void);
|
2008-08-11 22:34:28 +02:00
|
|
|
void serial_start_altcharset(void);
|
|
|
|
void serial_end_altcharset(void);
|
2008-09-03 21:59:44 +02:00
|
|
|
void serial_set_color(short fg, short bg);
|
2008-09-26 20:36:26 +02:00
|
|
|
void serial_cursor_enable(int state);
|
2008-06-20 02:01:42 +02:00
|
|
|
void serial_set_cursor(int y, int x);
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-06-20 02:01:42 +02:00
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
|
|
|
* @defgroup speaker Speaker functions
|
|
|
|
* @ingroup input
|
|
|
|
* @{
|
|
|
|
*/
|
2008-04-11 20:01:50 +02:00
|
|
|
void speaker_enable(u16 freq);
|
|
|
|
void speaker_disable(void);
|
|
|
|
void speaker_tone(u16 freq, unsigned int duration);
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-04-11 20:01:50 +02:00
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
|
|
|
* @defgroup video Video functions
|
|
|
|
* @ingroup input
|
|
|
|
* @{
|
|
|
|
*/
|
2012-10-06 08:35:04 +02:00
|
|
|
int video_init(void);
|
2008-04-11 00:49:02 +02:00
|
|
|
int video_console_init(void);
|
2012-10-06 08:43:37 +02:00
|
|
|
void video_get_rows_cols(unsigned int *rows, unsigned int *cols);
|
2008-04-11 00:49:02 +02:00
|
|
|
void video_console_putchar(unsigned int ch);
|
|
|
|
void video_console_putc(u8 row, u8 col, unsigned int ch);
|
|
|
|
void video_console_clear(void);
|
|
|
|
void video_console_cursor_enable(int state);
|
2008-08-19 19:44:49 +02:00
|
|
|
void video_console_get_cursor(unsigned int *x, unsigned int *y, unsigned int *en);
|
|
|
|
void video_console_set_cursor(unsigned int cursorx, unsigned int cursory);
|
2015-08-01 00:22:58 +02:00
|
|
|
/*
|
|
|
|
* print characters on video console with colors. note that there is a size
|
|
|
|
* restriction for the internal buffer. so, output string can be truncated.
|
|
|
|
*/
|
2015-08-13 03:49:50 +02:00
|
|
|
enum video_printf_align {
|
|
|
|
VIDEO_PRINTF_ALIGN_KEEP = 0,
|
|
|
|
VIDEO_PRINTF_ALIGN_LEFT,
|
|
|
|
VIDEO_PRINTF_ALIGN_CENTER,
|
|
|
|
VIDEO_PRINTF_ALIGN_RIGHT,
|
|
|
|
};
|
|
|
|
void video_printf(int foreground, int background, enum video_printf_align align,
|
|
|
|
const char *fmt, ...);
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-08-19 19:44:49 +02:00
|
|
|
|
2012-09-29 09:21:27 +02:00
|
|
|
/**
|
|
|
|
* @defgroup cbmem_console CBMEM memory console.
|
|
|
|
* @ingroup input
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
void cbmem_console_init(void);
|
libpayload: console: Allow output drivers to print whole strings at once
The console output driver framework in libpayload is currently built on
the putchar primitive, meaning that every driver's function gets called
one character at a time. This becomes an issue when we add drivers that
could output multiple characters at a time, but have a high constant
overhead per invocation (such as the planned GDB stub, which needs to
wrap a special frame around output strings and wait for an
acknowledgement from the server).
This patch adds a new 'write' function pointer to the
console_output_driver structure as an alternative to 'putchar'. Output
drivers need to provide at least one of the two ('write' is preferred if
available). The CBMEM console driver is ported as a proof of concept
(since it's our most performace-critical driver and should in theory
benefit the most from less function pointer invocations, although it's
probably still negligible compared to the big sprawling mess that is
printf()).
Even with this fix, the problem remains that printf() was written with
the putchar primitive in mind. Even though normal text already contains
an optimization to allow multiple characters at a time, almost all
formatting directives cause their output (including things like
padding whitespace) to be putchar()ed one character at a time.
Therefore, this patch reworks parts of the output code (especially
number printing) to all but remove that inefficiency (directives still
invoke an extra write() call, but at least not one per character). Since
I'm touching printf() core code anyway, I also tried to salvage what I
could from that weird, broken "return negative on error" code path (not
that any of our current output drivers can trigger it anyway).
A final consequence of this patch is that the responsibility to prepend
line feeds with carriage returns is moved into the output driver
implementations. Doing this only makes sense for drivers with explicit
cursor position control (i.e. serial or video), and things like the
CBMEM console that appears like a normal file to the system really have
no business containing carriage returns (we don't want people to
accidentally associate us with Windows, now, do we?).
BUG=chrome-os-partner:18390
TEST=Made sure video and CBMEM console still look good, tried printf()
with as many weird edge-case strings as I could find and compared serial
output as well as sprintf() return value.
Original-Change-Id: Ie05ae489332a0103461620f5348774b6d4afd91a
Original-Signed-off-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/196384
Original-Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
(cherry picked from commit ab1ef0c07736fe1aa3e0baaf02d258731e6856c0)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I78f5aedf6d0c3665924995cdab691ee0162de404
Reviewed-on: http://review.coreboot.org/7880
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2014-04-18 05:00:20 +02:00
|
|
|
void cbmem_console_write(const void *buffer, size_t count);
|
2012-09-29 09:21:27 +02:00
|
|
|
/** @} */
|
|
|
|
|
2008-08-19 19:44:49 +02:00
|
|
|
/* drivers/option.c */
|
2012-01-16 10:14:24 +01:00
|
|
|
struct nvram_accessor {
|
|
|
|
u8 (*read)(u8 reg);
|
|
|
|
void (*write)(u8 val, u8 reg);
|
|
|
|
};
|
|
|
|
|
2012-02-02 15:51:29 +01:00
|
|
|
extern u8 *mem_accessor_base;
|
|
|
|
extern struct nvram_accessor *use_nvram, *use_mem;
|
2012-01-16 10:14:24 +01:00
|
|
|
|
|
|
|
struct cb_cmos_option_table *get_system_option_table(void);
|
2012-01-16 15:03:11 +01:00
|
|
|
int options_checksum_valid(const struct nvram_accessor *nvram);
|
2012-01-16 10:14:24 +01:00
|
|
|
void fix_options_checksum_with(const struct nvram_accessor *nvram);
|
2010-08-17 12:14:50 +02:00
|
|
|
void fix_options_checksum(void);
|
2012-09-24 20:06:27 +02:00
|
|
|
|
2012-01-16 15:39:57 +01:00
|
|
|
struct cb_cmos_entries *first_cmos_entry(struct cb_cmos_option_table *option_table);
|
|
|
|
struct cb_cmos_entries *next_cmos_entry(struct cb_cmos_entries *cur);
|
2012-09-24 20:06:27 +02:00
|
|
|
|
|
|
|
struct cb_cmos_enums *first_cmos_enum(struct cb_cmos_option_table *option_table);
|
|
|
|
struct cb_cmos_enums *next_cmos_enum(struct cb_cmos_enums *cmos_enum);
|
|
|
|
struct cb_cmos_enums *first_cmos_enum_of_id(struct cb_cmos_option_table *option_table, int id);
|
|
|
|
struct cb_cmos_enums *next_cmos_enum_of_id(struct cb_cmos_enums *cmos_enum, int id);
|
|
|
|
|
2012-02-17 12:02:47 +01:00
|
|
|
int get_option_with(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, void *dest, const char *name);
|
|
|
|
int get_option_from(struct cb_cmos_option_table *option_table, void *dest, const char *name);
|
|
|
|
int get_option(void *dest, const char *name);
|
|
|
|
int set_option_with(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, const void *value, const char *name);
|
|
|
|
int set_option(const void *value, const char *name);
|
|
|
|
int get_option_as_string(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, char **dest, const char *name);
|
|
|
|
int set_option_from_string(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, const char *value, const char *name);
|
2008-03-20 02:53:30 +01:00
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
|
|
|
* @defgroup console Console functions
|
|
|
|
* @{
|
|
|
|
*/
|
2014-01-14 02:45:54 +01:00
|
|
|
typedef enum {
|
|
|
|
CONSOLE_INPUT_TYPE_UNKNOWN = 0,
|
|
|
|
CONSOLE_INPUT_TYPE_USB,
|
|
|
|
} console_input_type;
|
|
|
|
|
2008-03-20 02:53:30 +01:00
|
|
|
void console_init(void);
|
libpayload: console: Allow output drivers to print whole strings at once
The console output driver framework in libpayload is currently built on
the putchar primitive, meaning that every driver's function gets called
one character at a time. This becomes an issue when we add drivers that
could output multiple characters at a time, but have a high constant
overhead per invocation (such as the planned GDB stub, which needs to
wrap a special frame around output strings and wait for an
acknowledgement from the server).
This patch adds a new 'write' function pointer to the
console_output_driver structure as an alternative to 'putchar'. Output
drivers need to provide at least one of the two ('write' is preferred if
available). The CBMEM console driver is ported as a proof of concept
(since it's our most performace-critical driver and should in theory
benefit the most from less function pointer invocations, although it's
probably still negligible compared to the big sprawling mess that is
printf()).
Even with this fix, the problem remains that printf() was written with
the putchar primitive in mind. Even though normal text already contains
an optimization to allow multiple characters at a time, almost all
formatting directives cause their output (including things like
padding whitespace) to be putchar()ed one character at a time.
Therefore, this patch reworks parts of the output code (especially
number printing) to all but remove that inefficiency (directives still
invoke an extra write() call, but at least not one per character). Since
I'm touching printf() core code anyway, I also tried to salvage what I
could from that weird, broken "return negative on error" code path (not
that any of our current output drivers can trigger it anyway).
A final consequence of this patch is that the responsibility to prepend
line feeds with carriage returns is moved into the output driver
implementations. Doing this only makes sense for drivers with explicit
cursor position control (i.e. serial or video), and things like the
CBMEM console that appears like a normal file to the system really have
no business containing carriage returns (we don't want people to
accidentally associate us with Windows, now, do we?).
BUG=chrome-os-partner:18390
TEST=Made sure video and CBMEM console still look good, tried printf()
with as many weird edge-case strings as I could find and compared serial
output as well as sprintf() return value.
Original-Change-Id: Ie05ae489332a0103461620f5348774b6d4afd91a
Original-Signed-off-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/196384
Original-Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
(cherry picked from commit ab1ef0c07736fe1aa3e0baaf02d258731e6856c0)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I78f5aedf6d0c3665924995cdab691ee0162de404
Reviewed-on: http://review.coreboot.org/7880
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2014-04-18 05:00:20 +02:00
|
|
|
void console_write(const void *buffer, size_t count);
|
2008-10-21 17:08:18 +02:00
|
|
|
int putchar(unsigned int c);
|
2008-03-20 02:53:30 +01:00
|
|
|
int puts(const char *s);
|
|
|
|
int havekey(void);
|
|
|
|
int getchar(void);
|
2008-04-09 01:21:33 +02:00
|
|
|
int getchar_timeout(int *ms);
|
2014-01-14 02:45:54 +01:00
|
|
|
console_input_type last_key_input_type(void);
|
2008-03-20 02:53:30 +01:00
|
|
|
|
2008-03-20 00:56:58 +01:00
|
|
|
extern int last_putchar;
|
|
|
|
|
2008-10-21 17:08:18 +02:00
|
|
|
struct console_input_driver;
|
|
|
|
struct console_input_driver {
|
|
|
|
struct console_input_driver *next;
|
|
|
|
int (*havekey) (void);
|
|
|
|
int (*getchar) (void);
|
2014-01-14 02:45:54 +01:00
|
|
|
console_input_type input_type;
|
2008-10-21 17:08:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct console_output_driver;
|
|
|
|
struct console_output_driver {
|
|
|
|
struct console_output_driver *next;
|
|
|
|
void (*putchar) (unsigned int);
|
libpayload: console: Allow output drivers to print whole strings at once
The console output driver framework in libpayload is currently built on
the putchar primitive, meaning that every driver's function gets called
one character at a time. This becomes an issue when we add drivers that
could output multiple characters at a time, but have a high constant
overhead per invocation (such as the planned GDB stub, which needs to
wrap a special frame around output strings and wait for an
acknowledgement from the server).
This patch adds a new 'write' function pointer to the
console_output_driver structure as an alternative to 'putchar'. Output
drivers need to provide at least one of the two ('write' is preferred if
available). The CBMEM console driver is ported as a proof of concept
(since it's our most performace-critical driver and should in theory
benefit the most from less function pointer invocations, although it's
probably still negligible compared to the big sprawling mess that is
printf()).
Even with this fix, the problem remains that printf() was written with
the putchar primitive in mind. Even though normal text already contains
an optimization to allow multiple characters at a time, almost all
formatting directives cause their output (including things like
padding whitespace) to be putchar()ed one character at a time.
Therefore, this patch reworks parts of the output code (especially
number printing) to all but remove that inefficiency (directives still
invoke an extra write() call, but at least not one per character). Since
I'm touching printf() core code anyway, I also tried to salvage what I
could from that weird, broken "return negative on error" code path (not
that any of our current output drivers can trigger it anyway).
A final consequence of this patch is that the responsibility to prepend
line feeds with carriage returns is moved into the output driver
implementations. Doing this only makes sense for drivers with explicit
cursor position control (i.e. serial or video), and things like the
CBMEM console that appears like a normal file to the system really have
no business containing carriage returns (we don't want people to
accidentally associate us with Windows, now, do we?).
BUG=chrome-os-partner:18390
TEST=Made sure video and CBMEM console still look good, tried printf()
with as many weird edge-case strings as I could find and compared serial
output as well as sprintf() return value.
Original-Change-Id: Ie05ae489332a0103461620f5348774b6d4afd91a
Original-Signed-off-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/196384
Original-Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
(cherry picked from commit ab1ef0c07736fe1aa3e0baaf02d258731e6856c0)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I78f5aedf6d0c3665924995cdab691ee0162de404
Reviewed-on: http://review.coreboot.org/7880
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2014-04-18 05:00:20 +02:00
|
|
|
void (*write) (const void *, size_t);
|
2008-10-21 17:08:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
void console_add_output_driver(struct console_output_driver *out);
|
|
|
|
void console_add_input_driver(struct console_input_driver *in);
|
2014-06-03 05:13:51 +02:00
|
|
|
int console_remove_output_driver(void *function);
|
2008-10-21 17:08:18 +02:00
|
|
|
|
2008-03-20 00:56:58 +01:00
|
|
|
#define havechar havekey
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2017-02-06 15:02:25 +01:00
|
|
|
/**
|
|
|
|
* @defgroup mouse_cursor Mouse cursor functions
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
CURSOR_INPUT_TYPE_UNKNOWN = 0,
|
|
|
|
CURSOR_INPUT_TYPE_USB,
|
|
|
|
CURSOR_INPUT_TYPE_PS2,
|
|
|
|
} cursor_input_type;
|
|
|
|
|
|
|
|
void mouse_cursor_init(void);
|
|
|
|
|
|
|
|
struct mouse_cursor_input_driver;
|
|
|
|
struct mouse_cursor_input_driver {
|
|
|
|
struct mouse_cursor_input_driver *next;
|
|
|
|
/* X,Y,Z axis and buttons */
|
|
|
|
void (*get_state)(int *, int *, int *, u32 *);
|
|
|
|
cursor_input_type input_type;
|
|
|
|
};
|
|
|
|
|
|
|
|
void mouse_cursor_add_input_driver(struct mouse_cursor_input_driver *in);
|
|
|
|
|
|
|
|
/** @} */
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
2008-09-01 00:10:35 +02:00
|
|
|
* @defgroup exec Execution functions
|
2008-08-28 18:53:24 +02:00
|
|
|
* @{
|
|
|
|
*/
|
2008-05-20 22:10:49 +02:00
|
|
|
int exec(long addr, int argc, char **argv);
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-05-20 22:10:49 +02:00
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
2008-09-01 00:10:35 +02:00
|
|
|
* @defgroup misc Misc functions
|
2008-08-28 18:53:24 +02:00
|
|
|
* @{
|
|
|
|
*/
|
2008-03-28 00:26:40 +01:00
|
|
|
int bcd2dec(int b);
|
|
|
|
int dec2bcd(int d);
|
2008-04-11 20:38:04 +02:00
|
|
|
int abs(int j);
|
|
|
|
long int labs(long int j);
|
|
|
|
long long int llabs(long long int j);
|
|
|
|
u8 bin2hex(u8 b);
|
|
|
|
u8 hex2bin(u8 h);
|
2014-03-24 00:42:36 +01:00
|
|
|
void hexdump(const void *memory, size_t length);
|
2017-07-13 02:20:27 +02:00
|
|
|
void fatal(const char *msg) __attribute__((noreturn));
|
lib: Unify log2() and related functions
This patch adds a few bit counting functions that are commonly needed
for certain register calculations. We previously had a log2()
implementation already, but it was awkwardly split between some C code
that's only available in ramstage and an optimized x86-specific
implementation in pre-RAM that prevented other archs from pulling it
into earlier stages.
Using __builtin_clz() as the baseline allows GCC to inline optimized
assembly for most archs (including CLZ on ARM/ARM64 and BSR on x86), and
to perform constant-folding if possible. What was previously named log2f
on pre-RAM x86 is now ffs, since that's the standard name for that
operation and I honestly don't have the slightest idea how it could've
ever ended up being called log2f (which in POSIX is 'binary(2) LOGarithm
with Float result, whereas the Find First Set operation has no direct
correlation to logarithms that I know of). Make ffs result 0-based
instead of the POSIX standard's 1-based since that is consistent with
clz, log2 and the former log2f, and generally closer to what you want
for most applications (a value that can directly be used as a shift to
reach the found bit). Call it __ffs() instead of ffs() to avoid problems
when importing code, since that's what Linux uses for the 0-based
operation.
CQ-DEPEND=CL:273023
BRANCH=None
BUG=None
TEST=Built on Big, Falco, Jerry, Oak and Urara. Compared old and new
log2() and __ffs() results on Falco for a bunch of test values.
Change-Id: I599209b342059e17b3130621edb6b6bbeae26876
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 3701a16ae944ecff9c54fa9a50d28015690fcb2f
Original-Change-Id: I60f7cf893792508188fa04d088401a8bca4b4af6
Original-Signed-off-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/273008
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/10394
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2015-05-23 01:26:40 +02:00
|
|
|
|
|
|
|
/* Count Leading Zeroes: clz(0) == 32, clz(0xf) == 28, clz(1 << 31) == 0 */
|
|
|
|
static inline int clz(u32 x) { return x ? __builtin_clz(x) : sizeof(x) * 8; }
|
|
|
|
/* Integer binary logarithm (rounding down): log2(0) == -1, log2(5) == 2 */
|
|
|
|
static inline int log2(u32 x) { return sizeof(x) * 8 - clz(x) - 1; }
|
|
|
|
/* Find First Set: __ffs(0xf) == 0, __ffs(0) == -1, __ffs(1 << 31) == 31 */
|
|
|
|
static inline int __ffs(u32 x) { return log2(x & (u32)(-(s32)x)); }
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-03-28 00:26:40 +01:00
|
|
|
|
2008-04-09 01:38:15 +02:00
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
2008-09-01 00:10:35 +02:00
|
|
|
* @defgroup hash Hashing functions
|
2008-08-28 18:53:24 +02:00
|
|
|
* @{
|
|
|
|
*/
|
2008-04-04 01:01:23 +02:00
|
|
|
#define SHA1_BLOCK_LENGTH 64
|
|
|
|
#define SHA1_DIGEST_LENGTH 20
|
|
|
|
typedef struct {
|
|
|
|
u32 state[5];
|
|
|
|
u64 count;
|
|
|
|
u8 buffer[SHA1_BLOCK_LENGTH];
|
|
|
|
} SHA1_CTX;
|
|
|
|
void SHA1Init(SHA1_CTX *context);
|
|
|
|
void SHA1Transform(u32 state[5], const u8 buffer[SHA1_BLOCK_LENGTH]);
|
|
|
|
void SHA1Update(SHA1_CTX *context, const u8 *data, size_t len);
|
2011-04-21 18:57:16 +02:00
|
|
|
void SHA1Pad(SHA1_CTX *context);
|
2008-04-04 01:01:23 +02:00
|
|
|
void SHA1Final(u8 digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context);
|
|
|
|
u8 *sha1(const u8 *data, size_t len, u8 *buf);
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-04-04 01:01:23 +02:00
|
|
|
|
2008-11-11 20:51:14 +01:00
|
|
|
/**
|
|
|
|
* @defgroup info System information functions
|
|
|
|
* This module contains functions that return information about the system
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
int sysinfo_have_multiboot(unsigned long *addr);
|
|
|
|
/** @} */
|
2008-05-07 22:34:02 +02:00
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
2008-09-01 00:10:35 +02:00
|
|
|
* @defgroup arch Architecture specific functions
|
|
|
|
* This module contains global architecture specific functions.
|
2008-08-29 01:12:22 +02:00
|
|
|
* All architectures are expected to define these functions.
|
2008-08-28 18:53:24 +02:00
|
|
|
* @{
|
|
|
|
*/
|
2008-03-20 02:53:30 +01:00
|
|
|
int get_coreboot_info(struct sysinfo_t *info);
|
2008-10-20 18:51:43 +02:00
|
|
|
int get_multiboot_info(struct sysinfo_t *info);
|
2014-09-11 23:20:35 +02:00
|
|
|
void *get_cb_header_ptr(void);
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2011-12-24 02:33:05 +01:00
|
|
|
int lib_get_sysinfo(void);
|
2014-09-05 00:21:12 +02:00
|
|
|
void lib_sysinfo_get_memranges(struct memrange **ranges,
|
|
|
|
uint64_t *nranges);
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2013-02-23 01:38:53 +01:00
|
|
|
/* Timer functions. */
|
|
|
|
/* Defined by each architecture. */
|
2008-03-20 02:53:30 +01:00
|
|
|
unsigned int get_cpu_speed(void);
|
2013-02-23 01:38:53 +01:00
|
|
|
uint64_t timer_hz(void);
|
|
|
|
uint64_t timer_raw_value(void);
|
2013-12-07 08:30:10 +01:00
|
|
|
uint64_t timer_us(uint64_t base);
|
2018-08-20 20:47:19 +02:00
|
|
|
void arch_ndelay(uint64_t n);
|
2013-02-23 01:38:53 +01:00
|
|
|
/* Generic. */
|
2018-08-20 20:47:19 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Delay for a specified number of nanoseconds.
|
|
|
|
*
|
|
|
|
* @param ns Number of nanoseconds to delay for.
|
|
|
|
*/
|
|
|
|
static inline void ndelay(unsigned int ns)
|
|
|
|
{
|
|
|
|
arch_ndelay((uint64_t)ns);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delay for a specified number of microseconds.
|
|
|
|
*
|
|
|
|
* @param us Number of microseconds to delay for.
|
|
|
|
*/
|
|
|
|
static inline void udelay(unsigned int us)
|
|
|
|
{
|
|
|
|
arch_ndelay((uint64_t)us * NSECS_PER_USEC);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delay for a specified number of milliseconds.
|
|
|
|
*
|
|
|
|
* @param ms Number of milliseconds to delay for.
|
|
|
|
*/
|
|
|
|
static inline void mdelay(unsigned int ms)
|
|
|
|
{
|
|
|
|
arch_ndelay((uint64_t)ms * NSECS_PER_MSEC);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delay for a specified number of seconds.
|
|
|
|
*
|
|
|
|
* @param s Number of seconds to delay for.
|
|
|
|
*/
|
|
|
|
static inline void delay(unsigned int s)
|
|
|
|
{
|
|
|
|
arch_ndelay((uint64_t)s * NSECS_PER_SEC);
|
|
|
|
}
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2008-08-28 18:53:24 +02:00
|
|
|
/**
|
2008-09-01 00:10:35 +02:00
|
|
|
* @defgroup readline Readline functions
|
|
|
|
* This interface provides a simple implementation of the standard readline()
|
|
|
|
* and getline() functions. They read a line of input from the console.
|
2008-08-28 18:53:24 +02:00
|
|
|
* @{
|
|
|
|
*/
|
2008-09-01 00:10:35 +02:00
|
|
|
char *readline(const char *prompt);
|
2008-08-23 14:17:46 +02:00
|
|
|
int getline(char *buffer, int len);
|
2008-08-28 18:53:24 +02:00
|
|
|
/** @} */
|
2008-03-20 00:56:58 +01:00
|
|
|
|
2014-05-23 23:37:10 +02:00
|
|
|
/* Defined in arch/${ARCH}/selfboot.c */
|
|
|
|
void selfboot(void *entry);
|
|
|
|
|
2015-07-09 13:57:00 +02:00
|
|
|
/* look for area "name" in "fmap", setting offset and size to describe it.
|
|
|
|
Returns 0 on success, < 0 on error. */
|
|
|
|
int fmap_region_by_name(const uint32_t fmap_offset, const char * const name,
|
|
|
|
uint32_t * const offset, uint32_t * const size);
|
2008-03-20 00:56:58 +01:00
|
|
|
#endif
|