Home | History | Annotate | Download | only in src
      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