linux/drivers/acpi/apei/erst.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * APEI Error Record Serialization Table support
 *
 * ERST is a way provided by APEI to save and retrieve hardware error
 * information to and from a persistent store.
 *
 * For more information about ERST, please refer to ACPI Specification
 * version 4.0, section 17.4.
 *
 * Copyright 2010 Intel Corp.
 *   Author: Huang Ying <[email protected]>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/acpi.h>
#include <linux/uaccess.h>
#include <linux/cper.h>
#include <linux/nmi.h>
#include <linux/hardirq.h>
#include <linux/pstore.h>
#include <linux/vmalloc.h>
#include <linux/mm.h> /* kvfree() */
#include <acpi/apei.h>

#include "apei-internal.h"

#undef pr_fmt
#define pr_fmt(fmt)

/* ERST command status */
#define ERST_STATUS_SUCCESS
#define ERST_STATUS_NOT_ENOUGH_SPACE
#define ERST_STATUS_HARDWARE_NOT_AVAILABLE
#define ERST_STATUS_FAILED
#define ERST_STATUS_RECORD_STORE_EMPTY
#define ERST_STATUS_RECORD_NOT_FOUND

#define ERST_TAB_ENTRY(tab)

#define SPIN_UNIT
/* Firmware should respond within 1 milliseconds */
#define FIRMWARE_TIMEOUT
#define FIRMWARE_MAX_STALL

int erst_disable;
EXPORT_SYMBOL_GPL();

static struct acpi_table_erst *erst_tab;

/* ERST Error Log Address Range attributes */
#define ERST_RANGE_RESERVED
#define ERST_RANGE_NVRAM
#define ERST_RANGE_SLOW

/* ERST Exec max timings */
#define ERST_EXEC_TIMING_MAX_MASK
#define ERST_EXEC_TIMING_MAX_SHIFT

/*
 * ERST Error Log Address Range, used as buffer for reading/writing
 * error records.
 */
static struct erst_erange {} erst_erange;

/*
 * Prevent ERST interpreter to run simultaneously, because the
 * corresponding firmware implementation may not work properly when
 * invoked simultaneously.
 *
 * It is used to provide exclusive accessing for ERST Error Log
 * Address Range too.
 */
static DEFINE_RAW_SPINLOCK(erst_lock);

static inline int erst_errno(int command_status)
{}

static inline u64 erst_get_timeout(void)
{}

static int erst_timedout(u64 *t, u64 spin_unit)
{}

static int erst_exec_load_var1(struct apei_exec_context *ctx,
			       struct acpi_whea_header *entry)
{}

static int erst_exec_load_var2(struct apei_exec_context *ctx,
			       struct acpi_whea_header *entry)
{}

static int erst_exec_store_var1(struct apei_exec_context *ctx,
				struct acpi_whea_header *entry)
{}

static int erst_exec_add(struct apei_exec_context *ctx,
			 struct acpi_whea_header *entry)
{}

static int erst_exec_subtract(struct apei_exec_context *ctx,
			      struct acpi_whea_header *entry)
{}

static int erst_exec_add_value(struct apei_exec_context *ctx,
			       struct acpi_whea_header *entry)
{}

static int erst_exec_subtract_value(struct apei_exec_context *ctx,
				    struct acpi_whea_header *entry)
{}

static int erst_exec_stall(struct apei_exec_context *ctx,
			   struct acpi_whea_header *entry)
{}

static int erst_exec_stall_while_true(struct apei_exec_context *ctx,
				      struct acpi_whea_header *entry)
{}

static int erst_exec_skip_next_instruction_if_true(
	struct apei_exec_context *ctx,
	struct acpi_whea_header *entry)
{}

static int erst_exec_goto(struct apei_exec_context *ctx,
			  struct acpi_whea_header *entry)
{}

static int erst_exec_set_src_address_base(struct apei_exec_context *ctx,
					  struct acpi_whea_header *entry)
{}

static int erst_exec_set_dst_address_base(struct apei_exec_context *ctx,
					  struct acpi_whea_header *entry)
{}

