summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asm-generic/global_data.h8
-rw-r--r--include/charset.h15
-rw-r--r--include/common.h46
-rw-r--r--include/efi.h6
-rw-r--r--include/efi_api.h48
-rw-r--r--include/efi_loader.h66
-rw-r--r--include/efi_selftest.h21
-rw-r--r--include/log.h304
-rw-r--r--include/logbuff.h49
-rw-r--r--include/os.h20
-rw-r--r--include/post.h4
11 files changed, 442 insertions, 145 deletions
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 944f58195ca..73e036d6fd4 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -36,7 +36,7 @@ typedef struct global_data {
#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)
unsigned long fb_base; /* Base address of framebuffer mem */
#endif
-#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
+#if defined(CONFIG_POST)
unsigned long post_log_word; /* Record POST activities */
unsigned long post_log_res; /* success of POST test */
unsigned long post_init_f_time; /* When post_init_f started */
@@ -114,6 +114,11 @@ typedef struct global_data {
struct bootstage_data *bootstage; /* Bootstage information */
struct bootstage_data *new_bootstage; /* Relocated bootstage info */
#endif
+#ifdef CONFIG_LOG
+ int log_drop_count; /* Number of dropped log messages */
+ int default_log_level; /* For devices with no filters */
+ struct list_head log_head; /* List of struct log_device */
+#endif
} gd_t;
#endif
@@ -141,5 +146,6 @@ typedef struct global_data {
#define GD_FLG_RECORD 0x01000 /* Record console */
#define GD_FLG_ENV_DEFAULT 0x02000 /* Default variable flag */
#define GD_FLG_SPL_EARLY_INIT 0x04000 /* Early SPL init is done */
+#define GD_FLG_LOG_READY 0x08000 /* Log system is ready for use */
#endif /* __ASM_GENERIC_GBL_DATA_H */
diff --git a/include/charset.h b/include/charset.h
index 37a32784998..2662c2f7c9a 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -9,6 +9,8 @@
#ifndef __CHARSET_H_
#define __CHARSET_H_
+#include <linux/types.h>
+
#define MAX_UTF8_PER_UTF16 3
/**
@@ -62,4 +64,17 @@ uint16_t *utf16_strdup(const uint16_t *s);
*/
uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size);
+/**
+ * utf8_to_utf16() - Convert an utf8 string to utf16
+ *
+ * Converts up to 'size' characters of the utf16 string 'src' to utf8
+ * written to the 'dest' buffer. Stops at 0x00.
+ *
+ * @dest the destination buffer to write the utf8 characters
+ * @src the source utf16 string
+ * @size maximum number of utf16 characters to convert
+ * @return the pointer to the first unwritten byte in 'dest'
+ */
+uint16_t *utf8_to_utf16(uint16_t *dest, const uint8_t *src, size_t size);
+
#endif /* __CHARSET_H_ */
diff --git a/include/common.h b/include/common.h
index 6e245451789..436200044f3 100644
--- a/include/common.h
+++ b/include/common.h
@@ -45,51 +45,7 @@ typedef volatile unsigned char vu_char;
#define CONFIG_SYS_SUPPORT_64BIT_DATA
#endif
-#ifdef DEBUG
-#define _DEBUG 1
-#else
-#define _DEBUG 0
-#endif
-
-#ifdef CONFIG_SPL_BUILD
-#define _SPL_BUILD 1
-#else
-#define _SPL_BUILD 0
-#endif
-
-/*
- * Output a debug text when condition "cond" is met. The "cond" should be
- * computed by a preprocessor in the best case, allowing for the best
- * optimization.
- */
-#define debug_cond(cond, fmt, args...) \
- do { \
- if (cond) \
- printf(pr_fmt(fmt), ##args); \
- } while (0)
-
-/* Show a message if DEBUG is defined in a file */
-#define debug(fmt, args...) \
- debug_cond(_DEBUG, fmt, ##args)
-
-/* Show a message if not in SPL */
-#define warn_non_spl(fmt, args...) \
- debug_cond(!_SPL_BUILD, fmt, ##args)
-
-/*
- * An assertion is run-time check done in debug mode only. If DEBUG is not
- * defined then it is skipped. If DEBUG is defined and the assertion fails,
- * then it calls panic*( which may or may not reset/halt U-Boot (see
- * CONFIG_PANIC_HANG), It is hoped that all failing assertions are found
- * before release, and after release it is hoped that they don't matter. But
- * in any case these failing assertions cannot be fixed with a reset (which
- * may just do the same assertion again).
- */
-void __assert_fail(const char *assertion, const char *file, unsigned line,
- const char *function);
-#define assert(x) \
- ({ if (!(x) && _DEBUG) \
- __assert_fail(#x, __FILE__, __LINE__, __func__); })
+#include <log.h>
typedef void (interrupt_handler_t)(void *);
diff --git a/include/efi.h b/include/efi.h
index dc8edc8743a..2f0be9c86cb 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -227,9 +227,9 @@ struct efi_time_cap {
};
enum efi_locate_search_type {
- all_handles,
- by_register_notify,
- by_protocol
+ ALL_HANDLES,
+ BY_REGISTER_NOTIFY,
+ BY_PROTOCOL
};
struct efi_open_protocol_info_entry {
diff --git a/include/efi_api.h b/include/efi_api.h
index fcd7483ab21..584016dc302 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -28,8 +28,7 @@ enum efi_timer_delay {
EFI_TIMER_RELATIVE = 2
};
-#define UINTN size_t
-typedef long INTN;
+#define efi_uintn_t size_t
typedef uint16_t *efi_string_t;
#define EVT_TIMER 0x80000000
@@ -49,20 +48,22 @@ struct efi_event;
/* EFI Boot Services table */
struct efi_boot_services {
struct efi_table_hdr hdr;
- efi_status_t (EFIAPI *raise_tpl)(UINTN new_tpl);
- void (EFIAPI *restore_tpl)(UINTN old_tpl);
+ efi_status_t (EFIAPI *raise_tpl)(efi_uintn_t new_tpl);
+ void (EFIAPI *restore_tpl)(efi_uintn_t old_tpl);
- efi_status_t (EFIAPI *allocate_pages)(int, int, unsigned long,
+ efi_status_t (EFIAPI *allocate_pages)(int, int, efi_uintn_t,
efi_physical_addr_t *);
- efi_status_t (EFIAPI *free_pages)(efi_physical_addr_t, unsigned long);
- efi_status_t (EFIAPI *get_memory_map)(unsigned long *memory_map_size,
- struct efi_mem_desc *desc, unsigned long *key,
- unsigned long *desc_size, u32 *desc_version);
- efi_status_t (EFIAPI *allocate_pool)(int, unsigned long, void **);
+ efi_status_t (EFIAPI *free_pages)(efi_physical_addr_t, efi_uintn_t);
+ efi_status_t (EFIAPI *get_memory_map)(efi_uintn_t *memory_map_size,
+ struct efi_mem_desc *desc,
+ efi_uintn_t *key,
+ efi_uintn_t *desc_size,
+ u32 *desc_version);
+ efi_status_t (EFIAPI *allocate_pool)(int, efi_uintn_t, void **);
efi_status_t (EFIAPI *free_pool)(void *);
efi_status_t (EFIAPI *create_event)(uint32_t type,
- UINTN notify_tpl,
+ efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
struct efi_event *event,
void *context),
@@ -70,8 +71,9 @@ struct efi_boot_services {
efi_status_t (EFIAPI *set_timer)(struct efi_event *event,
enum efi_timer_delay type,
uint64_t trigger_time);
- efi_status_t (EFIAPI *wait_for_event)(unsigned long number_of_events,
- struct efi_event **event, size_t *index);
+ efi_status_t (EFIAPI *wait_for_event)(efi_uintn_t number_of_events,
+ struct efi_event **event,
+ efi_uintn_t *index);
efi_status_t (EFIAPI *signal_event)(struct efi_event *event);
efi_status_t (EFIAPI *close_event)(struct efi_event *event);
efi_status_t (EFIAPI *check_event)(struct efi_event *event);
@@ -94,7 +96,7 @@ struct efi_boot_services {
efi_status_t (EFIAPI *locate_handle)(
enum efi_locate_search_type search_type,
const efi_guid_t *protocol, void *search_key,
- unsigned long *buffer_size, efi_handle_t *buffer);
+ efi_uintn_t *buffer_size, efi_handle_t *buffer);
efi_status_t (EFIAPI *locate_device_path)(const efi_guid_t *protocol,
struct efi_device_path **device_path,
efi_handle_t *device);
@@ -141,14 +143,14 @@ struct efi_boot_services {
efi_status_t(EFIAPI *open_protocol_information)(efi_handle_t handle,
const efi_guid_t *protocol,
struct efi_open_protocol_info_entry **entry_buffer,
- unsigned long *entry_count);
+ efi_uintn_t *entry_count);
efi_status_t (EFIAPI *protocols_per_handle)(efi_handle_t handle,
efi_guid_t ***protocol_buffer,
- unsigned long *protocols_buffer_count);
+ efi_uintn_t *protocols_buffer_count);
efi_status_t (EFIAPI *locate_handle_buffer) (
enum efi_locate_search_type search_type,
const efi_guid_t *protocol, void *search_key,
- unsigned long *no_handles, efi_handle_t **buffer);
+ efi_uintn_t *no_handles, efi_handle_t **buffer);
efi_status_t (EFIAPI *locate_protocol)(const efi_guid_t *protocol,
void *registration, void **protocol_interface);
efi_status_t (EFIAPI *install_multiple_protocol_interfaces)(
@@ -249,7 +251,7 @@ struct efi_system_table {
struct efi_simple_text_output_protocol *std_err;
struct efi_runtime_services *runtime;
struct efi_boot_services *boottime;
- unsigned long nr_tables;
+ efi_uintn_t nr_tables;
struct efi_configuration_table *tables;
};
@@ -583,14 +585,14 @@ struct efi_gop_mode
struct efi_gop
{
efi_status_t (EFIAPI *query_mode)(struct efi_gop *this, u32 mode_number,
- unsigned long *size_of_info,
+ efi_uintn_t *size_of_info,
struct efi_gop_mode_info **info);
efi_status_t (EFIAPI *set_mode)(struct efi_gop *this, u32 mode_number);
efi_status_t (EFIAPI *blt)(struct efi_gop *this, void *buffer,
- unsigned long operation, unsigned long sx,
- unsigned long sy, unsigned long dx,
- unsigned long dy, unsigned long width,
- unsigned long height, unsigned long delta);
+ u32 operation, efi_uintn_t sx,
+ efi_uintn_t sy, efi_uintn_t dx,
+ efi_uintn_t dy, efi_uintn_t width,
+ efi_uintn_t height, efi_uintn_t delta);
struct efi_gop_mode *mode;
};
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 1b92edbd77c..c0caabddb12 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -6,6 +6,9 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#ifndef _EFI_LOADER_H
+#define _EFI_LOADER_H 1
+
#include <common.h>
#include <part_efi.h>
#include <efi_api.h>
@@ -75,9 +78,9 @@ const char *__efi_nesting_dec(void);
extern struct efi_runtime_services efi_runtime_services;
extern struct efi_system_table systab;
-extern const struct efi_simple_text_output_protocol efi_con_out;
+extern struct efi_simple_text_output_protocol efi_con_out;
extern struct efi_simple_input_interface efi_con_in;
-extern const struct efi_console_control_protocol efi_console_control;
+extern struct efi_console_control_protocol efi_console_control;
extern const struct efi_device_path_to_text_protocol efi_device_path_to_text;
uint16_t *efi_dp_str(struct efi_device_path *dp);
@@ -98,6 +101,8 @@ extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
* interface (usually a struct with callback functions), this struct maps the
* protocol GUID to the respective protocol interface */
struct efi_handler {
+ /* Link to the list of protocols of a handle */
+ struct list_head link;
const efi_guid_t *guid;
void *protocol_interface;
};
@@ -112,20 +117,12 @@ struct efi_handler {
struct efi_object {
/* Every UEFI object is part of a global object list */
struct list_head link;
- /* We support up to 16 "protocols" an object can be accessed through */
- struct efi_handler protocols[16];
+ /* The list of protocols */
+ struct list_head protocols;
/* The object spawner can either use this for data or as identifier */
void *handle;
};
-#define EFI_PROTOCOL_OBJECT(_guid, _protocol) (struct efi_object){ \
- .protocols = {{ \
- .guid = &(_guid), \
- .protocol_interface = (void *)(_protocol), \
- }}, \
- .handle = (void *)(_protocol), \
-}
-
/**
* struct efi_event
*
@@ -141,7 +138,7 @@ struct efi_object {
*/
struct efi_event {
uint32_t type;
- UINTN notify_tpl;
+ efi_uintn_t notify_tpl;
void (EFIAPI *notify_function)(struct efi_event *event, void *context);
void *notify_context;
u64 trigger_next;
@@ -163,6 +160,8 @@ int efi_disk_register(void);
int efi_gop_register(void);
/* Called by bootefi to make the network interface available */
int efi_net_register(void);
+/* Called by bootefi to make the watchdog available */
+int efi_watchdog_register(void);
/* Called by bootefi to make SMBIOS tables available */
void efi_smbios_register(void);
@@ -171,6 +170,8 @@ efi_fs_from_path(struct efi_device_path *fp);
/* Called by networking code to memorize the dhcp ack package */
void efi_net_set_dhcp_ack(void *pkt, int len);
+/* Called by efi_set_watchdog_timer to reset the timer */
+efi_status_t efi_set_watchdog(unsigned long timeout);
/* Called from places to check whether a timer expired */
void efi_timer_check(void);
@@ -185,8 +186,26 @@ void efi_restore_gd(void);
void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map);
/* Call this to set the current device name */
void efi_set_bootdev(const char *dev, const char *devnr, const char *path);
+/* Add a new object to the object list. */
+void efi_add_handle(struct efi_object *obj);
+/* Create handle */
+efi_status_t efi_create_handle(void **handle);
+/* Call this to validate a handle and find the EFI object for it */
+struct efi_object *efi_search_obj(const void *handle);
+/* Find a protocol on a handle */
+efi_status_t efi_search_protocol(const void *handle,
+ const efi_guid_t *protocol_guid,
+ struct efi_handler **handler);
+/* Install new protocol on a handle */
+efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
+ void *protocol_interface);
+/* Delete protocol from a handle */
+efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol,
+ void *protocol_interface);
+/* Delete all protocols from a handle */
+efi_status_t efi_remove_all_protocols(const void *handle);
/* Call this to create an event */
-efi_status_t efi_create_event(uint32_t type, UINTN notify_tpl,
+efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
struct efi_event *event,
void *context),
@@ -208,20 +227,20 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp);
/* Generic EFI memory allocator, call this to get memory */
void *efi_alloc(uint64_t len, int memory_type);
/* More specific EFI memory allocator, called by EFI payloads */
-efi_status_t efi_allocate_pages(int type, int memory_type, unsigned long pages,
+efi_status_t efi_allocate_pages(int type, int memory_type, efi_uintn_t pages,
uint64_t *memory);
/* EFI memory free function. */
-efi_status_t efi_free_pages(uint64_t memory, unsigned long pages);
+efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages);
/* EFI memory allocator for small allocations */
-efi_status_t efi_allocate_pool(int pool_type, unsigned long size,
+efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size,
void **buffer);
/* EFI pool memory free function. */
efi_status_t efi_free_pool(void *buffer);
/* Returns the EFI memory map */
-efi_status_t efi_get_memory_map(unsigned long *memory_map_size,
+efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
struct efi_mem_desc *memory_map,
- unsigned long *map_key,
- unsigned long *descriptor_size,
+ efi_uintn_t *map_key,
+ efi_uintn_t *descriptor_size,
uint32_t *descriptor_version);
/* Adds a range into the EFI memory map */
uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
@@ -243,7 +262,8 @@ extern void *efi_bounce_buffer;
struct efi_device_path *efi_dp_next(const struct efi_device_path *dp);
-int efi_dp_match(struct efi_device_path *a, struct efi_device_path *b);
+int efi_dp_match(const struct efi_device_path *a,
+ const struct efi_device_path *b);
struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
struct efi_device_path **rem);
unsigned efi_dp_size(const struct efi_device_path *dp);
@@ -341,4 +361,6 @@ static inline void efi_set_bootdev(const char *dev, const char *devnr,
const char *path) { }
static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
-#endif
+#endif /* CONFIG_EFI_LOADER && !CONFIG_SPL_BUILD */
+
+#endif /* _EFI_LOADER_H */
diff --git a/include/efi_selftest.h b/include/efi_selftest.h
index 7ec42a0406b..be5ba4bfa91 100644
--- a/include/efi_selftest.h
+++ b/include/efi_selftest.h
@@ -12,6 +12,7 @@
#include <common.h>
#include <efi.h>
#include <efi_api.h>
+#include <efi_loader.h>
#include <linker_lists.h>
#define EFI_ST_SUCCESS 0
@@ -27,6 +28,15 @@
efi_st_printf(__VA_ARGS__)) \
/*
+ * Prints a TODO message.
+ *
+ * @... format string followed by fields to print
+ */
+#define efi_st_todo(...) \
+ (efi_st_printf("%s(%u):\nTODO: ", __FILE__, __LINE__), \
+ efi_st_printf(__VA_ARGS__)) \
+
+/*
* A test may be setup and executed at boottime,
* it may be setup at boottime and executed at runtime,
* or it may be setup and executed at runtime.
@@ -72,6 +82,15 @@ void efi_st_printf(const char *fmt, ...)
int efi_st_memcmp(const void *buf1, const void *buf2, size_t length);
/*
+ * Compare an u16 string to a char string.
+ *
+ * @buf1: u16 string
+ * @buf2: char string
+ * @return: 0 if both buffers contain the same bytes
+ */
+int efi_st_strcmp_16_8(const u16 *buf1, const char *buf2);
+
+/*
* Reads an Unicode character from the input device.
*
* @return: Unicode character
@@ -88,6 +107,7 @@ u16 efi_st_get_key(void);
* @setup: set up the unit test
* @teardown: tear down the unit test
* @execute: execute the unit test
+ * @on_request: test is only executed on request
*/
struct efi_unit_test {
const char *name;
@@ -96,6 +116,7 @@ struct efi_unit_test {
const struct efi_system_table *systable);
int (*execute)(void);
int (*teardown)(void);
+ bool on_request;
};
/* Declare a new EFI unit test */
diff --git a/include/log.h b/include/log.h
new file mode 100644
index 00000000000..8083b64831d
--- /dev/null
+++ b/include/log.h
@@ -0,0 +1,304 @@
+/*
+ * Logging support
+ *
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LOG_H
+#define __LOG_H
+
+#include <dm/uclass-id.h>
+#include <linux/list.h>
+
+/** Log levels supported, ranging from most to least important */
+enum log_level_t {
+ LOGL_EMERG = 0, /*U-Boot is unstable */
+ LOGL_ALERT, /* Action must be taken immediately */
+ LOGL_CRIT, /* Critical conditions */
+ LOGL_ERR, /* Error that prevents something from working */
+ LOGL_WARNING, /* Warning may prevent optimial operation */
+ LOGL_NOTICE, /* Normal but significant condition, printf() */
+ LOGL_INFO, /* General information message */
+ LOGL_DEBUG, /* Basic debug-level message */
+ LOGL_DEBUG_CONTENT, /* Debug message showing full message content */
+ LOGL_DEBUG_IO, /* Debug message showing hardware I/O access */
+
+ LOGL_COUNT,
+ LOGL_FIRST = LOGL_EMERG,
+ LOGL_MAX = LOGL_DEBUG,
+};
+
+/**
+ * Log categories supported. Most of these correspond to uclasses (i.e.
+ * enum uclass_id) but there are also some more generic categories
+ */
+enum log_category_t {
+ LOGC_FIRST = 0, /* First part mirrors UCLASS_... */
+
+ LOGC_NONE = UCLASS_COUNT,
+ LOGC_ARCH,
+ LOGC_BOARD,
+ LOGC_CORE,
+ LOGC_DT,
+
+ LOGC_COUNT,
+ LOGC_END,
+};
+
+/* Helper to cast a uclass ID to a log category */
+static inline int log_uc_cat(enum uclass_id id)
+{
+ return (enum log_category_t)id;
+}
+
+/**
+ * _log() - Internal function to emit a new log record
+ *
+ * @cat: Category of log record (indicating which subsystem generated it)
+ * @level: Level of log record (indicating its severity)
+ * @file: File name of file where log record was generated
+ * @line: Line number in file where log record was generated
+ * @func: Function where log record was generated
+ * @fmt: printf() format string for log record
+ * @...: Optional parameters, according to the format string @fmt
+ * @return 0 if log record was emitted, -ve on error
+ */
+int _log(enum log_category_t cat, enum log_level_t level, const char *file,
+ int line, const char *func, const char *fmt, ...);
+
+/* Define this at the top of a file to add a prefix to debug messages */
+#ifndef pr_fmt
+#define pr_fmt(fmt) fmt
+#endif
+
+/* Use a default category if this file does not supply one */
+#ifndef LOG_CATEGORY
+#define LOG_CATEGORY LOGC_NONE
+#endif
+
+/*
+ * This header may be including when CONFIG_LOG is disabled, in which case
+ * CONFIG_LOG_MAX_LEVEL is not defined. Add a check for this.
+ */
+#if CONFIG_IS_ENABLED(LOG)
+#define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL)
+#else
+#define _LOG_MAX_LEVEL LOGL_INFO
+#endif
+
+/* Emit a log record if the level is less that the maximum */
+#define log(_cat, _level, _fmt, _args...) ({ \
+ int _l = _level; \
+ if (_l <= _LOG_MAX_LEVEL) \
+ _log((enum log_category_t)(_cat), _l, __FILE__, __LINE__, \
+ __func__, \
+ pr_fmt(_fmt), ##_args); \
+ })
+
+#ifdef DEBUG
+#define _DEBUG 1
+#else
+#define _DEBUG 0
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+#define _SPL_BUILD 1
+#else
+#define _SPL_BUILD 0
+#endif
+
+#if !_DEBUG && CONFIG_IS_ENABLED(LOG)
+
+#define debug_cond(cond, fmt, args...) \
+ do { \
+ if (1) \
+ log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \
+ } while (0)
+
+#else /* _DEBUG */
+
+/*
+ * Output a debug text when condition "cond" is met. The "cond" should be
+ * computed by a preprocessor in the best case, allowing for the best
+ * optimization.
+ */
+#define debug_cond(cond, fmt, args...) \
+ do { \
+ if (cond) \
+ printf(pr_fmt(fmt), ##args); \
+ } while (0)
+
+#endif /* _DEBUG */
+
+/* Show a message if DEBUG is defined in a file */
+#define debug(fmt, args...) \
+ debug_cond(_DEBUG, fmt, ##args)
+
+/* Show a message if not in SPL */
+#define warn_non_spl(fmt, args...) \
+ debug_cond(!_SPL_BUILD, fmt, ##args)
+
+/*
+ * An assertion is run-time check done in debug mode only. If DEBUG is not
+ * defined then it is skipped. If DEBUG is defined and the assertion fails,
+ * then it calls panic*( which may or may not reset/halt U-Boot (see
+ * CONFIG_PANIC_HANG), It is hoped that all failing assertions are found
+ * before release, and after release it is hoped that they don't matter. But
+ * in any case these failing assertions cannot be fixed with a reset (which
+ * may just do the same assertion again).
+ */
+void __assert_fail(const char *assertion, const char *file, unsigned int line,
+ const char *function);
+#define assert(x) \
+ ({ if (!(x) && _DEBUG) \
+ __assert_fail(#x, __FILE__, __LINE__, __func__); })
+
+/**
+ * struct log_rec - a single log record
+ *
+ * Holds information about a single record in the log
+ *
+ * Members marked as 'not allocated' are stored as pointers and the caller is
+ * responsible for making sure that the data pointed to is not overwritten.
+ * Memebers marked as 'allocated' are allocated (e.g. via strdup()) by the log
+ * system.
+ *
+ * @cat: Category, representing a uclass or part of U-Boot
+ * @level: Severity level, less severe is higher
+ * @file: Name of file where the log record was generated (not allocated)
+ * @line: Line number where the log record was generated
+ * @func: Function where the log record was generated (not allocated)
+ * @msg: Log message (allocated)
+ */
+struct log_rec {
+ enum log_category_t cat;
+ enum log_level_t level;
+ const char *file;
+ int line;
+ const char *func;
+ const char *msg;
+};
+
+struct log_device;
+
+/**
+ * struct log_driver - a driver which accepts and processes log records
+ *
+ * @name: Name of driver
+ */
+struct log_driver {
+ const char *name;
+ /**
+ * emit() - emit a log record
+ *
+ * Called by the log system to pass a log record to a particular driver
+ * for processing. The filter is checked before calling this function.
+ */
+ int (*emit)(struct log_device *ldev, struct log_rec *rec);
+};
+
+/**
+ * struct log_device - an instance of a log driver
+ *
+ * Since drivers are set up at build-time we need to have a separate device for
+ * the run-time aspects of drivers (currently just a list of filters to apply
+ * to records send to this device).
+ *
+ * @next_filter_num: Seqence number of next filter filter added (0=no filters
+ * yet). This increments with each new filter on the device, but never
+ * decrements
+ * @drv: Pointer to driver for this device
+ * @filter_head: List of filters for this device
+ * @sibling_node: Next device in the list of all devices
+ */
+struct log_device {
+ int next_filter_num;
+ struct log_driver *drv;
+ struct list_head filter_head;
+ struct list_head sibling_node;
+};
+
+enum {
+ LOGF_MAX_CATEGORIES = 5, /* maximum categories per filter */
+};
+
+enum log_filter_flags {
+ LOGFF_HAS_CAT = 1 << 0, /* Filter has a category list */
+};
+
+/**
+ * struct log_filter - criterial to filter out log messages
+ *
+ * @filter_num: Sequence number of this filter. This is returned when adding a
+ * new filter, and must be provided when removing a previously added
+ * filter.
+ * @flags: Flags for this filter (LOGFF_...)
+ * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
+ * then all categories are permitted. Up to LOGF_MAX_CATEGORIES entries
+ * can be provided
+ * @max_level: Maximum log level to allow
+ * @file_list: List of files to allow, separated by comma. If NULL then all
+ * files are permitted
+ * @sibling_node: Next filter in the list of filters for this log device
+ */
+struct log_filter {
+ int filter_num;
+ int flags;
+ enum log_category_t cat_list[LOGF_MAX_CATEGORIES];
+ enum log_level_t max_level;
+ const char *file_list;
+ struct list_head sibling_node;
+};
+
+#define LOG_DRIVER(_name) \
+ ll_entry_declare(struct log_driver, _name, log_driver)
+
+/* Handle the 'log test' command */
+int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
+
+/**
+ * log_add_filter() - Add a new filter to a log device
+ *
+ * @drv_name: Driver name to add the filter to (since each driver only has a
+ * single device)
+ * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
+ * then all categories are permitted. Up to LOGF_MAX_CATEGORIES entries
+ * can be provided
+ * @max_level: Maximum log level to allow
+ * @file_list: List of files to allow, separated by comma. If NULL then all
+ * files are permitted
+ * @return the sequence number of the new filter (>=0) if the filter was added,
+ * or a -ve value on error
+ */
+int log_add_filter(const char *drv_name, enum log_category_t cat_list[],
+ enum log_level_t max_level, const char *file_list);
+
+/**
+ * log_remove_filter() - Remove a filter from a log device
+ *
+ * @drv_name: Driver name to remove the filter from (since each driver only has
+ * a single device)
+ * @filter_num: Filter number to remove (as returned by log_add_filter())
+ * @return 0 if the filter was removed, -ENOENT if either the driver or the
+ * filter number was not found
+ */
+int log_remove_filter(const char *drv_name, int filter_num);
+
+#if CONFIG_IS_ENABLED(LOG)
+/**
+ * log_init() - Set up the log system ready for use
+ *
+ * @return 0 if OK, -ENOMEM if out of memory
+ */
+int log_init(void);
+#else
+static inline int log_init(void)
+{
+ return 0;
+}
+#endif
+
+#endif
diff --git a/include/logbuff.h b/include/logbuff.h
deleted file mode 100644
index 625feb9f95a..00000000000
--- a/include/logbuff.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * (C) Copyright 2002-2007
- * Detlev Zundel, dzu@denx.de.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-#ifndef _LOGBUFF_H
-#define _LOGBUFF_H
-
-#ifdef CONFIG_LOGBUFFER
-
-#define LOGBUFF_MAGIC 0xc0de4ced /* Forced by code, eh! */
-#define LOGBUFF_LEN (16384) /* Must be 16k right now */
-#define LOGBUFF_MASK (LOGBUFF_LEN-1)
-#define LOGBUFF_OVERHEAD (4096) /* Logbuffer overhead for extra info */
-#define LOGBUFF_RESERVE (LOGBUFF_LEN+LOGBUFF_OVERHEAD)
-
-/* The mapping used here has to be the same as in setup_ext_logbuff ()
- in linux/kernel/printk */
-
-typedef struct {
- union {
- struct {
- unsigned long tag;
- unsigned long start;
- unsigned long con;
- unsigned long end;
- unsigned long chars;
- } v2;
- struct {
- unsigned long dummy;
- unsigned long tag;
- unsigned long start;
- unsigned long size;
- unsigned long chars;
- } v1;
- };
- unsigned char buf[0];
-} logbuff_t;
-
-int drv_logbuff_init (void);
-void logbuff_init_ptrs (void);
-void logbuff_log(char *msg);
-void logbuff_reset (void);
-unsigned long logbuffer_base (void);
-
-#endif /* CONFIG_LOGBUFFER */
-
-#endif /* _LOGBUFF_H */
diff --git a/include/os.h b/include/os.h
index 2bf4bdb1b83..049b248c5b0 100644
--- a/include/os.h
+++ b/include/os.h
@@ -241,6 +241,26 @@ const char *os_dirent_get_typename(enum os_dirent_t type);
int os_get_filesize(const char *fname, loff_t *size);
/**
+ * Write a character to the controlling OS terminal
+ *
+ * This bypasses the U-Boot console support and writes directly to the OS
+ * stdout file descriptor.
+ *
+ * @param ch Character to write
+ */
+void os_putc(int ch);
+
+/**
+ * Write a string to the controlling OS terminal
+ *
+ * This bypasses the U-Boot console support and writes directly to the OS
+ * stdout file descriptor.
+ *
+ * @param str String to write (note that \n is not appended)
+ */
+void os_puts(const char *str);
+
+/**
* Write the sandbox RAM buffer to a existing file
*
* @param fname Filename to write memory to (simple binary format)
diff --git a/include/post.h b/include/post.h
index d5278111e85..b41a6c81272 100644
--- a/include/post.h
+++ b/include/post.h
@@ -15,7 +15,7 @@
#include <common.h>
#include <asm/io.h>
-#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
+#if defined(CONFIG_POST)
#ifndef CONFIG_POST_EXTERNAL_WORD_FUNCS
#ifdef CONFIG_SYS_POST_WORD_ADDR
@@ -58,7 +58,7 @@ extern ulong post_word_load(void);
extern void post_word_store(ulong value);
#endif /* CONFIG_POST_EXTERNAL_WORD_FUNCS */
-#endif /* defined (CONFIG_POST) || defined(CONFIG_LOGBUFFER) */
+#endif /* defined (CONFIG_POST) */
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_POST