blob: fb8e06f1491eec7bf7e5cf16a5bde3a03f58909b [file] [log] [blame]
Angel Pons118a9c72020-04-02 23:48:34 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Raul E Rangel21db6cc2018-03-29 10:18:14 -06002
3#include <dimm_info_util.h>
4#include <smbios.h>
5#include <spd.h>
6#include <console/console.h>
7
8uint8_t smbios_bus_width_to_spd_width(uint16_t total_width, uint16_t data_width)
9{
10 uint8_t out;
11
12 /* Lookup table as defined in the JEDEC Standard. */
13 switch (data_width) {
14 case 64:
15 out = MEMORY_BUS_WIDTH_64;
16 break;
17 case 32:
18 out = MEMORY_BUS_WIDTH_32;
19 break;
20 case 16:
21 out = MEMORY_BUS_WIDTH_16;
22 break;
23 case 8:
24 out = MEMORY_BUS_WIDTH_8;
25 break;
26 default:
27 printk(BIOS_NOTICE, "Unknown memory size %hu", data_width);
28 /*
29 * The SMBIOS spec says we should set 0xFFFF on an unknown
30 * value, but we don't have a way of passing that signal via SPD
31 * encoded values.
32 */
33 out = MEMORY_BUS_WIDTH_8;
34 break;
35 }
36
37 uint16_t extension_bits = total_width - data_width;
38
39 switch (extension_bits) {
40 case 8:
41 out |= SPD_ECC_8BIT;
42 break;
43 case 0:
44 /* No extension bits */
45 break;
46 default:
47 printk(BIOS_NOTICE, "Unknown number of extension bits %hu",
48 extension_bits);
49 break;
50 }
51
52 return out;
53}
54
55uint32_t smbios_memory_size_to_mib(uint16_t memory_size, uint32_t extended_size)
56{
57 /* Memory size is unknown */
58 if (memory_size == 0xFFFF)
59 return 0;
60 /* (32 GiB - 1 MiB) or greater is expressed in the extended size. */
61 else if (memory_size == 0x7FFF)
62 return extended_size;
63 /* When the MSB is flipped, the value is specified in kilobytes */
64 else if (memory_size & 0x8000)
65 return (memory_size ^ 0x8000) / KiB;
66 /* Value contains MiB */
67 else
68 return memory_size;
69}
70
71uint8_t
72smbios_form_factor_to_spd_mod_type(smbios_memory_form_factor form_factor)
73{
74 /* This switch reverses the switch in smbios.c */
75 switch (form_factor) {
76 case MEMORY_FORMFACTOR_DIMM:
77 return SPD_UDIMM;
78 case MEMORY_FORMFACTOR_RIMM:
79 return SPD_RDIMM;
80 case MEMORY_FORMFACTOR_SODIMM:
81 return SPD_SODIMM;
82 default:
83 return SPD_UNDEFINED;
84 }
85}