• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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