162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Functions corresponding to sure start object type attributes under 462306a36Sopenharmony_ci * BIOS for use with hp-bioscfg driver 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 2022 HP Development Company, L.P. 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "bioscfg.h" 1062306a36Sopenharmony_ci#include <linux/types.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* Maximum number of log entries supported when log entry size is 16 1362306a36Sopenharmony_ci * bytes. This value is calculated by dividing 4096 (page size) by 1462306a36Sopenharmony_ci * log entry size. 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci#define LOG_MAX_ENTRIES 254 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* 1962306a36Sopenharmony_ci * Current Log entry size. This value size will change in the 2062306a36Sopenharmony_ci * future. The driver reads a total of 128 bytes for each log entry 2162306a36Sopenharmony_ci * provided by BIOS but only the first 16 bytes are used/read. 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci#define LOG_ENTRY_SIZE 16 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* 2662306a36Sopenharmony_ci * audit_log_entry_count_show - Reports the number of 2762306a36Sopenharmony_ci * existing audit log entries available 2862306a36Sopenharmony_ci * to be read 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_cistatic ssize_t audit_log_entry_count_show(struct kobject *kobj, 3162306a36Sopenharmony_ci struct kobj_attribute *attr, char *buf) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci int ret; 3462306a36Sopenharmony_ci u32 count = 0; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci ret = hp_wmi_perform_query(HPWMI_SURESTART_GET_LOG_COUNT, 3762306a36Sopenharmony_ci HPWMI_SURESTART, 3862306a36Sopenharmony_ci &count, 1, sizeof(count)); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci if (ret < 0) 4162306a36Sopenharmony_ci return ret; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci return sysfs_emit(buf, "%d,%d,%d\n", count, LOG_ENTRY_SIZE, 4462306a36Sopenharmony_ci LOG_MAX_ENTRIES); 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/* 4862306a36Sopenharmony_ci * audit_log_entries_show() - Return all entries found in log file 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_cistatic ssize_t audit_log_entries_show(struct kobject *kobj, 5162306a36Sopenharmony_ci struct kobj_attribute *attr, char *buf) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci int ret; 5462306a36Sopenharmony_ci int i; 5562306a36Sopenharmony_ci u32 count = 0; 5662306a36Sopenharmony_ci u8 audit_log_buffer[128]; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci // Get the number of event logs 5962306a36Sopenharmony_ci ret = hp_wmi_perform_query(HPWMI_SURESTART_GET_LOG_COUNT, 6062306a36Sopenharmony_ci HPWMI_SURESTART, 6162306a36Sopenharmony_ci &count, 1, sizeof(count)); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci if (ret < 0) 6462306a36Sopenharmony_ci return ret; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci /* 6762306a36Sopenharmony_ci * The show() api will not work if the audit logs ever go 6862306a36Sopenharmony_ci * beyond 4KB 6962306a36Sopenharmony_ci */ 7062306a36Sopenharmony_ci if (count * LOG_ENTRY_SIZE > PAGE_SIZE) 7162306a36Sopenharmony_ci return -EIO; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci /* 7462306a36Sopenharmony_ci * We are guaranteed the buffer is 4KB so today all the event 7562306a36Sopenharmony_ci * logs will fit 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ci for (i = 0; i < count; i++) { 7862306a36Sopenharmony_ci audit_log_buffer[0] = i + 1; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci /* 8162306a36Sopenharmony_ci * read audit log entry at a time. 'buf' input value 8262306a36Sopenharmony_ci * provides the audit log entry to be read. On 8362306a36Sopenharmony_ci * input, Byte 0 = Audit Log entry number from 8462306a36Sopenharmony_ci * beginning (1..254) 8562306a36Sopenharmony_ci * Entry number 1 is the newest entry whereas the 8662306a36Sopenharmony_ci * highest entry number (number of entries) is the 8762306a36Sopenharmony_ci * oldest entry. 8862306a36Sopenharmony_ci */ 8962306a36Sopenharmony_ci ret = hp_wmi_perform_query(HPWMI_SURESTART_GET_LOG, 9062306a36Sopenharmony_ci HPWMI_SURESTART, 9162306a36Sopenharmony_ci audit_log_buffer, 1, 128); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci if (ret < 0 || (LOG_ENTRY_SIZE * i) > PAGE_SIZE) { 9462306a36Sopenharmony_ci /* 9562306a36Sopenharmony_ci * Encountered a failure while reading 9662306a36Sopenharmony_ci * individual logs. Only a partial list of 9762306a36Sopenharmony_ci * audit log will be returned. 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_ci break; 10062306a36Sopenharmony_ci } else { 10162306a36Sopenharmony_ci memcpy(buf, audit_log_buffer, LOG_ENTRY_SIZE); 10262306a36Sopenharmony_ci buf += LOG_ENTRY_SIZE; 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci } 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci return i * LOG_ENTRY_SIZE; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic struct kobj_attribute sure_start_audit_log_entry_count = __ATTR_RO(audit_log_entry_count); 11062306a36Sopenharmony_cistatic struct kobj_attribute sure_start_audit_log_entries = __ATTR_RO(audit_log_entries); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic struct attribute *sure_start_attrs[] = { 11362306a36Sopenharmony_ci &sure_start_audit_log_entry_count.attr, 11462306a36Sopenharmony_ci &sure_start_audit_log_entries.attr, 11562306a36Sopenharmony_ci NULL 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic const struct attribute_group sure_start_attr_group = { 11962306a36Sopenharmony_ci .attrs = sure_start_attrs, 12062306a36Sopenharmony_ci}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_civoid hp_exit_sure_start_attributes(void) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci sysfs_remove_group(bioscfg_drv.sure_start_attr_kobj, 12562306a36Sopenharmony_ci &sure_start_attr_group); 12662306a36Sopenharmony_ci} 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciint hp_populate_sure_start_data(struct kobject *attr_name_kobj) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci bioscfg_drv.sure_start_attr_kobj = attr_name_kobj; 13162306a36Sopenharmony_ci return sysfs_create_group(attr_name_kobj, &sure_start_attr_group); 13262306a36Sopenharmony_ci} 133