2011-08-14 20:56:34 +02:00
|
|
|
/*
|
|
|
|
* This file is part of the coreboot project.
|
|
|
|
*
|
2015-03-28 04:47:25 +01:00
|
|
|
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
|
2011-08-14 20:56:34 +02:00
|
|
|
* Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; version 2 of
|
|
|
|
* the License.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <smbios.h>
|
|
|
|
#include <console/console.h>
|
2014-11-18 11:41:16 +01:00
|
|
|
#include <version.h>
|
2011-08-14 20:56:34 +02:00
|
|
|
#include <device/device.h>
|
|
|
|
#include <arch/cpu.h>
|
|
|
|
#include <cpu/x86/name.h>
|
2012-06-24 01:13:42 +02:00
|
|
|
#include <elog.h>
|
Unify byte order macros and clrsetbits
This patch removes quite a bit of code duplication between cpu_to_le32()
and clrsetbits_le32() style macros on the different architectures. This
also syncs those macros back up to the new write32(a, v) style IO
accessor macros that are now used on ARM and ARM64.
CQ-DEPEND=CL:254862
BRANCH=none
BUG=chromium:444723
TEST=Compiled Cosmos, Daisy, Blaze, Falco, Pinky, Pit, Rambi, Ryu,
Storm and Urara. Booted on Jerry. Tried to compare binary images...
unfortunately something about the new macro notation makes the compiler
evaluate it more efficiently (not recalculating the address between the
read and the write), so this was of limited value.
Change-Id: If8ab62912c952d68a67a0f71e82b038732cd1317
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: fd43bf446581bfb84bec4f2ebb56b5de95971c3b
Original-Change-Id: I7d301b5bb5ac0db7f5ff39e3adc2b28a1f402a72
Original-Signed-off-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/254866
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/9838
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2015-02-23 23:31:09 +01:00
|
|
|
#include <endian.h>
|
2014-07-27 21:54:44 +02:00
|
|
|
#include <memory_info.h>
|
|
|
|
#include <spd.h>
|
|
|
|
#include <cbmem.h>
|
2012-04-04 01:02:54 +02:00
|
|
|
#if CONFIG_CHROMEOS
|
|
|
|
#include <vendorcode/google/chromeos/gnvs.h>
|
|
|
|
#endif
|
2011-08-14 20:56:34 +02:00
|
|
|
|
|
|
|
static u8 smbios_checksum(u8 *p, u32 length)
|
|
|
|
{
|
|
|
|
u8 ret = 0;
|
|
|
|
while (length--)
|
|
|
|
ret += *p++;
|
|
|
|
return -ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int smbios_add_string(char *start, const char *str)
|
|
|
|
{
|
|
|
|
int i = 1;
|
|
|
|
char *p = start;
|
|
|
|
|
2015-12-09 18:24:35 +01:00
|
|
|
/*
|
|
|
|
* Return 0 as required for empty strings.
|
|
|
|
* See Section 6.1.3 "Text Strings" of the SMBIOS specification.
|
|
|
|
*/
|
|
|
|
if (*str == '\0')
|
|
|
|
return 0;
|
|
|
|
|
2016-08-21 17:37:15 +02:00
|
|
|
for (;;) {
|
2011-08-14 20:56:34 +02:00
|
|
|
if (!*p) {
|
|
|
|
strcpy(p, str);
|
|
|
|
p += strlen(str);
|
|
|
|
*p++ = '\0';
|
|
|
|
*p++ = '\0';
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(p, str))
|
|
|
|
return i;
|
|
|
|
|
|
|
|
p += strlen(p)+1;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int smbios_string_table_len(char *start)
|
|
|
|
{
|
|
|
|
char *p = start;
|
|
|
|
int i, len = 0;
|
|
|
|
|
|
|
|
while(*p) {
|
|
|
|
i = strlen(p) + 1;
|
|
|
|
p += i;
|
|
|
|
len += i;
|
|
|
|
}
|
|
|
|
return len + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int smbios_cpu_vendor(char *start)
|
|
|
|
{
|
2012-02-25 23:51:12 +01:00
|
|
|
char tmp[13] = "Unknown";
|
2011-08-14 20:56:34 +02:00
|
|
|
u32 *_tmp = (u32 *)tmp;
|
2012-02-25 23:51:12 +01:00
|
|
|
struct cpuid_result res;
|
2011-08-14 20:56:34 +02:00
|
|
|
|
2012-02-25 23:51:12 +01:00
|
|
|
if (cpu_have_cpuid()) {
|
|
|
|
res = cpuid(0);
|
|
|
|
_tmp[0] = res.ebx;
|
|
|
|
_tmp[1] = res.edx;
|
|
|
|
_tmp[2] = res.ecx;
|
|
|
|
tmp[12] = '\0';
|
|
|
|
}
|
2011-08-14 20:56:34 +02:00
|
|
|
|
2012-02-25 23:51:12 +01:00
|
|
|
return smbios_add_string(start, tmp);
|
2011-08-14 20:56:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int smbios_processor_name(char *start)
|
|
|
|
{
|
2012-02-25 23:51:12 +01:00
|
|
|
char tmp[49] = "Unknown Processor Name";
|
2011-08-14 20:56:34 +02:00
|
|
|
u32 *_tmp = (u32 *)tmp;
|
|
|
|
struct cpuid_result res;
|
|
|
|
int i;
|
|
|
|
|
2012-02-25 23:51:12 +01:00
|
|
|
if (cpu_have_cpuid()) {
|
|
|
|
res = cpuid(0x80000000);
|
|
|
|
if (res.eax >= 0x80000004) {
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
res = cpuid(0x80000002 + i);
|
|
|
|
_tmp[i * 4 + 0] = res.eax;
|
|
|
|
_tmp[i * 4 + 1] = res.ebx;
|
|
|
|
_tmp[i * 4 + 2] = res.ecx;
|
|
|
|
_tmp[i * 4 + 3] = res.edx;
|
|
|
|
}
|
|
|
|
tmp[48] = 0;
|
|
|
|
}
|
2011-08-14 20:56:34 +02:00
|
|
|
}
|
|
|
|
return smbios_add_string(start, tmp);
|
|
|
|
}
|
|
|
|
|
2014-07-27 21:54:44 +02:00
|
|
|
/* this function will fill the corresponding manufacturer */
|
2015-03-28 05:05:36 +01:00
|
|
|
void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id, struct smbios_type17 *t)
|
2014-07-27 21:54:44 +02:00
|
|
|
{
|
|
|
|
switch (mod_id) {
|
Revert "arch/x86/smbios: Correct manufacturer ID"
This reverts commit c86da67436827c25919a2f5966049485a58fc984.
Alas, I have to disagree with this in every single line. The comment
added to the top of the file only applies to a single function therein
which sits over a hundred lines below. That's not much helpful. More-
over, the link in the comment is already down ofc.
The comment is also irritating as it doesn't state in which way (enco-
ding!) it applies to the code, which presumably led to the wrong in-
terpretation of the IDs.
At last, if anything should have changed it is the strings, the IDs
are resolved to. `smbios_fill_dimm_manufacturer_from_id()` has to
resolve the IDs it gets actually fed and not a random selection from
any spec.
Since I digged into it, here's why the numbers are correct: The func-
tion started with the SPD encoding of DDR3 in mind. There, the lower
byte is the number of a "bank" of IDs with an odd-parity in the upper
most bit. The upper byte is the ID within the bank. The "correction"
was to clear the parity bit for naught. The function was later exten-
ded with IDs in the DDR2-SPD encoding (which is actually 64-bit not
16). There, a byte, starting from the lowest, is either an ID below
127 plus odd-parity, or 127 which means look in the next byte/bank.
Unused bytes seem to be filled with 0xff, I guess from the 0xff2c.
Change-Id: Icdb48e4f2c102f619fbdca856e938e85135cfb18
Reviewed-on: https://review.coreboot.org/17873
Tested-by: build bot (Jenkins)
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Martin Roth <martinroth@google.com>
2016-12-14 23:48:09 +01:00
|
|
|
case 0x2c80:
|
2015-07-28 16:22:59 +02:00
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Crucial");
|
|
|
|
break;
|
2016-06-14 19:34:55 +02:00
|
|
|
case 0x4304:
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Ramaxel");
|
|
|
|
break;
|
2016-02-29 19:19:46 +01:00
|
|
|
case 0x4f01:
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Transcend");
|
|
|
|
break;
|
2015-06-26 01:37:58 +02:00
|
|
|
case 0x9801:
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Kingston");
|
|
|
|
break;
|
Revert "arch/x86/smbios: Correct manufacturer ID"
This reverts commit c86da67436827c25919a2f5966049485a58fc984.
Alas, I have to disagree with this in every single line. The comment
added to the top of the file only applies to a single function therein
which sits over a hundred lines below. That's not much helpful. More-
over, the link in the comment is already down ofc.
The comment is also irritating as it doesn't state in which way (enco-
ding!) it applies to the code, which presumably led to the wrong in-
terpretation of the IDs.
At last, if anything should have changed it is the strings, the IDs
are resolved to. `smbios_fill_dimm_manufacturer_from_id()` has to
resolve the IDs it gets actually fed and not a random selection from
any spec.
Since I digged into it, here's why the numbers are correct: The func-
tion started with the SPD encoding of DDR3 in mind. There, the lower
byte is the number of a "bank" of IDs with an odd-parity in the upper
most bit. The upper byte is the ID within the bank. The "correction"
was to clear the parity bit for naught. The function was later exten-
ded with IDs in the DDR2-SPD encoding (which is actually 64-bit not
16). There, a byte, starting from the lowest, is either an ID below
127 plus odd-parity, or 127 which means look in the next byte/bank.
Unused bytes seem to be filled with 0xff, I guess from the 0xff2c.
Change-Id: Icdb48e4f2c102f619fbdca856e938e85135cfb18
Reviewed-on: https://review.coreboot.org/17873
Tested-by: build bot (Jenkins)
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Martin Roth <martinroth@google.com>
2016-12-14 23:48:09 +01:00
|
|
|
case 0x987f:
|
2015-03-28 04:47:25 +01:00
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Hynix");
|
|
|
|
break;
|
2015-06-26 01:37:58 +02:00
|
|
|
case 0x9e02:
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Corsair");
|
|
|
|
break;
|
2016-02-29 19:19:46 +01:00
|
|
|
case 0xb004:
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"OCZ");
|
|
|
|
break;
|
Revert "arch/x86/smbios: Correct manufacturer ID"
This reverts commit c86da67436827c25919a2f5966049485a58fc984.
Alas, I have to disagree with this in every single line. The comment
added to the top of the file only applies to a single function therein
which sits over a hundred lines below. That's not much helpful. More-
over, the link in the comment is already down ofc.
The comment is also irritating as it doesn't state in which way (enco-
ding!) it applies to the code, which presumably led to the wrong in-
terpretation of the IDs.
At last, if anything should have changed it is the strings, the IDs
are resolved to. `smbios_fill_dimm_manufacturer_from_id()` has to
resolve the IDs it gets actually fed and not a random selection from
any spec.
Since I digged into it, here's why the numbers are correct: The func-
tion started with the SPD encoding of DDR3 in mind. There, the lower
byte is the number of a "bank" of IDs with an odd-parity in the upper
most bit. The upper byte is the ID within the bank. The "correction"
was to clear the parity bit for naught. The function was later exten-
ded with IDs in the DDR2-SPD encoding (which is actually 64-bit not
16). There, a byte, starting from the lowest, is either an ID below
127 plus odd-parity, or 127 which means look in the next byte/bank.
Unused bytes seem to be filled with 0xff, I guess from the 0xff2c.
Change-Id: Icdb48e4f2c102f619fbdca856e938e85135cfb18
Reviewed-on: https://review.coreboot.org/17873
Tested-by: build bot (Jenkins)
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Martin Roth <martinroth@google.com>
2016-12-14 23:48:09 +01:00
|
|
|
case 0xad80:
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Hynix/Hyundai");
|
|
|
|
break;
|
|
|
|
case 0xb502:
|
2016-05-08 00:25:42 +02:00
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"SuperTalent");
|
|
|
|
break;
|
2016-02-29 19:19:46 +01:00
|
|
|
case 0xcd04:
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"GSkill");
|
|
|
|
break;
|
Revert "arch/x86/smbios: Correct manufacturer ID"
This reverts commit c86da67436827c25919a2f5966049485a58fc984.
Alas, I have to disagree with this in every single line. The comment
added to the top of the file only applies to a single function therein
which sits over a hundred lines below. That's not much helpful. More-
over, the link in the comment is already down ofc.
The comment is also irritating as it doesn't state in which way (enco-
ding!) it applies to the code, which presumably led to the wrong in-
terpretation of the IDs.
At last, if anything should have changed it is the strings, the IDs
are resolved to. `smbios_fill_dimm_manufacturer_from_id()` has to
resolve the IDs it gets actually fed and not a random selection from
any spec.
Since I digged into it, here's why the numbers are correct: The func-
tion started with the SPD encoding of DDR3 in mind. There, the lower
byte is the number of a "bank" of IDs with an odd-parity in the upper
most bit. The upper byte is the ID within the bank. The "correction"
was to clear the parity bit for naught. The function was later exten-
ded with IDs in the DDR2-SPD encoding (which is actually 64-bit not
16). There, a byte, starting from the lowest, is either an ID below
127 plus odd-parity, or 127 which means look in the next byte/bank.
Unused bytes seem to be filled with 0xff, I guess from the 0xff2c.
Change-Id: Icdb48e4f2c102f619fbdca856e938e85135cfb18
Reviewed-on: https://review.coreboot.org/17873
Tested-by: build bot (Jenkins)
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Martin Roth <martinroth@google.com>
2016-12-14 23:48:09 +01:00
|
|
|
case 0xce80:
|
2014-07-27 21:54:44 +02:00
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Samsung");
|
|
|
|
break;
|
|
|
|
case 0xfe02:
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
"Elpida");
|
|
|
|
break;
|
Revert "arch/x86/smbios: Correct manufacturer ID"
This reverts commit c86da67436827c25919a2f5966049485a58fc984.
Alas, I have to disagree with this in every single line. The comment
added to the top of the file only applies to a single function therein
which sits over a hundred lines below. That's not much helpful. More-
over, the link in the comment is already down ofc.
The comment is also irritating as it doesn't state in which way (enco-
ding!) it applies to the code, which presumably led to the wrong in-
terpretation of the IDs.
At last, if anything should have changed it is the strings, the IDs
are resolved to. `smbios_fill_dimm_manufacturer_from_id()` has to
resolve the IDs it gets actually fed and not a random selection from
any spec.
Since I digged into it, here's why the numbers are correct: The func-
tion started with the SPD encoding of DDR3 in mind. There, the lower
byte is the number of a "bank" of IDs with an odd-parity in the upper
most bit. The upper byte is the ID within the bank. The "correction"
was to clear the parity bit for naught. The function was later exten-
ded with IDs in the DDR2-SPD encoding (which is actually 64-bit not
16). There, a byte, starting from the lowest, is either an ID below
127 plus odd-parity, or 127 which means look in the next byte/bank.
Unused bytes seem to be filled with 0xff, I guess from the 0xff2c.
Change-Id: Icdb48e4f2c102f619fbdca856e938e85135cfb18
Reviewed-on: https://review.coreboot.org/17873
Tested-by: build bot (Jenkins)
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Martin Roth <martinroth@google.com>
2016-12-14 23:48:09 +01:00
|
|
|
case 0xff2c:
|
2014-07-27 21:54:44 +02:00
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
2015-03-28 04:47:25 +01:00
|
|
|
"Micron");
|
2014-07-27 21:54:44 +02:00
|
|
|
break;
|
2015-03-28 04:47:25 +01:00
|
|
|
default: {
|
|
|
|
char string_buffer[256];
|
|
|
|
snprintf(string_buffer, sizeof(string_buffer),
|
|
|
|
"Unknown (%x)", mod_id);
|
|
|
|
t->manufacturer = smbios_add_string(t->eos,
|
|
|
|
string_buffer);
|
|
|
|
break;
|
|
|
|
}
|
2014-07-27 21:54:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int create_smbios_type17_for_dimm(struct dimm_info *dimm,
|
|
|
|
unsigned long *current, int *handle)
|
|
|
|
{
|
|
|
|
struct smbios_type17 *t = (struct smbios_type17 *)*current;
|
|
|
|
uint8_t length;
|
|
|
|
char locator[40];
|
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type17));
|
|
|
|
t->memory_type = dimm->ddr_type;
|
|
|
|
t->clock_speed = dimm->ddr_frequency;
|
|
|
|
t->speed = dimm->ddr_frequency;
|
|
|
|
t->type = SMBIOS_MEMORY_DEVICE;
|
|
|
|
t->size = dimm->dimm_size;
|
|
|
|
t->data_width = 8 * (1 << (dimm->bus_width & 0x7));
|
|
|
|
t->total_width = t->data_width + 8 * ((dimm->bus_width & 0x18) >> 3);
|
|
|
|
|
|
|
|
switch (dimm->mod_type) {
|
|
|
|
case SPD_RDIMM:
|
|
|
|
case SPD_MINI_RDIMM:
|
|
|
|
t->form_factor = MEMORY_FORMFACTOR_RIMM;
|
|
|
|
break;
|
|
|
|
case SPD_UDIMM:
|
|
|
|
case SPD_MICRO_DIMM:
|
|
|
|
case SPD_MINI_UDIMM:
|
|
|
|
t->form_factor = MEMORY_FORMFACTOR_DIMM;
|
|
|
|
break;
|
|
|
|
case SPD_SODIMM:
|
|
|
|
t->form_factor = MEMORY_FORMFACTOR_SODIMM;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
t->form_factor = MEMORY_FORMFACTOR_UNKNOWN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-03-28 05:05:36 +01:00
|
|
|
smbios_fill_dimm_manufacturer_from_id(dimm->mod_id, t);
|
2014-07-27 21:54:44 +02:00
|
|
|
/* put '\0' in the end of data */
|
|
|
|
length = sizeof(dimm->serial);
|
|
|
|
dimm->serial[length - 1] = '\0';
|
|
|
|
if (dimm->serial[0] == 0)
|
|
|
|
t->serial_number = smbios_add_string(t->eos, "None");
|
|
|
|
else
|
|
|
|
t->serial_number = smbios_add_string(t->eos,
|
|
|
|
(const char *)dimm->serial);
|
|
|
|
|
|
|
|
snprintf(locator, sizeof(locator), "Channel-%d-DIMM-%d",
|
|
|
|
dimm->channel_num, dimm->dimm_num);
|
|
|
|
t->device_locator = smbios_add_string(t->eos, locator);
|
|
|
|
|
|
|
|
snprintf(locator, sizeof(locator), "BANK %d", dimm->bank_locator);
|
|
|
|
t->bank_locator = smbios_add_string(t->eos, locator);
|
|
|
|
|
|
|
|
/* put '\0' in the end of data */
|
|
|
|
length = sizeof(dimm->module_part_number);
|
|
|
|
dimm->module_part_number[length - 1] = '\0';
|
|
|
|
t->part_number = smbios_add_string(t->eos,
|
|
|
|
(const char *)dimm->module_part_number);
|
|
|
|
|
|
|
|
/* Synchronous = 1 */
|
|
|
|
t->type_detail = 0x0080;
|
|
|
|
/* no handle for error information */
|
|
|
|
t->memory_error_information_handle = 0xFFFE;
|
|
|
|
t->attributes = dimm->rank_per_dimm;
|
|
|
|
t->handle = *handle;
|
|
|
|
*handle += 1;
|
|
|
|
t->length = sizeof(struct smbios_type17) - 2;
|
|
|
|
return t->length + smbios_string_table_len(t->eos);
|
|
|
|
}
|
|
|
|
|
2014-06-01 00:26:48 +02:00
|
|
|
const char *__attribute__((weak)) smbios_mainboard_bios_version(void)
|
|
|
|
{
|
|
|
|
if (strlen(CONFIG_LOCALVERSION))
|
|
|
|
return CONFIG_LOCALVERSION;
|
|
|
|
else
|
2014-11-18 11:41:16 +01:00
|
|
|
return coreboot_version;
|
2014-06-01 00:26:48 +02:00
|
|
|
}
|
|
|
|
|
2011-08-14 20:56:34 +02:00
|
|
|
static int smbios_write_type0(unsigned long *current, int handle)
|
|
|
|
{
|
|
|
|
struct smbios_type0 *t = (struct smbios_type0 *)*current;
|
|
|
|
int len = sizeof(struct smbios_type0);
|
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type0));
|
|
|
|
t->type = SMBIOS_BIOS_INFORMATION;
|
|
|
|
t->handle = handle;
|
|
|
|
t->length = len - 2;
|
|
|
|
|
|
|
|
t->vendor = smbios_add_string(t->eos, "coreboot");
|
2012-04-04 01:02:54 +02:00
|
|
|
#if !CONFIG_CHROMEOS
|
2014-11-18 11:41:16 +01:00
|
|
|
t->bios_release_date = smbios_add_string(t->eos, coreboot_dmi_date);
|
2013-02-04 16:22:46 +01:00
|
|
|
|
2014-06-01 00:26:48 +02:00
|
|
|
t->bios_version = smbios_add_string(t->eos, smbios_mainboard_bios_version());
|
2012-04-04 01:02:54 +02:00
|
|
|
#else
|
|
|
|
#define SPACES \
|
|
|
|
" "
|
2014-11-18 11:41:16 +01:00
|
|
|
t->bios_release_date = smbios_add_string(t->eos, coreboot_dmi_date);
|
2015-02-26 23:33:18 +01:00
|
|
|
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
|
2012-04-04 01:02:54 +02:00
|
|
|
u32 version_offset = (u32)smbios_string_table_len(t->eos);
|
2015-02-26 23:33:18 +01:00
|
|
|
#endif
|
2012-04-04 01:02:54 +02:00
|
|
|
t->bios_version = smbios_add_string(t->eos, SPACES);
|
2015-02-26 23:33:18 +01:00
|
|
|
|
|
|
|
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
|
2012-04-04 01:02:54 +02:00
|
|
|
/* SMBIOS offsets start at 1 rather than 0 */
|
|
|
|
vboot_data->vbt10 = (u32)t->eos + (version_offset - 1);
|
|
|
|
#endif
|
2015-02-26 23:33:18 +01:00
|
|
|
#endif /* CONFIG_CHROMEOS */
|
2011-08-14 20:56:34 +02:00
|
|
|
|
2016-06-08 21:47:07 +02:00
|
|
|
/* As a work around to prevent a compiler error, temporarily specify
|
|
|
|
* 16 MiB flash sizes when ROM size >= 16 MiB. An update is necessary
|
|
|
|
* once the SMBIOS specification addresses ROM sizes > 16 MiB.
|
|
|
|
*/
|
|
|
|
uint32_t rom_size = CONFIG_ROM_SIZE;
|
|
|
|
rom_size = MIN(CONFIG_ROM_SIZE, 16 * MiB);
|
|
|
|
t->bios_rom_size = (rom_size / 65535) - 1;
|
Extend CBFS to support arbitrary ROM source media.
Summary:
Isolate CBFS underlying I/O to board/arch-specific implementations as
"media stream", to allow loading and booting romstage on non-x86.
CBFS functions now all take a new "media source" parameter; use
CBFS_DEFAULT_MEDIA if you simply want to load from main firmware.
API Changes:
cbfs_find => cbfs_get_file.
cbfs_find_file => cbfs_get_file_content.
cbfs_get_file => cbfs_get_file_content with correct type.
CBFS used to work only on memory-mapped ROM (all x86). For platforms like ARM,
the ROM may come from USB, UART, or SPI -- any serial devices and not available
for memory mapping.
To support these devices (and allowing CBFS to read from multiple source
at the same time), CBFS operations are now virtual-ized into "cbfs_media". To
simplify porting existing code, every media source must support both "reading
into pre-allocated memory (read)" and "read and return an allocated buffer
(map)". For devices without native memory-mapped ROM, "cbfs_simple_buffer*"
provides simple memory mapping simulation.
Every CBFS function now takes a cbfs_media* as parameter. CBFS_DEFAULT_MEDIA
is defined for CBFS functions to automatically initialize a per-board default
media (CBFS will internally calls init_default_cbfs_media). Also revised CBFS
function names relying on memory mapped backend (ex, "cbfs_find" => actually
loads files). Now we only have two getters:
struct cbfs_file *entry = cbfs_get_file(media, name);
void *data = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, name, type);
Test results:
- Verified to work on x86/qemu.
- Compiles on ARM, and follow up commit will provide working SPI driver.
Change-Id: Iac911ded25a6f2feffbf3101a81364625bb07746
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: http://review.coreboot.org/2182
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2013-01-22 11:57:56 +01:00
|
|
|
|
2011-08-14 20:56:34 +02:00
|
|
|
t->system_bios_major_release = 4;
|
|
|
|
t->bios_characteristics =
|
|
|
|
BIOS_CHARACTERISTICS_PCI_SUPPORTED |
|
|
|
|
#if CONFIG_CARDBUS_PLUGIN_SUPPORT
|
|
|
|
BIOS_CHARACTERISTICS_PC_CARD |
|
|
|
|
#endif
|
|
|
|
BIOS_CHARACTERISTICS_SELECTABLE_BOOT |
|
|
|
|
BIOS_CHARACTERISTICS_UPGRADEABLE;
|
|
|
|
|
2014-01-03 15:55:40 +01:00
|
|
|
#if CONFIG_HAVE_ACPI_TABLES
|
2011-08-14 20:56:34 +02:00
|
|
|
t->bios_characteristics_ext1 = BIOS_EXT1_CHARACTERISTICS_ACPI;
|
|
|
|
#endif
|
|
|
|
t->bios_characteristics_ext2 = BIOS_EXT2_CHARACTERISTICS_TARGET;
|
|
|
|
len = t->length + smbios_string_table_len(t->eos);
|
|
|
|
*current += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-05-30 23:08:26 +02:00
|
|
|
#if !CONFIG_SMBIOS_PROVIDED_BY_MOBO
|
|
|
|
|
2012-07-25 13:42:40 +02:00
|
|
|
const char *__attribute__((weak)) smbios_mainboard_serial_number(void)
|
|
|
|
{
|
|
|
|
return CONFIG_MAINBOARD_SERIAL_NUMBER;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *__attribute__((weak)) smbios_mainboard_version(void)
|
|
|
|
{
|
|
|
|
return CONFIG_MAINBOARD_VERSION;
|
|
|
|
}
|
|
|
|
|
2013-11-13 13:37:23 +01:00
|
|
|
const char *__attribute__((weak)) smbios_mainboard_manufacturer(void)
|
|
|
|
{
|
|
|
|
return CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *__attribute__((weak)) smbios_mainboard_product_name(void)
|
|
|
|
{
|
|
|
|
return CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __attribute__((weak)) smbios_mainboard_set_uuid(u8 *uuid)
|
|
|
|
{
|
|
|
|
/* leave all zero */
|
|
|
|
}
|
2015-05-30 23:08:26 +02:00
|
|
|
#endif
|
2013-11-13 13:37:23 +01:00
|
|
|
|
2016-05-30 15:52:31 +02:00
|
|
|
const char *__attribute__((weak)) smbios_mainboard_sku(void)
|
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2014-09-09 03:40:30 +02:00
|
|
|
#ifdef CONFIG_MAINBOARD_FAMILY
|
|
|
|
const char *smbios_mainboard_family(void)
|
|
|
|
{
|
|
|
|
return CONFIG_MAINBOARD_FAMILY;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_MAINBOARD_FAMILY */
|
|
|
|
|
2011-08-14 20:56:34 +02:00
|
|
|
static int smbios_write_type1(unsigned long *current, int handle)
|
|
|
|
{
|
|
|
|
struct smbios_type1 *t = (struct smbios_type1 *)*current;
|
|
|
|
int len = sizeof(struct smbios_type1);
|
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type1));
|
|
|
|
t->type = SMBIOS_SYSTEM_INFORMATION;
|
|
|
|
t->handle = handle;
|
|
|
|
t->length = len - 2;
|
2013-11-13 13:37:23 +01:00
|
|
|
t->manufacturer = smbios_add_string(t->eos, smbios_mainboard_manufacturer());
|
|
|
|
t->product_name = smbios_add_string(t->eos, smbios_mainboard_product_name());
|
2012-07-25 13:42:40 +02:00
|
|
|
t->serial_number = smbios_add_string(t->eos, smbios_mainboard_serial_number());
|
2016-05-30 15:52:31 +02:00
|
|
|
t->sku = smbios_add_string(t->eos, smbios_mainboard_sku());
|
2012-07-25 13:42:40 +02:00
|
|
|
t->version = smbios_add_string(t->eos, smbios_mainboard_version());
|
2015-06-10 05:10:43 +02:00
|
|
|
#ifdef CONFIG_MAINBOARD_FAMILY
|
|
|
|
t->family = smbios_add_string(t->eos, smbios_mainboard_family());
|
|
|
|
#endif
|
2013-11-13 13:37:23 +01:00
|
|
|
smbios_mainboard_set_uuid(t->uuid);
|
2011-08-14 20:56:34 +02:00
|
|
|
len = t->length + smbios_string_table_len(t->eos);
|
|
|
|
*current += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2014-03-02 19:14:44 +01:00
|
|
|
static int smbios_write_type2(unsigned long *current, int handle)
|
|
|
|
{
|
|
|
|
struct smbios_type2 *t = (struct smbios_type2 *)*current;
|
|
|
|
int len = sizeof(struct smbios_type2);
|
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type2));
|
|
|
|
t->type = SMBIOS_BOARD_INFORMATION;
|
|
|
|
t->handle = handle;
|
|
|
|
t->length = len - 2;
|
|
|
|
t->manufacturer = smbios_add_string(t->eos, smbios_mainboard_manufacturer());
|
|
|
|
t->product_name = smbios_add_string(t->eos, smbios_mainboard_product_name());
|
|
|
|
t->serial_number = smbios_add_string(t->eos, smbios_mainboard_serial_number());
|
|
|
|
t->version = smbios_add_string(t->eos, smbios_mainboard_version());
|
|
|
|
len = t->length + smbios_string_table_len(t->eos);
|
|
|
|
*current += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2011-08-14 20:56:34 +02:00
|
|
|
static int smbios_write_type3(unsigned long *current, int handle)
|
|
|
|
{
|
|
|
|
struct smbios_type3 *t = (struct smbios_type3 *)*current;
|
|
|
|
int len = sizeof(struct smbios_type3);
|
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type3));
|
|
|
|
t->type = SMBIOS_SYSTEM_ENCLOSURE;
|
|
|
|
t->handle = handle;
|
|
|
|
t->length = len - 2;
|
2015-05-30 23:09:53 +02:00
|
|
|
t->manufacturer = smbios_add_string(t->eos, smbios_mainboard_manufacturer());
|
2011-08-14 20:56:34 +02:00
|
|
|
t->bootup_state = SMBIOS_STATE_SAFE;
|
|
|
|
t->power_supply_state = SMBIOS_STATE_SAFE;
|
|
|
|
t->thermal_state = SMBIOS_STATE_SAFE;
|
2017-03-16 19:24:09 +01:00
|
|
|
if (IS_ENABLED(CONFIG_SYSTEM_TYPE_LAPTOP))
|
2014-10-16 13:21:47 +02:00
|
|
|
t->_type = SMBIOS_ENCLOSURE_NOTEBOOK;
|
2017-03-16 19:24:09 +01:00
|
|
|
else
|
2014-10-16 13:21:47 +02:00
|
|
|
t->_type = SMBIOS_ENCLOSURE_DESKTOP;
|
2011-08-14 20:56:34 +02:00
|
|
|
t->security_status = SMBIOS_STATE_SAFE;
|
|
|
|
len = t->length + smbios_string_table_len(t->eos);
|
|
|
|
*current += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int smbios_write_type4(unsigned long *current, int handle)
|
|
|
|
{
|
|
|
|
struct cpuid_result res;
|
|
|
|
struct smbios_type4 *t = (struct smbios_type4 *)*current;
|
|
|
|
int len = sizeof(struct smbios_type4);
|
|
|
|
|
2012-02-25 23:51:12 +01:00
|
|
|
/* Provide sane defaults even for CPU without CPUID */
|
|
|
|
res.eax = res.edx = 0;
|
|
|
|
res.ebx = 0x10000;
|
|
|
|
|
2017-03-16 19:24:09 +01:00
|
|
|
if (cpu_have_cpuid())
|
2012-02-25 23:51:12 +01:00
|
|
|
res = cpuid(1);
|
2011-08-14 20:56:34 +02:00
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type4));
|
|
|
|
t->type = SMBIOS_PROCESSOR_INFORMATION;
|
|
|
|
t->handle = handle;
|
|
|
|
t->length = len - 2;
|
|
|
|
t->processor_id[0] = res.eax;
|
|
|
|
t->processor_id[1] = res.edx;
|
|
|
|
t->processor_manufacturer = smbios_cpu_vendor(t->eos);
|
|
|
|
t->processor_version = smbios_processor_name(t->eos);
|
2012-02-25 23:51:12 +01:00
|
|
|
t->processor_family = (res.eax > 0) ? 0x0c : 0x6;
|
2011-08-14 20:56:34 +02:00
|
|
|
t->processor_type = 3; /* System Processor */
|
|
|
|
t->processor_upgrade = 0x06;
|
|
|
|
t->core_count = (res.ebx >> 16) & 0xff;
|
|
|
|
t->l1_cache_handle = 0xffff;
|
|
|
|
t->l2_cache_handle = 0xffff;
|
|
|
|
t->l3_cache_handle = 0xffff;
|
|
|
|
t->processor_upgrade = 1;
|
|
|
|
len = t->length + smbios_string_table_len(t->eos);
|
|
|
|
*current += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2014-08-27 23:42:45 +02:00
|
|
|
static int smbios_write_type11(unsigned long *current, int *handle)
|
2013-07-06 19:51:12 +02:00
|
|
|
{
|
|
|
|
struct smbios_type11 *t = (struct smbios_type11 *)*current;
|
2014-08-27 23:42:45 +02:00
|
|
|
int len;
|
2014-10-27 13:29:29 +01:00
|
|
|
struct device *dev;
|
2013-07-06 19:51:12 +02:00
|
|
|
|
|
|
|
memset(t, 0, sizeof *t);
|
|
|
|
t->type = SMBIOS_OEM_STRINGS;
|
2014-08-27 23:42:45 +02:00
|
|
|
t->handle = *handle;
|
2013-07-06 19:51:12 +02:00
|
|
|
t->length = len = sizeof *t - 2;
|
|
|
|
|
2016-08-21 17:37:15 +02:00
|
|
|
for (dev = all_devices; dev; dev = dev->next) {
|
2014-08-27 23:42:45 +02:00
|
|
|
if (dev->ops && dev->ops->get_smbios_strings)
|
|
|
|
dev->ops->get_smbios_strings(dev, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (t->count == 0) {
|
|
|
|
memset(t, 0, sizeof *t);
|
|
|
|
return 0;
|
|
|
|
}
|
2013-07-06 19:51:12 +02:00
|
|
|
|
|
|
|
len += smbios_string_table_len(t->eos);
|
2014-08-27 23:42:45 +02:00
|
|
|
|
2013-07-06 19:51:12 +02:00
|
|
|
*current += len;
|
2014-08-27 23:42:45 +02:00
|
|
|
(*handle)++;
|
2013-07-06 19:51:12 +02:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2014-07-27 21:54:44 +02:00
|
|
|
static int smbios_write_type17(unsigned long *current, int *handle)
|
|
|
|
{
|
|
|
|
int len = sizeof(struct smbios_type17);
|
2016-03-09 16:22:58 +01:00
|
|
|
int totallen = 0;
|
2014-07-27 21:54:44 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
struct memory_info *meminfo;
|
|
|
|
meminfo = cbmem_find(CBMEM_ID_MEMINFO);
|
|
|
|
if (meminfo == NULL)
|
|
|
|
return 0; /* can't find mem info in cbmem */
|
|
|
|
|
|
|
|
printk(BIOS_INFO, "Create SMBIOS type 17\n");
|
|
|
|
for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) {
|
|
|
|
struct dimm_info *dimm;
|
|
|
|
dimm = &meminfo->dimm[i];
|
|
|
|
len = create_smbios_type17_for_dimm(dimm, current, handle);
|
|
|
|
*current += len;
|
2016-03-09 16:22:58 +01:00
|
|
|
totallen += len;
|
2014-07-27 21:54:44 +02:00
|
|
|
}
|
2016-03-09 16:22:58 +01:00
|
|
|
return totallen;
|
2014-07-27 21:54:44 +02:00
|
|
|
}
|
|
|
|
|
2011-08-14 20:56:34 +02:00
|
|
|
static int smbios_write_type32(unsigned long *current, int handle)
|
|
|
|
{
|
|
|
|
struct smbios_type32 *t = (struct smbios_type32 *)*current;
|
|
|
|
int len = sizeof(struct smbios_type32);
|
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type32));
|
|
|
|
t->type = SMBIOS_SYSTEM_BOOT_INFORMATION;
|
|
|
|
t->handle = handle;
|
|
|
|
t->length = len - 2;
|
|
|
|
*current += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2013-05-23 23:17:05 +02:00
|
|
|
int smbios_write_type41(unsigned long *current, int *handle,
|
|
|
|
const char *name, u8 instance, u16 segment,
|
|
|
|
u8 bus, u8 device, u8 function)
|
|
|
|
{
|
|
|
|
struct smbios_type41 *t = (struct smbios_type41 *)*current;
|
|
|
|
int len = sizeof(struct smbios_type41);
|
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type41));
|
|
|
|
t->type = SMBIOS_ONBOARD_DEVICES_EXTENDED_INFORMATION;
|
|
|
|
t->handle = *handle;
|
|
|
|
t->length = len - 2;
|
|
|
|
t->reference_designation = smbios_add_string(t->eos, name);
|
|
|
|
t->device_type = SMBIOS_DEVICE_TYPE_OTHER;
|
|
|
|
t->device_status = 1;
|
|
|
|
t->device_type_instance = instance;
|
|
|
|
t->segment_group_number = segment;
|
|
|
|
t->bus_number = bus;
|
|
|
|
t->device_number = device;
|
|
|
|
t->function_number = function;
|
|
|
|
|
|
|
|
len = t->length + smbios_string_table_len(t->eos);
|
|
|
|
*current += len;
|
|
|
|
*handle += 1;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2011-08-14 20:56:34 +02:00
|
|
|
static int smbios_write_type127(unsigned long *current, int handle)
|
|
|
|
{
|
|
|
|
struct smbios_type127 *t = (struct smbios_type127 *)*current;
|
|
|
|
int len = sizeof(struct smbios_type127);
|
|
|
|
|
|
|
|
memset(t, 0, sizeof(struct smbios_type127));
|
|
|
|
t->type = SMBIOS_END_OF_TABLE;
|
|
|
|
t->handle = handle;
|
|
|
|
t->length = len - 2;
|
|
|
|
*current += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2014-10-27 13:29:29 +01:00
|
|
|
static int smbios_walk_device_tree(struct device *tree, int *handle, unsigned long *current)
|
2011-08-14 20:56:34 +02:00
|
|
|
{
|
2014-10-27 13:29:29 +01:00
|
|
|
struct device *dev;
|
2011-08-14 20:56:34 +02:00
|
|
|
int len = 0;
|
|
|
|
|
2016-08-21 17:37:15 +02:00
|
|
|
for (dev = tree; dev; dev = dev->next) {
|
2012-10-07 14:57:15 +02:00
|
|
|
printk(BIOS_INFO, "%s (%s)\n", dev_path(dev), dev_name(dev));
|
2011-08-14 20:56:34 +02:00
|
|
|
|
|
|
|
if (dev->ops && dev->ops->get_smbios_data)
|
|
|
|
len += dev->ops->get_smbios_data(dev, handle, current);
|
|
|
|
}
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-05-10 02:52:18 +02:00
|
|
|
#define update_max(len, max_len, stmt) do { int tmp = stmt; max_len = MAX(max_len, tmp); len += tmp; } while(0)
|
2011-08-14 20:56:34 +02:00
|
|
|
unsigned long smbios_write_tables(unsigned long current)
|
|
|
|
{
|
|
|
|
struct smbios_entry *se;
|
|
|
|
unsigned long tables;
|
2015-05-10 02:52:18 +02:00
|
|
|
int len = 0;
|
|
|
|
int max_struct_size = 0;
|
|
|
|
int handle = 0;
|
2011-08-14 20:56:34 +02:00
|
|
|
|
|
|
|
current = ALIGN(current, 16);
|
|
|
|
printk(BIOS_DEBUG, "%s: %08lx\n", __func__, current);
|
|
|
|
|
|
|
|
se = (struct smbios_entry *)current;
|
|
|
|
current += sizeof(struct smbios_entry);
|
|
|
|
current = ALIGN(current, 16);
|
|
|
|
|
|
|
|
tables = current;
|
2015-05-10 02:52:18 +02:00
|
|
|
update_max(len, max_struct_size, smbios_write_type0(¤t, handle++));
|
|
|
|
update_max(len, max_struct_size, smbios_write_type1(¤t, handle++));
|
|
|
|
update_max(len, max_struct_size, smbios_write_type2(¤t, handle++));
|
|
|
|
update_max(len, max_struct_size, smbios_write_type3(¤t, handle++));
|
|
|
|
update_max(len, max_struct_size, smbios_write_type4(¤t, handle++));
|
|
|
|
update_max(len, max_struct_size, smbios_write_type11(¤t, &handle));
|
2012-06-24 01:13:42 +02:00
|
|
|
#if CONFIG_ELOG
|
2015-07-07 17:29:43 +02:00
|
|
|
update_max(len, max_struct_size, elog_smbios_write_type15(¤t, handle++));
|
2012-06-24 01:13:42 +02:00
|
|
|
#endif
|
2015-05-10 02:52:18 +02:00
|
|
|
update_max(len, max_struct_size, smbios_write_type17(¤t, &handle));
|
|
|
|
update_max(len, max_struct_size, smbios_write_type32(¤t, handle++));
|
2011-08-14 20:56:34 +02:00
|
|
|
|
2015-05-10 02:52:18 +02:00
|
|
|
update_max(len, max_struct_size, smbios_walk_device_tree(all_devices, &handle, ¤t));
|
2011-08-14 20:56:34 +02:00
|
|
|
|
2015-05-10 02:52:18 +02:00
|
|
|
update_max(len, max_struct_size, smbios_write_type127(¤t, handle++));
|
2011-08-14 20:56:34 +02:00
|
|
|
|
|
|
|
memset(se, 0, sizeof(struct smbios_entry));
|
|
|
|
memcpy(se->anchor, "_SM_", 4);
|
|
|
|
se->length = sizeof(struct smbios_entry);
|
|
|
|
se->major_version = 2;
|
|
|
|
se->minor_version = 7;
|
2015-05-10 02:52:18 +02:00
|
|
|
se->max_struct_size = max_struct_size;
|
2011-08-14 20:56:34 +02:00
|
|
|
se->struct_count = handle;
|
|
|
|
memcpy(se->intermediate_anchor_string, "_DMI_", 5);
|
|
|
|
|
|
|
|
se->struct_table_address = (u32)tables;
|
|
|
|
se->struct_table_length = len;
|
|
|
|
|
|
|
|
se->intermediate_checksum = smbios_checksum((u8 *)se + 0x10,
|
|
|
|
sizeof(struct smbios_entry) - 0x10);
|
|
|
|
se->checksum = smbios_checksum((u8 *)se, sizeof(struct smbios_entry));
|
|
|
|
return current;
|
|
|
|
}
|