1 /*
2 * Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 #if !defined(__i386__) && !defined(__x86_64__)
main(void)10 int main(void)
11 {
12 fprintf(stderr, "Unsupported architecture\n");
13 return EXIT_FAILURE;
14 }
15 #else
16
17 #include <pci/pci.h>
18 #include <sys/io.h>
19
20 #define D_LCK (1 << 4)
21 #define D_OPEN (1 << 6)
22
check_smram(struct pci_dev * northbridge,int offset)23 int check_smram(struct pci_dev *northbridge, int offset)
24 {
25 unsigned char smram_value;
26 int code = EXIT_SUCCESS;
27
28 smram_value = pci_read_byte(northbridge, offset);
29
30 if (smram_value & D_OPEN) {
31 fprintf(stderr, "FAIL: D_OPEN is set\n");
32 code = EXIT_FAILURE;
33 } else {
34 printf("ok: D_OPEN is unset\n");
35 }
36
37 if (smram_value & D_LCK) {
38 printf("ok: D_LCK is set\n");
39 } else {
40 fprintf(stderr, "FAIL: D_LCK is unset\n");
41 code = EXIT_FAILURE;
42 }
43
44 return code;
45 }
46
guess_offset(struct pci_dev * northbridge)47 int guess_offset(struct pci_dev *northbridge)
48 {
49 unsigned int id;
50 int offset = 0;
51
52 id = pci_read_word(northbridge, 2);
53 switch (id) {
54 case 0xa010:
55 printf("Detected Pineview Mobile\n");
56 offset = 0x9d;
57 break;
58 case 0x0100:
59 printf("Detected Sandybridge Desktop\n");
60 offset = 0x88;
61 break;
62 case 0x0104:
63 printf("Detected Sandybridge Mobile\n");
64 offset = 0x88;
65 break;
66 case 0x0154:
67 printf("Detected Ivybridge Mobile\n");
68 offset = 0x88;
69 break;
70 case 0x0c04:
71 printf("Detected Haswell Mobile\n");
72 offset = 0x88;
73 break;
74 case 0x0a04:
75 printf("Detected Haswell ULT\n");
76 offset = 0x88;
77 break;
78 case 0x0f00:
79 printf("Detected Baytrail, skipping test\n");
80 exit(EXIT_SUCCESS);
81 case 0x1604:
82 printf("Detected Broadwell ULT\n");
83 offset = 0x88;
84 break;
85 case 0x1904:
86 case 0x190c:
87 case 0x1910:
88 case 0x1918:
89 case 0x1924:
90 printf("Detected Sky lake\n");
91 offset = 0x88;
92 break;
93 case 0x31f0:
94 printf("Detected Gemini lake(uses SMRR).. skipping test\n");
95 exit(EXIT_SUCCESS);
96 break;
97 case 0x3e34:
98 case 0x3e35:
99 printf("Detected Whiskey lake\n");
100 offset = 0x88;
101 break;
102 case 0x3ed0:
103 printf("Detected Coffee lake\n");
104 offset = 0x88;
105 break;
106 case 0x5904:
107 case 0x590c:
108 case 0x590f:
109 case 0x5910:
110 case 0x5914:
111 case 0x591f:
112 printf("Detected Kaby lake\n");
113 offset = 0x88;
114 break;
115 case 0x5a02:
116 case 0x5a04:
117 printf("Detected Cannon lake\n");
118 offset = 0x88;
119 break;
120 case 0x5af0:
121 printf("Detected Apollo lake(uses SMRR).. skipping test\n");
122 exit(EXIT_SUCCESS);
123 break;
124 default:
125 fprintf(stderr, "FAIL: unknown Northbridge 0x%04x\n", id);
126 exit(1);
127 }
128
129 return offset;
130 }
131
main(int argc,char * argv[])132 int main(int argc, char *argv[])
133 {
134 int offset;
135 struct pci_access *handle;
136 struct pci_dev *device;
137
138 handle = pci_alloc();
139 if (!handle) {
140 fprintf(stderr, "Failed to allocate PCI resource.\n");
141 return EXIT_FAILURE;
142 }
143 pci_init(handle);
144
145 device = pci_get_dev(handle, 0, 0, 0, 0);
146 if (!device) {
147 fprintf(stderr, "Failed to fetch PCI device.\n");
148 return EXIT_FAILURE;
149 }
150
151 if (argc > 1) {
152 offset = strtoul(argv[1], NULL, 0);
153 } else {
154 offset = guess_offset(device);
155 }
156 printf("Using SMRAM offset 0x%02x:\n", offset);
157
158 return check_smram(device, offset);
159 }
160
161 #endif /* x86 */
162