Skip to content

Commit 18f5358

Browse files
committed
dev: loop over CPU nodes on disabling memory protection
DEV is specific to a northbridge, so there are multiple of them on systems with several CPU sockets. 0x18 is the device number of the first one with the rest using successive numbers (0x19, 0x1A, etc.). Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
1 parent 97b94fc commit 18f5358

File tree

2 files changed

+52
-29
lines changed

2 files changed

+52
-29
lines changed

dev.c

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,67 +20,89 @@
2020
#include <pci.h>
2121
#include <dev.h>
2222

23-
u32 dev_locate(void)
23+
/*
24+
* There are only 5 bits (0x00..0x1f) for PCI slot number (see definition of
25+
* PCI_DEVFN) and we start at 0x18 (DEV_PCI_DEVICE), so there is hard upper
26+
* limit on how many nodes can exist.
27+
*/
28+
#define MAX_CPU_NODES 8
29+
30+
u32 dev_locate(u8 cpu_node)
2431
{
2532
return pci_locate(DEV_PCI_BUS,
26-
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION));
33+
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION));
2734
}
2835

29-
u32 dev_read(u32 dev_cap, u32 function, u32 index)
36+
u32 dev_read(u8 cpu_node, u32 dev_cap, u32 function, u32 index)
3037
{
3138
u32 value;
3239

3340
pci_write(0, DEV_PCI_BUS,
34-
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION),
41+
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION),
3542
dev_cap + DEV_OP_OFFSET,
3643
4,
3744
(u32)(((function & 0xff) << 8) + (index & 0xff)));
3845

3946
pci_read(0, DEV_PCI_BUS,
40-
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION),
47+
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION),
4148
dev_cap + DEV_DATA_OFFSET,
4249
4, &value);
4350

4451
return value;
4552
}
4653

47-
void dev_write(u32 dev, u32 function, u32 index, u32 value)
54+
void dev_write(u8 cpu_node, u32 dev, u32 function, u32 index, u32 value)
4855
{
4956
pci_write(0, DEV_PCI_BUS,
50-
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION),
57+
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION),
5158
dev + DEV_OP_OFFSET,
5259
4,
5360
(u32)(((function & 0xff) << 8) + (index & 0xff)) );
5461

5562
pci_write(0, DEV_PCI_BUS,
56-
PCI_DEVFN(DEV_PCI_DEVICE, DEV_PCI_FUNCTION),
63+
PCI_DEVFN(DEV_PCI_DEVICE + cpu_node, DEV_PCI_FUNCTION),
5764
dev + DEV_DATA_OFFSET,
5865
4, value);
5966
}
6067

61-
void dev_disable_sl(u32 dev)
68+
void dev_disable_sl(u8 cpu_node, u32 dev)
6269
{
63-
u32 dev_cr = dev_read(dev, DEV_CR, 0);
64-
dev_write(dev, DEV_CR, 0, dev_cr & ~(DEV_CR_SL_DEV_EN_MASK));
70+
u32 dev_cr = dev_read(cpu_node, dev, DEV_CR, 0);
71+
dev_write(cpu_node, dev, DEV_CR, 0, dev_cr & ~(DEV_CR_SL_DEV_EN_MASK));
6572
}
6673

6774
void disable_memory_protection(void)
6875
{
69-
u32 dev_cap, sldev;
70-
71-
dev_cap = dev_locate();
72-
if (dev_cap) {
73-
/* Older families with remains of DEV */
74-
dev_disable_sl(dev_cap);
75-
return;
76-
}
77-
78-
/* Fam 17h uses different DMA protection control register */
79-
pci_read(0, MCH_PCI_BUS,
80-
PCI_DEVFN(MCH_PCI_DEVICE, MCH_PCI_FUNCTION),
81-
MEMPROT_CR, 4, &sldev);
82-
pci_write(0, MCH_PCI_BUS,
83-
PCI_DEVFN(MCH_PCI_DEVICE, MCH_PCI_FUNCTION),
84-
MEMPROT_CR, 4, sldev & ~(MEMPROT_EN));
76+
u32 dev_cap, sldev, vid_did;
77+
u8 cpu_node = 0;
78+
79+
dev_cap = dev_locate(cpu_node);
80+
if (dev_cap) {
81+
/* Older families with remains of DEV */
82+
do {
83+
dev_disable_sl(cpu_node, dev_cap);
84+
85+
cpu_node++;
86+
if (cpu_node == MAX_CPU_NODES)
87+
break;
88+
89+
dev_cap = dev_locate(cpu_node);
90+
} while (dev_cap);
91+
return;
92+
}
93+
94+
/* Fam 17h uses different DMA protection control register */
95+
while (cpu_node < MAX_CPU_NODES &&
96+
pci_read(0, MCH_PCI_BUS,
97+
PCI_DEVFN(MCH_PCI_DEVICE + cpu_node, MCH_PCI_FUNCTION),
98+
VIDDID, 4, &vid_did) == 0 &&
99+
vid_did != 0xffffffffU) {
100+
u8 devfn = PCI_DEVFN(MCH_PCI_DEVICE + cpu_node, MCH_PCI_FUNCTION);
101+
102+
pci_read(0, MCH_PCI_BUS, devfn, MEMPROT_CR, 4, &sldev);
103+
pci_write(0, MCH_PCI_BUS, devfn, MEMPROT_CR, 4, sldev & ~(MEMPROT_EN));
104+
105+
cpu_node++;
106+
}
85107
}
86108

include/dev.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@
3737
#define MCH_PCI_DEVICE 0x18
3838
#define MCH_PCI_FUNCTION 0x0
3939

40+
#define VIDDID 0
4041
#define MEMPROT_CR 0x384
4142

4243
#define MEMPROT_EN (1<<0)
4344

44-
u32 dev_locate(void);
45-
void dev_disable_sl(u32 dev);
45+
u32 dev_locate(u8 cpu_node);
46+
void dev_disable_sl(u8 cpu_node, u32 dev);
4647
void disable_memory_protection(void);
4748

4849
#endif /* __DEV_H__ */

0 commit comments

Comments
 (0)