1 /** @file
2   This driver installs SMBIOS information for ARM Juno platforms
3 
4   Copyright (c) 2015, ARM Limited. All rights reserved.
5 
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 #include <ArmPlatform.h>
10 #include <IndustryStandard/SmBios.h>
11 #include <Library/ArmLib.h>
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/IoLib.h>
16 #include <Library/MemoryAllocationLib.h>
17 #include <Library/PcdLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Library/UefiRuntimeServicesTableLib.h>
20 #include <PiDxe.h>
21 #include <Protocol/Smbios.h>
22 
23 #define TYPE0_STRINGS                                    \
24   "EFI Development Kit II / ARM LTD\0" /* Vendor */      \
25   "EDK II\0"                           /* BiosVersion */ \
26   __DATE__"\0"                         /* BiosReleaseDate */
27 
28 #define TYPE1_STRINGS                                   \
29   "ARM LTD\0"                        /* Manufacturer */ \
30   "ARM Juno Development Platform\0"  /* Product Name */ \
31   "None\0"                           /* Version */      \
32   "                    \0"           /* 20 character buffer */
33 
34 #define TYPE2_STRINGS                                     \
35   "ARM LTD\0"                        /* Manufacturer */   \
36   "ARM Juno Development Platform\0"  /* Product Name */   \
37   "R0\0"                             /* Version */        \
38   "Serial Not Set\0"                 /* Serial */         \
39   "Base of Chassis\0"                /* board location */ \
40   "R1\0"                             /* Version */        \
41   "R2\0"                             /* Version */
42 
43 #define TYPE3_STRINGS                                   \
44   "ARM LTD\0"                        /* Manufacturer */ \
45   "None\0"                           /* Version */      \
46   "Serial Not Set\0"                 /* Serial  */
47 
48 #define TYPE4_STRINGS                                               \
49   "BGA-1156\0"                       /* socket type */              \
50   "ARM LTD\0"                        /* manufactuer */              \
51   "Cortex-A57\0"                     /* processor 1 description */  \
52   "Cortex-A53\0"                     /* processor 2 description */  \
53   "Cortex-A72\0"                     /* processor 2 description */  \
54   "0xd03\0"                          /* A53 part number */          \
55   "0xd07\0"                          /* A57 part number */          \
56   "0xd08\0"                          /* A72 part number */
57 
58 #define TYPE7_STRINGS                              \
59   "L1 Instruction\0"                 /* L1I  */    \
60   "L1 Data\0"                        /* L1D  */    \
61   "L2\0"                             /* L2   */
62 
63 #define TYPE9_STRINGS                              \
64   "PCIE_SLOT0\0"                     /* Slot0 */   \
65   "PCIE_SLOT1\0"                     /* Slot1 */   \
66   "PCIE_SLOT2\0"                     /* Slot2 */   \
67   "PCIE_SLOT3\0"                     /* Slot3 */
68 
69 #define TYPE16_STRINGS                             \
70   "\0"                               /* nothing */
71 
72 #define TYPE17_STRINGS                                       \
73   "RIGHT SIDE\0"                     /* location */          \
74   "BANK 0\0"                         /* bank description */
75 
76 #define TYPE19_STRINGS                             \
77   "\0"                               /* nothing */
78 
79 #define TYPE32_STRINGS                             \
80   "\0"                               /* nothing */
81 
82 
83 //
84 // Type definition and contents of the default SMBIOS table.
85 // This table covers only the minimum structures required by
86 // the SMBIOS specification (section 6.2, version 3.0)
87 //
88 #pragma pack(1)
89 typedef struct {
90   SMBIOS_TABLE_TYPE0 Base;
91   INT8              Strings[sizeof(TYPE0_STRINGS)];
92 } ARM_TYPE0;
93 
94 typedef struct {
95   SMBIOS_TABLE_TYPE1 Base;
96   UINT8              Strings[sizeof(TYPE1_STRINGS)];
97 } ARM_TYPE1;
98 
99 typedef struct {
100   SMBIOS_TABLE_TYPE2 Base;
101   UINT8              Strings[sizeof(TYPE2_STRINGS)];
102 } ARM_TYPE2;
103 
104 typedef struct {
105   SMBIOS_TABLE_TYPE3 Base;
106   UINT8              Strings[sizeof(TYPE3_STRINGS)];
107 } ARM_TYPE3;
108 
109 typedef struct {
110   SMBIOS_TABLE_TYPE4 Base;
111   UINT8              Strings[sizeof(TYPE4_STRINGS)];
112 } ARM_TYPE4;
113 
114 typedef struct {
115   SMBIOS_TABLE_TYPE7 Base;
116   UINT8              Strings[sizeof(TYPE7_STRINGS)];
117 } ARM_TYPE7;
118 
119 typedef struct {
120   SMBIOS_TABLE_TYPE9 Base;
121   UINT8              Strings[sizeof(TYPE9_STRINGS)];
122 } ARM_TYPE9;
123 
124 typedef struct {
125   SMBIOS_TABLE_TYPE16 Base;
126   UINT8              Strings[sizeof(TYPE16_STRINGS)];
127 } ARM_TYPE16;
128 
129 typedef struct {
130   SMBIOS_TABLE_TYPE17 Base;
131   UINT8              Strings[sizeof(TYPE17_STRINGS)];
132 } ARM_TYPE17;
133 
134 typedef struct {
135   SMBIOS_TABLE_TYPE19 Base;
136   UINT8              Strings[sizeof(TYPE19_STRINGS)];
137 } ARM_TYPE19;
138 
139 typedef struct {
140   SMBIOS_TABLE_TYPE32 Base;
141   UINT8              Strings[sizeof(TYPE32_STRINGS)];
142 } ARM_TYPE32;
143 
144 // SMBIOS tables often reference each other using
145 // fixed constants, define a list of these constants
146 // for our hardcoded tables
147 enum SMBIOS_REFRENCE_HANDLES {
148   SMBIOS_HANDLE_A57_L1I = 0x1000,
149   SMBIOS_HANDLE_A57_L1D,
150   SMBIOS_HANDLE_A57_L2,
151   SMBIOS_HANDLE_A53_L1I,
152   SMBIOS_HANDLE_A53_L1D,
153   SMBIOS_HANDLE_A53_L2,
154   SMBIOS_HANDLE_MOTHERBOARD,
155   SMBIOS_HANDLE_CHASSIS,
156   SMBIOS_HANDLE_A72_CLUSTER,
157   SMBIOS_HANDLE_A57_CLUSTER,
158   SMBIOS_HANDLE_A53_CLUSTER,
159   SMBIOS_HANDLE_MEMORY,
160   SMBIOS_HANDLE_DIMM
161 };
162 
163 #define SERIAL_LEN 10  //this must be less than the buffer len allocated in the type1 structure
164 
165 #pragma pack()
166 
167 // BIOS information (section 7.1)
168 STATIC ARM_TYPE0 mArmDefaultType0 = {
169   {
170     { // SMBIOS_STRUCTURE Hdr
171       EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
172       sizeof (SMBIOS_TABLE_TYPE0),      // UINT8 Length
173       SMBIOS_HANDLE_PI_RESERVED,
174     },
175     1,     // SMBIOS_TABLE_STRING       Vendor
176     2,     // SMBIOS_TABLE_STRING       BiosVersion
177     0xE800,// UINT16                    BiosSegment
178     3,     // SMBIOS_TABLE_STRING       BiosReleaseDate
179     0,     // UINT8                     BiosSize
180     {
181       0,0,0,0,0,0,
182       1, //PCI supported
183       0,
184       1, //PNP supported
185       0,
186       1, //BIOS upgradable
187       0, 0, 0,
188       1, //Boot from CD
189       1, //selectable boot
190     },  // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
191     {      // BIOSCharacteristicsExtensionBytes[2]
192       0x3,
193       0xC,
194     },
195     0,     // UINT8                     SystemBiosMajorRelease
196     0,     // UINT8                     SystemBiosMinorRelease
197     0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease
198     0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease
199   },
200   // Text strings (unformatted area)
201   TYPE0_STRINGS
202 };
203 
204 // System information (section 7.2)
205 STATIC CONST ARM_TYPE1 mArmDefaultType1 = {
206   {
207     { // SMBIOS_STRUCTURE Hdr
208       EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,
209       sizeof(SMBIOS_TABLE_TYPE1),
210       SMBIOS_HANDLE_PI_RESERVED,
211     },
212     1,     //Manufacturer
213     2,     //Product Name
214     3,     //Version
215     4,     //Serial
216     { 0x8a95d198, 0x7f46, 0x11e5, { 0xbf,0x8b,0x08,0x00,0x27,0x04,0xd4,0x8e }},    //UUID
217     6,     //Wakeup type
218     0,     //SKU
219     0,     //Family
220   },
221   // Text strings (unformatted)
222   TYPE1_STRINGS
223 };
224 
225 // Baseboard (section 7.3)
226 STATIC ARM_TYPE2 mArmDefaultType2 = {
227   {
228     { // SMBIOS_STRUCTURE Hdr
229       EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, // UINT8 Type
230       sizeof (SMBIOS_TABLE_TYPE2),           // UINT8 Length
231       SMBIOS_HANDLE_MOTHERBOARD,
232     },
233     1,    //Manufacturer
234     2,    //Product Name
235     3,    //Version
236     4,    //Serial
237     0,    //Asset tag
238     {1},  //motherboard, not replaceable
239     5,    //location of board
240     SMBIOS_HANDLE_CHASSIS,
241     BaseBoardTypeMotherBoard,
242     1,
243     {SMBIOS_HANDLE_A53_CLUSTER}, //,SMBIOS_HANDLE_A53_CLUSTER,SMBIOS_HANDLE_MEMORY},
244   },
245   TYPE2_STRINGS
246 };
247 
248 // Enclosure
249 STATIC CONST ARM_TYPE3 mArmDefaultType3 = {
250   {
251     { // SMBIOS_STRUCTURE Hdr
252       EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, // UINT8 Type
253       sizeof (SMBIOS_TABLE_TYPE3),      // UINT8 Length
254       SMBIOS_HANDLE_CHASSIS,
255     },
256     1,   //Manufacturer
257     4,   //enclosure type (low profile desktop)
258     2,   //version
259     3,   //serial
260     0,   //asset tag
261     ChassisStateUnknown,   //boot chassis state
262     ChassisStateSafe,      //power supply state
263     ChassisStateSafe,      //thermal state
264     ChassisSecurityStatusNone,   //security state
265     {0,0,0,0,}, //OEM defined
266     1,  //1U height
267     1,  //number of power cords
268     0,  //no contained elements
269   },
270   TYPE3_STRINGS
271 };
272 
273 // Processor
274 STATIC CONST ARM_TYPE4 mArmDefaultType4_a72 = {
275   {
276     { // SMBIOS_STRUCTURE Hdr
277       EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
278       sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
279       SMBIOS_HANDLE_A72_CLUSTER,
280     },
281     1, //socket type
282     3, //processor type CPU
283     ProcessorFamilyIndicatorFamily2, //processor family, acquire from field2
284     2, //manufactuer
285     {{0,},{0.}}, //processor id
286     5, //version
287     {0,0,0,0,0,1}, //voltage
288     0, //external clock
289     1200, //max speed
290     1200, //current speed
291     0x41, //status
292     ProcessorUpgradeOther,
293     SMBIOS_HANDLE_A57_L1I, //l1 cache handle
294     SMBIOS_HANDLE_A57_L2, //l2 cache handle
295     0xFFFF, //l3 cache handle
296     0, //serial not set
297     0, //asset not set
298     8, //part number
299     2, //core count in socket
300     2, //enabled core count in socket
301     0, //threads per socket
302     0xEC, // processor characteristics
303     ProcessorFamilyARM, //ARM core
304   },
305   TYPE4_STRINGS
306 };
307 
308 STATIC CONST ARM_TYPE4 mArmDefaultType4_a57 = {
309   {
310     { // SMBIOS_STRUCTURE Hdr
311       EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
312       sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
313       SMBIOS_HANDLE_A57_CLUSTER,
314     },
315     1, //socket type
316     3, //processor type CPU
317     ProcessorFamilyIndicatorFamily2, //processor family, acquire from field2
318     2, //manufactuer
319     {{0,},{0.}}, //processor id
320     3, //version
321     {0,0,0,0,0,1}, //voltage
322     0, //external clock
323     1200, //max speed
324     1200, //current speed
325     0x41, //status
326     ProcessorUpgradeOther,
327     SMBIOS_HANDLE_A57_L1I, //l1 cache handle
328     SMBIOS_HANDLE_A57_L2, //l2 cache handle
329     0xFFFF, //l3 cache handle
330     0, //serial not set
331     0, //asset not set
332     7, //part number
333     2, //core count in socket
334     2, //enabled core count in socket
335     0, //threads per socket
336     0xEC, // processor characteristics
337     ProcessorFamilyARM, //ARM core
338   },
339   TYPE4_STRINGS
340 };
341 
342 STATIC CONST ARM_TYPE4 mArmDefaultType4_a53 = {
343   {
344     {   // SMBIOS_STRUCTURE Hdr
345         EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
346         sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
347         SMBIOS_HANDLE_A53_CLUSTER,
348     },
349     1, //socket type
350     3, //processor type CPU
351     ProcessorFamilyIndicatorFamily2, //processor family, acquire from field2
352     2, //manufactuer
353     {{0,},{0.}}, //processor id
354     4, //version
355     {0,0,0,0,0,1}, //voltage
356     0, //external clock
357     650, //max speed
358     650, //current speed
359     0x41, //status
360     ProcessorUpgradeOther,
361     SMBIOS_HANDLE_A53_L1I, //l1 cache handle
362     SMBIOS_HANDLE_A53_L2, //l2 cache handle
363     0xFFFF, //l3 cache handle
364     0, //serial not set
365     0, //asset not set
366     6, //part number
367     4, //core count in socket
368     4, //enabled core count in socket
369     0, //threads per socket
370     0xEC, // processor characteristics
371     ProcessorFamilyARM, //ARM core
372   },
373   TYPE4_STRINGS
374 };
375 
376 // Cache
377 STATIC CONST ARM_TYPE7 mArmDefaultType7_a57_l1i = {
378   {
379     { // SMBIOS_STRUCTURE Hdr
380       EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
381       sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
382       SMBIOS_HANDLE_A57_L1I,
383     },
384     1,
385     0x380, //L1 enabled, unknown WB
386     48, //48k i cache max
387     48, //48k installed
388     {0,1}, //SRAM type
389     {0,1}, //SRAM type
390     0, //unkown speed
391     CacheErrorParity, //parity checking
392     CacheTypeInstruction, //instruction cache
393     CacheAssociativityOther, //three way
394   },
395   TYPE7_STRINGS
396 };
397 
398 STATIC CONST ARM_TYPE7 mArmDefaultType7_a53_l1i = {
399   {
400     { // SMBIOS_STRUCTURE Hdr
401       EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
402       sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
403       SMBIOS_HANDLE_A53_L1I,
404     },
405     1,
406     0x380, //L1 enabled, unknown WB
407     32, //32k i cache max
408     32, //32k installed
409     {0,1}, //SRAM type
410     {0,1}, //SRAM type
411     0, //unkown speed
412     CacheErrorParity, //parity checking
413     CacheTypeInstruction, //instruction cache
414     CacheAssociativity2Way, //two way
415   },
416   TYPE7_STRINGS
417 };
418 
419 STATIC CONST ARM_TYPE7 mArmDefaultType7_a57_l1d = {
420   {
421     { // SMBIOS_STRUCTURE Hdr
422       EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
423       sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
424       SMBIOS_HANDLE_A57_L1D,
425     },
426     2,
427     0x180, //L1 enabled, WB
428     32, //32k d cache max
429     32, //32k installed
430     {0,1}, //SRAM type
431     {0,1}, //SRAM type
432     0, //unkown speed
433     CacheErrorSingleBit, //ECC checking
434     CacheTypeData, //instruction cache
435     CacheAssociativity2Way, //two way associative
436   },
437   TYPE7_STRINGS
438 };
439 
440 STATIC CONST ARM_TYPE7 mArmDefaultType7_a53_l1d = {
441   {
442     { // SMBIOS_STRUCTURE Hdr
443       EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
444       sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
445       SMBIOS_HANDLE_A53_L1D,
446     },
447     2,
448     0x180, //L1 enabled, WB
449     32, //32k d cache max
450     32, //32k installed
451     {0,1}, //SRAM type
452     {0,1}, //SRAM type
453     0, //unkown speed
454     CacheErrorSingleBit, //ECC checking
455     CacheTypeData, //instruction cache
456     CacheAssociativity4Way, //four way associative
457   },
458   TYPE7_STRINGS
459 };
460 
461 STATIC CONST ARM_TYPE7 mArmDefaultType7_a57_l2 = {
462   {
463     { // SMBIOS_STRUCTURE Hdr
464       EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
465       sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
466       SMBIOS_HANDLE_A57_L2,
467     },
468     3,
469     0x181, //L2 enabled, WB
470     2048, //2M d cache max
471     2048, //2M installed
472     {0,1}, //SRAM type
473     {0,1}, //SRAM type
474     0, //unkown speed
475     CacheErrorSingleBit, //ECC checking
476     CacheTypeUnified, //instruction cache
477     CacheAssociativity16Way, //16 way associative
478   },
479   TYPE7_STRINGS
480 };
481 
482 STATIC CONST ARM_TYPE7 mArmDefaultType7_a53_l2 = {
483   {
484     { // SMBIOS_STRUCTURE Hdr
485       EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
486       sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
487       SMBIOS_HANDLE_A53_L2,
488     },
489     3,
490     0x181, //L2 enabled, WB
491     1024, //1M D cache max
492     1024, //1M installed
493     {0,1}, //SRAM type
494     {0,1}, //SRAM type
495     0, //unkown speed
496     CacheErrorSingleBit, //ECC checking
497     CacheTypeUnified, //instruction cache
498     CacheAssociativity16Way, //16 way associative
499   },
500   TYPE7_STRINGS
501 };
502 
503 // Slots
504 STATIC CONST ARM_TYPE9 mArmDefaultType9_0 = {
505   {
506     { // SMBIOS_STRUCTURE Hdr
507       EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
508       sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
509       SMBIOS_HANDLE_PI_RESERVED,
510     },
511     1, //slot 0
512     SlotTypePciExpressGen2X4,
513     SlotDataBusWidth1X,
514     SlotUsageUnknown,
515     SlotLengthShort,
516     0,
517     {1}, //unknown
518     {1,0,1},  //PME and SMBUS
519     0,
520     2,
521     1,
522   },
523   TYPE9_STRINGS
524 };
525 
526 STATIC CONST ARM_TYPE9 mArmDefaultType9_1 = {
527   {
528     { // SMBIOS_STRUCTURE Hdr
529       EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
530       sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
531       SMBIOS_HANDLE_PI_RESERVED,
532     },
533     1, //slot 0
534     SlotTypePciExpressGen2X4,
535     SlotDataBusWidth1X,
536     SlotUsageUnknown,
537     SlotLengthShort,
538     0,
539     {1},
540     {1,0,1}, //PME and SMBUS
541     0,
542     2,
543     2,
544   },
545   TYPE9_STRINGS
546 };
547 
548 STATIC CONST ARM_TYPE9 mArmDefaultType9_2 = {
549   {
550     { // SMBIOS_STRUCTURE Hdr
551       EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
552       sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
553       SMBIOS_HANDLE_PI_RESERVED,
554     },
555     1, //slot 0
556     SlotTypePciExpressGen2X8,
557     SlotDataBusWidth4X,
558     SlotUsageUnknown,
559     SlotLengthShort,
560     0,
561     {1},
562     {1,0,1}, //PME and SMBUS
563     0,
564     2,
565     3,
566   },
567   TYPE9_STRINGS
568 };
569 
570 STATIC CONST ARM_TYPE9 mArmDefaultType9_3 = {
571   {
572     { // SMBIOS_STRUCTURE Hdr
573       EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
574       sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
575       SMBIOS_HANDLE_PI_RESERVED,
576     },
577     1, //slot 0
578     SlotTypePciExpressGen2X16,
579     SlotDataBusWidth4X,
580     SlotUsageUnknown,
581     SlotLengthShort,
582     0,
583     {1},
584     {1,0,1}, //PME and SMBUS
585     0,
586     2,
587     0xc,
588   },
589   TYPE9_STRINGS
590 };
591 
592 // Memory array
593 STATIC CONST ARM_TYPE16 mArmDefaultType16 = {
594   {
595     { // SMBIOS_STRUCTURE Hdr
596       EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, // UINT8 Type
597       sizeof (SMBIOS_TABLE_TYPE16),          // UINT8 Length
598       SMBIOS_HANDLE_MEMORY,
599     },
600     MemoryArrayLocationSystemBoard, //on motherboard
601     MemoryArrayUseSystemMemory,     //system RAM
602     MemoryErrorCorrectionNone,      //Juno doesn't have ECC RAM
603     0x800000, //8GB
604     0xFFFE,   //No error information structure
605     0x1,      //soldered memory
606   },
607   TYPE16_STRINGS
608 };
609 
610 // Memory device
611 STATIC CONST ARM_TYPE17 mArmDefaultType17 = {
612   {
613     { // SMBIOS_STRUCTURE Hdr
614       EFI_SMBIOS_TYPE_MEMORY_DEVICE, // UINT8 Type
615       sizeof (SMBIOS_TABLE_TYPE17),  // UINT8 Length
616       SMBIOS_HANDLE_DIMM,
617     },
618     SMBIOS_HANDLE_MEMORY, //array to which this module belongs
619     0xFFFE,               //no errors
620     64, //single DIMM, no ECC is 64bits (for ecc this would be 72)
621     64, //data width of this device (64-bits)
622     0x2000, //8GB
623     0x0B,   //row of chips
624     0,      //not part of a set
625     1,      //right side of board
626     2,      //bank 0
627 //  MemoryTypeLpddr3, //LP DDR3, isn't defined yet
628     MemoryTypeDdr3,                  //LP DDR3
629     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, //unbuffered
630     1600,                            //1600Mhz DDR
631     0, //varies between diffrent production runs
632     0, //serial
633     0, //asset tag
634     0, //part number
635     0, //rank
636   },
637   TYPE17_STRINGS
638 };
639 
640 // Memory array mapped address, this structure
641 // is overridden by InstallMemoryStructure
642 STATIC CONST ARM_TYPE19 mArmDefaultType19 = {
643   {
644     {  // SMBIOS_STRUCTURE Hdr
645       EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS, // UINT8 Type
646       sizeof (SMBIOS_TABLE_TYPE19),                // UINT8 Length
647       SMBIOS_HANDLE_PI_RESERVED,
648     },
649     0xFFFFFFFF, //invalid, look at extended addr field
650     0xFFFFFFFF,
651     SMBIOS_HANDLE_DIMM, //handle
652     1,
653     0x080000000,        //starting addr of first 2GB
654     0x100000000,        //ending addr of first 2GB
655   },
656   TYPE19_STRINGS
657 };
658 
659 // System boot info
660 STATIC CONST ARM_TYPE32 mArmDefaultType32 = {
661   {
662     { // SMBIOS_STRUCTURE Hdr
663       EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, // UINT8 Type
664       sizeof (SMBIOS_TABLE_TYPE32),            // UINT8 Length
665       SMBIOS_HANDLE_PI_RESERVED,
666     },
667     {0,0,0,0,0,0},                             //reserved
668     BootInformationStatusNoError,
669   },
670   TYPE32_STRINGS
671 };
672 
673 STATIC CONST VOID *DefaultCommonTables[]=
674 {
675   &mArmDefaultType0,
676   &mArmDefaultType1,
677   &mArmDefaultType2,
678   &mArmDefaultType3,
679   &mArmDefaultType7_a53_l1i,
680   &mArmDefaultType7_a53_l1d,
681   &mArmDefaultType7_a53_l2,
682   &mArmDefaultType4_a53,
683   &mArmDefaultType9_0,
684   &mArmDefaultType9_1,
685   &mArmDefaultType9_2,
686   &mArmDefaultType9_3,
687   &mArmDefaultType16,
688   &mArmDefaultType17,
689 //    &mArmDefaultType19, //memory range type 19 dynamically generated
690   &mArmDefaultType32,
691   NULL
692 };
693 
694 STATIC CONST VOID *DefaultTablesR0R1[]=
695 {
696   &mArmDefaultType7_a57_l1i,
697   &mArmDefaultType7_a57_l1d,
698   &mArmDefaultType7_a57_l2,
699   &mArmDefaultType4_a57,
700   NULL
701 };
702 
703 STATIC CONST VOID *DefaultTablesR2[]=
704 {
705   &mArmDefaultType7_a57_l1i, // Cache layout is the same on the A72 vs A57
706   &mArmDefaultType7_a57_l1d,
707   &mArmDefaultType7_a57_l2,
708   &mArmDefaultType4_a72,
709   NULL
710 };
711 
712 
713 /**
714    Installs a memory descriptor (type19) for the given address range
715 
716    @param  Smbios               SMBIOS protocol
717 
718 **/
719 EFI_STATUS
InstallMemoryStructure(IN EFI_SMBIOS_PROTOCOL * Smbios,IN UINT64 StartingAddress,IN UINT64 RegionLength)720 InstallMemoryStructure (
721   IN EFI_SMBIOS_PROTOCOL       *Smbios,
722   IN UINT64                    StartingAddress,
723   IN UINT64                    RegionLength
724   )
725 {
726   EFI_SMBIOS_HANDLE         SmbiosHandle;
727   ARM_TYPE19                MemoryDescriptor;
728   EFI_STATUS                Status = EFI_SUCCESS;
729 
730   CopyMem( &MemoryDescriptor, &mArmDefaultType19, sizeof(ARM_TYPE19));
731 
732   MemoryDescriptor.Base.ExtendedStartingAddress = StartingAddress;
733   MemoryDescriptor.Base.ExtendedEndingAddress = StartingAddress+RegionLength;
734   SmbiosHandle = MemoryDescriptor.Base.Hdr.Handle;
735 
736   Status = Smbios->Add (
737     Smbios,
738     NULL,
739     &SmbiosHandle,
740     (EFI_SMBIOS_TABLE_HEADER*) &MemoryDescriptor
741     );
742   return Status;
743 }
744 
745 /**
746    Install a whole table worth of structructures
747 
748    @parm
749 **/
750 EFI_STATUS
InstallStructures(IN EFI_SMBIOS_PROTOCOL * Smbios,IN CONST VOID * DefaultTables[])751 InstallStructures (
752    IN EFI_SMBIOS_PROTOCOL       *Smbios,
753    IN CONST VOID *DefaultTables[]
754    )
755 {
756     EFI_STATUS                Status = EFI_SUCCESS;
757     EFI_SMBIOS_HANDLE         SmbiosHandle;
758 
759     int TableEntry;
760     for ( TableEntry=0; DefaultTables[TableEntry] != NULL; TableEntry++)
761     {
762 	SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*)DefaultTables[TableEntry])->Handle;
763 	Status = Smbios->Add (
764 	    Smbios,
765 	    NULL,
766 	    &SmbiosHandle,
767 	    (EFI_SMBIOS_TABLE_HEADER*) DefaultTables[TableEntry]
768 	    );
769 	if (EFI_ERROR(Status))
770 	    break;
771     }
772     return Status;
773 }
774 
775 
776 /**
777    Install all structures from the DefaultTables structure
778 
779    @param  Smbios               SMBIOS protocol
780 
781 **/
782 EFI_STATUS
InstallAllStructures(IN EFI_SMBIOS_PROTOCOL * Smbios)783 InstallAllStructures (
784    IN EFI_SMBIOS_PROTOCOL       *Smbios
785    )
786 {
787   EFI_STATUS                Status = EFI_SUCCESS;
788   UINT32                    JunoRevision;
789   VOID                      *ExtraTables = DefaultTablesR0R1;
790 
791   GetJunoRevision(JunoRevision);
792 
793   // Fixup some table values
794   mArmDefaultType0.Base.SystemBiosMajorRelease = (PcdGet32 ( PcdFirmwareRevision ) >> 16) & 0xFF;
795   mArmDefaultType0.Base.SystemBiosMinorRelease = PcdGet32 ( PcdFirmwareRevision ) & 0xFF;
796   if ( JunoRevision == JUNO_REVISION_R1 )
797   {
798     mArmDefaultType2.Base.Version = 6;
799   }
800   else if ( JunoRevision == JUNO_REVISION_R2 )
801   {
802     mArmDefaultType2.Base.Version = 7;
803     ExtraTables=DefaultTablesR2;
804   }
805 
806   //
807   // Add all Juno table entries
808   //
809   Status=InstallStructures (Smbios,DefaultCommonTables);
810   ASSERT_EFI_ERROR (Status);
811 
812   Status=InstallStructures (Smbios,ExtraTables);
813   ASSERT_EFI_ERROR (Status);
814 
815   // Generate memory descriptors for the two memory ranges we know about
816   Status = InstallMemoryStructure ( Smbios, PcdGet64 (PcdSystemMemoryBase), PcdGet64 (PcdSystemMemorySize));
817   ASSERT_EFI_ERROR (Status);
818   Status = InstallMemoryStructure ( Smbios, ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE, ARM_JUNO_EXTRA_SYSTEM_MEMORY_SZ);
819   ASSERT_EFI_ERROR (Status);
820 
821   return Status;
822 }
823 
824 /**
825    Installs SMBIOS information for ARM platforms
826 
827    @param ImageHandle     Module's image handle
828    @param SystemTable     Pointer of EFI_SYSTEM_TABLE
829 
830    @retval EFI_SUCCESS    Smbios data successfully installed
831    @retval Other          Smbios data was not installed
832 
833 **/
834 EFI_STATUS
835 EFIAPI
SmbiosTablePublishEntry(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)836 SmbiosTablePublishEntry (
837   IN EFI_HANDLE           ImageHandle,
838   IN EFI_SYSTEM_TABLE     *SystemTable
839   )
840 {
841   EFI_STATUS                Status;
842   EFI_SMBIOS_PROTOCOL       *Smbios;
843 
844   //
845   // Find the SMBIOS protocol
846   //
847   Status = gBS->LocateProtocol (
848     &gEfiSmbiosProtocolGuid,
849     NULL,
850     (VOID**)&Smbios
851     );
852   if (EFI_ERROR (Status)) {
853     return Status;
854   }
855 
856   Status = InstallAllStructures (Smbios);
857 
858   return Status;
859 }
860