inteltool: added more device IDs
[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 "inteltool.h"
24
25 /*
26  * (G)MCH MMIO Config Space
27  */
28 int print_mchbar(struct pci_dev *nb, struct pci_access *pacc)
29 {
30         int i, size = (16 * 1024);
31         volatile uint8_t *mchbar;
32         uint64_t mchbar_phys;
33         struct pci_dev *nb_device6; /* "overflow device" on i865 */
34         uint16_t pcicmd6;
35
36         printf("\n============= MCHBAR ============\n\n");
37
38         switch (nb->device_id) {
39         case PCI_DEVICE_ID_INTEL_82865:
40                 /*
41                  * On i865, the memory access enable/disable bit (MCHBAREN on
42                  * i945/i965) is not in the MCHBAR (i945/i965) register but in
43                  * the PCICMD6 register. BAR6 and PCICMD6 reside on device 6.
44                  *
45                  * The actual base address is in BAR6 on i865 where on
46                  * i945/i965 the base address is in MCHBAR.
47                  */
48                 nb_device6 = pci_get_dev(pacc, 0, 0, 0x06, 0);  /* Device 6 */
49                 mchbar_phys = pci_read_long(nb_device6, 0x10);  /* BAR6 */
50                 pcicmd6 = pci_read_long(nb_device6, 0x04);      /* PCICMD6 */
51
52                 /* Try to enable Memory Access Enable (MAE). */
53                 if (!(pcicmd6 & (1 << 1))) {
54                         printf("Access to BAR6 is currently disabled, "
55                                "attempting to enable.\n");
56                         pci_write_long(nb_device6, 0x04, pcicmd6 | (1 << 1));
57                         if (pci_read_long(nb_device6, 0x04) & (1 << 1))
58                                 printf("Enabled successfully.\n");
59                         else
60                                 printf("Enable FAILED!\n");
61                 }
62                 mchbar_phys &= 0xfffff000; /* Bits 31:12 from BAR6 */
63                 break;
64         case PCI_DEVICE_ID_INTEL_82915:
65         case PCI_DEVICE_ID_INTEL_82945GM:
66         case PCI_DEVICE_ID_INTEL_82945GSE:
67         case PCI_DEVICE_ID_INTEL_82945P:
68         case PCI_DEVICE_ID_INTEL_82975X:
69                 mchbar_phys = pci_read_long(nb, 0x44) & 0xfffffffe;
70                 break;
71         case PCI_DEVICE_ID_INTEL_PM965:
72         case PCI_DEVICE_ID_INTEL_82Q35:
73         case PCI_DEVICE_ID_INTEL_82G33:
74         case PCI_DEVICE_ID_INTEL_82Q33:
75                 mchbar_phys = pci_read_long(nb, 0x48) & 0xfffffffe;
76                 mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32;
77                 break;
78         case PCI_DEVICE_ID_INTEL_Q965:
79         case PCI_DEVICE_ID_INTEL_ATOM_DXXX:
80         case PCI_DEVICE_ID_INTEL_ATOM_NXXX:
81                 mchbar_phys = pci_read_long(nb, 0x48);
82
83                 /* Test if bit 0 of the MCHBAR reg is 1 to enable memory reads.
84                  * If it isn't, try to set it. This may fail, because there is
85                  * some bit that locks that bit, and isn't in the public
86                  * datasheets.
87                  */
88
89                 if(!(mchbar_phys & 1))
90                 {
91                         printf("Access to the MCHBAR is currently disabled, "\
92                                                 "attempting to enable.\n");
93                         mchbar_phys |= 0x1;
94                         pci_write_long(nb, 0x48, mchbar_phys);
95                         if(pci_read_long(nb, 0x48) & 1)
96                                 printf("Enabled successfully.\n");
97                         else
98                                 printf("Enable FAILED!\n");
99                 }
100                 mchbar_phys &= 0xfffffffe;
101                 mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32;
102                 break;
103         case PCI_DEVICE_ID_INTEL_82443LX:
104         case PCI_DEVICE_ID_INTEL_82443BX:
105         case PCI_DEVICE_ID_INTEL_82810:
106         case PCI_DEVICE_ID_INTEL_82810E_MC:
107         case PCI_DEVICE_ID_INTEL_82810DC:
108         case PCI_DEVICE_ID_INTEL_82830M:
109                 printf("This northbridge does not have MCHBAR.\n");
110                 return 1;
111         case PCI_DEVICE_ID_INTEL_GS45:
112         case PCI_DEVICE_ID_INTEL_X44:
113         case PCI_DEVICE_ID_INTEL_32X0:
114                 mchbar_phys = pci_read_long(nb, 0x48) & 0xfffffffe;
115                 mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32;
116                 break;
117         default:
118                 printf("Error: Dumping MCHBAR on this northbridge is not (yet) supported.\n");
119                 return 1;
120         }
121
122         mchbar = map_physical(mchbar_phys, size);
123
124         if (mchbar == NULL) {
125                 if (nb->device_id == PCI_DEVICE_ID_INTEL_82865)
126                         perror("Error mapping BAR6");
127                 else
128                         perror("Error mapping MCHBAR");
129                 exit(1);
130         }
131
132         if (nb->device_id == PCI_DEVICE_ID_INTEL_82865)
133                 printf("BAR6 = 0x%08llx (MEM)\n\n", mchbar_phys);
134         else
135                 printf("MCHBAR = 0x%08llx (MEM)\n\n", mchbar_phys);
136
137         for (i = 0; i < size; i += 4) {
138                 if (*(uint32_t *)(mchbar + i))
139                         printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(mchbar+i));
140         }
141
142         unmap_physical((void *)mchbar, size);
143         return 0;
144 }
145
146