Fix warnings in coreboot utilities.
[coreboot.git] / util / inteltool / memory.c
1 /*
2  * inteltool - dump all registers on an Intel CPU + chipset based system.
3  *
4  * Copyright (C) 2008-2010 by coresystems GmbH
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <inttypes.h>
24 #include "inteltool.h"
25
26 /*
27  * (G)MCH MMIO Config Space
28  */
29 int print_mchbar(struct pci_dev *nb, struct pci_access *pacc)
30 {
31         int i, size = (16 * 1024);
32         volatile uint8_t *mchbar;
33         uint64_t mchbar_phys;
34         struct pci_dev *nb_device6; /* "overflow device" on i865 */
35         uint16_t pcicmd6;
36
37         printf("\n============= MCHBAR ============\n\n");
38
39         switch (nb->device_id) {
40         case PCI_DEVICE_ID_INTEL_82865:
41                 /*
42                  * On i865, the memory access enable/disable bit (MCHBAREN on
43                  * i945/i965) is not in the MCHBAR (i945/i965) register but in
44                  * the PCICMD6 register. BAR6 and PCICMD6 reside on device 6.
45                  *
46                  * The actual base address is in BAR6 on i865 where on
47                  * i945/i965 the base address is in MCHBAR.
48                  */
49                 nb_device6 = pci_get_dev(pacc, 0, 0, 0x06, 0);  /* Device 6 */
50                 mchbar_phys = pci_read_long(nb_device6, 0x10);  /* BAR6 */
51                 pcicmd6 = pci_read_long(nb_device6, 0x04);      /* PCICMD6 */
52
53                 /* Try to enable Memory Access Enable (MAE). */
54                 if (!(pcicmd6 & (1 << 1))) {
55                         printf("Access to BAR6 is currently disabled, "
56                                "attempting to enable.\n");
57                         pci_write_long(nb_device6, 0x04, pcicmd6 | (1 << 1));
58                         if (pci_read_long(nb_device6, 0x04) & (1 << 1))
59                                 printf("Enabled successfully.\n");
60                         else
61                                 printf("Enable FAILED!\n");
62                 }
63                 mchbar_phys &= 0xfffff000; /* Bits 31:12 from BAR6 */
64                 break;
65         case PCI_DEVICE_ID_INTEL_82915:
66         case PCI_DEVICE_ID_INTEL_82945GM:
67         case PCI_DEVICE_ID_INTEL_82945GSE:
68         case PCI_DEVICE_ID_INTEL_82945P:
69         case PCI_DEVICE_ID_INTEL_82975X:
70                 mchbar_phys = pci_read_long(nb, 0x44) & 0xfffffffe;
71                 break;
72         case PCI_DEVICE_ID_INTEL_PM965:
73         case PCI_DEVICE_ID_INTEL_82Q35:
74         case PCI_DEVICE_ID_INTEL_82G33:
75         case PCI_DEVICE_ID_INTEL_82Q33:
76                 mchbar_phys = pci_read_long(nb, 0x48) & 0xfffffffe;
77                 mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32;
78                 break;
79         case PCI_DEVICE_ID_INTEL_Q965:
80         case PCI_DEVICE_ID_INTEL_ATOM_DXXX:
81         case PCI_DEVICE_ID_INTEL_ATOM_NXXX:
82                 mchbar_phys = pci_read_long(nb, 0x48);
83
84                 /* Test if bit 0 of the MCHBAR reg is 1 to enable memory reads.
85                  * If it isn't, try to set it. This may fail, because there is
86                  * some bit that locks that bit, and isn't in the public
87                  * datasheets.
88                  */
89
90                 if(!(mchbar_phys & 1))
91                 {
92                         printf("Access to the MCHBAR is currently disabled, "\
93                                                 "attempting to enable.\n");
94                         mchbar_phys |= 0x1;
95                         pci_write_long(nb, 0x48, mchbar_phys);
96                         if(pci_read_long(nb, 0x48) & 1)
97                                 printf("Enabled successfully.\n");
98                         else
99                                 printf("Enable FAILED!\n");
100                 }
101                 mchbar_phys &= 0xfffffffe;
102                 mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32;
103                 break;
104         case PCI_DEVICE_ID_INTEL_82443LX:
105         case PCI_DEVICE_ID_INTEL_82443BX:
106         case PCI_DEVICE_ID_INTEL_82810:
107         case PCI_DEVICE_ID_INTEL_82810E_MC:
108         case PCI_DEVICE_ID_INTEL_82810DC:
109         case PCI_DEVICE_ID_INTEL_82830M:
110                 printf("This northbridge does not have MCHBAR.\n");
111                 return 1;
112         case PCI_DEVICE_ID_INTEL_GS45:
113         case PCI_DEVICE_ID_INTEL_X44:
114         case PCI_DEVICE_ID_INTEL_32X0:
115                 mchbar_phys = pci_read_long(nb, 0x48) & 0xfffffffe;
116                 mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32;
117                 break;
118         default:
119                 printf("Error: Dumping MCHBAR on this northbridge is not (yet) supported.\n");
120                 return 1;
121         }
122
123         mchbar = map_physical(mchbar_phys, size);
124
125         if (mchbar == NULL) {
126                 if (nb->device_id == PCI_DEVICE_ID_INTEL_82865)
127                         perror("Error mapping BAR6");
128                 else
129                         perror("Error mapping MCHBAR");
130                 exit(1);
131         }
132
133         if (nb->device_id == PCI_DEVICE_ID_INTEL_82865)
134                 printf("BAR6 = 0x%08" PRIx64 " (MEM)\n\n", mchbar_phys);
135         else
136                 printf("MCHBAR = 0x%08" PRIx64 " (MEM)\n\n", mchbar_phys);
137
138         for (i = 0; i < size; i += 4) {
139                 if (*(uint32_t *)(mchbar + i))
140                         printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(mchbar+i));
141         }
142
143         unmap_physical((void *)mchbar, size);
144         return 0;
145 }
146
147