coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
soc_util.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/cpu.h>
4 #include <console/console.h>
5 #include <FspGuids.h>
6 #include <fsp/util.h>
7 #include <misc_data.h>
8 #include <soc/cpu.h>
9 #include <soc/soc_util.h>
10 #include <types.h>
11 
12 /*
13  * The Zen/Zen+ based APUs can be RV (sometimes called RV1), PCO or RV2 silicon. RV2 has less
14  * PCIe, USB3 and DisplayPort connectivity than RV(1) or PCO. A Picasso SoC is always PCO
15  * silicon, a Dali SoC can either be RV2 or fused-down PCO silicon that has the same
16  * connectivity as the RV2 one and Pollock is always RV2 silicon. Picasso and Dali are in a FP5
17  * package while Pollock is in the smaller FT5 package.
18  */
19 
20 #define SOCKET_TYPE_SHIFT 28
21 #define SOCKET_TYPE_MASK (0xf << SOCKET_TYPE_SHIFT)
22 
23 /* some Pollock engineering samples return the wrong socket type */
25 {
26  uint32_t ebx = cpuid_ebx(0x80000001);
27  ebx = (ebx & SOCKET_TYPE_MASK) >> SOCKET_TYPE_SHIFT;
28  return (enum socket_type)ebx;
29 }
30 
32 {
33  enum socket_type socket = get_socket_type();
34 
35  printk(BIOS_INFO, "Socket type: ");
36 
37  switch (socket) {
38  case SOCKET_FP5:
39  printk(BIOS_INFO, "FP5\n");
40  break;
41  case SOCKET_AM4:
42  printk(BIOS_INFO, "AM4\n");
43  break;
44  case SOCKET_FT5:
45  printk(BIOS_INFO, "FT5\n");
46  break;
47  default:
48  printk(BIOS_INFO, "unknown\n");
49  }
50 }
51 
52 /* returns 0 in case or errors */
54 {
55  static uint32_t silicon_type;
56  size_t hob_size = 0;
57  const struct picasso_misc_data *hob;
58 
59  if (silicon_type)
60  return silicon_type;
61 
62  hob = fsp_find_extension_hob_by_guid(PICASSO_MISC_DATA_HOB_GUID.b, &hob_size);
63 
64  if (hob == NULL || hob_size == 0) {
65  printk(BIOS_ERR, "Couldn't find Picasso misc data HOB.\n");
66  return 0;
67  }
68 
69  if (hob->version != PICASSO_MISC_DATA_VERSION) {
70  printk(BIOS_ERR, "Unexpected Picasso misc data HOB version.\n");
71  return 0;
72  }
73 
74  silicon_type = hob->silicon_id;
75 
76  printk(BIOS_DEBUG, "Silicon ID = 0x%x\n", silicon_type);
77 
78  return silicon_type;
79 }
80 
81 #define SILICON_IS_MYSTERY_MEAT (1 << 31)
82 #define SILICON_IS_RV2 (1 << 30)
83 
84 static bool is_rv2_silicon(void)
85 {
87 }
88 
89 static bool is_mystery_silicon(void)
90 {
92 }
93 
94 static bool is_fam17_1x(void)
95 {
96  /* mask lower model number nibble and stepping */
97  return cpuid_eax(1) >> 8 == PICASSO_B1_CPUID >> 8;
98 }
99 
100 static bool is_fam17_11(void)
101 {
102  /* only mask stepping */
103  return cpuid_eax(1) >> 4 == RAVEN1_B0_CPUID >> 4;
104 }
105 
106 static bool is_fam17_18(void)
107 {
108  /* only mask stepping */
109  return cpuid_eax(1) >> 4 == PICASSO_B1_CPUID >> 4;
110 }
111 
112 static bool is_fam17_2x(void)
113 {
114  /* mask lower model number nibble and stepping */
115  return cpuid_eax(1) >> 8 == RAVEN2_A1_CPUID >> 8;
116 }
117 
118 static bool is_fam17_20(void)
119 {
120  /* only mask stepping */
121  return cpuid_eax(1) >> 4 == RAVEN2_A1_CPUID >> 4;
122 }
123 
125 {
126  /*
127  * RV2 is fam17_20, but might return a fam17_1x CPUID in the is_mystery_silicon() case.
128  * is_rv2_silicon() has the correct information, but requires the HOB to be present.
129  */
130  if (is_fam17_20() || is_rv2_silicon())
131  return SILICON_RV2;
132 
133  if (is_fam17_18() && !is_rv2_silicon())
134  return SILICON_PCO;
135 
136  if (is_fam17_11() && !is_rv2_silicon())
137  return SILICON_RV1;
138 
139  /* some cases might still be missing */
140 
141  return SILICON_UNKNOWN;
142 }
143 
144 /* some Pollock engineering samples return the wrong socket type and get detected as Dali */
145 enum soc_type get_soc_type(void)
146 {
147  switch (get_socket_type()) {
148  case SOCKET_FP5:
149  if (is_fam17_1x() && !is_mystery_silicon())
150  return SOC_PICASSO;
151 
152  if (is_fam17_2x() || (is_fam17_1x() && is_mystery_silicon()))
153  return SOC_DALI;
154 
155  break;
156  case SOCKET_FT5:
157  /* add is_fam17_20() CPUID sanity check here? */
158  return SOC_POLLOCK;
159  break;
160  case SOCKET_AM4:
161  /* AM4 SoC type detection logic not implemented */
162  break;
163  }
164 
165  return SOC_UNKNOWN;
166 }
167 
169 {
170  const enum silicon_type silicon = get_silicon_type();
171 
172  printk(BIOS_INFO, "Silicon type: ");
173 
174  switch (silicon) {
175  case SILICON_RV1:
176  printk(BIOS_INFO, "RV1\n");
177  break;
178  case SILICON_PCO:
179  printk(BIOS_INFO, "PCO\n");
180  break;
181  case SILICON_RV2:
182  printk(BIOS_INFO, "RV2\n");
183  break;
184  default:
185  printk(BIOS_INFO, "unknown\n");
186  }
187 }
188 
189 void print_soc_type(void)
190 {
191  const enum soc_type soc = get_soc_type();
192 
193  printk(BIOS_INFO, "SoC type: ");
194 
195  switch (soc) {
196  case SOC_PICASSO:
197  printk(BIOS_INFO, "Picasso\n");
198  break;
199  case SOC_DALI:
200  printk(BIOS_INFO, "Dali\n");
201  break;
202  case SOC_POLLOCK:
203  printk(BIOS_INFO, "Pollock\n");
204  break;
205  default:
206  printk(BIOS_INFO, "unknown\n");
207  }
208 }
209 
211 {
213 }
214 
215 bool soc_is_raven2(void)
216 {
217  return get_silicon_type() == SILICON_RV2;
218 }
silicon_type
Definition: soc_util.h:14
@ SILICON_UNKNOWN
Definition: soc_util.h:18
@ SILICON_PCO
Definition: soc_util.h:16
@ SILICON_RV2
Definition: soc_util.h:17
@ SILICON_RV1
Definition: soc_util.h:15
socket_type
Definition: soc_util.h:8
@ SOCKET_FT5
Definition: soc_util.h:11
@ SOCKET_AM4
Definition: soc_util.h:10
@ SOCKET_FP5
Definition: soc_util.h:9
soc_type
Definition: soc_util.h:21
@ SOC_POLLOCK
Definition: soc_util.h:24
@ SOC_DALI
Definition: soc_util.h:23
@ SOC_UNKNOWN
Definition: soc_util.h:25
@ SOC_PICASSO
Definition: soc_util.h:22
static bool is_fam17_1x(void)
Definition: soc_util.c:94
#define SOCKET_TYPE_MASK
Definition: soc_util.c:21
bool soc_is_raven2(void)
Definition: soc_util.c:215
bool soc_is_reduced_io_sku(void)
Definition: soc_util.c:210
#define SILICON_IS_MYSTERY_MEAT
Definition: soc_util.c:81
#define SOCKET_TYPE_SHIFT
Definition: soc_util.c:20
static bool is_rv2_silicon(void)
Definition: soc_util.c:84
enum soc_type get_soc_type(void)
Definition: soc_util.c:145
static uint32_t get_internal_silicon_type(void)
Definition: soc_util.c:53
static bool is_fam17_2x(void)
Definition: soc_util.c:112
void print_silicon_type(void)
Definition: soc_util.c:168
enum socket_type get_socket_type(void)
Definition: soc_util.c:24
static bool is_mystery_silicon(void)
Definition: soc_util.c:89
static bool is_fam17_18(void)
Definition: soc_util.c:106
enum silicon_type get_silicon_type(void)
Definition: soc_util.c:124
void print_socket_type(void)
Definition: soc_util.c:31
#define SILICON_IS_RV2
Definition: soc_util.c:82
static bool is_fam17_20(void)
Definition: soc_util.c:118
static bool is_fam17_11(void)
Definition: soc_util.c:100
void print_soc_type(void)
Definition: soc_util.c:189
static unsigned int cpuid_eax(unsigned int op)
Definition: cpu.h:79
static unsigned int cpuid_ebx(unsigned int op)
Definition: cpu.h:92
#define printk(level,...)
Definition: stdlib.h:16
const void * fsp_find_extension_hob_by_guid(const uint8_t *guid, size_t *size)
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define RAVEN2_A1_CPUID
Definition: cpu.h:10
#define PICASSO_B1_CPUID
Definition: cpu.h:8
#define RAVEN1_B0_CPUID
Definition: cpu.h:6
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14