mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
pciereg_cfg*: use assembly to access the mem-mapped cfg space
AMD BKDG for CPU families 10h and later requires that the memory mapped config is always read into or written from al/ax/eax register. Discussed with: kib, alc Reviewed by: kib (earlier version) MFC after: 25 days
This commit is contained in:
parent
a01d461b70
commit
851dbc07af
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=241540
@ -295,6 +295,13 @@ pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus)
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* AMD BIOS And Kernel Developer's Guides for CPU families starting with 10h
|
||||
* have a requirement that all accesses to the memory mapped PCI configuration
|
||||
* space are done using AX class of registers.
|
||||
* Since other vendors do not currently have any contradicting requirements
|
||||
* the AMD access pattern is applied universally.
|
||||
*/
|
||||
#define PCIE_VADDR(base, reg, bus, slot, func) \
|
||||
((base) + \
|
||||
((((bus) & 0xff) << 20) | \
|
||||
@ -317,13 +324,16 @@ pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg,
|
||||
|
||||
switch (bytes) {
|
||||
case 4:
|
||||
data = *(volatile uint32_t *)(va);
|
||||
__asm __volatile("mov %1, %%eax" : "=a" (data)
|
||||
: "m" (*(uint32_t *)va));
|
||||
break;
|
||||
case 2:
|
||||
data = *(volatile uint16_t *)(va);
|
||||
__asm __volatile("movzwl %1, %%eax" : "=a" (data)
|
||||
: "m" (*(uint16_t *)va));
|
||||
break;
|
||||
case 1:
|
||||
data = *(volatile uint8_t *)(va);
|
||||
__asm __volatile("movzbl %1, %%eax" : "=a" (data)
|
||||
: "m" (*(uint8_t *)va));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -344,13 +354,16 @@ pciereg_cfgwrite(int bus, unsigned slot, unsigned func, unsigned reg, int data,
|
||||
|
||||
switch (bytes) {
|
||||
case 4:
|
||||
*(volatile uint32_t *)(va) = data;
|
||||
__asm __volatile("mov %%eax, %0" : "=m" (*(uint32_t *)va)
|
||||
: "a" (data));
|
||||
break;
|
||||
case 2:
|
||||
*(volatile uint16_t *)(va) = data;
|
||||
__asm __volatile("mov %%ax, %0" : "=m" (*(uint16_t *)va)
|
||||
: "a" (data));
|
||||
break;
|
||||
case 1:
|
||||
*(volatile uint8_t *)(va) = data;
|
||||
__asm __volatile("mov %%al, %0" : "=m" (*(uint8_t *)va)
|
||||
: "a" (data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -652,6 +652,14 @@ pciereg_findelem(vm_paddr_t papage)
|
||||
return (elem);
|
||||
}
|
||||
|
||||
/*
|
||||
* AMD BIOS And Kernel Developer's Guides for CPU families starting with 10h
|
||||
* have a requirement that all accesses to the memory mapped PCI configuration
|
||||
* space are done using AX class of registers.
|
||||
* Since other vendors do not currently have any contradicting requirements
|
||||
* the AMD access pattern is applied universally.
|
||||
*/
|
||||
|
||||
static int
|
||||
pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg,
|
||||
unsigned bytes)
|
||||
@ -673,13 +681,16 @@ pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg,
|
||||
|
||||
switch (bytes) {
|
||||
case 4:
|
||||
data = *(volatile uint32_t *)(va);
|
||||
__asm __volatile("mov %1, %%eax" : "=a" (data)
|
||||
: "m" (*(uint32_t *)va));
|
||||
break;
|
||||
case 2:
|
||||
data = *(volatile uint16_t *)(va);
|
||||
__asm __volatile("movzwl %1, %%eax" : "=a" (data)
|
||||
: "m" (*(uint16_t *)va));
|
||||
break;
|
||||
case 1:
|
||||
data = *(volatile uint8_t *)(va);
|
||||
__asm __volatile("movzbl %1, %%eax" : "=a" (data)
|
||||
: "m" (*(uint8_t *)va));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -707,13 +718,16 @@ pciereg_cfgwrite(int bus, unsigned slot, unsigned func, unsigned reg, int data,
|
||||
|
||||
switch (bytes) {
|
||||
case 4:
|
||||
*(volatile uint32_t *)(va) = data;
|
||||
__asm __volatile("mov %%eax, %0" : "=m" (*(uint32_t *)va)
|
||||
: "a" (data));
|
||||
break;
|
||||
case 2:
|
||||
*(volatile uint16_t *)(va) = data;
|
||||
__asm __volatile("mov %%ax, %0" : "=m" (*(uint16_t *)va)
|
||||
: "a" (data));
|
||||
break;
|
||||
case 1:
|
||||
*(volatile uint8_t *)(va) = data;
|
||||
__asm __volatile("mov %%al, %0" : "=m" (*(uint8_t *)va)
|
||||
: "a" (data));
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user