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__) 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 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 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 default: 86 fprintf(stderr, "FAIL: unknown Northbridge 0x%04x\n", id); 87 exit(1); 88 } 89 90 return offset; 91 } 92 93 int main(int argc, char *argv[]) 94 { 95 int offset; 96 struct pci_access *handle; 97 struct pci_dev *device; 98 99 handle = pci_alloc(); 100 if (!handle) { 101 fprintf(stderr, "Failed to allocate PCI resource.\n"); 102 return EXIT_FAILURE; 103 } 104 pci_init(handle); 105 106 device = pci_get_dev(handle, 0, 0, 0, 0); 107 if (!device) { 108 fprintf(stderr, "Failed to fetch PCI device.\n"); 109 return EXIT_FAILURE; 110 } 111 112 if (argc > 1) { 113 offset = strtoul(argv[1], NULL, 0); 114 } else { 115 offset = guess_offset(device); 116 } 117 printf("Using SMRAM offset 0x%02x:\n", offset); 118 119 return check_smram(device, offset); 120 } 121 122 #endif /* x86 */ 123