aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/smbios.c49
-rw-r--r--src/include/smbios.h64
2 files changed, 113 insertions, 0 deletions
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c
index 24b18f2988..5b8df5bc64 100644
--- a/src/arch/x86/smbios.c
+++ b/src/arch/x86/smbios.c
@@ -1116,6 +1116,55 @@ int smbios_write_type38(unsigned long *current, int *handle,
return len;
}
+int smbios_write_type39(unsigned long *current, int *handle,
+ u8 unit_group, const char *loc, const char *dev_name,
+ const char *man, const char *serial_num,
+ const char *tag_num, const char *part_num,
+ const char *rev_lvl, u16 max_pow_cap,
+ const struct power_supply_ch *ps_ch)
+{
+ struct smbios_type39 *t = smbios_carve_table(*current,
+ SMBIOS_SYSTEM_POWER_SUPPLY,
+ sizeof(*t), *handle);
+
+ uint16_t val = 0;
+ uint16_t ps_type, ps_status, vol_switch, ps_unplug, ps_present, hot_rep;
+
+ t->power_unit_group = unit_group;
+ t->location = smbios_add_string(t->eos, loc);
+ t->device_name = smbios_add_string(t->eos, dev_name);
+ t->manufacturer = smbios_add_string(t->eos, man);
+ t->serial_number = smbios_add_string(t->eos, serial_num);
+ t->asset_tag_number = smbios_add_string(t->eos, tag_num);
+ t->model_part_number = smbios_add_string(t->eos, part_num);
+ t->revision_level = smbios_add_string(t->eos, rev_lvl);
+ t->max_power_capacity = max_pow_cap;
+
+ ps_type = ps_ch->power_supply_type & 0xF;
+ ps_status = ps_ch->power_supply_status & 0x7;
+ vol_switch = ps_ch->input_voltage_range_switch & 0xF;
+ ps_unplug = ps_ch->power_supply_unplugged & 0x1;
+ ps_present = ps_ch->power_supply_present & 0x1;
+ hot_rep = ps_ch->power_supply_hot_replaceble & 0x1;
+
+ val |= (ps_type << 10);
+ val |= (ps_status << 7);
+ val |= (vol_switch << 3);
+ val |= (ps_unplug << 2);
+ val |= (ps_present << 1);
+ val |= hot_rep;
+ t->power_supply_characteristics = val;
+
+ t->input_voltage_probe_handle = 0xFFFF;
+ t->cooling_device_handle = 0xFFFF;
+ t->input_current_probe_handle = 0xFFFF;
+
+ const int len = smbios_full_table_len(&t->header, t->eos);
+ *current += len;
+ *handle += 1;
+ return len;
+}
+
int smbios_write_type41(unsigned long *current, int *handle,
const char *name, u8 instance, u16 segment,
u8 bus, u8 device, u8 function, u8 device_type)
diff --git a/src/include/smbios.h b/src/include/smbios.h
index cb317b03a3..9217f5eaa0 100644
--- a/src/include/smbios.h
+++ b/src/include/smbios.h
@@ -270,6 +270,7 @@ typedef enum {
SMBIOS_TEMPERATURE_PROBE = 28,
SMBIOS_SYSTEM_BOOT_INFORMATION = 32,
SMBIOS_IPMI_DEVICE_INFORMATION = 38,
+ SMBIOS_SYSTEM_POWER_SUPPLY = 39,
SMBIOS_ONBOARD_DEVICES_EXTENDED_INFORMATION = 41,
SMBIOS_TPM_DEVICE = 43,
SMBIOS_END_OF_TABLE = 127,
@@ -1013,6 +1014,69 @@ enum smbios_bmc_interface_type {
};
typedef enum {
+ PowerSupplyTypeOther = 1,
+ PowerSupplyTypeUnknown = 2,
+ PowerSupplyTypeLinear = 3,
+ PowerSupplyTypeSwitching = 4,
+ PowerSupplyTypeBattery = 5,
+ PowerSupplyTypeUps = 6,
+ PowerSupplyTypeConverter = 7,
+ PowerSupplyTypeRegulator = 8
+} power_supply_type;
+
+typedef enum {
+ PowerSupplyStatusOther = 1,
+ PowerSupplyStatusUnknown = 2,
+ PowerSupplyStatusOk = 3,
+ PowerSupplyStatusNonCritical = 4,
+ PowerSupplyStatusCritical = 5
+} power_supply_status;
+
+typedef enum {
+ PowerSupplyInputVoltageRangeSwitchingOther = 1,
+ PowerSupplyInputVoltageRangeSwitchingUnknown = 2,
+ PowerSupplyInputVoltageRangeSwitchingManual = 3,
+ PowerSupplyInputVoltageRangeSwitchingAutoSwitch = 4,
+ PowerSupplyInputVoltageRangeSwitchingWideRange = 5,
+ PowerSupplyInputVoltageRangeSwitchingNotApplicable = 6
+} power_supply_input_voltage_range_switching;
+
+struct power_supply_ch {
+ u16 reserved :2;
+ u16 power_supply_type :4;
+ u16 power_supply_status :3;
+ u16 input_voltage_range_switch :4;
+ u16 power_supply_unplugged :1;
+ u16 power_supply_present :1;
+ u16 power_supply_hot_replaceble :1;
+};
+
+struct smbios_type39 {
+ struct smbios_header header;
+ u8 power_unit_group;
+ u8 location;
+ u8 device_name;
+ u8 manufacturer;
+ u8 serial_number;
+ u8 asset_tag_number;
+ u8 model_part_number;
+ u8 revision_level;
+ u16 max_power_capacity;
+ u16 power_supply_characteristics;
+ u16 input_voltage_probe_handle;
+ u16 cooling_device_handle;
+ u16 input_current_probe_handle;
+ u8 eos[2];
+} __packed;
+
+int smbios_write_type39(unsigned long *current, int *handle,
+ u8 unit_group, const char *loc, const char *dev_name,
+ const char *man, const char *serial_num,
+ const char *tag_num, const char *part_num,
+ const char *rev_lvl, u16 max_pow_cap,
+ const struct power_supply_ch *ps_ch);
+
+typedef enum {
SMBIOS_DEVICE_TYPE_OTHER = 0x01,
SMBIOS_DEVICE_TYPE_UNKNOWN,
SMBIOS_DEVICE_TYPE_VIDEO,