static int erst_exec_move_data(struct apei_exec_context *ctx,
			       struct acpi_whea_header *entry)
{}

static struct apei_exec_ins_type erst_ins_type[] =;

static inline void erst_exec_ctx_init(struct apei_exec_context *ctx)
{}

static int erst_get_erange(struct erst_erange *range)
{}

static ssize_t __erst_get_record_count(void)
{}

ssize_t erst_get_record_count(void)
{}
EXPORT_SYMBOL_GPL();

#define ERST_RECORD_ID_CACHE_SIZE_MIN
#define ERST_RECORD_ID_CACHE_SIZE_MAX

struct erst_record_id_cache {};

static struct erst_record_id_cache erst_record_id_cache =;

static int __erst_get_next_record_id(u64 *record_id)
{}

int erst_get_record_id_begin(int *pos)
{}
EXPORT_SYMBOL_GPL();

/* erst_record_id_cache.lock must be held by caller */
static int __erst_record_id_cache_add_one(void)
{}

/*
 * Get the record ID of an existing error record on the persistent
 * storage. If there is no error record on the persistent storage, the
 * returned record_id is APEI_ERST_INVALID_RECORD_ID.
 */
int erst_get_record_id_next(int *pos, u64 *record_id)
{}
EXPORT_SYMBOL_GPL();

/* erst_record_id_cache.lock must be held by caller */
static void __erst_record_id_cache_compact(void)
{}

void erst_get_record_id_end(void)
{}
EXPORT_SYMBOL_GPL();

static int __erst_write_to_storage(u64 offset)
{}

static int __erst_read_from_storage(u64 record_id, u64 offset)
{}

static int __erst_clear_from_storage(u64 record_id)
{}

/* NVRAM ERST Error Log Address Range is not supported yet */
static void pr_unimpl_nvram(void)
{}

static int __erst_write_to_nvram(const struct cper_record_header *record)
{}

static int __erst_read_to_erange_from_nvram(u64 record_id, u64 *offset)
{}

static int __erst_clear_from_nvram(u64 record_id)
{}

int erst_write(const struct cper_record_header *record)
{}
EXPORT_SYMBOL_GPL();

static int __erst_read_to_erange(u64 record_id, u64 *offset)
{}

static ssize_t __erst_read(u64 record_id, struct cper_record_header *record,
			   size_t buflen)
{}

/*
 * If return value > buflen, the buffer size is not big enough,
 * else if return value < 0, something goes wrong,
 * else everything is OK, and return value is record length
 */
ssize_t erst_read(u64 record_id, struct cper_record_header *record,
		  size_t buflen)
{}
EXPORT_SYMBOL_GPL();

static void erst_clear_cache(u64 record_id)
{}

ssize_t erst_read_record(u64 record_id, struct cper_record_header *record,
		size_t buflen, size_t recordlen, const guid_t *creatorid)
{}
EXPORT_SYMBOL_GPL();

int erst_clear(u64 record_id)
{}
EXPORT_SYMBOL_GPL();

static int __init setup_erst_disable(char *str)
{}

__setup();

static int erst_check_table(struct acpi_table_erst *erst_tab)
{}

static int erst_open_pstore(struct pstore_info *psi);
static int erst_close_pstore(struct pstore_info *psi);
static ssize_t erst_reader(struct pstore_record *record);
static int erst_writer(struct pstore_record *record);
static int erst_clearer(struct pstore_record *record);

static struct pstore_info erst_info =;

#define CPER_CREATOR_PSTORE
#define CPER_SECTION_TYPE_DMESG
#define CPER_SECTION_TYPE_DMESG_Z
#define CPER_SECTION_TYPE_MCE

struct cper_pstore_record {} __packed;

static int reader_pos;

static int erst_open_pstore(struct pstore_info *psi)
{}

static int erst_close_pstore(struct pstore_info *psi)
{}

static ssize_t erst_reader(struct pstore_record *record)
{}

static int erst_writer(struct pstore_record *record)
{}

static int erst_clearer(struct pstore_record *record)
{}

static int __init erst_init(void)
{}

device_initcall(erst_init);